* PROJECT: ReactOS user32.dll
* 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);
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;
}
}
}
}
- 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);
}
}
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++ )
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;
}
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;
}