[Win32k]
[reactos.git] / reactos / dll / win32 / user32 / windows / window.c
index 6ed38cc..4cc757f 100644 (file)
@@ -18,8 +18,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32);
 LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
 void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id );
 
-#define CW_USEDEFAULT16 0x00008000
-
 /* FUNCTIONS *****************************************************************/
 
 
@@ -29,9 +27,10 @@ User32CallSendAsyncProcForKernel(PVOID Arguments, ULONG ArgumentLength)
     PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs;
 
     TRACE("User32CallSendAsyncProcKernel()\n");
+
     CallbackArgs = (PSENDASYNCPROC_CALLBACK_ARGUMENTS)Arguments;
 
-    if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
+    if (ArgumentLength != sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS))
     {
         return(STATUS_INFO_LENGTH_MISMATCH);
     }
@@ -66,17 +65,7 @@ AllowSetForegroundWindow(DWORD dwProcessId)
 HDWP WINAPI
 BeginDeferWindowPos(int nNumWindows)
 {
-    if (nNumWindows < 0)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return 0;
-    }
-#if 0
-    UNIMPLEMENTED;
-    return (HDWP)0;
-#else
-    return (HDWP)1;
-#endif
+    return (HDWP)NtUserCallOneParam((DWORD_PTR)nNumWindows, ONEPARAM_ROUTINE_BEGINDEFERWNDPOS);
 }
 
 
@@ -134,9 +123,37 @@ CloseWindow(HWND hWnd)
 {
     SendMessageA(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
 
-    return (BOOL)(hWnd);
+    return HandleToUlong(hWnd);
+}
+
+VOID
+FORCEINLINE
+RtlInitLargeString(
+    OUT PLARGE_STRING plstr,
+    LPCVOID psz,
+    BOOL bUnicode)
+{
+    if(bUnicode)
+    {
+        RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)plstr, (PWSTR)psz, 0);
+    }
+    else
+    {
+        RtlInitLargeAnsiString((PLARGE_ANSI_STRING)plstr, (PSTR)psz, 0);
+    }
 }
 
+VOID
+NTAPI
+RtlFreeLargeString(
+    IN PLARGE_STRING LargeString)
+{
+    if (LargeString->Buffer)
+    {
+        RtlFreeHeap(GetProcessHeap(), 0, LargeString->Buffer);
+        RtlZeroMemory(LargeString, sizeof(LARGE_STRING));
+    }
+}
 
 HWND WINAPI
 User32CreateWindowEx(DWORD dwExStyle,
@@ -153,11 +170,12 @@ User32CreateWindowEx(DWORD dwExStyle,
                      LPVOID lpParam,
                      BOOL Unicode)
 {
-    UNICODE_STRING WindowName;
+    LARGE_STRING WindowName;
+    LARGE_STRING lstrClassName, *plstrClassName;
     UNICODE_STRING ClassName;
     WNDCLASSEXA wceA;
     WNDCLASSEXW wceW;
-    HWND Handle;
+    HWND Handle = NULL;
 
 #if 0
     DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent);
@@ -171,8 +189,7 @@ User32CreateWindowEx(DWORD dwExStyle,
 
     if (IS_ATOM(lpClassName))
     {
-        RtlInitUnicodeString(&ClassName, NULL);
-        ClassName.Buffer = (LPWSTR)lpClassName;
+        plstrClassName = (PVOID)lpClassName;
     }
     else
     {
@@ -180,26 +197,49 @@ User32CreateWindowEx(DWORD dwExStyle,
             RtlInitUnicodeString(&ClassName, (PCWSTR)lpClassName);
         else
         {
-            if (!RtlCreateUnicodeStringFromAsciiz(&(ClassName), (PCSZ)lpClassName))
+            if (!RtlCreateUnicodeStringFromAsciiz(&ClassName, (PCSZ)lpClassName))
             {
                 SetLastError(ERROR_OUTOFMEMORY);
                 return (HWND)0;
             }
         }
+        
+        /* Copy it to a LARGE_STRING */
+        lstrClassName.Buffer = ClassName.Buffer;
+        lstrClassName.Length = ClassName.Length;
+        lstrClassName.MaximumLength = ClassName.MaximumLength;
+        plstrClassName = &lstrClassName;
     }
 
-    if (Unicode)
-        RtlInitUnicodeString(&WindowName, (PCWSTR)lpWindowName);
-    else
+    /* Initialize a LARGE_STRING */
+    RtlInitLargeString(&WindowName, lpWindowName, Unicode);
+
+    // HACK: The current implementation expects the Window name to be UNICODE
+    if (!Unicode)
     {
-        if (!RtlCreateUnicodeStringFromAsciiz(&WindowName, (PCSZ)lpWindowName))
+        NTSTATUS Status;
+        PSTR AnsiBuffer = WindowName.Buffer;
+        ULONG AnsiLength = WindowName.Length;
+        
+        WindowName.Length = 0;
+        WindowName.MaximumLength = AnsiLength * sizeof(WCHAR);
+        WindowName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                                            0,
+                                            WindowName.MaximumLength);
+        if (!WindowName.Buffer)
         {
-            if (!IS_ATOM(lpClassName))
-            {
-                RtlFreeUnicodeString(&ClassName);
-            }
             SetLastError(ERROR_OUTOFMEMORY);
-            return (HWND)0;
+            goto cleanup;
+        }
+
+        Status = RtlMultiByteToUnicodeN(WindowName.Buffer,
+                                        WindowName.MaximumLength,
+                                        &WindowName.Length,
+                                        AnsiBuffer,
+                                        AnsiLength);
+        if (!NT_SUCCESS(Status))
+        {
+            goto cleanup;
         }
     }
 
@@ -223,8 +263,11 @@ User32CreateWindowEx(DWORD dwExStyle,
         }
     }
 
+    if (!Unicode) dwExStyle |= WS_EX_SETANSICREATOR;
+
     Handle = NtUserCreateWindowEx(dwExStyle,
-                                  &ClassName,
+                                  plstrClassName,
+                                  NULL,
                                   &WindowName,
                                   dwStyle,
                                   x,
@@ -235,23 +278,23 @@ User32CreateWindowEx(DWORD dwExStyle,
                                   hMenu,
                                   hInstance,
                                   lpParam,
-                                  SW_SHOW,
-                                  Unicode,
-                                  0);
+                                  0,
+                                  NULL);
 
 #if 0
     DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle);
 #endif
