• Advertisement
Sign in to follow this  

Win32 + Child / Parent keyboard focus

This topic is 2618 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey All,

I have my main window and then I spawn a child window inside it (passing in parent HWND and setting WS_Child) with some buttons and edit controls (following samples from here: http://msdn.microsoft.com/en-us/library/bb775456%28v=vs.85%29.aspx). Initially when I hit my keystrokes, I my parent window receives them - good. When I click on the child window, now the child window receives the keystrokes - dandy. When I click back on the main window, main window is receiving key strokes. Ok.

BUT - if I spawn a Control inside the child (like a button or edit), click on the control (giving it focus) and then click back to my main window area - the main window DOES NOT regain focus.

For example: Parent -> Child -> EditControl
Parent is supposed to quit when hit ESC. if I click on Edit Control, then back onto Parent area not occupied by the child and hit ESC, the EditControl receives the message, NOT parent.

Inside my WND Proc for Parent/Child I just have code for, when a keystroke is not handled, it just calls default wnd proc. There is no custom WndProc for edit control.

Am I setting something wrong? Or do I need to explicitly set focus back to my main window? I noticed that the WM_ACTIVE message is NEVER sent (be either child or parent) when I click on either.

Here's my window creation code (snipped):

KPBool CWindow::Init( CWindowManager* inWindowManager, HINSTANCE inHInstance, const KPString& inTitle, KPDWord inWindowStyle, KPUInt inWidth, KPUInt inHeight, KPInt inX, KPInt inY, boost::weak_ptr<IWindow> inParentWindow)
mWindowStyle = inWindowStyle | ( !inParentWindow.expired() ? WS_CHILD : WS_CLIPCHILDREN ) ;

//set up our window class
K::MemZero( &mWindowClass, sizeof( WNDCLASSEX ) );
mWindowClass.cbSize = sizeof(WNDCLASSEX);
mWindowClass.style = CS_HREDRAW | CS_VREDRAW;
//mWindowClass.lpfnWndProc = WndProc; //TODO: IMPLEMENT
mWindowClass.lpfnWndProc = (WNDPROC)StaticProcessMessage;
mWindowClass.cbClsExtra = 0;
mWindowClass.cbWndExtra = 0;
mWindowClass.hInstance = mHInstance;
//mWindowClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
mWindowClass.hIcon = NULL;
//mWindowClass.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
mWindowClass.hIconSm = NULL;
mWindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
mWindowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
mWindowClass.lpszMenuName = NULL;
mWindowClass.lpszClassName = mWindowClassName.CStr();

//Create our actual widnow!
boost::shared_ptr<CWindow> parentWindow = boost::dynamic_pointer_cast<CWindow>( mParentWindow.lock() );
mHWnd = CreateWindow(
mX, mY,
mWidth, mHeight,
( parentWindow != NULL ? parentWindow->GetHWnd() : NULL),
NULL, //hMenu

/* ... */

And my edit control:

CEditBox::CEditBox( KPWord inID, const boost::shared_ptr< CWindow >& inParentWindow,
const CPoint& inPos,
const CPoint& inSize,
const KPString& inCaption,
KPInt inMaxLength,
KPBool inIsMultiLine,
KPBool inIsNumeric,
KPBool inIsPassword,
KPBool inIsReadOnly )
/* ... */
mID = inID;
mPosition = inPos;
mSize = inSize;
mIsMultiLine = inIsMultiLine;
mIsNumeric = inIsNumeric;
mMaxLength = inMaxLength;
mIsPassword = inIsPassword;
mIsReadOnly = inIsReadOnly;
mCaption = inCaption;
mParentWindow = inParentWindow;

(mIsMultiLine ? ES_MULTILINE : 0 ) | (mIsPassword ? ES_PASSWORD : 0 ) |
(mIsReadOnly ? ES_READONLY : 0 ) | (mIsNumeric ? ES_NUMBER : 0 );

mHWnd = CreateWindow( _T("EDIT"), // Predefined class; Unicode assumed.
inCaption.CStr(), // text.
style, // Styles.
mPosition.mX, // x position.
mPosition.mY, // y position.
mSize.mX, // Button width.
mSize.mY, // Button height.
inParentWindow->GetHWnd(), // Parent window.
(HMENU)mID, //id of button
NULL); // Pointer not needed.


For inWindowStyleI just pass WS_OVERLAPPEDWINDOW

Any idea?


So I just added a call to SetFocus(mHWnd); inside my generic WndProc and it's working. Hopefully that wont have any bad side effects.
I also noticed calling SetFocus() does not trigger the WM_ACTIVE message. Seems like the parent window is active even if its a child control

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement