C++ Modeless Dialog created from DLL doesn't process input properly

1.2k Views Asked by At

I am having issues with creating a modeless dialog from a DLL file. My dialog has nothing special on it, just an OK button and an edit box. I have looked at this Microsoft KB Article (http://support.microsoft.com/kb/233263) and have implemented its solution to create a window hook to grab and process messages.

The method provided by Microsoft solves the tab key problem, however, it creates another problem. When I type into the edit box on the dialog, whatever I press is duplicated 4 times. For example, if I press 'a' on the keyboard, 'aaaa' will show up in the edit box.

If I disable the Window Hook, then the edit box works correctly and only displays one 'a'.

What do I need to do to the Window Hook procedure to solve this problem?

Any help is greatly appreciated.

- - EDIT - -

As per request, my Window Hook Procedure Code: (It's the same as the KB article)

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);
}

My Dialog Callback Procedure:

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;
    }
}

Both hHook and hwndDllDlg are defined as HHOOK and HWND respectively.

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

There are 2 best solutions below

0
On

I looked at the KB article. It sounds reasonable. There is some point where you was not enough accurate while following the instructions from KB. Post your code. This may help.

If you have control over the message pump of the executable and can add IsDialogMessage there, then you do not need any hook. Code from the dll is part of the code of the process. Window handles are in the common space either.

Other approach is starting your own UI thread. If you create your dialog on this thread, then you will have your own message pump. The hook will not be needed in this case either.

0
On

Well, this is more of a question to author of the post.. I have the tab key issue and am trying to understand the microsoft article better. So my dialog is shipped out as Dll and the application which I don't have access to is launching dialog from my dll.

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

I don't understand what dialog the code refers to when they said hwndDllDlg in the article. Should I point my dialog creation to this variable ?