patch by Jonathon Wilson - complete implemenation of GWL_WNDPROC, GCL_WNDPROC and GCL_MENUNAME..

svn path=/trunk/; revision=5467
This commit is contained in:
Royce Mitchell III 2003-08-08 02:57:54 +00:00
parent 529277d521
commit 120453cd7c
13 changed files with 529 additions and 260 deletions

View file

@ -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 \

View file

@ -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 */

View file

@ -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

View file

@ -5,6 +5,7 @@
#include <window.h>
#include <menu.h>
#include <user32.h>
#include <strpool.h>
#ifdef DBG
@ -110,6 +111,7 @@ DllMain(PVOID hinstDll,
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
hProcessHeap = RtlGetProcessHeap();
Init();
InitThread();
break;

View file

@ -0,0 +1,165 @@
// strpool.c
#include <windows.h>
#include <ddk\ntddk.h>
#include <strpool.h>
#include <string.h>
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;
}

View file

@ -499,7 +499,6 @@ PtInRect@12
;QuerySendMessage
;QueryUserCounters
RealChildWindowFromPoint@12
RealGetWindowClass@12
RealGetWindowClassA@12
RealGetWindowClassW@12
RedrawWindow@16

View file

@ -499,7 +499,6 @@ PtInRect=PtInRect@12
;QuerySendMessage
;QueryUserCounters
RealChildWindowFromPoint=RealChildWindowFromPoint@12
RealGetWindowClass=RealGetWindowClass@12
RealGetWindowClassA=RealGetWindowClassA@12
RealGetWindowClassW=RealGetWindowClassW@12
RedrawWindow=RedrawWindow@16

View file

@ -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 <string.h>
#include <stdlib.h>
#include <debug.h>
#include <window.h> /* 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 <window.h>
#include <strpool.h>
/*
* @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 );
}
}

View file

@ -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 <string.h>
#include <draw.h>
#include <window.h>
#include <strpool.h>
/* 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;
}

View file

@ -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
*/

View file

@ -54,4 +54,4 @@ W32kGetClassLong(struct _WINDOW_OBJECT *WindowObject, ULONG Offset, BOOL Ansi);
#endif /* __WIN32K_CLASS_H */
/* EOF */
/* EOF */

View file

@ -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);
}

View file

@ -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: