问题是这样的:
    现在有一个程序,没有源码。我需要点击该程序中的表格,弹出右键菜单,然后选择一项,这一项下面有子菜单,我要选子菜单的最后一项,然后点击该项,弹出窗体。
    我现在已经可以在自己的程序中弹出右键菜单啦,但是怎么选择右键菜单中的一项,再选择该项下的子菜单的最后一项,再点击该项?上面的这几步操作,我该怎么编程实现呢?或朝那个方向找资料呢?

解决方案 »

  1.   

    首先你需要用到
      FindWindow 函数来获得另一个程序窗口Handle然后用ChildWindowFromPoint 取得窗口里控件的Handle再用SendMessage 对其发消息来控制它ChildWindowFromPoint 需要控件在其窗口上的坐标可以用Delphi自有的WinSight32程序查看,因为你的程序控制对象是固定的程序所以这些坐标可以事先取得SendMessage发送的消息号要自已查,,
     
    如: sTemp := 'Hello';
         SendMessage(EditHandel,WM_SETTEXT,0,Integer(sTemp));
         SendMessage(wButton,BM_CLICK,0,0);在一个Edit中输入Hello并点击了另一个Button
      

  2.   

    恩,我也建议用发消息的方式
    SendMessage(最后一项的句炳,WM_LBUTTONDOWM,0,0);
      

  3.   

    多谢各位,这个技术我知道的。
    我的问题其实就是,弹出的菜单,
    我发什么消息能够选择弹出菜单的第一项,让他选出子菜单。
    然后我再发消息选子菜单的一项,
    再发什么消息可以让子菜单的一项点击?实际就是,我该发什么消息?或者我该怎么找这些消息?另外窗体句柄的获取我用的是EnumChildWindows,然后在回调函数中根据控件类名找到该句柄。
    现在我不知道弹出菜单是否有句柄呢?菜单中的某一项是否有句柄呢?你们说的edit或者button我都知道的,现在我要操作的是弹出菜单,和选择一项,点击菜单一项。
    这些消息我不知道,也没查到!
      

  4.   

    procedure TForm1.Button1Click(Sender: TObject);
    begin
       keybd_event(91,  0,  KEYEVENTF_EXTENDEDKEY,  0);  //KEYDOWN£?
       keybd_event(91,  0,  KEYEVENTF_EXTENDEDKEY  or  KEYEVENTF_KEYUP,  0);
       sleep(20);
       keybd_event(ord('S'),  0,  KEYEVENTF_EXTENDEDKEY,  0);  //KEYDOWN£?
       keybd_event(ord('S'),  0,  KEYEVENTF_EXTENDEDKEY  or  KEYEVENTF_KEYUP,  0);
       sleep(20);
       keybd_event(ord('c'),  0,  KEYEVENTF_EXTENDEDKEY,  0);  //KEYDOWN£?
       keybd_event(ord('c'),  0,  KEYEVENTF_EXTENDEDKEY  or  KEYEVENTF_KEYUP,  0);
       sleep(20);
       keybd_event(13,  0,  KEYEVENTF_EXTENDEDKEY,  0);  //KEYDOWN£?
       keybd_event(13,  0,  KEYEVENTF_EXTENDEDKEY  or  KEYEVENTF_KEYUP,  0);
    end;
      

  5.   

    不知道这个对你有没有帮助.
    上面的代码是通过开始菜单打开控制面板的.
    其中sleep的时间,在不同的机器上可能不同,可能要做些调整;
      

  6.   

    有啊,在Windows下用键盘模拟鼠标右键是 Shift + F10你弹出 PopoMenu后可以发送 方向键的向上 向下来选择菜单  发送方向键滴 向右键来展开子菜单, 发个Enter键来打开    具体发几次方向键,因为你程序固定可以预先设置好
      

  7.   

    谢谢skertone() ,你的思路我也想到了,确实是可行的。不过我想,会不会有直接的消息可以控制选菜单的某项,点击菜单呢(而不是通过模拟键盘操作)。
      

  8.   

    mouse_event 不好吗,就象你亲手操作
      

  9.   

    看看这个://找到窗体ChildHandle3中第一个Edit
    EditHandle1 := FindWindowEx(ChildHandle3,0,'Edit',nil);
    SendMessage(EditHandle1,WM_SETTEXT,0, IdStr1);//找到下一个Edit
    EditHandle2 := GetWindow(EditHandle1,GW_HWNDNEXT);
    SendMessage(EditHandle2,WM_SETTEXT,0, IdStr2);
      

  10.   

    GW_HWNDFIRST = 0;
      {$EXTERNALSYM GW_HWNDLAST}
      GW_HWNDLAST = 1;
      {$EXTERNALSYM GW_HWNDNEXT}
      GW_HWNDNEXT = 2;
      {$EXTERNALSYM GW_HWNDPREV}
      GW_HWNDPREV = 3;
      {$EXTERNALSYM GW_OWNER}
      GW_OWNER = 4;
      {$EXTERNALSYM GW_CHILD}
      GW_CHILD = 5;
      {$EXTERNALSYM GW_MAX}
      GW_MAX = 5;
      

  11.   

    mouse_event 不好吗,就象你亲手操作这个好,但是我不想控制别人机器的鼠标。因为我会不断循环操作。就造成完全接管了机器鼠标了。to navyfish(深蓝色的鱼):
      我需要的不是向edit发消息,是向弹出菜单发消息。这个该发什么消息呢?而且我也不要修改文本,我要选择菜单一项,和该项的子项,再点击该子项。这个又该发什么消息呢?
      你后面发的是什么东西?是菜单相关的消息吗?
      

  12.   

    to navyfish(深蓝色的鱼):
      你这是遍历窗体的句柄东西,我想问一下,弹出菜单是窗体吗?弹出菜单的某一项是窗体吗?
      

  13.   

    用句柄只能得到菜单项的ID,不能得到句柄.
      AppHD := FindWindow('NoteXPadClass', 'NoteXPad - [需求分析.txt]');
      MenuHD := GetMenu(AppHD);
      SubMenuHD := GetSubMenu(MenuHD, 0);
      MenuItem := GetMenuItemID(SubMenuHD, 2);目前的方法好像只有模拟鼠标操作.
      

  14.   

    事实上只有mouse_event在控制其它程序是最好的,也不用考虑太多的东西,设置位置就可以了,这和你自己反复操作是一样的,你也可以设置一点东西,你自己开始操作就停止模拟操作
    当然,一家之说,高手们说声7~,就当没看见好了。//==========================================================
    // 快使用DELPHI 7,哼哼哈兮
    //==========================================================
      

  15.   

    问题解决(针对主菜单):  AppHD := FindWindow('Notepad', '需求分析.txt - 记事本');
      MenuHD := GetMenu(AppHD);
      SubMenuHD := GetSubMenu(MenuHD, 0);
      MenuItem := GetMenuItemID(SubMenuHD, 1);
      PostMessage(AppHD, WM_COMMAND, MenuItem, 0);弹出菜单类似,但很多都不是通用的WM_COMMAND消息,要具体分析.
      

  16.   

    navyfish(深蓝色的鱼):你的方法我再试试看!
      

  17.   

    考慮一下!
    function TMenu.DispatchCommand(ACommand: Word): Boolean;
    var
      Item: TMenuItem;
    begin
      Result := False;
      Item := FindItem(ACommand, fkCommand);
      if Item <> nil then
      begin
        Item.Click;
        Result := True;
      end;
    end;
      

  18.   

    用Spy++ 或 WinSight32 抓消息,再发送对应消息控制
      

  19.   

    kp1150(小蛛) :你这个怎么用啊?那个程序可能不是delphi写的啊!
     navyfish(深蓝色的鱼):你的最后的方式可行,不过弹出菜单我还没有试!
      

  20.   

    本来是打算把这个问题自己实现以后再结帖的,可惜最近事情很多,没有时间做这个,所以还是先结帖把!
    navyfish(深蓝色的鱼):你的方法最贴近我的要求,以后有时间我还是要详细实现的!
    g961681(PerryWang),skertone() :感谢两位给我提供另一个办法,虽然不是最好,但是很简单,我现在就是暂时用这种方式处理的!
    也感谢其它人的热心参与,我很反对来着有分的处理方式,所以就不给分啦!请理解。