I have a program with several custom controls. One of these custom controls is a text input control. Since a window does not automatically receive keyboard focus when you click on it, i've created a mouse hook in my program that calls SetFocus() on a window when the user clicks in that window. However, there is a problem.
If another program has focus when you click on my program's window (or any of the controls in that window) SetFocus() fails. I then have to click again for it to succeed. Here's the code:
LRESULT CALLBACK kbfProc(int nCode, WPARAM wParam, LPARAM lParam) // Keyboard focus switching procedure
{
switch(nCode)
{
case HC_ACTION:
{
if(wParam == WM_LBUTTONDOWN || wParam == WM_NCLBUTTONDOWN)
{
MOUSEHOOKSTRUCT * mhs = (MOUSEHOOKSTRUCT*) lParam;
if(SetFocus(mhs->hwnd) == NULL)
{
printf("SetFocus(Hwnd = %.8x) failed. Error code: %lu\n", mhs->hwnd, GetLastError());
} else {
printf("SetFocus(Hwnd = %.8x) returned success.\n", mhs->hwnd);
}
}
}
break;
}
return CallNextHookEx(0, nCode, wParam, lParam);
}
And the output of those printf calls is this:
SetFocus(Hwnd = 00410c06) failed. Error code: 87
SetFocus(Hwnd = 00410c06) returned success.
SetFocus(Hwnd = 01740fc8) failed. Error code: 87
SetFocus(Hwnd = 01740fc8) returned success.
Error code 87 is ERROR_INVALID_PARAMETER, but i'm obviously passing a valid window handle to the function, so why is it failing?
Whenever you're calling SetFocus, the window must be attached to the calling thread's message queue or SetFocus will return invalid if it's not. To workaround this, use SetForegroundWindow
first when the mouse moves over your window before calling SetFocus
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With