【问题标题】:C# PInvoke Finding the window handle of a child window from a known windowC# PInvoke 从已知窗口中查找子窗口的窗口句柄
【发布时间】:2011-10-24 22:17:55
【问题描述】:

我目前正在尝试通过 C# pinvoke 使用 SendMessage 从子窗口获取一些文本。但是,我之前对窗口句柄进行硬核的尝试失败了,因为值在应用程序启动时发生了变化。有没有办法可靠地获取这个子窗口的窗口句柄? Winspector spy 显示这个窗口的类名是 RichEdit20W。我目前的代码如下:

IntPtr hWnd= (IntPtr) 0xA0E88; // Hardcode window handle


        int txtlen = SendMessage(hWnd, WM_GETTEXTLENGTH, 20, null);
        StringBuilder text = new StringBuilder(txtlen);
        int RetVal = SendMessage(hWnd, WM_GETTEXT, text.Capacity, text);

【问题讨论】:

    标签: c# pinvoke


    【解决方案1】:

    如果您可以获得顶级窗口(带有标题栏的窗口),您可以使用FindWindowEx 递归遍历子级。这使您可以指定窗口的文本(使用 null,因为您不知道它)和/或类(您知道)。

    http://www.pinvoke.net/default.aspx/user32.findwindowex

    【讨论】:

      【解决方案2】:

      我最终使用托管 Windows API 来枚举窗口的所有后代窗口。

                  var descendantwindows = childWindows[0].AllDescendantWindows; // Get all descendant windows of CMainWindow
      
              for (int i = 0; i<descendantwindows.Length; i++)
              {
                  if (descendantwindows[i].ClassName == "RichEdit20W")
                      childHandle = descendantwindows[i].HWnd;
              }
      

      【讨论】:

        【解决方案3】:

        您可以 PInvoke API [FindWindow][1] 以获得顶级窗口,或者如果您知道进程名称可能更好,使用:

        Process[] processes = Process.GetProcessesByName("yourprocessname");
        
        foreach (Process p in processes)
        
        {
        
            IntPtr pFoundWindow = p.MainWindowHandle;
        
            // Do something with the handle...
        
            //
        
        }
        

        请注意有更多条目,因为可能同时运行更多流程实例。然后,您需要一些策略来查找顶级子级以准确指向您正在寻找的窗口。

        【讨论】:

          猜你喜欢
          • 2010-12-06
          • 2011-02-26
          • 1970-01-01
          • 1970-01-01
          • 2011-01-28
          • 1970-01-01
          • 2010-11-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多