// dialog window proc
// ---------------------------------------------------------------------------
+// the DialogProc for all wxWindows dialogs
+LONG APIENTRY _EXPORT
+wxDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch ( message )
+ {
+#if 0
+ case WM_ACTIVATE:
+ case WM_SHOWWINDOW:
+ // DefDlgProc() has a bug which makes it enter an infinite loop
+ // when a dialog containing a notebook whose children have
+ // WS_EX_CONTROLPARENT (automatically set for the windows with
+ // wxTAB_TRAVERSAL style as it's needed to get it right) is
+ // deactivated or hidden -- simply remove this code to see this
+ // happen in the notebook sample
+ //
+ // The only way I found to prevent this from happening is to never
+ // let it process these messages at all.
+ if ( !wParam )
+ return TRUE;
+#endif
+
+ case WM_INITDIALOG:
+ // for this message, returning TRUE tells system to set focus to
+ // the first control in the dialog box, but as we set the focus
+ // ourselves, we return FALSE from here as well, so fall through
+
+ default:
+ // for all the other ones, FALSE means that we didn't process the
+ // message
+ return FALSE;
+ }
+}
+
long wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
{
long rc = 0;
#endif // __WXMICROWIN__
+// this is defined in dialog.cpp
+LONG APIENTRY _EXPORT
+wxDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
+
// ----------------------------------------------------------------------------
// globals
// ----------------------------------------------------------------------------
EVT_ACTIVATE(wxTopLevelWindowMSW::OnActivate)
END_EVENT_TABLE()
-// ----------------------------------------------------------------------------
-// wxDialog helpers
-// ----------------------------------------------------------------------------
-
-// Dialog window proc
-LONG APIENTRY _EXPORT
-wxDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
- switch ( message )
- {
- case WM_INITDIALOG:
- // for this message, returning TRUE tells system to set focus to
- // the first control in the dialog box, but as we set the focus
- // ourselves, we return FALSE from here as well, so fall through
-
- default:
- // for all the other ones, FALSE means that we didn't process the
- // message
- return FALSE;
- }
-}
-
// ----------------------------------------------------------------------------
// wxTopLevelWindowMSW creation
// ----------------------------------------------------------------------------
// window creation/destruction
// ---------------------------------------------------------------------------
-bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT WXUNUSED(cs), bool *mayCreate)
-{
+bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate)
+{
+ // if we have WS_EX_CONTROLPARENT flag we absolutely *must* set it for our
+ // parent as well as otherwise several Win32 functions using
+ // GetNextDlgTabItem() to iterate over all controls such as
+ // IsDialogMessage() or DefDlgProc() would enter an infinite loop: indeed,
+ // all of them iterate over all the controls starting from the focus and
+ // stop iterating when they get back to the focus but unless all parents
+ // have WS_EX_CONTROLPARENT bit set, they would never get back to focus
+ if ( ((CREATESTRUCT *)cs)->dwExStyle & WS_EX_CONTROLPARENT )
+ {
+ // there is no need to do anything for the top level windows
+ const wxWindow *parent = GetParent();
+ if ( parent && !parent->IsTopLevel() )
+ {
+ LONG exStyle = ::GetWindowLong(GetHwndOf(parent), GWL_EXSTYLE);
+ if ( !(exStyle & WS_EX_CONTROLPARENT) )
+ {
+ // force the parent to have this style
+ ::SetWindowLong(GetHwndOf(parent), GWL_EXSTYLE,
+ exStyle | WS_EX_CONTROLPARENT);
+ }
+ }
+ }
+
// TODO: should generate this event from WM_NCCREATE
wxWindowCreateEvent event((wxWindow *)this);
(void)GetEventHandler()->ProcessEvent(event);