Index: trunk/src/user32/win32wbase.cpp
===================================================================
--- trunk/src/user32/win32wbase.cpp	(revision 6168)
+++ trunk/src/user32/win32wbase.cpp	(revision 6169)
@@ -1,3 +1,3 @@
-/* $Id: win32wbase.cpp,v 1.273 2001-07-04 09:55:18 sandervl Exp $ */
+/* $Id: win32wbase.cpp,v 1.274 2001-07-04 17:46:04 sandervl Exp $ */
 /*
  * Win32 Window Base Class for OS/2
@@ -25,4 +25,12 @@
  *       Window rectangle in parent coordinates (relative to parent's client window)
  *       (screen coord. if no parent)
+ *
+ * NOTE: Status of window:
+ *       Before a window has processed WM_NCCREATE:
+ *       - GetTopWindow can't return that window handle
+ *       - GetWindow(parent, GW_CHILD) can't return that window handle
+ *       - IsChild works
+ *       TODO: Does this affect more functions?? (other GetWindow ops)
+ *       (verified in NT4, SP6)
  *
  * Project Odin Software License can be found in LICENSE.TXT
@@ -105,18 +113,14 @@
   OS2HwndModalDialog  = 0;
   fInternalMsg     = FALSE;
-  fNoSizeMsg       = FALSE;
   fParentChange    = FALSE;
-  fIsDestroyed     = FALSE;
   fDestroyWindowCalled = FALSE;
-  fCreated         = FALSE;
   fTaskList        = FALSE;
   fParentDC        = FALSE;
   fComingToTop     = FALSE;
-  fCreateSetWindowPos = FALSE;
-  fCreationFinished= FALSE;
   fMinMaxChange    = FALSE;
   fVisibleRegionChanged = FALSE;
   fEraseBkgndFlag  = TRUE;
 
+  state            = STATE_INIT;
   windowNameA      = NULL;
   windowNameW      = NULL;
@@ -502,5 +506,5 @@
     }
     OSLibWinSetVisibleRegionNotify(OS2Hwnd, TRUE);
-    fCreationFinished = TRUE;   //creation done with success
+    state = STATE_CREATED;
     SetLastError(0);
     return TRUE;
@@ -516,6 +520,4 @@
 
     OS2Hwnd      = hwndOS2;
-
-    fNoSizeMsg = TRUE;
 
     if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, getWindowHandle()) == FALSE) {
@@ -718,7 +720,4 @@
     maxPos.x = rectWindow.left; maxPos.y = rectWindow.top;
 
-    //Note: Solitaire crashes when receiving WM_SIZE messages before WM_CREATE
-    fCreated = TRUE;
-
     if(fTaskList) {
         hTaskList = OSLibWinAddToTaskList(OS2HwndFrame, windowNameA, (cs->style & WS_VISIBLE) ? 1 : 0);
@@ -727,4 +726,5 @@
     localSend32 = (isUnicode) ? ::SendMessageW : ::SendMessageA;
 
+    state = STATE_PRE_WMNCCREATE;
     if(localSend32(getWindowHandle(), WM_NCCREATE,0,(LPARAM)cs))
     {
@@ -744,13 +744,15 @@
         }
         tmpRect = rectWindow;
-
-        fCreateSetWindowPos = TRUE;
+        state   = STATE_POST_WMNCCREATE;
 
         //set the window size and update the client
         SetWindowPos(hwndLinkAfter, tmpRect.left, tmpRect.top, tmpRect.right-tmpRect.left, tmpRect.bottom-tmpRect.top,SWP_NOACTIVATE | SWP_NOREDRAW | SWP_FRAMECHANGED);
-        fNoSizeMsg = FALSE;
+
+        state = STATE_PRE_WMCREATE;
         if (cs->style & WS_VISIBLE) dwStyle |= WS_VISIBLE; //program could change position in WM_CREATE
         if( (localSend32(getWindowHandle(), WM_CREATE, 0, (LPARAM)cs )) != -1 )
         {
+            state = STATE_POST_WMCREATE;
+
             if(!(flags & WIN_NEED_SIZE))
             {
@@ -839,5 +841,5 @@
  HWND hwnd = getWindowHandle();
 
-    fIsDestroyed = TRUE;
+    state = STATE_DESTROYED;
 
     if(fDestroyWindowCalled == FALSE)
@@ -863,5 +865,5 @@
     TIMER_KillTimerFromWindow(getWindowHandle());
 
-    if(getRefCount() == 0 && getFirstChild() == NULL && fCreationFinished) {
+    if(getRefCount() == 0 && getFirstChild() == NULL && state == STATE_CREATED) {
         delete this;
     }
@@ -895,5 +897,5 @@
 ULONG Win32BaseWindow::MsgShow(BOOL fShow)
 {
-    if(fNoSizeMsg || fDestroyWindowCalled) {
+    if(!CanReceiveSizeMsgs() || fDestroyWindowCalled) {
         return 1;
     }
@@ -917,5 +919,5 @@
     //SvL: Notes crashes when switching views (calls DestroyWindow -> PM sends
     //     a WM_WINDOWPOSCHANGED msg -> crash)
-    if(fNoSizeMsg || fDestroyWindowCalled)
+    if(!CanReceiveSizeMsgs() || fDestroyWindowCalled)
         return 0;
 
@@ -928,5 +930,5 @@
     //SvL: Notes crashes when switching views (calls DestroyWindow -> PM sends
     //     a WM_WINDOWPOSCHANGED msg -> crash)
-    if(fNoSizeMsg || fDestroyWindowCalled)
+    if(CanReceiveSizeMsgs() || fDestroyWindowCalled)
         return 1;
 
@@ -1202,5 +1204,5 @@
     dprintf(("MsgFormatFrame: old window rect (%d,%d)(%d,%d), new window (%d,%d)(%d,%d)", oldWindowRect.left, oldWindowRect.top, oldWindowRect.right, oldWindowRect.bottom, rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom));
 
-    if(fNoSizeMsg || !EqualRect(&client, &rectClient)) {
+    if(!CanReceiveSizeMsgs() || !EqualRect(&client, &rectClient)) {
         OSLibWinSetClientPos(getOS2WindowHandle(), rectClient.left, rectClient.top, getClientWidth(), getClientHeight(), getWindowHeight());
     }
@@ -1208,6 +1210,6 @@
 #if 1
 //this doesn't always work
-//  if(!fNoSizeMsg && (client.left != rectClient.left || client.top != rectClient.top))
-  if(!fNoSizeMsg && ((oldWindowRect.right - oldWindowRect.left < rectClient.left
+//  if(CanReceiveSizeMsgs() && (client.left != rectClient.left || client.top != rectClient.top))
+  if(CanReceiveSizeMsgs() && ((oldWindowRect.right - oldWindowRect.left < rectClient.left
                   || oldWindowRect.bottom - oldWindowRect.top < rectClient.top) ||
      (EqualRect(&oldWindowRect, &rectWindow) && (client.left != rectClient.left || client.top != rectClient.top))))
@@ -2447,5 +2449,6 @@
 #endif
 
-    if(!fCreateSetWindowPos)
+    //Note: Solitaire crashes when receiving WM_SIZE messages before WM_CREATE
+    if(state < STATE_POST_WMNCCREATE)
     {//don't change size; modify internal structures only
         //TODO: not 100% correct yet (activate)
@@ -2783,5 +2786,5 @@
    /* Windows hides the window first, then shows it again
     * including the WM_SHOWWINDOW messages and all */
