1

我在使用 user32.dll 向应用程序发送 Click 时遇到问题。该按钮没有被点击,但在 spy++ 中确实出现了该消息。我用的是win7 x64

代码是用c#编写的:

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr FindWindow(string strClassName, string strWindowName);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lpClassName, string lpWindowTitle);

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

    [DllImport("user32.dll")]
    static extern IntPtr GetWindow(IntPtr hWnd, uint wCmd);

    //
    // Finds a window in the whole tree of childs for a parent window.
    //
    static IntPtr FindWindowRecursive(IntPtr hParent, string szClass, string szCaption)
    {
        IntPtr hResult = FindWindowEx(hParent, IntPtr.Zero, szClass, szCaption);
        if (hResult != IntPtr.Zero)
            return hResult; // found it

        // enumerate all childs and if found one that has childs go in
        IntPtr hChild = FindWindowEx(hParent, IntPtr.Zero, null, null); // first child
        if (hChild != IntPtr.Zero)
        {
            // let's enumerate
            do
            {
                hResult = FindWindowRecursive(hChild, szClass, szCaption);
                if (hResult != IntPtr.Zero)
                    return hResult;  // found it
            } while ((hChild = GetWindow(hChild, GW_HWNDNEXT)) != IntPtr.Zero);
        }

        return IntPtr.Zero; // no childs, so no window was found
    }

    static void Main(string[] args)
    {
        IntPtr win = FindWindow("Omnipage17_MainWnd_Class", "Unbenanntes OmniPage-Dokument 1 - OmniPage");
                SetForegroundWindow(win);
        ShowWindowAsync(win, SW_RESTORE);
        IntPtr ButtonHandle = FindWindowRecursive(win, "BarButton", "c");
        SetActiveWindow(win);
        //sEND Lbuttondown
        IntPtr ptr = SendMessage(ButtonHandle, 0x0201, new IntPtr(0x0001), MakeLParam(81,28));
        //Thread.Sleep(10);
        //Mousemove
        ptr = SendMessage(ButtonHandle, 0x0200, new IntPtr(0x0001), MakeLParam(86,24));
        //lbuttonup
        ptr = SendMessage(ButtonHandle, 0x0202, new IntPtr(0x0001), MakeLParam(81, 28));

        //SendMessage(ButtonHandle, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
    }

以下是该按钮的 spy++ 消息: 在此处输入图像描述

如果我发送以下消息,我会收到以下消息:如果那是问题,我不知道,但 lbuttondown,buttoup 出现 2 次(S + R),如果我手动单击它,它会收到 1 条消息(P)也试图用 WM_CLICK 做,但我有同样的问题

编辑:现在使用 PostMessage 所以 spy++ 显示与我手动单击它相同的消息,但似乎仍然没有单击该按钮

在此处输入图像描述


使用这个库我有同样的问题。

代码:

SetForegroundWindow(win);
Rectangle re;
GetWindowRect(ButtonHandle, out re);

Cursor.Position = new Point((re.X + re.Width)/2, (re.Y + re.Height)/2);
WindowsInput.InputSimulator.SimulateKeyDown(WindowsInput.VirtualKeyCode.LBUTTON);
WindowsInput.InputSimulator.SimulateKeyUp(WindowsInput.VirtualKeyCode.LBUTTON);

消息已发送,但未单击按钮 在此处输入图像描述

编辑:

感谢该链接(http://www.hanselman.com/blog/IntroducingLync2010SuperSimpleAutoAnswerVideoKioskWithFullScreen.aspx),但对于这个库我也有同样的问题:/

代码:

SetForegroundWindow(win);
Rectangle re;
GetWindowRect(ButtonHandle, out re);

Cursor.Position = new Point((re.X + re.Width)/2, (re.Y + re.Height)/2);
WindowsInput.InputSimulator.SimulateKeyDown(WindowsInput.VirtualKeyCode.LBUTTON);
WindowsInput.InputSimulator.SimulateKeyUp(WindowsInput.VirtualKeyCode.LBUTTON);

消息已发送,但未单击按钮 在此处输入图像描述

编辑2:

用户的回答已被删除,因为我发布了我的评论作为答案:

这不是答案,这属于你的问题。它与您的代码不匹配,显然您仍在发布 BM_CLICK。这是错误的,应该发送它,您应该发送 BM_CLICK 或发布鼠标消息。而且您正在查看错误的窗口,它是按钮的父级获取 BN_CLICK 通知并对其进行操作。进程的键盘状态错误将是一种典型的故障模式。– 汉斯·帕桑特 18 小时前

关于那个,为什么应该是父母的窗户?spy++ 中的 bcs(我为该按钮(类:BarButton)搜索了下面的屏幕截图,并且我从 user32.dll 获得的句柄也与 spy++ 中的相同 在此处输入图像描述

4

1 回答 1

2

Scott Hanselman 最近发表了与此类似的博客http://www.hanselman.com/blog/IntroducingLync2010SuperSimpleAutoAnswerVideoKioskWithFullScreen.aspx

于 2012-07-12T10:27:48.110 回答