* Sync up to trunk head (r64921).
[reactos.git] / win32ss / user / ntuser / window.c
index 6259742..b04f6ba 100644 (file)
@@ -587,14 +587,14 @@ static LRESULT co_UserFreeWindow(PWND Window,
         Window->IDMenu &&
         (Menu = UserGetMenuObject((HMENU)Window->IDMenu)))
    {
-      IntDestroyMenuObject(Menu, TRUE, TRUE);
+      IntDestroyMenuObject(Menu, TRUE);
       Window->IDMenu = 0;
    }
 
    if(Window->SystemMenu
          && (Menu = UserGetMenuObject(Window->SystemMenu)))
    {
-      IntDestroyMenuObject(Menu, TRUE, TRUE);
+      IntDestroyMenuObject(Menu, TRUE);
       Window->SystemMenu = (HMENU)0;
    }
 
@@ -861,158 +861,6 @@ IntSetMenu(
 /* INTERNAL ******************************************************************/
 
 
-VOID FASTCALL
-co_DestroyThreadWindows(struct _ETHREAD *Thread)
-{
-   PTHREADINFO WThread;
-   PLIST_ENTRY Current;
-   PWND Wnd;
-   USER_REFERENCE_ENTRY Ref;
-   WThread = (PTHREADINFO)Thread->Tcb.Win32Thread;
-
-   while (!IsListEmpty(&WThread->WindowListHead))
-   {
-      Current = WThread->WindowListHead.Flink;
-      Wnd = CONTAINING_RECORD(Current, WND, ThreadListEntry);
-
-      TRACE("thread cleanup: while destroy wnds, wnd=%p\n", Wnd);
-
-      /* Window removes itself from the list */
-
-      /*
-       * FIXME: It is critical that the window removes itself! If now, we will loop
-       * here forever...
-       */
-
-      //ASSERT(co_UserDestroyWindow(Wnd));
-
-      UserRefObjectCo(Wnd, &Ref); // FIXME: Temp HACK??
-      if (!co_UserDestroyWindow(Wnd))
-      {
-         ERR("Unable to destroy window %p at thread cleanup... This is _VERY_ bad!\n", Wnd);
-      }
-      UserDerefObjectCo(Wnd); // FIXME: Temp HACK??
-   }
-}
-
-PMENU FASTCALL
-IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
-{
-   PMENU Menu, NewMenu = NULL, SysMenu = NULL, ret = NULL;
-   PTHREADINFO W32Thread;
-   HMENU hNewMenu, hSysMenu;
-   ROSMENUITEMINFO ItemInfo = {0};
-
-   if(bRevert)
-   {
-      W32Thread = PsGetCurrentThreadWin32Thread();
-
-      if(!W32Thread->rpdesk)
-         return NULL;
-
-      if(Window->SystemMenu)
-      {
-         Menu = UserGetMenuObject(Window->SystemMenu);
-         if(Menu)
-         {
-            IntDestroyMenuObject(Menu, TRUE, TRUE);
-            Window->SystemMenu = (HMENU)0;
-         }
-      }
-
-      if(W32Thread->rpdesk->rpwinstaParent->SystemMenuTemplate)
-      {
-         /* Clone system menu */
-         Menu = UserGetMenuObject(W32Thread->rpdesk->rpwinstaParent->SystemMenuTemplate);
-         if(!Menu)
-            return NULL;
-
-         NewMenu = IntCloneMenu(Menu);
-         if(NewMenu)
-         {  // Use spmenuSys
-            Window->SystemMenu = NewMenu->head.h;
-            NewMenu->fFlags |= MNF_SYSDESKMN;
-            NewMenu->hWnd = Window->head.h;
-            ret = NewMenu;
-            //IntReleaseMenuObject(NewMenu);
-         }
-      }
-      else
-      {
-         hSysMenu = UserCreateMenu(FALSE);
-         if (NULL == hSysMenu)
-         {
-            return NULL;
-         }
-         SysMenu = IntGetMenuObject(hSysMenu);
-         if (NULL == SysMenu)
-         {
-            UserDestroyMenu(hSysMenu);
-            return NULL;
-         }
-         SysMenu->fFlags |= MNF_SYSDESKMN;
-         SysMenu->hWnd = Window->head.h;
-         hNewMenu = co_IntLoadSysMenuTemplate();
-         //if ( Window->ExStyle & WS_EX_MDICHILD )
-         //hNewMenu = co_IntCallLoadMenu( NULL, L"SYSMENUMDI");
-         // else
-         //hNewMenu = co_IntCallLoadMenu( NULL, L"SYSMENU");
-         // Do the rest in here.
-         if(!hNewMenu)
-         {
-            IntReleaseMenuObject(SysMenu);
-            UserDestroyMenu(hSysMenu);
-            return NULL;
-         }
-         Menu = IntGetMenuObject(hNewMenu);
-         if(!Menu)
-         {
-            IntReleaseMenuObject(SysMenu);
-            UserDestroyMenu(hSysMenu);
-            return NULL;
-         }
-
-         NewMenu = IntCloneMenu(Menu);
-         if(NewMenu)
-         {
-            NewMenu->fFlags |= MNF_SYSDESKMN | MNF_POPUP;
-            // Do not set MNS_CHECKORBMP it breaks menus, also original code destroyed the style anyway.
-            IntReleaseMenuObject(NewMenu);
-            UserSetMenuDefaultItem(NewMenu, SC_CLOSE, FALSE);
-
-            if (Window->pcls->style & CS_NOCLOSE)
-               IntRemoveMenuItem(NewMenu, SC_CLOSE, MF_BYCOMMAND, TRUE);
-
-            ItemInfo.cbSize = sizeof(MENUITEMINFOW);
-            ItemInfo.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE | MIIM_SUBMENU;
-            ItemInfo.fType = 0;
-            ItemInfo.fState = MFS_ENABLED;
-            ItemInfo.dwTypeData = NULL;
-            ItemInfo.cch = 0;
-            ItemInfo.hSubMenu = NewMenu->head.h;
-            IntInsertMenuItem(SysMenu, (UINT) -1, TRUE, &ItemInfo, NULL);
-
-            Window->SystemMenu = SysMenu->head.h;
-
-            ret = SysMenu;
-         }
-         IntDestroyMenuObject(Menu, FALSE, TRUE);
-      }
-      if(RetMenu)
-         return ret;
-      else
-         return NULL;
-   }
-   else
-   {
-      if(Window->SystemMenu)
-         return IntGetMenuObject((HMENU)Window->SystemMenu);
-      else
-         return NULL;
-   }
-}
-
-
 BOOL FASTCALL
 IntIsChildWindow(PWND Parent, PWND BaseWindow)
 {
@@ -1426,32 +1274,6 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
    return( hWndOldParent);
 }
 
-BOOL FASTCALL
-IntSetSystemMenu(PWND Window, PMENU Menu)
-{
-   PMENU OldMenu;
-   if(Window->SystemMenu)
-   {
-      OldMenu = IntGetMenuObject(Window->SystemMenu);
-      if(OldMenu)
-      {
-         OldMenu->fFlags &= ~ MNF_SYSDESKMN;
-         IntReleaseMenuObject(OldMenu);
-      }
-   }
-
-   if(Menu)
-   {
-      /* FIXME: Check window style, propably return FALSE? */
-      Window->SystemMenu = Menu->head.h;
-      Menu->fFlags |= MNF_SYSDESKMN;
-   }
-   else // Use spmenuSys too!
-      Window->SystemMenu = (HMENU)0;
-
-   return TRUE;
-}
-
 /* Unlink the window from siblings. children and parent are kept in place. */
 VOID FASTCALL
 IntUnlinkWindow(PWND Wnd)
@@ -1760,7 +1582,6 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
    PWND pWnd = NULL;
    HWND hWnd;
    PTHREADINFO pti = NULL;
-   PMENU SystemMenu;
    BOOL MenuChanged;
    BOOL bUnicodeWindow;
 
@@ -1853,7 +1674,38 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
    }
 
    pWnd->head.pti->cWindows++;