-   if(fCreated && (getStyle() & WS_VISIBLE)) {
+   if(IsWindowCreated() && (getStyle() & WS_VISIBLE)) {
         ShowWindow(SW_HIDE);
         fShow = TRUE;
@@ -2832,5 +2835,5 @@
       WM_WINDOWPOSCHANGED notification messages.
    */
-   if(fCreated) {
+   if(state >= STATE_PRE_WMNCCREATE) {
         SetWindowPos(HWND_TOPMOST, 0, 0, 0, 0,
                      SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|(fShow? SWP_SHOWWINDOW : 0));
@@ -2864,18 +2867,24 @@
     {
         topwindow = GetWindowFromOS2FrameHandle(hwndTop);
-        if(topwindow) {
+        //Note: GetTopWindow can't return a window that hasn't processed
+        //      WM_NCCREATE yet (verified in NT4, SP6)
+        if(topwindow && topwindow->state >= STATE_POST_WMNCCREATE) {
             hwndTop = topwindow->getWindowHandle();
             RELEASE_WNDOBJ(topwindow);
             return hwndTop;
         }
+        if(topwindow) RELEASE_WNDOBJ(topwindow);
         return 0;
     }
     while(hwndTop) {
         topwindow = GetWindowFromOS2FrameHandle(hwndTop);
-        if(topwindow) {
+        //Note: GetTopWindow can't return a window that hasn't processed
+        //      WM_NCCREATE yet (verified in NT4, SP6)
+        if(topwindow && topwindow->state >= STATE_POST_WMNCCREATE) {
             hwndTop = topwindow->getWindowHandle();
             RELEASE_WNDOBJ(topwindow);
             return hwndTop;
         }
+        if(topwindow) RELEASE_WNDOBJ(topwindow);
         hwndTop = OSLibWinQueryWindow(hwndTop, QWOS_NEXT);
     }
@@ -3201,9 +3210,20 @@
         hwndRelated = OSLibWinQueryWindow(getOS2WindowHandle(), QWOS_TOP);
         window = GetWindowFromOS2FrameHandle(hwndRelated);
+
+        //Before a window has processed WM_NCCREATE:
+        //- GetWindow(parent, GW_CHILD) can't return that window handle
+        //(verified in NT4, SP6)
         if(window) {
-             hwndRelated = window->getWindowHandle();
-             RELEASE_WNDOBJ(window);
+             if(window->state >= STATE_POST_WMNCCREATE) {
+                 hwndRelated = window->getWindowHandle();
+                 RELEASE_WNDOBJ(window); 
+             }
+             else {
+                 hwndRelated = window->GetWindow(GW_HWNDNEXT);
+                 RELEASE_WNDOBJ(window); 
+             }
         }
         else hwndRelated = 0;
+
         break;
     }
Index: trunk/src/user32/win32wbase.h
===================================================================
--- trunk/src/user32/win32wbase.h	(revision 6168)
+++ trunk/src/user32/win32wbase.h	(revision 6169)
@@ -1,3 +1,3 @@
-/* $Id: win32wbase.h,v 1.122 2001-07-04 09:29:52 sandervl Exp $ */
+/* $Id: win32wbase.h,v 1.123 2001-07-04 17:46:05 sandervl Exp $ */
 /*
  * Win32 Window Base Class for OS/2
@@ -108,4 +108,13 @@
 
 #define HAS_MENU() (!(getStyle() & WS_CHILD) && (GetMenu() != 0))
+
+#define STATE_INIT	         0   //initial state
+#define STATE_PRE_WMNCCREATE     1   //before WM_NCCREATE
+#define STATE_POST_WMNCCREATE    2   //after WM_NCCREATE
+#define STATE_PRE_WMCREATE       3   //before WM_CREATE
+#define STATE_POST_WMCREATE      4   //after WM_CREATE
+#define STATE_CREATED            5   //after successful return of WinCreateWindow
+#define STATE_DESTROYED          6   //DestroyWindow called for window
+
 
 class Win32BaseWindow : public GenericObject, public ChildWindow
@@ -252,8 +261,8 @@
          VOID   setOS2HwndModalDialog(HWND aHwnd) { OS2HwndModalDialog = aHwnd; };
          HWND   getOS2HwndModalDialog()       { return OS2HwndModalDialog; };
-         BOOL   CanReceiveSizeMsgs()          { return !fNoSizeMsg; };
+         BOOL   CanReceiveSizeMsgs()          { return state >= STATE_PRE_WMCREATE; };
          BOOL   IsParentChanging()            { return fParentChange; };
-         BOOL   IsWindowCreated()             { return fCreated; }
-         BOOL   IsWindowDestroyed()           { return fIsDestroyed; };
+         BOOL   IsWindowCreated()             { return state >= STATE_PRE_WMNCCREATE; }
+         BOOL   IsWindowDestroyed()           { return state >= STATE_DESTROYED; };
          BOOL   IsWindowIconic();
          //Window procedure type
@@ -373,12 +382,6 @@
                  fInternalMsg:1,         //Used to distinguish between messages
                                          //sent by PM and those sent by apps
-                 fNoSizeMsg:1,
                  fParentChange:1,
-                 fIsDestroyed:1,
                  fDestroyWindowCalled:1, //DestroyWindow was called for this window
-                 fCreated:1,
-                 fCreationFinished:1,    //True when window or dialog has been created successfully
-                                         //Needed to prevent DestroyWindow from deleting the window
-                                         //object during construction
                  fTaskList:1,            //should be listed in PM tasklist or not
                  fXDefault:1,
@@ -386,5 +389,4 @@
                  fParentDC:1,
 	         fComingToTop:1,
-                 fCreateSetWindowPos:1,  //FALSE -> SetWindowPos in Win32BaseWindow::MsgCreate not yet called
                  isUnicode:1,
                  fMinMaxChange:1,        //set when switching between min/max/restored state
@@ -392,4 +394,5 @@
                  fEraseBkgndFlag:1;
 
+        ULONG   state;
         HRGN    hWindowRegion;
         HRGN    hClipRegion;
