*/
#include <windows.h>
#include <user32.h>
+#include <string.h>
+#include <stdlib.h>
#include <debug.h>
+#include <window.h>
+#include <strpool.h>
-WINBOOL
-STDCALL
-GetClassInfoA(
- HINSTANCE hInstance,
- LPCSTR lpClassName,
- LPWNDCLASS lpWndClass)
+
+static WINBOOL GetClassInfoExCommon(
+ HINSTANCE hInst,
+ LPCWSTR lpszClass,
+ LPWNDCLASSEXW lpwcx,
+ BOOL unicode)
{
- return FALSE;
+ LPWSTR str;
+ UNICODE_STRING str2, str3;
+ WNDCLASSEXW w;
+ BOOL retval;
+ NTSTATUS Status;
+
+ if ( !lpszClass || !lpwcx )
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if(IS_ATOM(lpszClass))
+ str = (LPWSTR)lpszClass;
+ else
+ {
+ if (unicode)
+ {
+ str = HEAP_strdupW ( lpszClass, wcslen(lpszClass) );
+
+ if ( !str )
+ {
+ SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY));
+ return FALSE;
+ }
+ }
+
+ else
+ {
+ Status = HEAP_strdupAtoW(&str, (LPCSTR)lpszClass, NULL);
+
+ if (! NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+ }
+ }
+
+ str2.Length = str3.Length = 0;
+ str2.MaximumLength = str3.MaximumLength = 255;
+ str2.Buffer = (PWSTR)HEAP_alloc ( str2.MaximumLength * sizeof(WCHAR) );
+ if ( !str2.Buffer )
+ {
+ SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY));
+ if ( !IS_ATOM(str) )
+ HEAP_free ( str );
+ return FALSE;
+ }
+
+ str3.Buffer = (PWSTR)HEAP_alloc ( str3.MaximumLength * sizeof(WCHAR) );
+ if ( !str3.Buffer )
+ {
+ SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY));
+ if ( !IS_ATOM(str) )
+ HEAP_free ( str );
+ return FALSE;
+ }
+
+ w.lpszMenuName = (LPCWSTR)&str2;
+ w.lpszClassName = (LPCWSTR)&str3;
+ retval = (BOOL)NtUserGetClassInfo(hInst, str, &w, TRUE, 0);
+ if ( !IS_ATOM(str) )
+ HEAP_free(str);
+
+ RtlCopyMemory ( lpwcx, &w, sizeof(WNDCLASSEXW) );
+
+ if ( !IS_INTRESOURCE(w.lpszMenuName) && w.lpszMenuName )
+ {
+ if (unicode)
+ lpwcx->lpszMenuName = heap_string_poolW ( str2.Buffer, str2.Length );
+ else
+ (LPWNDCLASSEXA) lpwcx->lpszMenuName = heap_string_poolA ( str2.Buffer, str2.Length );
+ }
+
+ if ( !IS_ATOM(w.lpszClassName) && w.lpszClassName )
+ {
+ if (unicode)
+ lpwcx->lpszClassName = heap_string_poolW ( str3.Buffer, str3.Length );
+ else
+ (LPWNDCLASSEXA) lpwcx->lpszClassName = heap_string_poolA ( str3.Buffer, str3.Length );
+ }
+
+ HEAP_free ( str2.Buffer );
+ HEAP_free ( str3.Buffer );
+
+ return retval;
}
+
+/*
+ * @implemented
+ */
WINBOOL
STDCALL
GetClassInfoExA(
HINSTANCE hinst,
LPCSTR lpszClass,
- LPWNDCLASSEX lpwcx)
+ LPWNDCLASSEXA lpwcx)
{
- return FALSE;
+ return GetClassInfoExCommon(hinst, (LPWSTR)lpszClass, (LPWNDCLASSEXW)lpwcx, FALSE);
}
+
+/*
+ * @implemented
+ */
WINBOOL
STDCALL
GetClassInfoExW(
HINSTANCE hinst,
LPCWSTR lpszClass,
- LPWNDCLASSEX lpwcx)
+ LPWNDCLASSEXW lpwcx)
{
- return FALSE;
+ return GetClassInfoExCommon(hinst, lpszClass, lpwcx, TRUE);
+
+ // AG: I've kept this here (commented out) in case of bugs with my
+ // own "common" routine (see above):
+
+/*LPWSTR str;
+ UNICODE_STRING str2;
+=======
+ LPWSTR str;
+ UNICODE_STRING str2, str3;
+>>>>>>> 1.36
+ WNDCLASSEXW w;
+ WINBOOL retval;
+
+ if ( !lpszClass || !lpwcx )
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if(IS_ATOM(lpszClass))
+ str = (LPWSTR)lpszClass;
+ else
+ {
+ str = HEAP_strdupW ( lpszClass, wcslen(lpszClass) );
+ if ( !str )
+ {
+ SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY));
+ return FALSE;
+ }
+ }
+
+ str2.Length = str3.Length = 0;
+ str2.MaximumLength = str3.MaximumLength = 255;
+ str2.Buffer = (PWSTR)HEAP_alloc ( str2.MaximumLength * sizeof(WCHAR) );
+ if ( !str2.Buffer )
+ {
+ SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY));
+ if ( !IS_ATOM(str) )
+ HEAP_free ( str );
+ return FALSE;
+ }
+
+ str3.Buffer = (PWSTR)HEAP_alloc ( str3.MaximumLength * sizeof(WCHAR) );
+ if ( !str3.Buffer )
+ {
+ SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY));
+ if ( !IS_ATOM(str) )
+ HEAP_free ( str );
+ HEAP_free ( str2.Buffer );
+ return FALSE;
+ }
+
+ w.lpszMenuName = (LPCWSTR)&str2;
+ w.lpszClassName = (LPCWSTR)&str3;
+ retval = (BOOL)NtUserGetClassInfo(hinst, str, &w, TRUE, 0);
+ if ( !IS_ATOM(str) )
+ HEAP_free(str);
+ RtlCopyMemory ( lpwcx, &w, sizeof(WNDCLASSEXW) );
+
+ if ( !IS_INTRESOURCE(w.lpszMenuName) && w.lpszMenuName )
+ {
+ lpwcx->lpszMenuName = heap_string_poolW ( str2.Buffer, str2.Length );
+ }
+ if ( !IS_ATOM(w.lpszClassName) && w.lpszClassName )
+ {
+ lpwcx->lpszClassName = heap_string_poolW ( str3.Buffer, str3.Length );
+ }
+
+ HEAP_free ( str2.Buffer );
+ HEAP_free ( str3.Buffer );
+
+ return retval;*/
+}
+
+
+/*
+ * @implemented
+ */
+WINBOOL
+STDCALL
+GetClassInfoA(
+ HINSTANCE hInstance,
+ LPCSTR lpClassName,
+ LPWNDCLASSA lpWndClass)
+{
+ WNDCLASSEXA w;
+ WINBOOL retval;
+
+ if ( !lpClassName || !lpWndClass )
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ retval = GetClassInfoExA(hInstance,lpClassName,&w);
+ RtlCopyMemory ( lpWndClass, &w.style, sizeof(WNDCLASSA) );
+ return retval;
}
+/*
+ * @implemented
+ */
WINBOOL
STDCALL
GetClassInfoW(
HINSTANCE hInstance,
LPCWSTR lpClassName,
- LPWNDCLASS lpWndClass)
+ LPWNDCLASSW lpWndClass)
{
- return FALSE;
+ WNDCLASSEXW w;
+ WINBOOL retval;
+
+ if(!lpClassName || !lpWndClass)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ retval = GetClassInfoExW(hInstance,lpClassName,&w);
+ RtlCopyMemory (lpWndClass,&w.style,sizeof(WNDCLASSW));
+ return retval;
}
+
+/*
+ * @implemented
+ */
DWORD STDCALL
-GetClassLongA(HWND hWnd, int nIndex)
+GetClassLongA ( HWND hWnd, int nIndex )
{
- switch (nIndex)
- {
- case GCL_WNDPROC:
- UNIMPLEMENTED;
- return(0);
- case GCL_MENUNAME:
- UNIMPLEMENTED;
- return(0);
- default:
- return(GetClassLongW(hWnd, 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));
+ 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 );
+ }
}
-int
-STDCALL
+
+/*
+ * @implemented
+ */
+int STDCALL
GetClassNameA(
HWND hWnd,
LPSTR lpClassName,
int nMaxCount)
{
- return 0;
+ int result;
+ LPWSTR ClassNameW;
+ NTSTATUS Status;
+
+ if(!lpClassName)
+ return 0;
+
+ 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;
}
+
+/*
+ * @implemented
+ */
int
STDCALL
GetClassNameW(
LPWSTR lpClassName,
int nMaxCount)
{
- return 0;
+ int result;
+ LPWSTR ClassNameW;
+
+ if(!lpClassName)
+ return 0;
+
+ ClassNameW = HEAP_alloc ( (nMaxCount+1) * sizeof(WCHAR) );
+
+ result = NtUserGetClassName ( hWnd, ClassNameW, nMaxCount );
+
+ RtlCopyMemory ( lpClassName, ClassNameW, result );
+
+ HEAP_free ( ClassNameW );
+
+ return result;
}
+
+/*
+ * @implemented
+ */
WORD
STDCALL
GetClassWord(
* NOTE: Obsoleted in 32-bit windows
*/
{
- return 0;
+ if ((nIndex < 0) && (nIndex != GCW_ATOM))
+ return 0;
+
+ return (WORD) NtUserGetClassLong ( hWnd, nIndex, TRUE );
}
-LONG STDCALL
-GetWindowLongA(HWND hWnd, int nIndex)
+
+/*
+ * @implemented
+ */
+LONG
+STDCALL
+GetWindowLongA ( HWND hWnd, int nIndex )
{
- return 0;
+ return NtUserGetWindowLong(hWnd, nIndex, TRUE);
}
-LONG STDCALL
+
+/*
+ * @implemented
+ */
+LONG
+STDCALL
GetWindowLongW(HWND hWnd, int nIndex)
{
- return(NtUserGetWindowLong(hWnd, nIndex));
+ return NtUserGetWindowLong(hWnd, nIndex, FALSE);
}
-UINT
+/*
+ * @implemented
+ */
+WORD
STDCALL
-RealGetWindowClass(
- HWND hwnd,
- LPSTR pszType,
- UINT cchType)
+GetWindowWord(HWND hWnd, int nIndex)
{
- return 0;
+ return (WORD)NtUserGetWindowLong(hWnd, nIndex, TRUE);
}
+/*
+ * @implemented
+ */
+WORD
+STDCALL
+SetWindowWord ( HWND hWnd,int nIndex,WORD wNewWord )
+{
+ return (WORD)NtUserSetWindowLong ( hWnd, nIndex, (LONG)wNewWord, TRUE );
+}
+
+/*
+ * @implemented
+ */
UINT
STDCALL
-RealGetWindowClassA(
+RealGetWindowClassW(
HWND hwnd,
- LPSTR pszType,
+ LPWSTR pszType,
UINT cchType)
{
- return 0;
+ /* FIXME: Implement correct functionality of RealGetWindowClass */
+ return GetClassNameW(hwnd,pszType,cchType);
}
+
+/*
+ * @implemented
+ */
UINT
STDCALL
-RealGetWindowClassW(
+RealGetWindowClassA(
HWND hwnd,
- LPWSTR pszType,
+ LPSTR pszType,
UINT cchType)
{
- return 0;
+ /* FIXME: Implement correct functionality of RealGetWindowClass */
+ return GetClassNameA(hwnd,pszType,cchType);
}
-ATOM STDCALL
-RegisterClassA(CONST WNDCLASS *lpWndClass)
+/*
+ * @implemented
+ */
+ATOM
+STDCALL
+RegisterClassA(CONST WNDCLASSA *lpWndClass)
{
- WNDCLASSEX Class;
+ WNDCLASSEXA Class;
- RtlMoveMemory(&Class.style, lpWndClass, sizeof(WNDCLASS));
- Class.cbSize = sizeof(WNDCLASSEX);
+ if ( !lpWndClass )
+ return 0;
+
+ RtlCopyMemory ( &Class.style, lpWndClass, sizeof(WNDCLASSA) );
+
+ Class.cbSize = sizeof(WNDCLASSEXA);
Class.hIconSm = INVALID_HANDLE_VALUE;
- return RegisterClassExA(&Class);
+
+ return RegisterClassExA ( &Class );
}
+/*
+ * @implemented
+ */
ATOM STDCALL
-RegisterClassExA(CONST WNDCLASSEX *lpwcx)
+RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
{
- UNICODE_STRING MenuName;
- UNICODE_STRING ClassName;
- WNDCLASSEX Class;
RTL_ATOM Atom;
+ WNDCLASSEXW wndclass;
+ NTSTATUS Status;
+ LPWSTR ClassName = NULL;
+ LPWSTR MenuName = NULL;
+
+ if ( !lpwcx || (lpwcx->cbSize != sizeof(WNDCLASSEXA)) )
+ return 0;
+
+ if ( !lpwcx->lpszClassName )
+ return 0;
+
+ RtlCopyMemory ( &wndclass, lpwcx, sizeof(WNDCLASSEXW) );
- if (!RtlCreateUnicodeStringFromAsciiz(&MenuName, (PCSZ)lpwcx->lpszMenuName))
+ if ( !IS_ATOM(lpwcx->lpszClassName) )
{
- RtlFreeUnicodeString(&MenuName);
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return (ATOM)0;
+ Status = HEAP_strdupAtoW ( &ClassName, (LPCSTR)lpwcx->lpszClassName, NULL );
+ if ( !NT_SUCCESS (Status) )
+ {
+ SetLastError (RtlNtStatusToDosError(Status));
+ return 0;
+ }
+ wndclass.lpszClassName = ClassName;
}
-
- if (!RtlCreateUnicodeStringFromAsciiz(&ClassName, (PCSZ)lpwcx->lpszClassName))
+
+ if ( !IS_INTRESOURCE(lpwcx->lpszMenuName) )
+ {
+ Status = HEAP_strdupAtoW ( &MenuName, (LPCSTR)lpwcx->lpszMenuName, NULL );
+ if ( !NT_SUCCESS (Status) )
{
- RtlFreeUnicodeString(&ClassName);
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return (ATOM)0;
+ if ( ClassName )
+ HEAP_free ( ClassName );
+ SetLastError (RtlNtStatusToDosError(Status));
+ return 0;
}
-
- RtlMoveMemory(&Class, lpwcx, sizeof(WNDCLASSEX));
- Class.lpszMenuName = (LPCTSTR)MenuName.Buffer;
- Class.lpszClassName = (LPCTSTR)ClassName.Buffer;
-
- Atom = NtUserRegisterClassExWOW(&Class,
- FALSE,
- 0,
- 0,
- 0,
- 0);
-
- RtlFreeUnicodeString(&ClassName);
- RtlFreeUnicodeString(&MenuName);
-
+ wndclass.lpszMenuName = MenuName;
+ }
+
+ Atom = NtUserRegisterClassExWOW ( &wndclass, FALSE, 0, 0, 0 );
+
+ /* free strings if neccessary */
+ if ( MenuName ) HEAP_free ( MenuName );
+ if ( ClassName ) HEAP_free ( ClassName );
+
return (ATOM)Atom;
}
+
+
+/*
+ * @implemented
+ */
ATOM STDCALL
-RegisterClassExW(CONST WNDCLASSEX *lpwcx)
+RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
{
RTL_ATOM Atom;
+ HANDLE hHeap;
+ WNDCLASSEXW wndclass;
+ LPWSTR ClassName = NULL;
+ LPWSTR MenuName = NULL;
+
+ if ( !lpwcx || (lpwcx->cbSize != sizeof(WNDCLASSEXA)) )
+ return 0;
+
+ if ( !lpwcx->lpszClassName )
+ return 0;
+
+ hHeap = RtlGetProcessHeap();
+ RtlCopyMemory ( &wndclass, lpwcx, sizeof(WNDCLASSEXW) );
+
+ /* copy strings if needed */
+
+ if ( !IS_ATOM(lpwcx->lpszClassName) )
+ {
+ ClassName = HEAP_strdupW ( lpwcx->lpszClassName, lstrlenW(lpwcx->lpszClassName) );
+ if ( !ClassName )
+ {
+ SetLastError(RtlNtStatusToDosError(STATUS_NO_MEMORY));
+ return 0;
+ }
+ wndclass.lpszClassName = ClassName;
+ }
+
+ if ( !IS_INTRESOURCE(lpwcx->lpszMenuName) )
+ {
+ MenuName = HEAP_strdupW ( lpwcx->lpszMenuName, lstrlenW(lpwcx->lpszMenuName) );
+ if ( !MenuName )
+ {
+ if ( ClassName )
+ HEAP_free ( MenuName );
+ SetLastError(RtlNtStatusToDosError(STATUS_NO_MEMORY));
+ return 0;
+ }
+ wndclass.lpszMenuName = MenuName;
+ }
+
+ Atom = NtUserRegisterClassExWOW ( &wndclass, TRUE, 0, 0, 0 );
+
+ /* free strings if neccessary */
+ if ( MenuName ) HEAP_free ( MenuName );
+ if ( ClassName ) HEAP_free ( ClassName );
- Atom = NtUserRegisterClassExWOW((WNDCLASSEX*)lpwcx,
- TRUE,
- 0,
- 0,
- 0,
- 0);
-
return (ATOM)Atom;
}
+/*
+ * @implemented
+ */
ATOM STDCALL
-RegisterClassW(CONST WNDCLASS *lpWndClass)
+RegisterClassW(CONST WNDCLASSW *lpWndClass)
{
- WNDCLASSEX Class;
+ WNDCLASSEXW Class;
+
+ if ( !lpWndClass )
+ return 0;
- RtlMoveMemory(&Class.style, lpWndClass, sizeof(WNDCLASS));
- Class.cbSize = sizeof(WNDCLASSEX);
+ RtlCopyMemory ( &Class.style, lpWndClass, sizeof(WNDCLASSW) );
+
+ Class.cbSize = sizeof(WNDCLASSEXW);
Class.hIconSm = INVALID_HANDLE_VALUE;
- return RegisterClassExW(&Class);
+
+ return RegisterClassExW ( &Class );
}
+/*
+ * @implemented
+ */
DWORD
STDCALL
-SetClassLongA(
+SetClassLongA (
HWND hWnd,
int nIndex,
LONG dwNewLong)
{
- return 0;
+ 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 );
+ }
}
+
+/*
+ * @implemented
+ */
DWORD
STDCALL
SetClassLongW(
int nIndex,
LONG dwNewLong)
{
- return 0;
+ 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 );
+ }
}
+
+/*
+ * @implemented
+ */
WORD
STDCALL
SetClassWord(
* NOTE: Obsoleted in 32-bit windows
*/
{
- return 0;
+ if ((nIndex < 0) && (nIndex != GCW_ATOM))
+ return 0;
+
+ return (WORD) NtUserSetClassLong ( hWnd, nIndex, wNewWord, TRUE );
}
+
+/*
+ * @implemented
+ */
LONG
STDCALL
SetWindowLongA(
int nIndex,
LONG dwNewLong)
{
- return 0;
+ return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, TRUE);
}
+
+/*
+ * @implemented
+ */
LONG
STDCALL
SetWindowLongW(
int nIndex,
LONG dwNewLong)
{
- return 0;
+ return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, FALSE);
}
+
+/*
+ * @unimplemented
+ */
WINBOOL
STDCALL
UnregisterClassA(
LPCSTR lpClassName,
HINSTANCE hInstance)
{
+ UNIMPLEMENTED;
return FALSE;
}
+
+/*
+ * @unimplemented
+ */
WINBOOL
STDCALL
UnregisterClassW(
LPCWSTR lpClassName,
HINSTANCE hInstance)
{
+ UNIMPLEMENTED;
return FALSE;
}