+#ifdef NEW_CURSORICON
+   if (Class->spicn && !Class->spicnSm)
+   {
+       HICON IconSmHandle = NULL;
+       if((Class->spicn->CURSORF_flags & (CURSORF_LRSHARED | CURSORF_FROMRESOURCE))
+               == (CURSORF_LRSHARED | CURSORF_FROMRESOURCE))
+       {
+           IconSmHandle = co_IntCopyImage(
+               UserHMGetHandle(Class->spicn),
+               IMAGE_ICON,
+               UserGetSystemMetrics( SM_CXSMICON ),
+               UserGetSystemMetrics( SM_CYSMICON ),
+               LR_COPYFROMRESOURCE | LR_SHARED);
+       }
+       if (!IconSmHandle)
+       {
+           /* Retry without copying from resource */
+           IconSmHandle = co_IntCopyImage(
+               UserHMGetHandle(Class->spicn),
+               IMAGE_ICON,
+               UserGetSystemMetrics( SM_CXSMICON ),
+               UserGetSystemMetrics( SM_CYSMICON ),
+               LR_SHARED);
+       }
 
+       if (IconSmHandle)
+       {
+           Class->spicnSm = UserGetCurIconObject(IconSmHandle);
+           Class->CSF_flags |= CSF_CACHEDSMICON;
+       }
+   }
+#else
    if (Class->hIcon && !Class->hIconSm)
    {
       Class->hIconSmIntern = co_IntCopyImage( Class->hIcon, IMAGE_ICON,
@@ -1862,6 +1714,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
       TRACE("IntCreateWindow hIconSmIntern %p\n",Class->hIconSmIntern);
       Class->CSF_flags |= CSF_CACHEDSMICON;
    }
+#endif
 
    if (pWnd->pcls->CSF_flags & CSF_SERVERSIDEPROC)
       pWnd->state |= WNDS_SERVERSIDEWINDOWPROC;
@@ -1933,7 +1786,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
    if (Class->atomClassName == gpsi->atomSysClass[ICLS_EDIT])
    {
       PCALLPROCDATA CallProc;
-      CallProc = CreateCallProc(NULL, pWnd->lpfnWndProc, pWnd->Unicode , pWnd->head.pti->ppi);
+      CallProc = CreateCallProc(pWnd->head.rpdesk, pWnd->lpfnWndProc, pWnd->Unicode , pWnd->head.pti->ppi);
 
       if (!CallProc)
       {
@@ -1947,6 +1800,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
    }
 
    InitializeListHead(&pWnd->PropListHead);
+   pWnd->PropListItems = 0;
 
    if ( WindowName->Buffer != NULL && WindowName->Length > 0 )
    {
@@ -1988,22 +1842,13 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
    if (!(pWnd->style & (WS_CHILD | WS_POPUP)))
       pWnd->state |= WNDS_SENDSIZEMOVEMSGS;
 
-   /* Create system menu */
-   if ((Cs->style & WS_SYSMENU)) // && (dwStyle & WS_CAPTION) == WS_CAPTION)
-   {
-      SystemMenu = IntGetSystemMenu(pWnd, TRUE, TRUE);
-      if(SystemMenu)
-      {  //    spmenuSys
-         pWnd->SystemMenu = SystemMenu->head.h;
-         IntReleaseMenuObject(SystemMenu);
-      }
-   }
-
    /* Set the window menu */
    if ((Cs->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
    {
-       if (Cs->hMenu)
+      if (Cs->hMenu)
+      {
          IntSetMenu(pWnd, Cs->hMenu, &MenuChanged);
+      }
       else if (pWnd->pcls->lpszMenuName) // Take it from the parent.
       {
           UNICODE_STRING MenuName;
@@ -2314,15 +2159,15 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
    Window->rcWindow.top = Cs->y;
    Window->rcWindow.right = Cs->x + Size.cx;
    Window->rcWindow.bottom = Cs->y + Size.cy;
-/*
+ /*
    if (0 != (Window->style & WS_CHILD) && ParentWindow)
    {
-//      ERR("co_UserCreateWindowEx(): Offset rcWindow\n");
+      ERR("co_UserCreateWindowEx(): Offset rcWindow\n");
       RECTL_vOffsetRect(&Window->rcWindow,
                         ParentWindow->rcClient.left,
                         ParentWindow->rcClient.top);
    }
-*/
+ */
    /* correct child window coordinates if mirroring on parent is enabled */
    if (ParentWindow != NULL)
    {
@@ -2428,7 +2273,11 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
    IntSendParentNotify(Window, WM_CREATE);
 
    /* Notify the shell that a new window was created */
-   if ((!hWndParent) && (!hWndOwner))
+   if (Window->spwndParent == UserGetDesktopWindow() &&
+       Window->spwndOwner == NULL &&
+       (Window->style & WS_VISIBLE) &&
+       (!(Window->ExStyle & WS_EX_TOOLWINDOW) ||
+        (Window->ExStyle & WS_EX_APPWINDOW)))
    {
       co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)hWnd, 0);
    }
@@ -2584,9 +2433,10 @@ NtUserCreateWindowEx(
     if ( (dwStyle & (WS_POPUP|WS_CHILD)) != WS_CHILD) 
     {
         /* check hMenu is valid handle */
-        if (hMenu && !ValidateHandle(hMenu, TYPE_MENU))
+        if (hMenu && !UserGetMenuObject(hMenu))
         {
-            /* error is set in ValidateHandle */
+            ERR("NtUserCreateWindowEx: Got an invalid menu handle!\n");
+            EngSetLastError(ERROR_INVALID_MENU_HANDLE);
             return NULL;
         }
     } 
@@ -2673,12 +2523,13 @@ cleanup:
 }
 
 
-BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
+BOOLEAN co_UserDestroyWindow(PVOID Object)
 {
    HWND hWnd;
    PWND pwndTemp;
    PTHREADINFO ti;
    MSG msg;
+   PWND Window = Object;
 
    ASSERT_REFS_CO(Window); // FIXME: Temp HACK?
 
@@ -3655,105 +3506,6 @@ CLEANUP:
    END_CLEANUP;
 }
 
-/*
- * NtUserGetSystemMenu
- *
- * The NtUserGetSystemMenu function allows the application to access the
- * window menu (also known as the system menu or the control menu) for
- * copying and modifying.
- *
- * Parameters
- *    hWnd
- *       Handle to the window that will own a copy of the window menu.
- *    bRevert
- *       Specifies the action to be taken. If this parameter is FALSE,
- *       NtUserGetSystemMenu returns a handle to the copy of the window menu
- *       currently in use. The copy is initially identical to the window menu
- *       but it can be modified.
- *       If this parameter is TRUE, GetSystemMenu resets the window menu back
- *       to the default state. The previous window menu, if any, is destroyed.
- *
- * Return Value
- *    If the bRevert parameter is FALSE, the return value is a handle to a
- *    copy of the window menu. If the bRevert parameter is TRUE, the return
- *    value is NULL.
- *
- * Status
- *    @implemented
- */
-
-HMENU APIENTRY
-NtUserGetSystemMenu(HWND hWnd, BOOL bRevert)
-{
-   PWND Window;
-   PMENU Menu;
-   DECLARE_RETURN(HMENU);
-
-   TRACE("Enter NtUserGetSystemMenu\n");
-   UserEnterShared();
-
-   if (!(Window = UserGetWindowObject(hWnd)))
-   {
-      RETURN(NULL);
-   }
-
-   if (!(Menu = IntGetSystemMenu(Window, bRevert, FALSE)))
-   {
-      RETURN(NULL);
-   }
-
-   RETURN(Menu->head.h);
-
-CLEANUP:
-   TRACE("Leave NtUserGetSystemMenu, ret=%p\n", _ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
-/*
- * NtUserSetSystemMenu
- *
- * Status
- *    @implemented
- */
-
-BOOL APIENTRY
-NtUserSetSystemMenu(HWND hWnd, HMENU hMenu)
-{
-   BOOL Result = FALSE;
-   PWND Window;
-   PMENU Menu;
-   DECLARE_RETURN(BOOL);
-
-   TRACE("Enter NtUserSetSystemMenu\n");
-   UserEnterExclusive();
-
-   if (!(Window = UserGetWindowObject(hWnd)))
-   {
-      RETURN( FALSE);
-   }
-
-   if (hMenu)
-   {
-      /*
-       * Assign new menu handle.
-       */
-      if (!(Menu = UserGetMenuObject(hMenu)))
-      {
-         RETURN( FALSE);
-      }
-
-      Result = IntSetSystemMenu(Window, Menu);
-   }
-
-   RETURN( Result);
-
-CLEANUP:
-   TRACE("Leave NtUserSetSystemMenu, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
 // Fixes wine Win test_window_styles and todo tests...
 static BOOL FASTCALL
 IntCheckFrameEdge(ULONG Style, ULONG ExStyle)