【问题标题】:How do you get a child window using its control ID?如何使用控件 ID 获取子窗口?
【发布时间】:2015-09-30 23:03:52
【问题描述】:

我是 WINAPI 的新手,并且已经知道如何将消息发送到另一个程序。我正在使用的程序但是我希望能够让它点击一个特定的按钮。从我通过查看 Spy++ 窗口了解到的情况来看,每次重新加载程序时,程序的句柄都会发生变化,控件的句柄也是如此。控制 ID 保持不变。经过两天的尝试,我来到了这里。

在 SendMesssageA 下,如果我将当前句柄指定为 Spy++ 可以查看并使用它并运行代码,它可以正常工作并单击我的外部应用程序上的按钮。我正在尝试使用 GetDlgItem,因为我已经读到我可以使用它来获取控件(子窗口)的句柄。但是,我做错了什么,因为无论我做什么,它都会返回 0 或“null”。

如何让 GetDlgItem 返回子控件句柄,以便我可以使用它发送消息以在外部应用程序中单击该控件?

感谢您提前提供的帮助。

    [DllImport("User32.dll")]
    static extern bool SetForegroundWindow(IntPtr hWnd);
    Process[] myProcess = Process.GetProcessesByName("program name here");

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern int SendMessageA(IntPtr hwnd, int wMsg, int wParam, uint lParam);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr GetDlgItem(int hwnd, int childID);

    public const int WM_LBUTTONDOWN = 0x0201;
    public const int WM_LBUTTONUP = 0x0202;


    public void SendClick()
    {
        IntPtr hwnd = myProcess[0].MainWindowHandle;
        SetForegroundWindow(hwnd);

        int intCID = 1389;
        IntPtr ptrTest = GetDlgItem(hwnd, intCID);
        SendKeys.SendWait(" ");
        Thread.Sleep(1000);
        SendKeys.SendWait("various text to be sent here");
        Thread.Sleep(1000);
        SendKeys.SendWait("{ENTER}");
        Thread.Sleep(1000);

        SendMessageA(ptrTest, WM_LBUTTONDOWN, WM_LBUTTONDOWN, 0);
    }

【问题讨论】:

  • 对于任何登陆这里的人,因为他们只想使用其控制 ID 获取 HWND:是的,GetDlgItem 是答案,它应该可以工作。它甚至可以跨进程边界工作,except 如果所需的 HWND 属于 64 位进程。我不确定,但也许那是 OP 的问题。

标签: c# winapi


【解决方案1】:

我认为您必须使用 Win32 API 找到“接收”应用程序窗口,然后找到该句柄的子窗口。 这是我在谷歌上搜索 Win32 API FindWindow 时发现的

http://www.c-sharpcorner.com/UploadFile/shrijeetnair/win32api12062005005528AM/win32api.aspx

【讨论】:

  • 我发布的代码确实适用于建立父窗口或按钮所在的主应用程序。唯一不能与发布的代码一起使用的是 GetDlgItem 来查找子控件的句柄。根据 MSDN GetDlgItem 使用我使用 myprocess 的父句柄,它还使用我作为变量 intCID 的子控件的控件 ID。但是,GetDlgItem 返回 0 或 'null'。
  • 你确定 hwnd 指向你认为它的作用吗?您需要使用 Spy++ 进行验证。 MainWindowHandle 是进程创建的第一个(可见?)窗口,它可能是也可能不是您尝试使用的对话框(取决于相关应用程序的体系结构)。
  • 是的,hwnd 指向为程序命名的第一个进程。我知道它确实如此,因为它将它设置为活动窗口,并且 sendkeys 将文本发送给它接收到的文本。当它到达 sendmessageA 时,如果我将 ptrTest 变量更改为 hwnd,它将把点击发送到程序。然而,我的问题是,我需要单击发送到我试图用 GetDlgItem 建立的父窗口的特定子控件。 ptrTest 一直在 '0' 出现,我不确定如何将 ptrTest 设置为子控件句柄(我可以用控件 ID 识别)
  • 我认为您需要使用 EnumChildWindows 枚举窗口:support.microsoft.com/kb/183009
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-21
  • 2011-01-28
  • 2016-10-28
  • 2010-10-21
  • 2012-04-06
相关资源
最近更新 更多