【问题标题】:Getting a Button handle from another application从另一个应用程序获取按钮句柄
【发布时间】:2023-03-19 14:59:01
【问题描述】:

我有一个程序需要将 BM_CLICK 消息发送到另一个应用程序按钮。 我可以获取父窗口句柄,但是当我尝试获取按钮句柄时,如果总是返回 0

我从 Spy++ 获得了按钮标题名称和按钮类型,这似乎是正确的,但我知道我一定是搞错了。下面是我的代码

 public const Int BM_CLICK = 0x00F5;

 [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SendMessage(IntPtr hwnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);



private void button1_Click(object sender, EventArgs e)
{
    Process[] processes = Process.GetProcessesByName("QSXer");

    foreach (Process p in processes)
    {
        ////the Button's Caption is "Send" and it is a "Button".  
        IntPtr ButtonHandle = FindWindowEx(p.MainWindowHandle, IntPtr.Zero, "Button", "Send");
       //ButtonHandle is always zero thats where I think the problem is 
    SendMessage(ButtonHandle, BM_CLICK, IntPtr.Zero, IntPtr.Zero);

    }

}

间谍屏幕截图

【问题讨论】:

    标签: c# winapi sendmessage


    【解决方案1】:

    尝试为窗口文本传递 null 并尝试查找任何按钮:

    IntPtr ButtonHandle = FindWindowEx(p.MainWindowHandle, IntPtr.Zero, "Button", null);
    

    之后,您可以使用第二个参数和一个新的调用来多次获取下一个按钮句柄。

    您能否尝试检查Marshal.GetLastWin32Error 以查看错误结果是什么?

    【讨论】:

    • 嗨,Brian,除非我误解了你的要求,否则我相信类名总是必须是字符串 no?
    • 嗨,Brian,好的,试一试,还是一无所获:-)
    • 嗨布赖恩,p.MainWindowHandle 是有效的我捕获了这样的应用程序标题 button1.text = p.MainWindowTitle 是的,我尝试了“&Send”和“Send”
    • Marshal.GetLastWin32Error 返回什么?我也更改了上面的答案,请再次尝试我的建议。
    • 我捕获了 GetLastWin32Error 并显示 0 MessageBox.Show(Marshal.GetLastWin32Error().ToString());
    【解决方案2】:

    试试这个:

    IntPtr ButtonHandle = FindWindowEx(p.MainWindowHandle, IntPtr.Zero, null, "Send");
    

    【讨论】:

      【解决方案3】:

      你可以这样做:

      //Program finds a window and looks for button in window and clicks it
      
      HWND buttonHandle = 0;
      
      BOOL CALLBACK GetButtonHandle(HWND handle, LPARAM)
      {
          char label[100];
          int size = GetWindowTextA(handle, label, sizeof(label));
          if (strcmp(label, "Send") == 0) // your button name
          {
              buttonHandle = handle;
              cout << "button id is: " << handle << endl;
              return false;
          }
          return true;
      }
      
      int main()
      
      {
          HWND windowHandle = FindWindowA(NULL, "**Your Window Name**");
      
          if (windowHandle == NULL)
          {
              cout << "app isn't open." << endl;
          }
      
          else
          {
              cout << "app is open :) " << endl;
              cout << "ID is: " << windowHandle << endl;
              SetForegroundWindow(windowHandle);
              BOOL ret = EnumChildWindows(windowHandle, GetButtonHandle, 0); //find the button
              cout << buttonHandle << endl;
              if (buttonHandle != 0)
              {
                  LRESULT res = SendMessage(buttonHandle, BM_CLICK, 0, 0);
              }
          }
      }
      

      这应该可以解决问题。

      【讨论】:

        【解决方案4】:

        尝试将项目构建为 x86。我尝试并成功了!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多