diff --git a/reactos/lib/user32/Makefile b/reactos/lib/user32/Makefile index d0a8f825d42..05b1973d575 100644 --- a/reactos/lib/user32/Makefile +++ b/reactos/lib/user32/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.23 2003/08/07 04:03:23 royce Exp $ +# $Id: Makefile,v 1.24 2003/08/08 02:57:53 royce Exp $ PATH_TO_TOP = ../.. @@ -45,7 +45,8 @@ MISC_OBJECTS = \ misc/winsta.o \ misc/resources.o \ misc/object.o \ - misc/timer.o + misc/timer.o \ + misc/strpool.o WINDOWS_OBJECTS = \ windows/caret.o \ diff --git a/reactos/lib/user32/include/menu.h b/reactos/lib/user32/include/menu.h index 5a38b18de4f..443dcc4364b 100644 --- a/reactos/lib/user32/include/menu.h +++ b/reactos/lib/user32/include/menu.h @@ -19,9 +19,4 @@ MenuTrackMouseMenuBar(HWND hWnd, ULONG Ht, POINT Pt); VOID MenuTrackKbdMenuBar(HWND hWnd, ULONG wParam, ULONG Key); -NTSTATUS -HEAP_strdupA2Wlen ( HANDLE hHeap, LPWSTR* ppszW, LPCSTR lpszA, ULONG len ); -VOID -HEAP_free ( HANDLE hHeap, LPVOID memory ); - #endif /* __LIB_USER32_INCLUDE_MENU_H */ diff --git a/reactos/lib/user32/include/strpool.h b/reactos/lib/user32/include/strpool.h new file mode 100644 index 00000000000..fa511a42e90 --- /dev/null +++ b/reactos/lib/user32/include/strpool.h @@ -0,0 +1,35 @@ +// strpool.h + +#ifndef __USER32_INTERNAL_STRING_POOL_H +#define __USER32_INTERNAL_STRING_POOL_H + +extern HANDLE hProcessHeap; + +PVOID +HEAP_alloc ( DWORD len ); + +VOID +HEAP_free ( LPVOID memory ); + +LPWSTR +HEAP_strdupW ( LPCWSTR src, DWORD len ); + +NTSTATUS +HEAP_strcpyWtoA ( LPSTR lpszA, LPCWSTR lpszW, DWORD len ); + +NTSTATUS +HEAP_strcpyAtoW ( LPWSTR lpszW, LPCSTR lpszA, DWORD len ); + +NTSTATUS +HEAP_strdupWtoA ( LPSTR* ppszA, LPCWSTR lpszW, DWORD len ); + +NTSTATUS +HEAP_strdupAtoW ( LPWSTR* ppszW, LPCSTR lpszA, UINT* NewLen ); + +char* +heap_string_poolA ( const wchar_t* pstrW, DWORD length ); + +wchar_t* +heap_string_poolW ( const wchar_t* pstrWSrc, DWORD length ); + +#endif//__USER32_INTERNAL_STRING_POOL_H diff --git a/reactos/lib/user32/misc/dllmain.c b/reactos/lib/user32/misc/dllmain.c index 190ea2e79a2..1cfd1fac4ba 100644 --- a/reactos/lib/user32/misc/dllmain.c +++ b/reactos/lib/user32/misc/dllmain.c @@ -5,6 +5,7 @@ #include #include #include +#include #ifdef DBG @@ -110,6 +111,7 @@ DllMain(PVOID hinstDll, switch (dwReason) { case DLL_PROCESS_ATTACH: + hProcessHeap = RtlGetProcessHeap(); Init(); InitThread(); break; diff --git a/reactos/lib/user32/misc/strpool.c b/reactos/lib/user32/misc/strpool.c new file mode 100644 index 00000000000..4afc909ecbc --- /dev/null +++ b/reactos/lib/user32/misc/strpool.c @@ -0,0 +1,165 @@ +// strpool.c + +#include +#include +#include +#include + +typedef struct tagHEAP_STRING_POOLA +{ + char* data; + struct tagHEAP_STRING_POOLA* next; +} HEAP_STRING_POOLA, *PHEAP_STRING_POOLA; + +typedef struct tagHEAP_STRING_POOLW +{ + wchar_t* data; + struct tagHEAP_STRING_POOLW* next; +} HEAP_STRING_POOLW, *PHEAP_STRING_POOLW; + +PHEAP_STRING_POOLA heap_string_Apool = NULL; + +PHEAP_STRING_POOLW heap_string_Wpool = NULL; + +HANDLE hProcessHeap = NULL; + +PVOID +HEAP_alloc ( DWORD len ) +{ + return RtlAllocateHeap ( hProcessHeap, 0, len ); +} + +VOID +HEAP_free ( LPVOID memory ) +{ + RtlFreeHeap ( hProcessHeap, 0, memory ); +} + +LPWSTR +HEAP_strdupW ( LPCWSTR src, DWORD len ) +{ + LPWSTR dst; + + if ( !src ) + return NULL; + + dst = HEAP_alloc ( (len+1) * sizeof(WCHAR) ); + if ( !dst ) + return NULL; + memcpy ( dst, src, (len+1)*sizeof(WCHAR) ); + return dst; +} + +NTSTATUS +HEAP_strcpyWtoA ( LPSTR lpszA, LPCWSTR lpszW, DWORD len ) +{ + NTSTATUS Status = + RtlUnicodeToMultiByteN ( lpszA, len, NULL, (LPWSTR)lpszW, len*sizeof(WCHAR) ); + lpszA[len] = '\0'; + return Status; +} + +NTSTATUS +HEAP_strcpyAtoW ( LPWSTR lpszW, LPCSTR lpszA, DWORD len ) +{ + NTSTATUS Status = + RtlMultiByteToUnicodeN ( lpszW, len*sizeof(WCHAR), NULL, (LPSTR)lpszA, len ); + lpszW[len] = L'\0'; + return Status; +} + +NTSTATUS +HEAP_strdupWtoA ( LPSTR* ppszA, LPCWSTR lpszW, DWORD len ) +{ + *ppszA = NULL; + + if ( !lpszW ) + return STATUS_SUCCESS; + + *ppszA = HEAP_alloc ( len + 1 ); + + if ( !*ppszA ) + return STATUS_NO_MEMORY; + + return HEAP_strcpyWtoA ( *ppszA, lpszW, len ); +} + +NTSTATUS +HEAP_strdupAtoW ( LPWSTR* ppszW, LPCSTR lpszA, UINT* NewLen ) +{ + ULONG len; + + *ppszW = NULL; + + if ( !lpszA ) + return STATUS_SUCCESS; + + len = lstrlenA ( lpszA ); + + *ppszW = HEAP_alloc ( (len+1) * sizeof(WCHAR) ); + + if ( !*ppszW ) + return STATUS_NO_MEMORY; + + if ( NewLen ) *NewLen = (UINT)len; + + return HEAP_strcpyAtoW ( *ppszW, lpszA, len ); +} + +char* heap_string_poolA ( const wchar_t* pstrW, DWORD length ) +{ + PHEAP_STRING_POOLA pPoolEntry = heap_string_Apool; + char* pstrA = NULL; + HEAP_strdupWtoA ( &pstrA, pstrW, length ); + if ( !pstrA ) + return NULL; + while ( pPoolEntry ) + { + if ( !strcmp ( pPoolEntry->data, pstrA ) ) + { + HEAP_free ( pstrA ); + return pPoolEntry->data; + } + pPoolEntry = pPoolEntry->next; + } + pPoolEntry = (PHEAP_STRING_POOLA)HEAP_alloc ( sizeof(HEAP_STRING_POOLA) ); + pPoolEntry->data = pstrA; + + // IMHO, synchronization is *not* needed here. This data is process- + // local, so the only possible contention is among threads. If a + // conflict does occur, the only problem will be a small memory + // leak that gets cleared up when the heap is destroyed by the + // process exiting. + pPoolEntry->next = heap_string_Apool; + heap_string_Apool = pPoolEntry; + return pPoolEntry->data; +} + +wchar_t* heap_string_poolW ( const wchar_t* pstrWSrc, DWORD length ) +{ + PHEAP_STRING_POOLW pPoolEntry = heap_string_Wpool; + wchar_t* pstrW = NULL; + pstrW = HEAP_strdupW ( (LPWSTR)pstrWSrc, length ); + if ( !pstrW ) + return NULL; + while ( pPoolEntry ) + { + if ( !wcscmp (pPoolEntry->data, pstrW ) ) + { + HEAP_free ( pstrW ); + return pPoolEntry->data; + } + pPoolEntry = pPoolEntry->next; + } + pPoolEntry = (PHEAP_STRING_POOLW)HEAP_alloc ( sizeof(HEAP_STRING_POOLW) ); + pPoolEntry->data = pstrW; + + // IMHO, synchronization is *not* needed here. This data is process- + // local, so the only possible contention is among threads. If a + // conflict does occur, the only problem will be a small memory + // leak that gets cleared up when the heap is destroyed by the + // process exiting. + pPoolEntry->next = heap_string_Wpool; + heap_string_Wpool = pPoolEntry; + return pPoolEntry->data; +} diff --git a/reactos/lib/user32/user32.def b/reactos/lib/user32/user32.def index a716be2156b..9d1ae2a5dd1 100644 --- a/reactos/lib/user32/user32.def +++ b/reactos/lib/user32/user32.def @@ -499,7 +499,6 @@ PtInRect@12 ;QuerySendMessage ;QueryUserCounters RealChildWindowFromPoint@12 -RealGetWindowClass@12 RealGetWindowClassA@12 RealGetWindowClassW@12 RedrawWindow@16 diff --git a/reactos/lib/user32/user32.edf b/reactos/lib/user32/user32.edf index 60462043854..febd3a9054e 100644 --- a/reactos/lib/user32/user32.edf +++ b/reactos/lib/user32/user32.edf @@ -499,7 +499,6 @@ PtInRect=PtInRect@12 ;QuerySendMessage ;QueryUserCounters RealChildWindowFromPoint=RealChildWindowFromPoint@12 -RealGetWindowClass=RealGetWindowClass@12 RealGetWindowClassA=RealGetWindowClassA@12 RealGetWindowClassW=RealGetWindowClassW@12 RedrawWindow=RedrawWindow@16 diff --git a/reactos/lib/user32/windows/class.c b/reactos/lib/user32/windows/class.c index 3ff35fd064d..198d66a7a9d 100644 --- a/reactos/lib/user32/windows/class.c +++ b/reactos/lib/user32/windows/class.c @@ -1,4 +1,4 @@ -/* $Id: class.c,v 1.26 2003/08/07 04:03:24 royce Exp $ +/* $Id: class.c,v 1.27 2003/08/08 02:57:54 royce Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -13,26 +13,8 @@ #include #include #include -#include /* for IS_ATOM */ - -/* copied from menu.c */ -NTSTATUS -STATIC HEAP_strdupA2W ( HANDLE hHeap, LPWSTR* ppszW, LPCSTR lpszA, UINT* NewLen ) -{ - ULONG len; - NTSTATUS Status; - *ppszW = NULL; - if ( !lpszA ) - return STATUS_SUCCESS; - len = lstrlenA(lpszA); - *ppszW = RtlAllocateHeap ( hHeap, 0, (len+1) * sizeof(WCHAR) ); - if ( !*ppszW ) - return STATUS_NO_MEMORY; - Status = RtlMultiByteToUnicodeN ( *ppszW, len*sizeof(WCHAR), NULL, (PCHAR)lpszA, len ); - (*ppszW)[len] = L'\0'; - if(NewLen) (*NewLen) = (UINT)len; - return Status; -} +#include +#include /* * @unimplemented @@ -95,56 +77,79 @@ GetClassInfoW( /* - * @unimplemented + * @implemented */ DWORD STDCALL -GetClassLongA(HWND hWnd, int nIndex) -{ - /* - * FIXME - for GCL_MENUNAME, we need to allocate a buffer - * in thread-local storage and convert the results back - * to that. Subsequent calls should be sure and clean that - * up - */ - return(NtUserGetClassLong(hWnd, nIndex, TRUE)); +GetClassLongA ( HWND hWnd, int nIndex ) +{ + PUNICODE_STRING str; + + if ( nIndex != GCL_MENUNAME ) + { + return NtUserGetClassLong ( hWnd, nIndex, TRUE ); + } + + str = (PUNICODE_STRING)NtUserGetClassLong ( hWnd, nIndex, TRUE ); + if ( IS_INTRESOURCE(str) ) + { + return (DWORD)str; + } + else + { + return (DWORD)heap_string_poolA ( str->Buffer, str->Length ); + } } /* * @implemented */ DWORD STDCALL -GetClassLongW(HWND hWnd, int nIndex) +GetClassLongW ( HWND hWnd, int nIndex ) { - return(NtUserGetClassLong(hWnd, nIndex, FALSE)); + PUNICODE_STRING str; + + if ( nIndex != GCL_MENUNAME ) + { + return NtUserGetClassLong ( hWnd, nIndex, FALSE ); + } + + str = (PUNICODE_STRING)NtUserGetClassLong(hWnd, nIndex, TRUE); + if ( IS_INTRESOURCE(str) ) + { + return (DWORD)str; + } + else + { + return (DWORD)heap_string_poolW ( str->Buffer, str->Length ); + } } /* * @implemented */ -int -STDCALL +int STDCALL GetClassNameA( HWND hWnd, LPSTR lpClassName, int nMaxCount) { - int result; - LPWSTR ClassName; - NTSTATUS Status; - ClassName = RtlAllocateHeap(RtlGetProcessHeap(),HEAP_ZERO_MEMORY,nMaxCount); - result = NtUserGetClassName(hWnd, ClassName, nMaxCount); - Status = RtlUnicodeToMultiByteN (lpClassName, - result, - NULL, - ClassName, - result); - if (!NT_SUCCESS(Status)) - { - return 0; - } - RtlFreeHeap(RtlGetProcessHeap(),0,ClassName); - return result; + int result; + LPWSTR ClassNameW; + NTSTATUS Status; + + ClassNameW = HEAP_alloc ( (nMaxCount+1)*sizeof(WCHAR) ); + + result = NtUserGetClassName ( hWnd, ClassNameW, nMaxCount ); + + Status = HEAP_strcpyWtoA ( lpClassName, ClassNameW, result ); + + HEAP_free ( ClassNameW ); + + if ( !NT_SUCCESS(Status) ) + return 0; + + return result; } @@ -158,13 +163,18 @@ GetClassNameW( LPWSTR lpClassName, int nMaxCount) { - int result; - LPWSTR ClassName; - ClassName = RtlAllocateHeap(RtlGetProcessHeap(),HEAP_ZERO_MEMORY,nMaxCount); - result = NtUserGetClassName(hWnd, ClassName, nMaxCount); - RtlCopyMemory(ClassName,lpClassName,result); - RtlFreeHeap(RtlGetProcessHeap(),0,ClassName); - return result; + int result; + LPWSTR ClassNameW; + + ClassNameW = HEAP_alloc ( (nMaxCount+1) * sizeof(WCHAR) ); + + result = NtUserGetClassName ( hWnd, ClassNameW, nMaxCount ); + + RtlCopyMemory ( lpClassName, ClassNameW, result ); + + HEAP_free ( ClassNameW ); + + return result; } @@ -250,9 +260,10 @@ RegisterClassA(CONST WNDCLASSA *lpWndClass) { WNDCLASSEXA Class; - if ( !lpWndClass ) return (ATOM)0; + if ( !lpWndClass ) + return 0; - RtlMoveMemory ( &Class.style, lpWndClass, sizeof(WNDCLASSA) ); + RtlCopyMemory ( &Class.style, lpWndClass, sizeof(WNDCLASSA) ); Class.cbSize = sizeof(WNDCLASSEXA); Class.hIconSm = INVALID_HANDLE_VALUE; @@ -268,23 +279,22 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx) { RTL_ATOM Atom; WNDCLASSEXW wndclass; - HANDLE hHeap; NTSTATUS Status; LPWSTR ClassName = NULL; LPWSTR MenuName = NULL; - if(!lpwcx || (lpwcx->cbSize != sizeof(WNDCLASSEXA))) - return (ATOM)0; + if ( !lpwcx || (lpwcx->cbSize != sizeof(WNDCLASSEXA)) ) + return 0; - if(!lpwcx->lpszClassName) return (ATOM)0; + if ( !lpwcx->lpszClassName ) + return 0; - hHeap = RtlGetProcessHeap(); - RtlMoveMemory(&wndclass, lpwcx, sizeof(WNDCLASSEXW)); + RtlCopyMemory ( &wndclass, lpwcx, sizeof(WNDCLASSEXW) ); if ( !IS_ATOM(lpwcx->lpszClassName) ) { - Status = HEAP_strdupA2W (hHeap, &ClassName, (LPCSTR)lpwcx->lpszClassName, NULL); - if (!NT_SUCCESS (Status)) + Status = HEAP_strdupAtoW ( &ClassName, (LPCSTR)lpwcx->lpszClassName, NULL ); + if ( !NT_SUCCESS (Status) ) { SetLastError (RtlNtStatusToDosError(Status)); return 0; @@ -292,31 +302,24 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx) wndclass.lpszClassName = ClassName; } - if ( !IS_ATOM(lpwcx->lpszMenuName) ) + if ( !IS_INTRESOURCE(lpwcx->lpszMenuName) ) { - Status = HEAP_strdupA2W (hHeap, &MenuName, (LPCSTR)lpwcx->lpszMenuName, NULL); - if (!NT_SUCCESS (Status)) + Status = HEAP_strdupAtoW ( &MenuName, (LPCSTR)lpwcx->lpszMenuName, NULL ); + if ( !NT_SUCCESS (Status) ) { - if(HIWORD(lpwcx->lpszClassName)) - { - RtlFreeHeap (hHeap, 0, ClassName); - } + if ( ClassName ) + HEAP_free ( ClassName ); SetLastError (RtlNtStatusToDosError(Status)); return 0; } wndclass.lpszMenuName = MenuName; } - Atom = NtUserRegisterClassExWOW ( - &wndclass, - FALSE, - 0, - 0, - 0); + Atom = NtUserRegisterClassExWOW ( &wndclass, FALSE, 0, 0, 0 ); /* free strings if neccessary */ - if(MenuName) RtlFreeHeap (hHeap, 0, MenuName); - if(ClassName) RtlFreeHeap (hHeap, 0, ClassName); + if ( MenuName ) HEAP_free ( MenuName ); + if ( ClassName ) HEAP_free ( ClassName ); return (ATOM)Atom; } @@ -334,60 +337,47 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx) WNDCLASSEXW wndclass; LPWSTR ClassName = NULL; LPWSTR MenuName = NULL; - ULONG len; - if(!lpwcx || (lpwcx->cbSize != sizeof(WNDCLASSEXA))) - return (ATOM)0; + if ( !lpwcx || (lpwcx->cbSize != sizeof(WNDCLASSEXA)) ) + return 0; - if(!lpwcx->lpszClassName) return (ATOM)0; + if ( !lpwcx->lpszClassName ) + return 0; hHeap = RtlGetProcessHeap(); - RtlMoveMemory(&wndclass, lpwcx, sizeof(WNDCLASSEXW)); + RtlCopyMemory ( &wndclass, lpwcx, sizeof(WNDCLASSEXW) ); /* copy strings if needed */ if ( !IS_ATOM(lpwcx->lpszClassName) ) { - len = lstrlenW(lpwcx->lpszClassName); - ClassName = RtlAllocateHeap (hHeap, 0, (len + 1) * sizeof(WCHAR)); - if(!ClassName) + ClassName = HEAP_strdupW ( lpwcx->lpszClassName, lstrlenW(lpwcx->lpszClassName) ); + if ( !ClassName ) { SetLastError(RtlNtStatusToDosError(STATUS_NO_MEMORY)); return 0; } - RtlMoveMemory(&ClassName, &lpwcx->lpszClassName, len); - wndclass.lpszClassName = ClassName; } - if ( !IS_ATOM(lpwcx->lpszMenuName) ) + if ( !IS_INTRESOURCE(lpwcx->lpszMenuName) ) { - len = lstrlenW(lpwcx->lpszMenuName); - MenuName = RtlAllocateHeap (hHeap, 0, (len + 1) * sizeof(WCHAR)); - if(!MenuName) + MenuName = HEAP_strdupW ( lpwcx->lpszMenuName, lstrlenW(lpwcx->lpszMenuName) ); + if ( !MenuName ) { - if(HIWORD(lpwcx->lpszClassName)) - { - RtlFreeHeap (hHeap, 0, MenuName); - } + if ( ClassName ) + HEAP_free ( MenuName ); SetLastError(RtlNtStatusToDosError(STATUS_NO_MEMORY)); return 0; } - RtlMoveMemory(&MenuName, &lpwcx->lpszMenuName, len); - wndclass.lpszMenuName = MenuName; } - Atom = NtUserRegisterClassExWOW ( - &wndclass, - TRUE, - 0, - 0, - 0); + Atom = NtUserRegisterClassExWOW ( &wndclass, TRUE, 0, 0, 0 ); /* free strings if neccessary */ - if(MenuName) RtlFreeHeap (hHeap, 0, MenuName); - if(ClassName) RtlFreeHeap (hHeap, 0, ClassName); + if ( MenuName ) HEAP_free ( MenuName ); + if ( ClassName ) HEAP_free ( ClassName ); return (ATOM)Atom; } @@ -400,31 +390,62 @@ RegisterClassW(CONST WNDCLASSW *lpWndClass) { WNDCLASSEXW Class; - if ( !lpWndClass ) return (ATOM)0; + if ( !lpWndClass ) + return 0; + + RtlCopyMemory ( &Class.style, lpWndClass, sizeof(WNDCLASSW) ); - RtlMoveMemory ( &Class.style, lpWndClass, sizeof(WNDCLASSW) ); Class.cbSize = sizeof(WNDCLASSEXW); Class.hIconSm = INVALID_HANDLE_VALUE; + return RegisterClassExW ( &Class ); } /* - * @unimplemented + * @implemented */ DWORD STDCALL -SetClassLongA( +SetClassLongA ( HWND hWnd, int nIndex, LONG dwNewLong) { - /* FIXME - handle GCL_MENUNAME special case */ - return(NtUserSetClassLong(hWnd, nIndex, dwNewLong, TRUE)); + PUNICODE_STRING str; + PUNICODE_STRING str2; + + if ( nIndex != GCL_MENUNAME ) + { + return NtUserSetClassLong ( hWnd, nIndex, dwNewLong, TRUE ); + } + if ( IS_INTRESOURCE(dwNewLong) ) + { + str2 = (PUNICODE_STRING)dwNewLong; + } + else + { + RtlCreateUnicodeString ( str2, (LPWSTR)dwNewLong ); + } + + str = (PUNICODE_STRING)NtUserSetClassLong(hWnd, nIndex, (DWORD)str2, TRUE); + + if ( !IS_INTRESOURCE(dwNewLong) ) + { + RtlFreeUnicodeString ( str2 ); + } + if ( IS_INTRESOURCE(str) ) + { + return (DWORD)str; + } + else + { + return (DWORD)heap_string_poolA ( str->Buffer, str->Length ); + } } /* - * @unimplemented + * @implemented */ DWORD STDCALL @@ -433,8 +454,36 @@ SetClassLongW( int nIndex, LONG dwNewLong) { - /* FIXME - handle GCL_MENUNAME special case */ - return(NtUserSetClassLong(hWnd, nIndex, dwNewLong, FALSE)); + PUNICODE_STRING str; + PUNICODE_STRING str2; + + if (nIndex != GCL_MENUNAME ) + { + return NtUserSetClassLong ( hWnd, nIndex, dwNewLong, FALSE ); + } + if ( IS_INTRESOURCE(dwNewLong) ) + { + str2 = (PUNICODE_STRING)dwNewLong; + } + else + { + RtlCreateUnicodeStringFromAsciiz ( str2,(LPSTR)dwNewLong ); + } + + str = (PUNICODE_STRING)NtUserSetClassLong(hWnd, nIndex, (DWORD)str2, TRUE); + + if ( !IS_INTRESOURCE(dwNewLong) ) + { + RtlFreeUnicodeString(str2); + } + if ( IS_INTRESOURCE(str) ) + { + return (DWORD)str; + } + else + { + return (DWORD)heap_string_poolW ( str->Buffer, str->Length ); + } } diff --git a/reactos/lib/user32/windows/menu.c b/reactos/lib/user32/windows/menu.c index 8abd9b4385b..4c013ec30e6 100644 --- a/reactos/lib/user32/windows/menu.c +++ b/reactos/lib/user32/windows/menu.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: menu.c,v 1.21 2003/08/07 04:03:24 royce Exp $ +/* $Id: menu.c,v 1.22 2003/08/08 02:57:54 royce Exp $ * * PROJECT: ReactOS user32.dll * FILE: lib/user32/windows/menu.c @@ -34,6 +34,7 @@ #include #include #include +#include /* TYPES *********************************************************************/ @@ -94,24 +95,6 @@ static inline WCHAR *strcatW( WCHAR *dst, const WCHAR *src ) return dst; } -NTSTATUS -STATIC HEAP_strdupA2W ( HANDLE hHeap, LPWSTR* ppszW, LPCSTR lpszA, UINT* NewLen ) -{ - ULONG len; - NTSTATUS Status; - *ppszW = NULL; - if ( !lpszA ) - return STATUS_SUCCESS; - len = lstrlenA(lpszA); - *ppszW = RtlAllocateHeap ( hHeap, 0, (len+1) * sizeof(WCHAR) ); - if ( !*ppszW ) - return STATUS_NO_MEMORY; - Status = RtlMultiByteToUnicodeN ( *ppszW, len*sizeof(WCHAR), NULL, (PCHAR)lpszA, len ); - (*ppszW)[len] = L'\0'; - if(NewLen) (*NewLen) = (UINT)len; - return Status; -} - #ifndef GET_WORD #define GET_WORD(ptr) (*(WORD *)(ptr)) #endif @@ -754,18 +737,17 @@ InsertMenuItemA( WINBOOL res = FALSE; BOOL CleanHeap = FALSE; NTSTATUS Status; - HANDLE hHeap = RtlGetProcessHeap(); if((lpmii->cbSize == sizeof(MENUITEMINFOA)) || (lpmii->cbSize == sizeof(MENUITEMINFOA) - sizeof(HBITMAP))) { - memcpy(&mi, lpmii, lpmii->cbSize); - + RtlMoveMemory ( &mi, lpmii, lpmii->cbSize ); + /* copy the text string */ if((mi.fMask & (MIIM_TYPE | MIIM_STRING)) && (MENU_ITEM_TYPE(mi.fType) == MF_STRING) && mi.dwTypeData) { - Status = HEAP_strdupA2W (hHeap, &mi.dwTypeData, (LPCSTR)mi.dwTypeData, &mi.cch); + Status = HEAP_strdupAtoW ( &mi.dwTypeData, (LPCSTR)mi.dwTypeData, &mi.cch ); if (!NT_SUCCESS (Status)) { SetLastError (RtlNtStatusToDosError(Status)); @@ -773,10 +755,10 @@ InsertMenuItemA( } CleanHeap = TRUE; } - + res = NtUserInsertMenuItem(hMenu, uItem, fByPosition, &mi); - - if(CleanHeap) RtlFreeHeap (hHeap, 0, mi.dwTypeData); + + if ( CleanHeap ) HEAP_free ( mi.dwTypeData ); } return res; } diff --git a/reactos/lib/user32/windows/window.c b/reactos/lib/user32/windows/window.c index 536ac225267..a674f04d5a1 100644 --- a/reactos/lib/user32/windows/window.c +++ b/reactos/lib/user32/windows/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.52 2003/08/07 04:03:24 royce Exp $ +/* $Id: window.c,v 1.53 2003/08/08 02:57:54 royce Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -45,8 +45,14 @@ User32SendNCCALCSIZEMessageForKernel(PVOID Arguments, ULONG ArgumentLength) DPRINT("Wrong length.\n"); return(STATUS_INFO_LENGTH_MISMATCH); } - /* FIXME: handle ANSI windows vs Unicode windows */ - Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + if (IsWindowUnicode(CallbackArgs->Wnd)) + { + Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + } + else + { + Proc = (WNDPROC)GetWindowLongA(CallbackArgs->Wnd, GWL_WNDPROC); + } DPRINT("Proc %X\n", Proc); /* Call the window procedure; notice kernel messages are always unicode. */ if (CallbackArgs->Validate) @@ -81,8 +87,14 @@ User32SendGETMINMAXINFOMessageForKernel(PVOID Arguments, ULONG ArgumentLength) DPRINT("Wrong length.\n"); return(STATUS_INFO_LENGTH_MISMATCH); } - /* FIXME: handle ANSI windows vs Unicode windows */ - Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + if (IsWindowUnicode(CallbackArgs->Wnd)) + { + Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + } + else + { + Proc = (WNDPROC)GetWindowLongA(CallbackArgs->Wnd, GWL_WNDPROC); + } DPRINT("Proc %X\n", Proc); /* Call the window procedure; notice kernel messages are always unicode. */ Result.Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_GETMINMAXINFO, @@ -107,8 +119,14 @@ User32SendCREATEMessageForKernel(PVOID Arguments, ULONG ArgumentLength) DPRINT("Wrong length.\n"); return(STATUS_INFO_LENGTH_MISMATCH); } - /* FIXME: handle ANSI windows vs Unicode windows */ - Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + if (IsWindowUnicode(CallbackArgs->Wnd)) + { + Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + } + else + { + Proc = (WNDPROC)GetWindowLongA(CallbackArgs->Wnd, GWL_WNDPROC); + } DPRINT("Proc %X\n", Proc); /* Call the window procedure; notice kernel messages are always unicode. */ Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_CREATE, 0, @@ -132,8 +150,14 @@ User32SendNCCREATEMessageForKernel(PVOID Arguments, ULONG ArgumentLength) DPRINT("Wrong length.\n"); return(STATUS_INFO_LENGTH_MISMATCH); } - /* FIXME: handle ANSI windows vs Unicode windows */ - Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + if (IsWindowUnicode(CallbackArgs->Wnd)) + { + Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + } + else + { + Proc = (WNDPROC)GetWindowLongA(CallbackArgs->Wnd, GWL_WNDPROC); + } DPRINT("Proc %X\n", Proc); /* Call the window procedure; notice kernel messages are always unicode. */ Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_NCCREATE, 0, @@ -157,8 +181,14 @@ User32SendWINDOWPOSCHANGINGMessageForKernel(PVOID Arguments, ULONG ArgumentLengt DPRINT("Wrong length.\n"); return(STATUS_INFO_LENGTH_MISMATCH); } - /* FIXME: handle ANSI windows vs Unicode windows */ - Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + if (IsWindowUnicode(CallbackArgs->Wnd)) + { + Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + } + else + { + Proc = (WNDPROC)GetWindowLongA(CallbackArgs->Wnd, GWL_WNDPROC); + } DPRINT("Proc %X\n", Proc); /* Call the window procedure; notice kernel messages are always unicode. */ Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_WINDOWPOSCHANGING, 0, @@ -182,8 +212,14 @@ User32SendWINDOWPOSCHANGEDMessageForKernel(PVOID Arguments, ULONG ArgumentLength DPRINT("Wrong length.\n"); return(STATUS_INFO_LENGTH_MISMATCH); } - /* FIXME: handle ANSI windows vs Unicode windows */ - Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + if (IsWindowUnicode(CallbackArgs->Wnd)) + { + Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + } + else + { + Proc = (WNDPROC)GetWindowLongA(CallbackArgs->Wnd, GWL_WNDPROC); + } DPRINT("Proc %X\n", Proc); /* Call the window procedure; notice kernel messages are always unicode. */ Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_WINDOWPOSCHANGED, 0, @@ -207,8 +243,14 @@ User32SendSTYLECHANGINGMessageForKernel(PVOID Arguments, ULONG ArgumentLength) DPRINT("Wrong length.\n"); return(STATUS_INFO_LENGTH_MISMATCH); } - /* FIXME: handle ANSI windows vs Unicode windows */ - Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + if (IsWindowUnicode(CallbackArgs->Wnd)) + { + Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + } + else + { + Proc = (WNDPROC)GetWindowLongA(CallbackArgs->Wnd, GWL_WNDPROC); + } DPRINT("Proc %X\n", Proc); /* Call the window procedure; notice kernel messages are always unicode. */ Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_STYLECHANGING, CallbackArgs->WhichStyle, @@ -232,8 +274,14 @@ User32SendSTYLECHANGEDMessageForKernel(PVOID Arguments, ULONG ArgumentLength) DPRINT("Wrong length.\n"); return(STATUS_INFO_LENGTH_MISMATCH); } - /* FIXME: handle ANSI windows vs Unicode windows */ - Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + if (IsWindowUnicode(CallbackArgs->Wnd)) + { + Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + } + else + { + Proc = (WNDPROC)GetWindowLongA(CallbackArgs->Wnd, GWL_WNDPROC); + } DPRINT("Proc %X\n", Proc); /* Call the window procedure; notice kernel messages are always unicode. */ Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_STYLECHANGED, CallbackArgs->WhichStyle, @@ -273,9 +321,14 @@ User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength) } if (CallbackArgs->Proc == NULL) { - /* FIXME: handle ANSI windows vs Unicode windows */ - CallbackArgs->Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, - GWL_WNDPROC); + if (IsWindowUnicode(CallbackArgs->Wnd)) + { + CallbackArgs->Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC); + } + else + { + CallbackArgs->Proc = (WNDPROC)GetWindowLongA(CallbackArgs->Wnd, GWL_WNDPROC); + } } Result = CallWindowProcW(CallbackArgs->Proc, CallbackArgs->Wnd, CallbackArgs->Msg, CallbackArgs->wParam, @@ -959,7 +1012,6 @@ FindWindowExW(HWND hwndParent, return NtUserFindWindowEx(hwndParent, hwndChildAfter, &ucClassName, &ucWindowName); } - /* * @unimplemented */ @@ -1203,13 +1255,12 @@ GetWindowTextLengthA(HWND hWnd) /* - * @unimplemented + * @implemented */ int STDCALL GetWindowTextLengthW(HWND hWnd) { - UNIMPLEMENTED; - return 0; + return(SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0)); } @@ -1272,10 +1323,7 @@ IsWindow(HWND hWnd) WINBOOL STDCALL IsWindowUnicode(HWND hWnd) { -#ifdef TODO - UNIMPLEMENTED; -#endif - return FALSE; + return (WINBOOL)NtUserCallOneParam((DWORD)hWnd,ONEPARAM_ROUTINE_ISWINDOWUNICODE); } @@ -1357,24 +1405,6 @@ RealChildWindowFromPoint(HWND hwndParent, return (HWND)0; } - -/* - * @unimplemented - */ -UINT -RealGetWindowClass(HWND hwnd, - PVOID pszType, - UINT cchType) -{ - /* - * FIXME - I don't think this function should exist... - * see RealGetWindowClassA & RealGetWindowClassW - */ - UNIMPLEMENTED; - return 0; -} - - /* * @unimplemented */ diff --git a/reactos/subsys/win32k/include/class.h b/reactos/subsys/win32k/include/class.h index 91d09c0b0a3..008bfef35e2 100644 --- a/reactos/subsys/win32k/include/class.h +++ b/reactos/subsys/win32k/include/class.h @@ -54,4 +54,4 @@ W32kGetClassLong(struct _WINDOW_OBJECT *WindowObject, ULONG Offset, BOOL Ansi); #endif /* __WIN32K_CLASS_H */ -/* EOF */ \ No newline at end of file +/* EOF */ diff --git a/reactos/subsys/win32k/ntuser/class.c b/reactos/subsys/win32k/ntuser/class.c index ca70b31ac35..9d52fc2aa80 100644 --- a/reactos/subsys/win32k/ntuser/class.c +++ b/reactos/subsys/win32k/ntuser/class.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: class.c,v 1.24 2003/08/07 04:03:25 royce Exp $ +/* $Id: class.c,v 1.25 2003/08/08 02:57:54 royce Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -158,7 +158,6 @@ NtUserGetClassInfo(IN LPWSTR ClassName, OUT PULONG ReturnedLength) { UNIMPLEMENTED; - return(0); } @@ -167,32 +166,33 @@ W32kGetClassName(struct _WINDOW_OBJECT *WindowObject, LPWSTR lpClassName, int nMaxCount) { - int length; - LPCWSTR name; - if (IS_ATOM(WindowObject->Class->lpszClassName)) - { - /* FIXME find the string from the atom */ - name = L"\0"; - length = wcslen(name); - } - else - { - name = WindowObject->Class->lpszClassName->Buffer; - length = WindowObject->Class->lpszClassName->Length / sizeof(WCHAR); - } - if (length > nMaxCount) - { - length = nMaxCount; - } - *(lpClassName+length) = 0; - wcsncpy(lpClassName,name,length); - return length; + int length; + LPCWSTR name; + if (IS_ATOM(WindowObject->Class->lpszClassName)) + { + /* FIXME find the string from the atom */ + name = L"\0"; + length = wcslen(name); + } + else + { + name = WindowObject->Class->lpszClassName->Buffer; + length = WindowObject->Class->lpszClassName->Length / sizeof(WCHAR); + } + if (length > nMaxCount) + { + length = nMaxCount; + } + *(lpClassName+length) = 0; + wcsncpy(lpClassName,name,length); + return length; } DWORD STDCALL -NtUserGetClassName(HWND hWnd, - LPWSTR lpClassName, - int nMaxCount) +NtUserGetClassName ( + HWND hWnd, + LPWSTR lpClassName, + int nMaxCount) { PWINDOW_OBJECT WindowObject; LONG Ret; @@ -212,7 +212,6 @@ NtUserGetWOWClass(DWORD Unknown0, DWORD Unknown1) { UNIMPLEMENTED; - return(0); } @@ -251,7 +250,7 @@ W32kCreateClass(CONST WNDCLASSEXW *lpwcx, ClassObject->lpfnWndProcA = lpwcx->lpfnWndProc; ClassObject->lpfnWndProcW = (WNDPROC)0xCCCCCCCC; } - if (HIWORD(lpwcx->lpszMenuName) == 0) + if (IS_INTRESOURCE(lpwcx->lpszMenuName)) { ClassObject->lpszMenuName = (PUNICODE_STRING)lpwcx->lpszMenuName; } @@ -307,7 +306,7 @@ NtUserRegisterClassExWOW( ObDereferenceObject(WinStaObject); DPRINT("Failed adding class name (%wS) to atom table\n", lpwcx->lpszClassName); - SetLastNtError(Status); + SetLastNtError(Status); return((RTL_ATOM)0); } } @@ -361,27 +360,20 @@ W32kGetClassLong(struct _WINDOW_OBJECT *WindowObject, ULONG Offset, BOOL Ansi) case GCL_HMODULE: Ret = (ULONG)WindowObject->Class->hInstance; break; - /*case GCL_MENUNAME: - if (Ansi) - { - Ret = (ULONG)WindowObject->Class->ClassA.lpszMenuName; - } - else - { - Ret = (ULONG)WindowObject->Class->ClassW.lpszMenuName; - } - break;*/ + case GCL_MENUNAME: + Ret = (ULONG)WindowObject->Class->lpszMenuName; + break; case GCL_STYLE: Ret = WindowObject->Class->style; break; case GCL_WNDPROC: - if (WindowObject->Unicode) + if (Ansi) { - Ret = (ULONG)WindowObject->Class->lpfnWndProcW; + Ret = (ULONG)WindowObject->Class->lpfnWndProcA; } else { - Ret = (ULONG)WindowObject->Class->lpfnWndProcA; + Ret = (ULONG)WindowObject->Class->lpfnWndProcW; } break; default: @@ -410,6 +402,7 @@ NtUserGetClassLong(HWND hWnd, DWORD Offset, BOOL Ansi) void FASTCALL W32kSetClassLong(PWINDOW_OBJECT WindowObject, ULONG Offset, LONG dwNewLong, BOOL Ansi) { + PUNICODE_STRING str; switch (Offset) { case GCL_CBWNDEXTRA: @@ -433,15 +426,31 @@ W32kSetClassLong(PWINDOW_OBJECT WindowObject, ULONG Offset, LONG dwNewLong, BOOL case GCL_HMODULE: WindowObject->Class->hInstance = (HINSTANCE)dwNewLong; break; - /*case GCL_MENUNAME: - WindowObject->Class->Class.lpszMenuName = (LPCWSTR)dwNewLong; - break;*/ + case GCL_MENUNAME: + if (!IS_INTRESOURCE(dwNewLong)) + { + str = ExAllocatePool(PagedPool,sizeof(UNICODE_STRING)+((PUNICODE_STRING)dwNewLong)->Length); + memcpy(str,(PUNICODE_STRING)dwNewLong,sizeof(UNICODE_STRING)+((PUNICODE_STRING)dwNewLong)->Length); + WindowObject->Class->lpszMenuName = str; + } + else + { + WindowObject->Class->lpszMenuName = (PUNICODE_STRING)dwNewLong; + } + break; case GCL_STYLE: WindowObject->Class->style = dwNewLong; break; - /*case GCL_WNDPROC: - WindowObject->Class->Class.lpfnWndProc = (WNDPROC)dwNewLong; - break;*/ + case GCL_WNDPROC: + if (Ansi) + { + WindowObject->Class->lpfnWndProcA = (WNDPROC)dwNewLong; + } + else + { + WindowObject->Class->lpfnWndProcW = (WNDPROC)dwNewLong; + } + break; } } @@ -471,7 +480,6 @@ NtUserSetClassWord(DWORD Unknown0, DWORD Unknown2) { UNIMPLEMENTED; - return(0); } @@ -481,7 +489,6 @@ NtUserUnregisterClass(DWORD Unknown0, DWORD Unknown2) { UNIMPLEMENTED; - return(0); } diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 40c8252acfb..161b37cbf8c 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: window.c,v 1.80 2003/08/06 18:43:58 weiden Exp $ +/* $Id: window.c,v 1.81 2003/08/08 02:57:54 royce Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -1730,16 +1730,14 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi) case GWL_STYLE: Result = WindowObject->Style; break; - /* FIXME: need to return the "invalid" value if the caller asks for it - (but we cant do that because that breaks stuff in user32 which wont be fixable until we have an implementation of IsWindowUnicode available */ case GWL_WNDPROC: - if (WindowObject->Unicode) + if (Ansi) { - Result = (LONG) WindowObject->WndProcW; + Result = (LONG) WindowObject->WndProcA; } else { - Result = (LONG) WindowObject->WndProcA; + Result = (LONG) WindowObject->WndProcW; } break; @@ -1826,9 +1824,16 @@ NtUserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi) case GWL_WNDPROC: /* FIXME: should check if window belongs to current process */ - /*OldValue = (LONG) WindowObject->WndProc; - WindowObject->WndProc = (WNDPROC) NewValue;*/ - OldValue = 0; + if (Ansi) + { + OldValue = (LONG) WindowObject->WndProcA; + WindowObject->WndProcA = (WNDPROC) NewValue; + } + else + { + OldValue = (LONG) WindowObject->WndProcW; + WindowObject->WndProcW = (WNDPROC) NewValue; + } break; case GWL_HINSTANCE: