Jump to content
  • Advertisement
Sign in to follow this  

Win32 + Child / Parent keyboard focus

This topic is 2888 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

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!