SendMessageCallback粉碎

时间:2015-07-17 15:39:01

标签: winapi c#-4.0

我正在尝试将按键发送到有时在后台的窗口。大多数时候它运作良好,但有时它只是粉碎。正如我已经注意到,当用户在发送消息的同时按下键盘上的相同键时,会发生这种情况......你能告诉我一些如何避免这些粉碎的建议吗? 这是我调用SendMessageCallback的代码:

Native.SendAsyncProc del = new Native.SendAsyncProc(Helpers.Win32.Native.SendMessage_Callback);
Native.SendMessageCallback(MainWindowHandle, 256U, (int)System.Windows.Forms.Keys.D3, 0, del, UIntPtr.Zero);
        Thread.Sleep(5);
Native.SendMessageCallback(MainWindowHandle, 257U, (int)System.Windows.Forms.Keys.D3, 0, del, UIntPtr.Zero);

和原住民:

[DllImport("user32.dll")]
    public static extern bool SendMessageCallback(IntPtr hWnd, uint Msg, int
    wParam, int lParam, SendAsyncProc lpCallback, UIntPtr dwData);
    public delegate void SendAsyncProc(IntPtr hwnd, uint uMsg, UIntPtr dwData,
    IntPtr lResult);
    public static void SendMessage_Callback(IntPtr hwnd, uint uMsg, UIntPtr dwData, IntPtr lResult)
    {
        //LogManager.LogError("SM CB {0}",(DateTime.Now - td).TotalMilliseconds.ToString());
        return;
    }

我也注意到它永远不会引发SendMessage_Callback ......但是直到现在才明白为什么......

1 个答案:

答案 0 :(得分:1)

您的问题是您尝试使用PostMessage的道德等效模拟键盘输入。 That doesn't work reliably.特别是,后台的应用程序失去了焦点和激活,许多应用程序依赖焦点和激活消息来正确处理输入。 Raymond Chen有more about how Windows handles input here

此外,由于您不是pumping messages while your sleeping,因此您未收到回叫。使用WaitHandle等待,因为它会在等待时抽取消息。当然,您需要在回调中设置事件。

所以,如果你的代码看起来像这样:

[DllImport("user32.dll")]
public static extern bool SendMessageCallback(IntPtr hWnd, uint Msg, int
wParam, int lParam, SendAsyncProc lpCallback, UIntPtr dwData);
public delegate void SendAsyncProc(IntPtr hwnd, uint uMsg, UIntPtr dwData,
IntPtr lResult);

WaitHandle waiter = new EventWaitHandle (false, EventResetMode.ManualReset);

public static void SendMessage_Callback(IntPtr hwnd, uint uMsg, UIntPtr dwData, IntPtr lResult)
{
    waiter.Set();
    return;
}

Native.SendAsyncProc del = Helpers.Win32.Native.SendMessage_Callback;
Native.SendMessageCallback(MainWindowHandle, 256U, (int)System.Windows.Forms.Keys.D3, 0, del, UIntPtr.Zero);
waiter.WaitOne();
Native.SendMessageCallback(MainWindowHandle, 257U, (int)System.Windows.Forms.Keys.D3, 0, del);
waiter.WaitOne();

你应该至少得到你的回调。但是,您需要从头开始重新考虑键盘模拟。至少考虑UI Automation