/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
- * FILE: lib/user32/windows/window.c
+ * FILE: win32ss/user/user32/windows/window.c
* PURPOSE: Window management
- * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
* UPDATE HISTORY:
* 06-06-2001 CSH Created
*/
-/* INCLUDES ******************************************************************/
#define DEBUG
#include <user32.h>
-#include <wine/debug.h>
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 );
+extern LPCWSTR FASTCALL ClassNameToVersion(const void *lpszClass, LPCWSTR lpszMenuName, LPCWSTR *plpLibFileName, HANDLE *pContext, BOOL bAnsi);
/* FUNCTIONS *****************************************************************/
VOID WINAPI
-SwitchToThisWindow(HWND hwnd, BOOL fUnknown)
+SwitchToThisWindow(HWND hwnd, BOOL bUnknown)
{
- ShowWindow(hwnd, SW_SHOW);
+ NtUserxSwitchToThisWindow(hwnd, bUnknown);
}
BOOL WINAPI
CloseWindow(HWND hWnd)
{
- SendMessageA(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
-
- return HandleToUlong(hWnd);
+ /* NOTE: CloseWindow does minimizes, and doesn't close. */
+ SetActiveWindow(hWnd);
+ return ShowWindow(hWnd, SW_SHOWMINIMIZED);
}
FORCEINLINE
{
LARGE_STRING WindowName;
LARGE_STRING lstrClassName, *plstrClassName;
+ LARGE_STRING lstrClassVersion, *plstrClassVersion;
UNICODE_STRING ClassName;
+ UNICODE_STRING ClassVersion;
WNDCLASSEXA wceA;
WNDCLASSEXW wceW;
HMODULE hLibModule = NULL;
- DWORD save_error;
+ DWORD dwLastError;
BOOL Unicode, ClassFound = FALSE;
HWND Handle = NULL;
+ LPCWSTR lpszClsVersion;
+ LPCWSTR lpLibFileName = NULL;
+ HANDLE pCtx = NULL;
#if 0
DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent);
if (!RegisterDefaultClasses)
{
- TRACE("RegisterSystemControls\n");
- RegisterSystemControls();
+ TRACE("RegisterSystemControls\n");
+ RegisterSystemControls();
}
Unicode = !(dwFlags & NUCWE_ANSI);
}
else
{
- if(Unicode)
+ if (Unicode)
+ {
RtlInitUnicodeString(&ClassName, (PCWSTR)lpClassName);
+ }
else
{
if (!RtlCreateUnicodeStringFromAsciiz(&ClassName, (PCSZ)lpClassName))
{
SetLastError(ERROR_OUTOFMEMORY);
- return (HWND)0;
+ return NULL;
}
}
-
+
/* Copy it to a LARGE_STRING */
lstrClassName.Buffer = ClassName.Buffer;
lstrClassName.Length = ClassName.Length;
NTSTATUS Status;
PSTR AnsiBuffer = WindowName.Buffer;
ULONG AnsiLength = WindowName.Length;
-
+
WindowName.Length = 0;
WindowName.MaximumLength = AnsiLength * sizeof(WCHAR);
WindowName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
}
}
- if(!hMenu && (dwStyle & (WS_OVERLAPPEDWINDOW | WS_POPUP)))
+ if (!hMenu && (dwStyle & (WS_OVERLAPPEDWINDOW | WS_POPUP)))
{
- if(Unicode)
+ if (Unicode)
{
- wceW.cbSize = sizeof(WNDCLASSEXW);
- if(GetClassInfoExW(hInstance, (LPCWSTR)lpClassName, &wceW) && wceW.lpszMenuName)
+ wceW.cbSize = sizeof(wceW);
+ if (GetClassInfoExW(hInstance, (LPCWSTR)lpClassName, &wceW) && wceW.lpszMenuName)
{
hMenu = LoadMenuW(hInstance, wceW.lpszMenuName);
}
}
else
{
- wceA.cbSize = sizeof(WNDCLASSEXA);
- if(GetClassInfoExA(hInstance, lpClassName, &wceA) && wceA.lpszMenuName)
+ wceA.cbSize = sizeof(wceA);
+ if (GetClassInfoExA(hInstance, lpClassName, &wceA) && wceA.lpszMenuName)
{
hMenu = LoadMenuA(hInstance, wceA.lpszMenuName);
}
if (!Unicode) dwExStyle |= WS_EX_SETANSICREATOR;
- for(;;)
+ lpszClsVersion = ClassNameToVersion(lpClassName, NULL, &lpLibFileName, &pCtx, !Unicode);
+ if (!lpszClsVersion)
{
- Handle = NtUserCreateWindowEx(dwExStyle,
- plstrClassName,
- NULL,
- &WindowName,
- dwStyle,
- x,
- y,
- nWidth,
- nHeight,
- hWndParent,
- hMenu,
- hInstance,
- lpParam,
- dwFlags,
- NULL);
- if (Handle) break;
- if (!ClassFound)
- {
- save_error = GetLastError();
- if ( save_error == ERROR_CANNOT_FIND_WND_CLASS )
- {
- ClassFound = VersionRegisterClass(ClassName.Buffer, NULL, NULL, &hLibModule);
- if (ClassFound) continue;
- }
- }
- if (hLibModule)
- {
- save_error = GetLastError();
- FreeLibrary(hLibModule);
- SetLastError(save_error);
- hLibModule = 0;
- }
- break;
+ plstrClassVersion = plstrClassName;
+ }
+ else
+ {
+ RtlInitUnicodeString(&ClassVersion, lpszClsVersion);
+ lstrClassVersion.Buffer = ClassVersion.Buffer;
+ lstrClassVersion.Length = ClassVersion.Length;
+ lstrClassVersion.MaximumLength = ClassVersion.MaximumLength;
+ plstrClassVersion = &lstrClassVersion;
+ }
+
+ for (;;)
+ {
+ Handle = NtUserCreateWindowEx(dwExStyle,
+ plstrClassName,
+ plstrClassVersion,
+ &WindowName,
+ dwStyle,
+ x,
+ y,
+ nWidth,
+ nHeight,
+ hWndParent,
+ hMenu,
+ hInstance,
+ lpParam,
+ dwFlags,
+ NULL);
+ if (Handle) break;
+ if (!lpLibFileName) break;
+ if (!ClassFound)
+ {
+ dwLastError = GetLastError();
+ if (dwLastError == ERROR_CANNOT_FIND_WND_CLASS)
+ {
+ ClassFound = VersionRegisterClass(ClassName.Buffer, lpLibFileName, pCtx, &hLibModule);
+ if (ClassFound) continue;
+ }
+ }
+ if (hLibModule)
+ {
+ dwLastError = GetLastError();
+ FreeLibrary(hLibModule);
+ SetLastError(dwLastError);
+ hLibModule = NULL;
+ }
+ break;
}
#if 0
DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle);
#endif
+
cleanup:
- if(!Unicode)
+ if (!Unicode)
{
if (!IS_ATOM(lpClassName))
- {
RtlFreeUnicodeString(&ClassName);
- }
-
+
RtlFreeLargeString(&WindowName);
}
if (!RegisterDefaultClasses)
{
- ERR("CreateWindowExA RegisterSystemControls\n");
+ TRACE("CreateWindowExA RegisterSystemControls\n");
RegisterSystemControls();
}
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.
*/
}
hwnd = User32CreateWindowEx(dwExStyle,
- (LPCSTR) lpClassName,
- (LPCSTR) lpWindowName,
+ (LPCSTR)lpClassName,
+ (LPCSTR)lpWindowName,
dwStyle,
x,
y,
if (!NT_SUCCESS(Status))
return FALSE;
+ if (!dwCount)
+ {
+ if (!dwThreadId)
+ return FALSE;
+ else
+ return TRUE;
+ }
+
/* allocate buffer to receive HWND handles */
hHeap = GetProcessHeap();
pHwnd = HeapAlloc(hHeap, 0, sizeof(HWND)*(dwCount+1));
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++ )
/* 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 (!pHwnd[i]) /* don't enumerate a NULL HWND */
{
HWND Ret = NULL;
PWND Ancestor, Wnd;
-
+
Wnd = ValidateHwnd(hwnd);
if (!Wnd)
return NULL;
lpRect->bottom = GetSystemMetrics(SM_CYMINIMIZED);
return TRUE;
}
- if ( hWnd != GetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
+ if ( hWnd != GetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
{
/* lpRect->left = lpRect->top = 0;
lpRect->right = Wnd->rcClient.right - Wnd->rcClient.left;
/* Do this until Init bug is fixed. This sets 640x480, see InitMetrics.
lpRect->right = GetSystemMetrics(SM_CXSCREEN);
lpRect->bottom = GetSystemMetrics(SM_CYSCREEN);
-*/ }
+*/ }
return TRUE;
}
if (Wnd->spwndPrev != NULL)
FoundWnd = DesktopPtrToUser(Wnd->spwndPrev);
break;
-
+
case GW_CHILD:
if (Wnd->spwndChild != NULL)
FoundWnd = DesktopPtrToUser(Wnd->spwndChild);
lpString[0] = '\0';
- if (!TestWindowProcess( Wnd))
+ if (!TestWindowProcess(Wnd))
{
- _SEH2_TRY
- {
- Length = DefWindowProcA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Length = 0;
- }
- _SEH2_END;
+ _SEH2_TRY
+ {
+ Length = DefWindowProcA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Length = 0;
+ }
+ _SEH2_END;
}
else
- Length = SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
+ {
+ Length = SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
+ }
//ERR("GWTA Len %d : %s\n",Length,lpString);
return Length;
}
int WINAPI
GetWindowTextLengthA(HWND hWnd)
{
- return(SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0));
+ PWND Wnd;
+
+ Wnd = ValidateHwnd(hWnd);
+ if (!Wnd)
+ return 0;
+
+ if (!TestWindowProcess(Wnd))
+ {
+ return DefWindowProcA(hWnd, WM_GETTEXTLENGTH, 0, 0);
+ }
+ else
+ {
+ return SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
+ }
}
/*
int WINAPI
GetWindowTextLengthW(HWND hWnd)
{
- return(SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0));
+ PWND Wnd;
+
+ Wnd = ValidateHwnd(hWnd);
+ if (!Wnd)
+ return 0;
+
+ if (!TestWindowProcess(Wnd))
+ {
+ return DefWindowProcW(hWnd, WM_GETTEXTLENGTH, 0, 0);
+ }
+ else
+ {
+ return SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0);
+ }
}
/*
lpString[0] = L'\0';
- if (!TestWindowProcess( Wnd))
+ if (!TestWindowProcess(Wnd))
{
- _SEH2_TRY
- {
- Length = DefWindowProcW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Length = 0;
- }
- _SEH2_END;
+ _SEH2_TRY
+ {
+ Length = DefWindowProcW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Length = 0;
+ }
+ _SEH2_END;
}
else
- Length = SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
+ {
+ Length = SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
+ }
//ERR("GWTW Len %d : %S\n",Length,lpString);
return Length;
}
if (!pWnd) return Ret;
ti = pWnd->head.pti;
-
+
if (ti)
{
if (ti == GetW32ThreadInfo())
BLENDFUNCTION *pbl,
DWORD dwFlags)
{
- if ( dwFlags & ULW_EX_NORESIZE)
- dwFlags = ~(ULW_EX_NORESIZE|ULW_OPAQUE|ULW_ALPHA|ULW_COLORKEY);
+ if (dwFlags & ULW_EX_NORESIZE) /* only valid for UpdateLayeredWindowIndirect */
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
return NtUserUpdateLayeredWindow( hwnd,
hdcDst,
pptDst,
InternalGetWindowText(HWND hWnd, LPWSTR lpString, int nMaxCount)
{
INT Ret = NtUserInternalGetWindowText(hWnd, lpString, nMaxCount);
- if (Ret == 0)
+ if (Ret == 0 && lpString)
*lpString = L'\0';
return Ret;
}