【问题标题】:How to avoid repeated SendMessage如何避免重复发送消息
【发布时间】:2011-08-18 14:06:28
【问题描述】:

我有一个问题:我使用 DLL 中的一个过程中的 SendMessage 与主窗口进行通信;过程是一个钩子过程,它允许主窗口知道何时在编辑框中单击鼠标右键;它还发送编辑框的句柄。它运行良好,除了这个错误:当程序在没有断点的情况下运行时,主窗口会收到两次相同的消息(在本例中为 WM_APP),而如果我在挂钩过程或处理 WM_APP 消息的块中放置断点,则消息是考虑一次。进一步的描述问我。遵循挂钩过程和处理 WM_APP 消息的块的代码。谢谢

挂钩程序

MYDLL_API LRESULT CALLBACK mouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// processes the message
if(nCode >= 0)
{
    // if user clicked with mouse right button
    if(wParam != NULL && (wParam == WM_RBUTTONDOWN || wParam == WM_RBUTTONUP))
    {
        wchar_t *s = (wchar_t*) malloc(CLASSNAMELEN*sizeof(wchar_t));
        //MessageBox(mainHwnd, (LPCWSTR)L"Captured mouse right button", (LPCWSTR)L"Test", MB_OK);
        MOUSEHOOKSTRUCT *m = (MOUSEHOOKSTRUCT*) lParam;
        GetClassName(m->hwnd, (LPWSTR) s, CLASSNAMELEN);
        //MessageBox(mainHwnd, (LPCWSTR) s, (LPCWSTR)L"Test", MB_OK);
        // only if user clicked on a edit box
        if(wcsncmp(s, L"Edit", 4) == 0)
            SendMessage(mainHwnd, WM_APP, 0, (LPARAM) lParam);
        free(s);
        s = NULL;
    }
}

// calls next hook in chain
return CallNextHookEx(NULL, nCode, wParam, lParam);
}

处理 WM_APP 消息的主程序中的块

case WM_APP:
    {
        //MessageBox(hWnd, (LPCWSTR)L"Received WM_APP", (LPCWSTR)L"Test", MB_OK);
        // copies text from the edit box
        MOUSEHOOKSTRUCT *m = (MOUSEHOOKSTRUCT*) lParam;
        int n = GetWindowTextLength(m->hwnd);
        // if text has been inserted
        if(n > 0 && n < 1024)
        {
            wchar_t *s = (wchar_t*) malloc((n+1)*sizeof(wchar_t));
            // gets text
            GetWindowText(m->hwnd, (LPWSTR) s, n+1);
            s[n] = (wchar_t) 0;
            //MessageBox(hWnd, (LPCWSTR)s, (LPCWSTR)L"Test", MB_OK);
            // saves text in database
            stateClassPointer->insertInList(s); 
        }
    }
    break;

【问题讨论】:

    标签: c++ winapi hook dry sendmessage


    【解决方案1】:

    这可能是因为您正在发送 WM_RBUTTONDOWN 和 WM_RBUTTONUP 的消息,即右键按下和释放的时间。

    当您调试时,WM_RBUTTONUP 会被调试器吃掉,所以您不会得到它。

    PS:为了安全起见,你不应该使用 PostMessage() 代替 SendMessage() 吗?

    【讨论】:

    • 你是对的 :) 但是,我检查得更好,钩子过程由接收消息的窗口过程的同一线程处理。在这种情况下我也必须使用 PostMessage 或我可以使用 SendMessage 吗? msdn好像说我可以用SendMessage..还是我错了?
    • 当然可以,而且如果您使用的是同一个线程,那没有问题。但我更喜欢将钩子的代码保持在最低限度,以避免干扰其他程序/线程的行为。 PostMessage 立即返回,因此您可以在主循环中流连忘返。
    • 考虑到它也是一个具有足够开销的全局钩子,这是一个好主意。谢谢:)