1

我在从 DLL 文件创建无模式对话框时遇到问题。我的对话框没有什么特别之处,只有一个确定按钮和一个编辑框。我查看了这篇 Microsoft 知识库文章 ( http://support.microsoft.com/kb/233263 ) 并实施了它的解决方案来创建一个窗口挂钩来抓取和处理消息。

Microsoft 提供的方法解决了 Tab 键问题,但是,它产生了另一个问题。当我在对话框的编辑框中键入时,我按的任何内容都会重复 4 次。例如,如果我在键盘上按“a”,“aaaa”将出现在编辑框中。

如果我禁用 Window Hook,那么编辑框可以正常工作并且只显示一个“a”。

我需要对 Window Hook 程序做些什么来解决这个问题?

任何帮助是极大的赞赏。

- - 编辑 - -

根据要求,我的窗口挂钩程序代码:(与知识库文章相同)

LRESULT FAR PASCAL GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) {
    LPMSG lpMsg = (LPMSG) lParam;

    if (nCode >= 0 && PM_REMOVE == wParam) {
        // Don't translate non-input events.
        if ((lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST)) {
            if (IsDialogMessage(hwndDllDlg, lpMsg)) {
                // The value returned from this hookproc is ignored, 
                // and it cannot be used to tell Windows the message has been handled.
                // To avoid further processing, convert the message to WM_NULL 
                // before returning.
                lpMsg->message = WM_NULL;
                lpMsg->lParam  = 0;
                lpMsg->wParam  = 0;
            }
        }
    }

    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

我的对话框回调过程:

BOOL CALLBACK DllDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
        case WM_INITDIALOG:
            hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, NULL, GetCurrentThreadId());
            return TRUE;

        case WM_COMMAND:
            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
                DestroyWindow(hwndDlg);
                hwndDllDlg = NULL;
            }
        return TRUE;

        case WM_DESTROY:
            UnhookWindowsHookEx(hHook);
            return FALSE;
        }
        return FALSE;
    }
}

两者hHookhwndDllDlg分别定义为HHOOKHWND

HHOOK hHook;
HWND hwndDllDlg = CreateDialog(0, MAKEINTRESOURCE(DLG_MAIN), 0, DllDlgProc);
4

2 回答 2

0

好吧,这对帖子的作者来说更像是一个问题。我有标签键问题,我试图更好地理解微软的文章。因此,我的对话框作为 Dll 发布,而我无权访问的应用程序正在从我的 dll 启动对话框。

HWND hwndDllDlg = CreateDialog(0, MAKEINTRESOURCE(DLG_MAIN), 0, DllDlgProc);

当他们在文章中说 hwndDllDlg 时,我不明白代码指的是什么对话框。我应该将我的对话框创建指向这个变量吗?

于 2014-07-09T00:18:43.273 回答
0

我看了知识库文章。听起来很合理。在遵循 KB 的说明时,有时您不够准确。发布您的代码。这可能会有所帮助。

如果您可以控制可执行文件的消息泵并且可以在IsDialogMessage那里添加,那么您不需要任何挂钩。来自 dll 的代码是进程代码的一部分。窗把手也在公共空间。

其他方法是启动您自己的 UI 线程。如果您在此线程上创建对话框,那么您将拥有自己的消息泵。在这种情况下也不需要钩子。

于 2013-07-09T02:54:34.907 回答