-
+cleanup:
     if(!Unicode)
     {
-        RtlFreeUnicodeString(&WindowName);
-
         if (!IS_ATOM(lpClassName))
         {
             RtlFreeUnicodeString(&ClassName);
         }
+        
+        RtlFreeLargeString(&WindowName);
     }
+
     return Handle;
 }
 
@@ -287,6 +330,17 @@ CreateWindowExA(DWORD dwExStyle,
         POINT mPos[2];
         UINT id = 0;
         HWND top_child;
+        PWND pWndParent;
+
+        pWndParent = ValidateHwnd(hWndParent);
+
+        if (!pWndParent) return NULL;
+
+        if (pWndParent->fnid != FNID_MDICLIENT) // wine uses WIN_ISMDICLIENT
+        {
+           WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent);
+           return NULL;
+        }
 
         /* lpParams of WM_[NC]CREATE is different for MDI children.
         * MDICREATESTRUCT members have the originally passed values.
@@ -303,7 +357,7 @@ CreateWindowExA(DWORD dwExStyle,
 
         lpParam = (LPVOID)&mdi;
 
-        if (GetWindowLongPtrW(hWndParent, GWL_STYLE) & MDIS_ALLCHILDSTYLES)
+        if (pWndParent->style & MDIS_ALLCHILDSTYLES)
         {
             if (dwStyle & WS_POPUP)
             {
@@ -335,7 +389,7 @@ CreateWindowExA(DWORD dwExStyle,
 
         MDI_CalcDefaultChildPos(hWndParent, -1, mPos, 0, &id);
 
-        if (!(dwStyle & WS_POPUP)) hMenu = (HMENU)id;
+        if (!(dwStyle & WS_POPUP)) hMenu = UlongToHandle(id);
 
         if (dwStyle & (WS_CHILD | WS_POPUP))
         {
@@ -399,7 +453,18 @@ CreateWindowExW(DWORD dwExStyle,
         POINT mPos[2];
         UINT id = 0;
         HWND top_child;
+        PWND pWndParent;
+
+        pWndParent = ValidateHwnd(hWndParent);
 
+        if (!pWndParent) return NULL;
+
+        if (pWndParent->fnid != FNID_MDICLIENT)
+        {
+           WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent);
+           return NULL;
+        }
+        
         /* lpParams of WM_[NC]CREATE is different for MDI children.
         * MDICREATESTRUCT members have the originally passed values.
         */
@@ -415,7 +480,7 @@ CreateWindowExW(DWORD dwExStyle,
 
         lpParam = (LPVOID)&mdi;
 
-        if (GetWindowLongPtrW(hWndParent, GWL_STYLE) & MDIS_ALLCHILDSTYLES)
+        if (pWndParent->style & MDIS_ALLCHILDSTYLES)
         {
             if (dwStyle & WS_POPUP)
             {
@@ -447,7 +512,7 @@ CreateWindowExW(DWORD dwExStyle,
 
         MDI_CalcDefaultChildPos(hWndParent, -1, mPos, 0, &id);
 
-        if (!(dwStyle & WS_POPUP)) hMenu = (HMENU)id;
+        if (!(dwStyle & WS_POPUP)) hMenu = UlongToHandle(id);
 
         if (dwStyle & (WS_CHILD | WS_POPUP))
         {
@@ -492,12 +557,7 @@ DeferWindowPos(HDWP hWinPosInfo,
                int cy,
                UINT uFlags)
 {
-#if 0
     return NtUserDeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
-#else
-    SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
-    return hWinPosInfo;
-#endif
 }
 
 
@@ -507,12 +567,7 @@ DeferWindowPos(HDWP hWinPosInfo,
 BOOL WINAPI
 EndDeferWindowPos(HDWP hWinPosInfo)
 {
-#if 0
-    UNIMPLEMENTED;
-    return FALSE;
-#else
-    return TRUE;
-#endif
+    return NtUserEndDeferWindowPosEx(hWinPosInfo, 0);
 }
 
 
@@ -598,6 +653,14 @@ User32EnumWindows(HDESK hDesktop,
         return FALSE;
     }
 
+    if (!dwCount)
+    {
+       if (!dwThreadId)
+          return FALSE; 
+       else
+          return TRUE;
+    }
+
     /* call the user's callback function until we're done or
        they tell us to quit */
     for ( i = 0; i < dwCount; i++ )
@@ -605,9 +668,10 @@ User32EnumWindows(HDESK hDesktop,
         /* FIXME I'm only getting NULLs from Thread Enumeration, and it's
          * probably because I'm not doing it right in NtUserBuildHwndList.
          * Once that's fixed, we shouldn't have to check for a NULL HWND
-         * here
+         * here 
+         * This is now fixed in revision 50205. (jt)
          */
-        if (!(ULONG)pHwnd[i]) /* don't enumerate a NULL HWND */
+        if (!pHwnd[i]) /* don't enumerate a NULL HWND */
             continue;
         if (!(*lpfn)(pHwnd[i], lParam))
         {
@@ -945,16 +1009,16 @@ GetParent(HWND hWnd)
         _SEH2_TRY
         {
             WndParent = NULL;
-            if (Wnd->style & WS_CHILD)
-            {
-                if (Wnd->spwndParent != NULL)
-                    WndParent = DesktopPtrToUser(Wnd->spwndParent);
-            }
-            else if (Wnd->style & WS_POPUP)
+            if (Wnd->style & WS_POPUP)
             {
                 if (Wnd->spwndOwner != NULL)
                     WndParent = DesktopPtrToUser(Wnd->spwndOwner);
             }
+            else if (Wnd->style & WS_CHILD)
+            {
+                if (Wnd->spwndParent != NULL)
+                    WndParent = DesktopPtrToUser(Wnd->spwndParent);
+            }
 
             if (WndParent != NULL)
                 Ret = UserHMGetHandle(WndParent);
@@ -1357,8 +1421,8 @@ GetWindowThreadProcessId(HWND hWnd,
         { // We are current.
           //FIXME("Current!\n");
             if (lpdwProcessId)
-                *lpdwProcessId = (DWORD)NtCurrentTeb()->ClientId.UniqueProcess;
-            Ret = (DWORD)NtCurrentTeb()->ClientId.UniqueThread;
+                *lpdwProcessId = (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueProcess;
+            Ret = (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueThread;
         }
         else
         { // Ask kernel for info.
@@ -1379,7 +1443,7 @@ BOOL WINAPI
 IsChild(HWND hWndParent,
     HWND hWnd)
 {
-    PWND WndParent, Wnd;
+    PWND WndParent, DesktopWnd,  Wnd;
     BOOL Ret = FALSE;
 
     WndParent = ValidateHwnd(hWndParent);
@@ -1389,13 +1453,18 @@ IsChild(HWND hWndParent,
     if (!Wnd)
         return FALSE;
 
+    DesktopWnd = GetThreadDesktopWnd();
+    if (!DesktopWnd)
+        return FALSE;
+
     _SEH2_TRY
     {
-        while (Wnd != NULL)
+        while (Wnd != NULL && ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD))
         {
             if (Wnd->spwndParent != NULL)
             {
                 Wnd = DesktopPtrToUser(Wnd->spwndParent);
+
                 if (Wnd == WndParent)
                 {
                     Ret = TRUE;
@@ -1638,7 +1707,7 @@ SetWindowTextA(HWND hWnd,
 
         if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
         {
-            DefWndNCPaint(hWnd, (HRGN)1, -1);
+            DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
         }
         return TRUE;
     }
@@ -1668,7 +1737,7 @@ SetWindowTextW(HWND hWnd,
 
         if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
         {
-            DefWndNCPaint(hWnd, (HRGN)1, -1);
+            DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
         }
         return TRUE;
     }
@@ -1740,92 +1809,6 @@ UpdateLayeredWindowIndirect(HWND hwnd,
   return FALSE;
 }
 
-
-/*
- * @implemented
- */
-HWND WINAPI
-WindowFromPoint(POINT Point)
-{
-    //TODO: Determine what the actual parameters to
-    // NtUserWindowFromPoint are.
-    return NtUserWindowFromPoint(Point.x, Point.y);
-}
-
-
-/*
- * @implemented
- */
-int WINAPI
-MapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT cPoints)
-{
-    PWND FromWnd, ToWnd;
-    POINT Delta;
-    UINT i;
-
-    FromWnd = ValidateHwndOrDesk(hWndFrom);
-    if (!FromWnd)
-        return 0;
-
-    ToWnd = ValidateHwndOrDesk(hWndTo);
-    if (!ToWnd)
-        return 0;
-
-    Delta.x = FromWnd->rcClient.left - ToWnd->rcClient.left;
-    Delta.y = FromWnd->rcClient.top - ToWnd->rcClient.top;
-
-    for (i = 0; i != cPoints; i++)
-    {
-        lpPoints[i].x += Delta.x;
-        lpPoints[i].y += Delta.y;
-    }
-
-    return MAKELONG(LOWORD(Delta.x), LOWORD(Delta.y));
-}
-
-
-/*
- * @implemented
- */
-BOOL WINAPI
-ScreenToClient(HWND hWnd, LPPOINT lpPoint)
-{
-    PWND Wnd, DesktopWnd;
-
-    Wnd = ValidateHwnd(hWnd);
-    if (!Wnd)
-        return FALSE;
-
-    DesktopWnd = GetThreadDesktopWnd();
-
-    lpPoint->x += DesktopWnd->rcClient.left - Wnd->rcClient.left;
-    lpPoint->y += DesktopWnd->rcClient.top - Wnd->rcClient.top;
-
-    return TRUE;
-}
-
-
-/*
- * @implemented
- */
-BOOL WINAPI
-ClientToScreen(HWND hWnd, LPPOINT lpPoint)
-{
-    PWND Wnd, DesktopWnd;
-
-    Wnd = ValidateHwnd(hWnd);
-    if (!Wnd)
-        return FALSE;
-
-    DesktopWnd = GetThreadDesktopWnd();
-
-    lpPoint->x += Wnd->rcClient.left - DesktopWnd->rcClient.left;
-    lpPoint->y += Wnd->rcClient.top - DesktopWnd->rcClient.top;
-
-    return TRUE;
-}
-
-
 /*
  * @implemented
  */
@@ -1836,7 +1819,6 @@ SetWindowContextHelpId(HWND hwnd,
     return NtUserSetWindowContextHelpId(hwnd, dwContextHelpId);
 }
 
-
 /*
  * @implemented
  */
@@ -1977,7 +1959,18 @@ ScrollWindowEx(HWND hWnd,
 BOOL WINAPI
 AnyPopup(VOID)
 {
-    return NtUserAnyPopup();
+    int i;
+    BOOL retvalue;
+    HWND *list = WIN_ListChildren( GetDesktopWindow() );
+
+    if (!list) return FALSE;
+    for (i = 0; list[i]; i++)
+    {
+        if (IsWindowVisible( list[i] ) && GetWindow( list[i], GW_OWNER )) break;
+    }
+    retvalue = (list[i] != 0);
+    HeapFree( GetProcessHeap(), 0, list );
+    return retvalue;
 }
 
 /*
@@ -1986,7 +1979,11 @@ AnyPopup(VOID)
 BOOL WINAPI
 IsWindowInDestroy(HWND hWnd)
 {
-    return NtUserIsWindowInDestroy(hWnd);
+    PWND pwnd;
+    pwnd = ValidateHwnd(hWnd);
+    if (!pwnd)
+       return FALSE;
+    return ((pwnd->state2 & WNDS2_INDESTROY) == WNDS2_INDESTROY);
 }
 
 /*