سؤال

I have a small C++/MFC dialog-based application with an embedded Internet Explorer ActiveX control. I want to know when that embedded control receives and loses keyboard focus. I thought to do this:

BOOL CWinAppDerivedClass::PreTranslateMessage(MSG* pMsg)
{
    if(pMsg->message == WM_SETFOCUS)
    {
        //if(checkIEWindow(pMsg->hwnd))
        {
            //Process it
        }
    }

    return CWinApp::PreTranslateMessage(pMsg);
}

but no matter what I do, WM_SETFOCUS doesn't seem to be sent out at all.

Any idea how to do this?

هل كانت مفيدة؟

المحلول

One way to do this is to use the process-wide window procedure hook.

First you need to install the hook somewhere from the main thread of your GUI application. In case of an MFC dialog window the good location is the OnInitDialog notification handler:

//hHook is "this" class member variable, declared as HHOOK. Set it to NULL initially.
hHook = ::SetWindowsHookEx(WH_CALLWNDPROC, CallWndProcHook, AfxGetInstanceHandle(), ::GetCurrentThreadId());

Then the hook procedure can be set up as such:

static LRESULT CALLBACK CallWndProcHook(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode == HC_ACTION) 
    {
        CWPSTRUCT* pCWS = (CWPSTRUCT*)lParam;

        //Check if this is the message we need
        if(pCWS->message == WM_SETFOCUS ||
            pCWS->message == WM_KILLFOCUS)
        {
            //Check if this is the window we need
            if(pCWS->hwnd == hRequiredWnd)
            {
                //Process your message here
            }
        }
    }

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

Also remember to unhook. A good spot for it is the PostNcDestroy handler:

if(hHook != NULL)
{
    ::UnhookWindowsHookEx(hHook);
    hHook = NULL;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top