mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 02:10:07 +00:00
- [Win32k] Class rewrite
- This is part 1, tested with Wine user32 class, Seamonkey, FireFox and AbiWord. - Please refer to bug report 4778. svn path=/trunk/; revision=43010
This commit is contained in:
parent
f5617658a3
commit
5221d11896
|
@ -1,9 +1,8 @@
|
|||
/* $Id$
|
||||
*
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS User32
|
||||
* PURPOSE: Built-in control registration
|
||||
* FILE: lib/user32/controls/regcontrol.c
|
||||
* FILE: dll/win32/user32/controls/regcontrol.c
|
||||
* PROGRAMER: Ge van Geldorp (ge@gse.nl)
|
||||
* REVISION HISTORY: 2003/06/16 GvG Created
|
||||
* NOTES: Adapted from Wine
|
||||
|
@ -12,57 +11,76 @@
|
|||
#include <user32.h>
|
||||
|
||||
#include <wine/debug.h>
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(user32);
|
||||
|
||||
DWORD RegisterDefaultClasses = FALSE;
|
||||
|
||||
static PFNCLIENT pfnClientA;
|
||||
static PFNCLIENT pfnClientW;
|
||||
static PFNCLIENTWORKER pfnClientWorker;
|
||||
|
||||
//
|
||||
// FIXME!
|
||||
// These are not "System Classes" but Global Classes that are registered
|
||||
// every time a process is created, so these can be unregistered as the msdn
|
||||
// documents states.
|
||||
//
|
||||
static const struct
|
||||
{
|
||||
const struct builtin_class_descr *desc;
|
||||
UINT ClsId;
|
||||
WORD fnid;
|
||||
WORD ClsId;
|
||||
} g_SysClasses[] =
|
||||
{
|
||||
{ &DIALOG_builtin_class, FNID_DIALOG },
|
||||
{ &POPUPMENU_builtin_class, FNID_MENU },
|
||||
{ &COMBO_builtin_class, FNID_COMBOBOX },
|
||||
{ &COMBOLBOX_builtin_class, FNID_COMBOLBOX },
|
||||
{ &MDICLIENT_builtin_class, FNID_MDICLIENT },
|
||||
{ &DIALOG_builtin_class, FNID_DIALOG, ICLS_DIALOG},
|
||||
/* { &POPUPMENU_builtin_class, FNID_MENU, ICLS_MENU}, // moved to win32k */
|
||||
{ &COMBO_builtin_class, FNID_COMBOBOX, ICLS_COMBOBOX},
|
||||
{ &COMBOLBOX_builtin_class, FNID_COMBOLBOX, ICLS_COMBOLBOX},
|
||||
{ &MDICLIENT_builtin_class, FNID_MDICLIENT, ICLS_MDICLIENT},
|
||||
#if 0
|
||||
{ &MENU_builtin_class, FNID_MENU },
|
||||
{ &MENU_builtin_class, FNID_MENU, ICLS_MENU},
|
||||
#endif
|
||||
{ &SCROLL_builtin_class, FNID_SCROLLBAR },
|
||||
{ &BUTTON_builtin_class, FNID_BUTTON },
|
||||
{ &LISTBOX_builtin_class, FNID_LISTBOX },
|
||||
{ &EDIT_builtin_class, FNID_EDIT },
|
||||
{ &ICONTITLE_builtin_class, FNID_ICONTITLE },
|
||||
{ &STATIC_builtin_class, FNID_STATIC },
|
||||
/* { &SCROLL_builtin_class, FNID_SCROLLBAR, ICLS_SCROLLBAR}, // moved to win32k */
|
||||
{ &BUTTON_builtin_class, FNID_BUTTON, ICLS_BUTTON},
|
||||
{ &LISTBOX_builtin_class, FNID_LISTBOX, ICLS_LISTBOX},
|
||||
{ &EDIT_builtin_class, FNID_EDIT, ICLS_EDIT},
|
||||
/* { &ICONTITLE_builtin_class, FNID_ICONTITLE, ICLS_ICONTITLE}, // moved to win32k */
|
||||
{ &STATIC_builtin_class, FNID_STATIC, ICLS_STATIC},
|
||||
};
|
||||
|
||||
BOOL WINAPI RegisterSystemControls(VOID)
|
||||
{
|
||||
REGISTER_SYSCLASS cls[sizeof(g_SysClasses) / sizeof(g_SysClasses[0])];
|
||||
WNDCLASSEXW WndClass;
|
||||
UINT i;
|
||||
ATOM atom;
|
||||
|
||||
ZeroMemory(cls, sizeof(cls));
|
||||
if (RegisterDefaultClasses) return TRUE;
|
||||
|
||||
for (i = 0; i != sizeof(cls) / sizeof(cls[0]); i++)
|
||||
ZeroMemory(&WndClass, sizeof(WndClass));
|
||||
|
||||
WndClass.cbSize = sizeof(WndClass);
|
||||
|
||||
for (i = 0; i != sizeof(g_SysClasses) / sizeof(g_SysClasses[0]); i++)
|
||||
{
|
||||
if (IS_ATOM(g_SysClasses[i].desc->name))
|
||||
cls[i].ClassName.Buffer = (PWSTR)((ULONG_PTR)g_SysClasses[i].desc->name);
|
||||
else
|
||||
RtlInitUnicodeString(&cls[i].ClassName, g_SysClasses[i].desc->name);
|
||||
WndClass.lpszClassName = g_SysClasses[i].desc->name;
|
||||
|
||||
cls[i].Style = g_SysClasses[i].desc->style;
|
||||
cls[i].ProcW = g_SysClasses[i].desc->procW;
|
||||
cls[i].ProcA = g_SysClasses[i].desc->procA;
|
||||
cls[i].ExtraBytes = g_SysClasses[i].desc->extra;
|
||||
cls[i].hCursor = LoadCursorW(NULL, g_SysClasses[i].desc->cursor);
|
||||
cls[i].hBrush = g_SysClasses[i].desc->brush;
|
||||
cls[i].ClassId = g_SysClasses[i].ClsId;
|
||||
// Set Global bit!
|
||||
WndClass.style = g_SysClasses[i].desc->style|CS_GLOBALCLASS;
|
||||
WndClass.lpfnWndProc = g_SysClasses[i].desc->procW;
|
||||
WndClass.cbWndExtra = g_SysClasses[i].desc->extra;
|
||||
WndClass.hCursor = LoadCursorW(NULL, g_SysClasses[i].desc->cursor);
|
||||
WndClass.hbrBackground= g_SysClasses[i].desc->brush;
|
||||
|
||||
atom = RegisterClassExWOWW( &WndClass,
|
||||
0,
|
||||
g_SysClasses[i].fnid,
|
||||
0,
|
||||
FALSE);
|
||||
if (atom)
|
||||
RegisterDefaultClasses |= ICLASS_TO_MASK(g_SysClasses[i].ClsId);
|
||||
}
|
||||
|
||||
return NtUserRegisterSystemClasses(sizeof(cls) / sizeof(cls[0]), cls);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LRESULT
|
||||
|
|
|
@ -26,6 +26,7 @@ struct builtin_class_descr
|
|||
HBRUSH brush; /* brush or system color */
|
||||
};
|
||||
|
||||
extern DWORD RegisterDefaultClasses;
|
||||
BOOL WINAPI RegisterSystemControls(VOID);
|
||||
|
||||
extern const struct builtin_class_descr BUTTON_builtin_class;
|
||||
|
@ -42,4 +43,6 @@ extern const struct builtin_class_descr MENU_builtin_class;
|
|||
extern const struct builtin_class_descr SCROLL_builtin_class;
|
||||
extern const struct builtin_class_descr STATIC_builtin_class;
|
||||
|
||||
ATOM WINAPI RegisterClassExWOWW(WNDCLASSEXW *,LPDWORD,WORD,DWORD,BOOL);
|
||||
|
||||
#endif /* ROS_REGCONTROL_H */
|
||||
|
|
|
@ -117,9 +117,6 @@
|
|||
#define HideCaret(hwnd) \
|
||||
NtUserHideCaret(hwnd)
|
||||
|
||||
#define NtUserRegisterSystemClasses(Count,SysClasses) \
|
||||
(BOOL)NtUserCallTwoParam((DWORD)Count, (DWORD)SysClasses, TWOPARAM_ROUTINE_ROS_REGSYSCLASSES)
|
||||
|
||||
/* Internal Thread Data */
|
||||
extern HINSTANCE User32Instance;
|
||||
extern HINSTANCE hImmInstance;
|
||||
|
|
|
@ -65,3 +65,4 @@ User32CreateWindowEx(DWORD dwExStyle,
|
|||
BOOL Unicode);
|
||||
|
||||
HWND* WIN_ListChildren (HWND hWndparent);
|
||||
ULONG_PTR FASTCALL IntGetWndProc(PWND, BOOL);
|
||||
|
|
|
@ -291,8 +291,7 @@ DllMain(
|
|||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
User32Instance = hInstanceDll;
|
||||
if (!RegisterClientPFN() ||
|
||||
!RegisterSystemControls())
|
||||
if (!RegisterClientPFN())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,12 @@ GetClassInfoExA(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!RegisterDefaultClasses)
|
||||
{
|
||||
ERR("GetClassInfoExA RegisterSystemControls\n");
|
||||
RegisterSystemControls();
|
||||
}
|
||||
|
||||
if (IS_ATOM(lpszClass))
|
||||
{
|
||||
ClassName.Buffer = (PWSTR)((ULONG_PTR)lpszClass);
|
||||
|
@ -113,6 +119,12 @@ GetClassInfoExW(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!RegisterDefaultClasses)
|
||||
{
|
||||
ERR("GetClassInfoExW RegisterSystemControls\n");
|
||||
RegisterSystemControls();
|
||||
}
|
||||
|
||||
if (IS_ATOM(lpszClass))
|
||||
{
|
||||
ClassName.Buffer = (PWSTR)((ULONG_PTR)lpszClass);
|
||||
|
@ -198,6 +210,126 @@ GetClassInfoW(
|
|||
return retval;
|
||||
}
|
||||
|
||||
//
|
||||
// Based on find_winproc... Fixes many whine tests......
|
||||
//
|
||||
ULONG_PTR FASTCALL
|
||||
IntGetClsWndProc(PWND pWnd, PCLS Class, BOOL Ansi)
|
||||
{
|
||||
INT i;
|
||||
ULONG_PTR gcpd, Ret = 0;
|
||||
// If server side, sweep through proc list and return the client side proc.
|
||||
if (Class->CSF_flags & CSF_SERVERSIDEPROC)
|
||||
{ // Always scan through the list due to wine class "deftest".
|
||||
for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
|
||||
{
|
||||
if (GETPFNSERVER(i) == Class->lpfnWndProc)
|
||||
{
|
||||
if (Ansi)
|
||||
Ret = (ULONG_PTR)GETPFNCLIENTA(i);
|
||||
else
|
||||
Ret = (ULONG_PTR)GETPFNCLIENTW(i);
|
||||
}
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
// Set return proc.
|
||||
Ret = (ULONG_PTR)Class->lpfnWndProc;
|
||||
// Return the proc if one of the FnId default class type.
|
||||
if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
|
||||
{
|
||||
if (Ansi)
|
||||
{ // If match return the right proc by type.
|
||||
if (GETPFNCLIENTW(Class->fnid) == Class->lpfnWndProc)
|
||||
Ret = (ULONG_PTR)GETPFNCLIENTA(Class->fnid);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GETPFNCLIENTA(Class->fnid) == Class->lpfnWndProc)
|
||||
Ret = (ULONG_PTR)GETPFNCLIENTW(Class->fnid);
|
||||
}
|
||||
}
|
||||
// Return on change or Ansi/Unicode proc equal.
|
||||
if ( Ret != (ULONG_PTR)Class->lpfnWndProc ||
|
||||
Ansi == !!(Class->CSF_flags & CSF_ANSIPROC) )
|
||||
return Ret;
|
||||
|
||||
/* We have an Ansi and Unicode swap! If Ansi create Unicode proc handle.
|
||||
This will force CallWindowProc to deal with it. */
|
||||
gcpd = NtUserGetCPD( UserHMGetHandle(pWnd),
|
||||
(Ansi ? UserGetCPDA2U : UserGetCPDU2A )|UserGetCPDWndtoCls,
|
||||
Ret);
|
||||
|
||||
return (gcpd ? gcpd : Ret);
|
||||
}
|
||||
|
||||
//
|
||||
// Based on IntGetClsWndProc
|
||||
//
|
||||
ULONG_PTR FASTCALL
|
||||
IntGetWndProc(PWND pWnd, BOOL Ansi)
|
||||
{
|
||||
INT i;
|
||||
ULONG_PTR gcpd, Ret = 0;
|
||||
PCLS Class = DesktopPtrToUser(pWnd->pcls);
|
||||
|
||||
if (!Class) return Ret;
|
||||
|
||||
if (pWnd->state & WNDS_SERVERSIDEWINDOWPROC)
|
||||
{
|
||||
for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
|
||||
{
|
||||
if (GETPFNSERVER(i) == pWnd->lpfnWndProc)
|
||||
{
|
||||
if (Ansi)
|
||||
Ret = (ULONG_PTR)GETPFNCLIENTA(i);
|
||||
else
|
||||
Ret = (ULONG_PTR)GETPFNCLIENTW(i);
|
||||
}
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
// Wine Class tests:
|
||||
/* Edit controls are special - they return a wndproc handle when
|
||||
GetWindowLongPtr is called with a different A/W.
|
||||
On the other hand there is no W->A->W conversion so this control
|
||||
is treated specially.
|
||||
*/
|
||||
if (Class->fnid == FNID_EDIT)
|
||||
Ret = (ULONG_PTR)pWnd->lpfnWndProc;
|
||||
else
|
||||
{
|
||||
// Set return proc.
|
||||
Ret = (ULONG_PTR)pWnd->lpfnWndProc;
|
||||
|
||||
if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
|
||||
{
|
||||
if (Ansi)
|
||||
{
|
||||
if (GETPFNCLIENTW(Class->fnid) == pWnd->lpfnWndProc)
|
||||
Ret = (ULONG_PTR)GETPFNCLIENTA(Class->fnid);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GETPFNCLIENTA(Class->fnid) == pWnd->lpfnWndProc)
|
||||
Ret = (ULONG_PTR)GETPFNCLIENTW(Class->fnid);
|
||||
}
|
||||
}
|
||||
// Return on the change.
|
||||
if ( Ret != (ULONG_PTR)pWnd->lpfnWndProc)
|
||||
return Ret;
|
||||
}
|
||||
|
||||
if ( Ansi == !!(pWnd->state & WNDS_ANSIWINDOWPROC) )
|
||||
return Ret;
|
||||
|
||||
gcpd = NtUserGetCPD( UserHMGetHandle(pWnd),
|
||||
(Ansi ? UserGetCPDA2U : UserGetCPDU2A )|UserGetCPDWindow,
|
||||
Ret);
|
||||
|
||||
return (gcpd ? gcpd : Ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
@ -248,6 +380,7 @@ GetClassLongA(HWND hWnd, int nIndex)
|
|||
break;
|
||||
|
||||
case GCL_HMODULE:
|
||||
//ERR("Cls 0x%x GCL_HMODULE 0x%x\n", Wnd->pcls, Class->hModule);
|
||||
Ret = (ULONG_PTR)Class->hModule;
|
||||
break;
|
||||
|
||||
|
@ -279,9 +412,7 @@ GetClassLongA(HWND hWnd, int nIndex)
|
|||
break;
|
||||
|
||||
case GCLP_WNDPROC:
|
||||
/* We need to make a call to win32k as it may be required to
|
||||
create a callproc handle */
|
||||
Wnd = NULL;
|
||||
Ret = IntGetClsWndProc(Wnd, Class, TRUE);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -392,9 +523,7 @@ GetClassLongW ( HWND hWnd, int nIndex )
|
|||
break;
|
||||
|
||||
case GCLP_WNDPROC:
|
||||
/* We need to make a call to win32k as it may be required to
|
||||
create a callproc handle */
|
||||
Wnd = NULL;
|
||||
Ret = IntGetClsWndProc(Wnd, Class, FALSE);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -523,7 +652,6 @@ GetWindowLongA ( HWND hWnd, int nIndex )
|
|||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return *((LONG *)((PCHAR)(Wnd + 1) + nIndex));
|
||||
}
|
||||
else
|
||||
|
@ -548,9 +676,12 @@ GetWindowLongA ( HWND hWnd, int nIndex )
|
|||
return (LONG)parent;
|
||||
}
|
||||
case GWL_WNDPROC:
|
||||
/* Call win32k for this as a callproc handle may need
|
||||
to be created */
|
||||
return NtUserGetWindowLong(hWnd, nIndex, TRUE);
|
||||
if (!TestWindowProcess(Wnd))
|
||||
{
|
||||
SetLastError(ERROR_ACCESS_DENIED);
|
||||
return 0;
|
||||
}
|
||||
return IntGetWndProc(Wnd, TRUE);
|
||||
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
|
@ -580,7 +711,6 @@ GetWindowLongW(HWND hWnd, int nIndex)
|
|||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return *((LONG *)((PCHAR)(Wnd + 1) + nIndex));
|
||||
}
|
||||
else
|
||||
|
@ -605,9 +735,12 @@ GetWindowLongW(HWND hWnd, int nIndex)
|
|||
return (LONG)parent;
|
||||
}
|
||||
case GWL_WNDPROC:
|
||||
/* Call win32k for this as a callproc handle may need
|
||||
to be created */
|
||||
return NtUserGetWindowLong(hWnd, nIndex, FALSE);
|
||||
if (!TestWindowProcess(Wnd))
|
||||
{
|
||||
SetLastError(ERROR_ACCESS_DENIED);
|
||||
return 0;
|
||||
}
|
||||
return IntGetWndProc(Wnd, FALSE);
|
||||
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
|
@ -834,7 +967,8 @@ ATOM WINAPI
|
|||
RegisterClassExWOWW(WNDCLASSEXW *lpwcx,
|
||||
LPDWORD pdwWowData,
|
||||
WORD fnID,
|
||||
DWORD dwFlags)
|
||||
DWORD dwFlags,
|
||||
BOOL ChkRegCls)
|
||||
{
|
||||
ATOM Atom;
|
||||
WNDCLASSEXW WndClass;
|
||||
|
@ -847,16 +981,31 @@ RegisterClassExWOWW(WNDCLASSEXW *lpwcx,
|
|||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
|
||||
lpwcx->lpszClassName == NULL)
|
||||
{
|
||||
ERR("RegisterClassExWOWW Invalid Parameter Error!\n");
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ChkRegCls)
|
||||
{
|
||||
if (!RegisterDefaultClasses) RegisterSystemControls();
|
||||
}
|
||||
/*
|
||||
* On real Windows this looks more like:
|
||||
* if (lpwcx->hInstance == User32Instance &&
|
||||
* *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
|
||||
* But since I have no idea what the magic field in the
|
||||
* TEB structure means, I rather decided to omit that.
|
||||
* -- Filip Navara
|
||||
|
||||
GetWin32ClientInfo()->dwExpWinVer & (WINVER == 0x400)
|
||||
*/
|
||||
if (lpwcx->hInstance == User32Instance)
|
||||
{
|
||||
ERR("RegisterClassExWOWW User32Instance!\n");
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Yes, this is correct. We should modify the passed structure. */
|
||||
if (lpwcx->hInstance == NULL)
|
||||
((WNDCLASSEXW*)lpwcx)->hInstance = GetModuleHandleW(NULL);
|
||||
|
@ -875,11 +1024,13 @@ RegisterClassExWOWW(WNDCLASSEXW *lpwcx,
|
|||
if (WndClass.lpszMenuName[0])
|
||||
{
|
||||
RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName);
|
||||
RtlUnicodeStringToAnsiString( &AnsiMenuName, &MenuName, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
|
||||
AnsiMenuName.Buffer = (PCHAR)WndClass.lpszMenuName;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -894,8 +1045,6 @@ RegisterClassExWOWW(WNDCLASSEXW *lpwcx,
|
|||
RtlInitUnicodeString(&ClassName, WndClass.lpszClassName);
|
||||
}
|
||||
|
||||
RtlUnicodeStringToAnsiString( &AnsiMenuName, &MenuName, TRUE);
|
||||
|
||||
clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer;
|
||||
clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer;
|
||||
clsMenuName.pusMenuName = &MenuName;
|
||||
|
@ -922,89 +1071,42 @@ ATOM WINAPI
|
|||
RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
|
||||
{
|
||||
RTL_ATOM Atom;
|
||||
WNDCLASSEXA WndClass;
|
||||
UNICODE_STRING ClassName;
|
||||
UNICODE_STRING MenuName = {0};
|
||||
CLSMENUNAME clsMenuName;
|
||||
ANSI_STRING AnsiMenuName;
|
||||
|
||||
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXA) ||
|
||||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
|
||||
lpwcx->lpszClassName == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lpwcx->hInstance == User32Instance)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Yes, this is correct. We should modify the passed structure. */
|
||||
if (lpwcx->hInstance == NULL)
|
||||
((WNDCLASSEXA*)lpwcx)->hInstance = GetModuleHandleW(NULL);
|
||||
WNDCLASSEXW WndClass;
|
||||
WCHAR mname[MAX_BUFFER_LEN];
|
||||
WCHAR cname[MAX_BUFFER_LEN];
|
||||
|
||||
RtlCopyMemory(&WndClass, lpwcx, sizeof(WNDCLASSEXA));
|
||||
|
||||
if (NULL == WndClass.hIconSm)
|
||||
{
|
||||
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
|
||||
}
|
||||
|
||||
if (WndClass.lpszMenuName != NULL)
|
||||
{
|
||||
if (!IS_INTRESOURCE(WndClass.lpszMenuName))
|
||||
{
|
||||
if (WndClass.lpszMenuName[0])
|
||||
{
|
||||
RtlCreateUnicodeStringFromAsciiz(&MenuName, WndClass.lpszMenuName);
|
||||
if (!MultiByteToWideChar( CP_ACP, 0, lpwcx->lpszMenuName, -1, mname, MAX_ATOM_LEN + 1 )) return 0;
|
||||
|
||||
WndClass.lpszMenuName = mname;
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
if (!IS_ATOM(WndClass.lpszClassName))
|
||||
{
|
||||
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
|
||||
}
|
||||
if (!MultiByteToWideChar( CP_ACP, 0, lpwcx->lpszClassName, -1, cname, MAX_ATOM_LEN + 1 )) return 0;
|
||||
|
||||
WndClass.lpszClassName = cname;
|
||||
}
|
||||
|
||||
if (IS_ATOM(WndClass.lpszClassName))
|
||||
{
|
||||
ClassName.Length =
|
||||
ClassName.MaximumLength = 0;
|
||||
ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlCreateUnicodeStringFromAsciiz(&ClassName, WndClass.lpszClassName);
|
||||
}
|
||||
|
||||
RtlUnicodeStringToAnsiString( &AnsiMenuName, &MenuName, TRUE);
|
||||
|
||||
clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer;
|
||||
clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer;
|
||||
clsMenuName.pusMenuName = &MenuName;
|
||||
|
||||
Atom = NtUserRegisterClassExWOW( (WNDCLASSEXW*)&WndClass,
|
||||
&ClassName,
|
||||
NULL, //PUNICODE_STRING ClsNVersion,
|
||||
&clsMenuName,
|
||||
Atom = RegisterClassExWOWW( &WndClass,
|
||||
0,
|
||||
0,
|
||||
CSF_ANSIPROC,
|
||||
0);
|
||||
TRUE);
|
||||
|
||||
TRACE("A atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
|
||||
Atom, lpwcx->lpfnWndProc, lpwcx->hInstance, lpwcx->hbrBackground,
|
||||
lpwcx->style, lpwcx->cbClsExtra, lpwcx->cbWndExtra, WndClass);
|
||||
|
||||
if (!IS_INTRESOURCE(WndClass.lpszMenuName))
|
||||
{
|
||||
RtlFreeUnicodeString(&MenuName);
|
||||
RtlFreeAnsiString(&AnsiMenuName);
|
||||
}
|
||||
if (!IS_ATOM(WndClass.lpszClassName))
|
||||
RtlFreeUnicodeString(&ClassName);
|
||||
|
||||
return (ATOM)Atom;
|
||||
}
|
||||
|
||||
|
@ -1015,90 +1117,12 @@ ATOM WINAPI
|
|||
RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
|
||||
{
|
||||
ATOM Atom;
|
||||
WNDCLASSEXW WndClass;
|
||||
UNICODE_STRING ClassName;
|
||||
UNICODE_STRING MenuName = {0};
|
||||
CLSMENUNAME clsMenuName;
|
||||
ANSI_STRING AnsiMenuName;
|
||||
|
||||
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) ||
|
||||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
|
||||
lpwcx->lpszClassName == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
Atom = RegisterClassExWOWW( (WNDCLASSEXW *)lpwcx, 0, 0, 0, TRUE);
|
||||
|
||||
/*
|
||||
* On real Windows this looks more like:
|
||||
* if (lpwcx->hInstance == User32Instance &&
|
||||
* *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
|
||||
* But since I have no idea what the magic field in the
|
||||
* TEB structure means, I rather decided to omit that.
|
||||
* -- Filip Navara
|
||||
|
||||
GetWin32ClientInfo()->ulWindowsVersion & (WINVER == 400)
|
||||
*/
|
||||
if (lpwcx->hInstance == User32Instance)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Yes, this is correct. We should modify the passed structure. */
|
||||
if (lpwcx->hInstance == NULL)
|
||||
((WNDCLASSEXW*)lpwcx)->hInstance = GetModuleHandleW(NULL);
|
||||
|
||||
RtlCopyMemory(&WndClass, lpwcx, sizeof(WNDCLASSEXW));
|
||||
|
||||
if (NULL == WndClass.hIconSm)
|
||||
{
|
||||
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
|
||||
}
|
||||
|
||||
if (WndClass.lpszMenuName != NULL)
|
||||
{
|
||||
if (!IS_INTRESOURCE(WndClass.lpszMenuName))
|
||||
{
|
||||
if (WndClass.lpszMenuName[0])
|
||||
{
|
||||
RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ATOM(WndClass.lpszClassName))
|
||||
{
|
||||
ClassName.Length =
|
||||
ClassName.MaximumLength = 0;
|
||||
ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlInitUnicodeString(&ClassName, WndClass.lpszClassName);
|
||||
}
|
||||
|
||||
RtlUnicodeStringToAnsiString( &AnsiMenuName, &MenuName, TRUE);
|
||||
|
||||
clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer;
|
||||
clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer;
|
||||
clsMenuName.pusMenuName = &MenuName;
|
||||
|
||||
Atom = NtUserRegisterClassExWOW( &WndClass,
|
||||
&ClassName,
|
||||
NULL, //PUNICODE_STRING ClsNVersion,
|
||||
&clsMenuName,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
|
||||
TRACE("W atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
|
||||
TRACE("W atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d\n",
|
||||
Atom, lpwcx->lpfnWndProc, lpwcx->hInstance, lpwcx->hbrBackground,
|
||||
lpwcx->style, lpwcx->cbClsExtra, lpwcx->cbWndExtra, WndClass);
|
||||
lpwcx->style, lpwcx->cbClsExtra, lpwcx->cbWndExtra);
|
||||
|
||||
return Atom;
|
||||
}
|
||||
|
@ -1153,8 +1177,6 @@ SetClassLongA (HWND hWnd,
|
|||
BOOL Allocated = FALSE;
|
||||
DWORD Ret;
|
||||
|
||||
TRACE("%p %d %lx\n", hWnd, nIndex, dwNewLong);
|
||||
|
||||
/* FIXME - portability!!!! */
|
||||
|
||||
if (nIndex == GCL_MENUNAME && lpStr != NULL)
|
||||
|
|
|
@ -1221,6 +1221,58 @@ IntCallWindowProcA(BOOL IsAnsiProc,
|
|||
}
|
||||
|
||||
|
||||
static LRESULT WINAPI
|
||||
IntCallMessageProc(IN PWND Wnd, IN HWND hWnd, IN UINT Msg, IN WPARAM wParam, IN LPARAM lParam, IN BOOL Ansi)
|
||||
{
|
||||
WNDPROC WndProc;
|
||||
BOOL IsAnsi;
|
||||
PCLS Class;
|
||||
|
||||
Class = DesktopPtrToUser(Wnd->pcls);
|
||||
WndProc = NULL;
|
||||
/*
|
||||
This is the message exchange for user32. If there's a need to monitor messages,
|
||||
do it here!
|
||||
*/
|
||||
TRACE("HWND 0x%x, MSG %d, WPARAM 0x%x, LPARAM 0x%x, Ansi &d\n",hWnd,Msg,wParam,lParam,Ansi);
|
||||
// if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON )
|
||||
if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_FIRST )
|
||||
{
|
||||
if (Ansi)
|
||||
{
|
||||
if (GETPFNCLIENTW(Class->fnid) == Wnd->lpfnWndProc)
|
||||
WndProc = GETPFNCLIENTA(Class->fnid);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GETPFNCLIENTA(Class->fnid) == Wnd->lpfnWndProc)
|
||||
WndProc = GETPFNCLIENTW(Class->fnid);
|
||||
}
|
||||
|
||||
IsAnsi = Ansi;
|
||||
|
||||
if (!WndProc)
|
||||
{
|
||||
IsAnsi = !Wnd->Unicode;
|
||||
WndProc = Wnd->lpfnWndProc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IsAnsi = !Wnd->Unicode;
|
||||
WndProc = Wnd->lpfnWndProc;
|
||||
}
|
||||
/*
|
||||
Message caller can be Ansi/Unicode and the receiver can be Unicode/Ansi or
|
||||
the same.
|
||||
*/
|
||||
if (!Ansi)
|
||||
return IntCallWindowProcW(IsAnsi, WndProc, hWnd, Msg, wParam, lParam);
|
||||
else
|
||||
return IntCallWindowProcA(IsAnsi, WndProc, hWnd, Msg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
@ -1246,8 +1298,12 @@ CallWindowProcA(WNDPROC lpPrevWndFunc,
|
|||
CallProc = ValidateCallProc((HANDLE)lpPrevWndFunc);
|
||||
if (CallProc != NULL)
|
||||
{
|
||||
return IntCallWindowProcA(!CallProc->Unicode, CallProc->pfnClientPrevious,
|
||||
hWnd, Msg, wParam, lParam);
|
||||
return IntCallWindowProcA(!(CallProc->wType & UserGetCPDA2U),
|
||||
CallProc->pfnClientPrevious,
|
||||
hWnd,
|
||||
Msg,
|
||||
wParam,
|
||||
lParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1284,8 +1340,12 @@ CallWindowProcW(WNDPROC lpPrevWndFunc,
|
|||
CallProc = ValidateCallProc((HANDLE)lpPrevWndFunc);
|
||||
if (CallProc != NULL)
|
||||
{
|
||||
return IntCallWindowProcW(!CallProc->Unicode, CallProc->pfnClientPrevious,
|
||||
hWnd, Msg, wParam, lParam);
|
||||
return IntCallWindowProcW(!(CallProc->wType & UserGetCPDA2U),
|
||||
CallProc->pfnClientPrevious,
|
||||
hWnd,
|
||||
Msg,
|
||||
wParam,
|
||||
lParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1296,30 +1356,6 @@ CallWindowProcW(WNDPROC lpPrevWndFunc,
|
|||
}
|
||||
|
||||
|
||||
static LRESULT WINAPI
|
||||
IntCallMessageProc(IN PWND Wnd, IN HWND hWnd, IN UINT Msg, IN WPARAM wParam, IN LPARAM lParam, IN BOOL Ansi)
|
||||
{
|
||||
WNDPROC WndProc;
|
||||
BOOL IsAnsi;
|
||||
|
||||
if (Wnd->IsSystem)
|
||||
{
|
||||
WndProc = (Ansi ? Wnd->WndProcExtra : Wnd->lpfnWndProc);
|
||||
IsAnsi = Ansi;
|
||||
}
|
||||
else
|
||||
{
|
||||
WndProc = Wnd->lpfnWndProc;
|
||||
IsAnsi = !Wnd->Unicode;
|
||||
}
|
||||
|
||||
if (!Ansi)
|
||||
return IntCallWindowProcW(IsAnsi, WndProc, hWnd, Msg, wParam, lParam);
|
||||
else
|
||||
return IntCallWindowProcA(IsAnsi, WndProc, hWnd, Msg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
@ -1353,8 +1389,7 @@ DispatchMessageA(CONST MSG *lpmsg)
|
|||
}
|
||||
else if (Wnd != NULL)
|
||||
{
|
||||
// FIXME Need to test for calling proc inside win32k!
|
||||
if ( (lpmsg->message != WM_PAINT) ) // && !(Wnd->state & WNDS_SERVERSIDEWINDOWPROC) )
|
||||
if ( (lpmsg->message != WM_PAINT) && !(Wnd->state & WNDS_SERVERSIDEWINDOWPROC) )
|
||||
{
|
||||
Ret = IntCallMessageProc(Wnd,
|
||||
lpmsg->hwnd,
|
||||
|
@ -1414,8 +1449,7 @@ DispatchMessageW(CONST MSG *lpmsg)
|
|||
}
|
||||
else if (Wnd != NULL)
|
||||
{
|
||||
// FIXME Need to test for calling proc inside win32k!
|
||||
if ( (lpmsg->message != WM_PAINT) ) // && !(Wnd->state & WNDS_SERVERSIDEWINDOWPROC) )
|
||||
if ( (lpmsg->message != WM_PAINT) && !(Wnd->state & WNDS_SERVERSIDEWINDOWPROC) )
|
||||
{
|
||||
Ret = IntCallMessageProc(Wnd,
|
||||
lpmsg->hwnd,
|
||||
|
@ -2328,9 +2362,12 @@ User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
|||
{
|
||||
}
|
||||
|
||||
CallbackArgs->Result = IntCallWindowProcW(CallbackArgs->IsAnsiProc, CallbackArgs->Proc,
|
||||
UMMsg.hwnd, UMMsg.message,
|
||||
UMMsg.wParam, UMMsg.lParam);
|
||||
CallbackArgs->Result = IntCallWindowProcW( CallbackArgs->IsAnsiProc,
|
||||
CallbackArgs->Proc,
|
||||
UMMsg.hwnd,
|
||||
UMMsg.message,
|
||||
UMMsg.wParam,
|
||||
UMMsg.lParam);
|
||||
|
||||
if (! MsgiKMToUMReply(&KMMsg, &UMMsg, &CallbackArgs->Result))
|
||||
{
|
||||
|
|
|
@ -174,6 +174,12 @@ User32CreateWindowEx(DWORD dwExStyle,
|
|||
DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent);
|
||||
#endif
|
||||
|
||||
if (!RegisterDefaultClasses)
|
||||
{
|
||||
ERR("User32CreateWindowEx RegisterSystemControls\n");
|
||||
RegisterSystemControls();
|
||||
}
|
||||
|
||||
if (IS_ATOM(lpClassName))
|
||||
{
|
||||
RtlInitUnicodeString(&ClassName, NULL);
|
||||
|
@ -281,6 +287,12 @@ CreateWindowExA(DWORD dwExStyle,
|
|||
MDICREATESTRUCTA mdi;
|
||||
HWND hwnd;
|
||||
|
||||
if (!RegisterDefaultClasses)
|
||||
{
|
||||
ERR("CreateWindowExA RegisterSystemControls\n");
|
||||
RegisterSystemControls();
|
||||
}
|
||||
|
||||
if (dwExStyle & WS_EX_MDICHILD)
|
||||
{
|
||||
POINT mPos[2];
|
||||
|
@ -387,6 +399,12 @@ CreateWindowExW(DWORD dwExStyle,
|
|||
MDICREATESTRUCTW mdi;
|
||||
HWND hwnd;
|
||||
|
||||
if (!RegisterDefaultClasses)
|
||||
{
|
||||
ERR("CreateWindowExW RegisterSystemControls\n");
|
||||
RegisterSystemControls();
|
||||
}
|
||||
|
||||
if (dwExStyle & WS_EX_MDICHILD)
|
||||
{
|
||||
POINT mPos[2];
|
||||
|
|
|
@ -167,14 +167,14 @@ typedef struct _REGISTER_SYSCLASS
|
|||
{
|
||||
/* This is a reactos specific class used to initialize the
|
||||
system window classes during user32 initialization */
|
||||
UNICODE_STRING ClassName;
|
||||
PWSTR ClassName;
|
||||
UINT Style;
|
||||
WNDPROC ProcW;
|
||||
WNDPROC ProcA;
|
||||
UINT ExtraBytes;
|
||||
HICON hCursor;
|
||||
HBRUSH hBrush;
|
||||
UINT ClassId;
|
||||
WORD fiId;
|
||||
WORD iCls;
|
||||
} REGISTER_SYSCLASS, *PREGISTER_SYSCLASS;
|
||||
|
||||
typedef struct _CLSMENUNAME
|
||||
|
@ -201,8 +201,8 @@ typedef struct tagSBINFO
|
|||
|
||||
typedef enum _GETCPD
|
||||
{
|
||||
UserGetCPDU2A = 0x01,
|
||||
UserGetCPDA2U = 0X02,
|
||||
UserGetCPDA2U = 0x01, // " Unicode "
|
||||
UserGetCPDU2A = 0X02, // " Ansi "
|
||||
UserGetCPDClass = 0X10,
|
||||
UserGetCPDWindow = 0X20,
|
||||
UserGetCPDDialog = 0X40,
|
||||
|
@ -214,11 +214,7 @@ typedef struct _CALLPROCDATA
|
|||
PROCDESKHEAD head;
|
||||
struct _CALLPROCDATA *spcpdNext;
|
||||
WNDPROC pfnClientPrevious;
|
||||
union
|
||||
{
|
||||
GETCPD wType;
|
||||
UINT Unicode : 1;
|
||||
};
|
||||
} CALLPROCDATA, *PCALLPROCDATA;
|
||||
|
||||
#define CSF_SERVERSIDEPROC 0x0001
|
||||
|
@ -247,11 +243,6 @@ typedef struct _CLS
|
|||
ULONG cWndReferenceCount;
|
||||
UINT style;
|
||||
WNDPROC lpfnWndProc;
|
||||
union
|
||||
{
|
||||
WNDPROC WndProcExtra;
|
||||
PCALLPROCDATA CallProc;
|
||||
};
|
||||
INT cbclsExtra;
|
||||
INT cbwndExtra;
|
||||
HINSTANCE hModule;
|
||||
|
@ -265,12 +256,10 @@ typedef struct _CLS
|
|||
HANDLE hIconSm; /* FIXME - Use pointer! */
|
||||
//PCURSOR spicnSm;
|
||||
|
||||
UINT Destroying : 1; // CSF_WOWDEFERDESTROY
|
||||
UINT Unicode : 1; // !CSF_ANSIPROC
|
||||
UINT System : 1; // CSF_SYSTEMCLASS
|
||||
UINT Global : 1; // CS_GLOBALCLASS
|
||||
UINT Global : 1; // CS_GLOBALCLASS or CSF_SERVERSIDEPROC
|
||||
UINT MenuNameIsString : 1;
|
||||
UINT NotUsed : 27;
|
||||
UINT NotUsed : 29;
|
||||
} CLS, *PCLS;
|
||||
|
||||
|
||||
|
@ -342,10 +331,12 @@ typedef struct _CLS
|
|||
|
||||
/* Non SDK ExStyles */
|
||||
#define WS_EX_MAKEVISIBLEWHENUNGHOSTED 0x00000800
|
||||
#define WS_EX_FORCELEGACYRESIZENCMETR 0x00800000
|
||||
#define WS_EX_UISTATEACTIVE 0x04000000
|
||||
#define WS_EX_REDIRECTED 0X20000000
|
||||
#define WS_EX_UISTATEKBACCELHIDDEN 0X40000000
|
||||
#define WS_EX_UISTATEFOCUSRECTHIDDEN 0X80000000
|
||||
#define WS_EX_SETANSICREATOR 0x80000000 // For WNDS_ANSICREATOR
|
||||
|
||||
/* Non SDK Styles */
|
||||
#define WS_MAXIMIZED WS_MAXIMIZE
|
||||
|
@ -385,14 +376,6 @@ typedef struct _WND
|
|||
RECT rcWindow;
|
||||
RECT rcClient;
|
||||
WNDPROC lpfnWndProc;
|
||||
union
|
||||
{
|
||||
/* Pointer to a call procedure handle */
|
||||
PCALLPROCDATA CallProc;
|
||||
/* Extra Wnd proc (windows of system classes) */
|
||||
WNDPROC WndProcExtra;
|
||||
};
|
||||
|
||||
/* Pointer to the window class. */
|
||||
PCLS pcls;
|
||||
HRGN hrgnUpdate;
|
||||
|
@ -431,7 +414,6 @@ typedef struct _WND
|
|||
|
||||
UINT Unicode : 1; // !(WNDS_ANSICREATOR|WNDS_ANSIWINDOWPROC) ?
|
||||
/* Indicates whether the window is derived from a system class */
|
||||
UINT IsSystem : 1; // System class ?
|
||||
UINT InternalPosInitialized : 1;
|
||||
UINT HideFocus : 1; // WS_EX_UISTATEFOCUSRECTHIDDEN ?
|
||||
UINT HideAccel : 1; // WS_EX_UISTATEKBACCELHIDDEN ?
|
||||
|
@ -525,10 +507,21 @@ typedef LONG_PTR (NTAPI *PFN_FNID)(PWND, UINT, WPARAM, LPARAM, ULONG_PTR);
|
|||
#define FNID_LAST 0x02B9
|
||||
|
||||
#define FNID_NUM FNID_LAST - FNID_FIRST + 1
|
||||
#define FNID_NUMSERVERPROC FNID_SWITCH - FNID_FIRST + 1
|
||||
|
||||
#define FNID_DDEML 0x2000 // Registers DDEML
|
||||
#define FNID_DESTROY 0x4000 // This is sent when WM_NCDESTROY or in the support routine.
|
||||
// Seen during WM_CREATE on error exit too.
|
||||
#define FNID_FREED 0x8000 // Window being Freed...
|
||||
|
||||
#define ICLASS_TO_MASK(iCls) (1 << ((iCls)))
|
||||
|
||||
#define GETPFNCLIENTA(fnid)\
|
||||
(WNDPROC)(*(((ULONG_PTR *)&gpsi->apfnClientA) + (fnid - FNID_FIRST)))
|
||||
#define GETPFNCLIENTW(fnid)\
|
||||
(WNDPROC)(*(((ULONG_PTR *)&gpsi->apfnClientW) + (fnid - FNID_FIRST)))
|
||||
|
||||
#define GETPFNSERVER(fnid) gpsi->aStoCidPfn[fnid - FNID_FIRST]
|
||||
|
||||
// ICLS's for NtUserGetClassName FNID to ICLS, NtUserInitializeClientPfnArrays
|
||||
#define ICLS_BUTTON 0
|
||||
|
@ -641,7 +634,7 @@ typedef struct tagSERVERINFO
|
|||
DWORD dwSRVIFlags;
|
||||
ULONG_PTR cHandleEntries;
|
||||
PFN_FNID mpFnidPfn[FNID_NUM];
|
||||
WNDPROC aStoCidPfn[7];
|
||||
WNDPROC aStoCidPfn[FNID_NUMSERVERPROC];
|
||||
USHORT mpFnid_serverCBWndProc[FNID_NUM];
|
||||
PFNCLIENT apfnClientA;
|
||||
PFNCLIENT apfnClientW;
|
||||
|
@ -1374,7 +1367,7 @@ NtUserCreateWindowEx(
|
|||
HWND
|
||||
NTAPI
|
||||
NtUserCreateWindowEx(
|
||||
DWORD dwExStyle,
|
||||
DWORD dwExStyle, // |= 0x80000000 == Ansi used to set WNDS_ANSICREATOR
|
||||
PLARGE_STRING plstrClassName,
|
||||
PLARGE_STRING plstrClsVesrion,
|
||||
PLARGE_STRING plstrWindowName,
|
||||
|
@ -1387,7 +1380,7 @@ NtUserCreateWindowEx(
|
|||
HMENU hMenu,
|
||||
HINSTANCE hInstance,
|
||||
LPVOID lpParam,
|
||||
DWORD dwFlags, // |= 1 == Ansi
|
||||
DWORD dwFlags,
|
||||
PVOID acbiBuffer);
|
||||
#endif
|
||||
|
||||
|
@ -3053,7 +3046,6 @@ typedef struct tagKMDDELPARAM
|
|||
#define TWOPARAM_ROUTINE_REGISTERLOGONPROC 0xfffd0062
|
||||
#define TWOPARAM_ROUTINE_ROS_ISACTIVEICON 0x1001
|
||||
#define TWOPARAM_ROUTINE_ROS_NCDESTROY 0x1002
|
||||
#define TWOPARAM_ROUTINE_ROS_REGSYSCLASSES 0x1003
|
||||
#define TWOPARAM_ROUTINE_ROS_UPDATEUISTATE 0x1004
|
||||
|
||||
DWORD
|
||||
|
|
|
@ -58,13 +58,13 @@ RTL_ATOM
|
|||
UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
|
||||
IN PUNICODE_STRING ClassName,
|
||||
IN PUNICODE_STRING MenuName,
|
||||
IN WNDPROC wpExtra,
|
||||
IN DWORD fnID,
|
||||
IN DWORD dwFlags);
|
||||
|
||||
BOOL
|
||||
UserUnregisterClass(IN PUNICODE_STRING ClassName,
|
||||
IN HINSTANCE hInstance);
|
||||
IN HINSTANCE hInstance,
|
||||
OUT PCLSMENUNAME pClassMenuName);
|
||||
|
||||
ULONG_PTR
|
||||
UserGetClassLongPtr(IN PCLS Class,
|
||||
|
@ -83,20 +83,12 @@ FASTCALL
|
|||
IntCreateClass(IN CONST WNDCLASSEXW* lpwcx,
|
||||
IN PUNICODE_STRING ClassName,
|
||||
IN PUNICODE_STRING MenuName,
|
||||
IN WNDPROC wpExtra,
|
||||
IN DWORD fnID,
|
||||
IN DWORD dwFlags,
|
||||
IN PDESKTOP Desktop,
|
||||
IN PPROCESSINFO pi);
|
||||
|
||||
PCALLPROCDATA
|
||||
UserFindCallProc(IN PCLS Class,
|
||||
IN WNDPROC WndProc,
|
||||
IN BOOL bUnicode);
|
||||
|
||||
BOOL
|
||||
UserRegisterSystemClasses(IN ULONG Count,
|
||||
IN PREGISTER_SYSCLASS SystemClasses);
|
||||
BOOL FASTCALL UserRegisterSystemClasses(VOID);
|
||||
|
||||
VOID
|
||||
UserAddCallProcToClass(IN OUT PCLS Class,
|
||||
|
@ -110,6 +102,10 @@ BOOL
|
|||
IntCheckProcessDesktopClasses(IN PDESKTOP Desktop,
|
||||
IN BOOL FreeOnFailure);
|
||||
|
||||
BOOL FASTCALL LookupFnIdToiCls(int, int * );
|
||||
WNDPROC FASTCALL IntGetClassWndProc(PCLS, BOOL);
|
||||
ULONG_PTR FASTCALL UserGetCPD(PVOID,GETCPD,ULONG_PTR);
|
||||
|
||||
#endif /* _WIN32K_CLASS_H */
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -31,6 +31,37 @@
|
|||
#define W32PF_MANUALGUICHECK (0x02000000)
|
||||
#define W32PF_CREATEDWINORDC (0x04000000)
|
||||
|
||||
/* THREADINFO Flags */
|
||||
#define TIF_INCLEANUP 0x00000001
|
||||
#define TIF_16BIT 0x00000002
|
||||
#define TIF_SYSTEMTHREAD 0x00000004
|
||||
#define TIF_CSRSSTHREAD 0x00000008
|
||||
#define TIF_TRACKRECTVISIBLE 0x00000010
|
||||
#define TIF_ALLOWFOREGROUNDACTIVATE 0x00000020
|
||||
#define TIF_DONTATTACHQUEUE 0x00000040
|
||||
#define TIF_DONTJOURNALATTACH 0x00000080
|
||||
#define TIF_WOW64 0x00000100
|
||||
#define TIF_INACTIVATEAPPMSG 0x00000200
|
||||
#define TIF_SPINNING 0x00000400
|
||||
#define TIF_PALETTEAWARE 0x00000800
|
||||
#define TIF_SHAREDWOW 0x00001000
|
||||
#define TIF_FIRSTIDLE 0x00002000
|
||||
#define TIF_WAITFORINPUTIDLE 0x00004000
|
||||
#define TIF_MOVESIZETRACKING 0x00008000
|
||||
#define TIF_VDMAPP 0x00010000
|
||||
#define TIF_DOSEMULATOR 0x00020000
|
||||
#define TIF_GLOBALHOOKER 0x00040000
|
||||
#define TIF_DELAYEDEVENT 0x00080000
|
||||
#define TIF_MSGPOSCHANGED 0x00100000
|
||||
#define TIF_SHUTDOWNCOMPLETE 0x00200000
|
||||
#define TIF_IGNOREPLAYBACKDELAY 0x00400000
|
||||
#define TIF_ALLOWOTHERACCOUNTHOOK 0x00800000
|
||||
#define TIF_GUITHREADINITIALIZED 0x02000000
|
||||
#define TIF_DISABLEIME 0x04000000
|
||||
#define TIF_INGETTEXTLENGTH 0x08000000
|
||||
#define TIF_ANSILENGTH 0x10000000
|
||||
#define TIF_DISABLEHOOKS 0x20000000
|
||||
|
||||
extern BOOL ClientPfnInit;
|
||||
extern HINSTANCE hModClient;
|
||||
extern HANDLE hModuleWin; // This Win32k Instance.
|
||||
|
@ -86,7 +117,7 @@ typedef struct _THREADINFO
|
|||
/* ReactOS */
|
||||
LIST_ENTRY WindowListHead;
|
||||
LIST_ENTRY W32CallbackListHead;
|
||||
BOOLEAN IsExiting;
|
||||
BOOLEAN IsExiting; // Use TIF_INCLEANUP
|
||||
SINGLE_LIST_ENTRY ReferencesList;
|
||||
} THREADINFO;
|
||||
|
||||
|
@ -135,7 +166,7 @@ typedef struct _PROCESSINFO
|
|||
LIST_ENTRY PrivateFontListHead;
|
||||
FAST_MUTEX DriverObjListLock;
|
||||
LIST_ENTRY DriverObjListHead;
|
||||
struct _KBL* KeyboardLayout;
|
||||
struct _KBL* KeyboardLayout; // THREADINFO only
|
||||
W32HEAP_USER_MAPPING HeapMappings;
|
||||
} PROCESSINFO;
|
||||
|
||||
|
|
|
@ -67,14 +67,14 @@ typedef struct _WINDOW_OBJECT
|
|||
} WINDOW_OBJECT; /* PWINDOW_OBJECT already declared at top of file */
|
||||
|
||||
/* Window flags. */
|
||||
#define WINDOWOBJECT_NEED_SIZE (0x00000001)
|
||||
#define WINDOWOBJECT_NEED_ERASEBKGND (0x00000002)
|
||||
#define WINDOWOBJECT_NEED_NCPAINT (0x00000004)
|
||||
#define WINDOWOBJECT_NEED_INTERNALPAINT (0x00000008)
|
||||
#define WINDOWOBJECT_NEED_SIZE (0x00000001) // WNDS_SENDSIZEMOVEMSGS?
|
||||
#define WINDOWOBJECT_NEED_ERASEBKGND (0x00000002) // WNDS_ERASEBACKGROUND
|
||||
#define WINDOWOBJECT_NEED_NCPAINT (0x00000004) // WNDS_SENDNCPAINT
|
||||
#define WINDOWOBJECT_NEED_INTERNALPAINT (0x00000008) // WNDS_INTERNALPAINT
|
||||
#define WINDOWOBJECT_RESTOREMAX (0x00000020)
|
||||
|
||||
#define WINDOWSTATUS_DESTROYING (0x1)
|
||||
#define WINDOWSTATUS_DESTROYED (0x2)
|
||||
#define WINDOWSTATUS_DESTROYING (0x1) // WNDS2_INDESTROY
|
||||
#define WINDOWSTATUS_DESTROYED (0x2) // WNDS_DESTROYED
|
||||
|
||||
#define HAS_DLGFRAME(Style, ExStyle) \
|
||||
(((ExStyle) & WS_EX_DLGMODALFRAME) || \
|
||||
|
@ -172,6 +172,8 @@ IntDefWindowProc( PWINDOW_OBJECT Window, UINT Msg, WPARAM wParam, LPARAM lParam,
|
|||
VOID FASTCALL IntNotifyWinEvent(DWORD, PWND, LONG, LONG);
|
||||
|
||||
PWND APIENTRY co_IntCreateWindowEx(DWORD,PUNICODE_STRING,PUNICODE_STRING,DWORD,LONG,LONG,LONG,LONG,HWND,HMENU,HINSTANCE,LPVOID,DWORD,BOOL);
|
||||
WNDPROC FASTCALL IntGetWindowProc(PWND,BOOL);
|
||||
|
||||
#endif /* _WIN32K_WINDOW_H */
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -384,7 +384,7 @@ DriverEntry (
|
|||
}
|
||||
|
||||
hModuleWin = MmPageEntireDriver(DriverEntry);
|
||||
|
||||
DPRINT("Win32k hInstance 0x%x!\n",hModuleWin);
|
||||
/*
|
||||
* Register Object Manager Callbacks
|
||||
*/
|
||||
|
|
|
@ -50,7 +50,7 @@ CloneCallProc(IN PDESKTOPINFO Desktop,
|
|||
{
|
||||
NewCallProc->head.h = Handle;
|
||||
NewCallProc->pfnClientPrevious = CallProc->pfnClientPrevious;
|
||||
NewCallProc->Unicode = CallProc->Unicode;
|
||||
NewCallProc->wType = CallProc->wType;
|
||||
NewCallProc->spcpdNext = NULL;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ CreateCallProc(IN PDESKTOPINFO Desktop,
|
|||
{
|
||||
NewCallProc->head.h = Handle;
|
||||
NewCallProc->pfnClientPrevious = WndProc;
|
||||
NewCallProc->Unicode = Unicode;
|
||||
NewCallProc->wType |= Unicode ? UserGetCPDA2U : UserGetCPDU2A ;
|
||||
NewCallProc->spcpdNext = NULL;
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ UserGetCallProcInfo(IN HANDLE hCallProc,
|
|||
}*/
|
||||
|
||||
wpInfo->WindowProc = CallProc->pfnClientPrevious;
|
||||
wpInfo->IsUnicode = CallProc->Unicode;
|
||||
wpInfo->IsUnicode = !!(CallProc->wType & UserGetCPDA2U);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ UserGetCPD(
|
|||
{
|
||||
CallProc = CreateCallProc( NULL,
|
||||
(WNDPROC)ProcIn,
|
||||
(Flags & UserGetCPDU2A),
|
||||
!!(Flags & UserGetCPDA2U),
|
||||
pti->ppi);
|
||||
if (CallProc)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -912,10 +912,7 @@ NtUserCreateDesktop(
|
|||
HWINSTA hWindowStation = NULL ;
|
||||
PUNICODE_STRING lpszDesktopName = NULL;
|
||||
UNICODE_STRING ClassName, WindowName, MenuName;
|
||||
PPROCESSINFO pi = GetW32ProcessInfo();
|
||||
WNDCLASSEXW wc;
|
||||
PCLS Class;
|
||||
PWND pWnd;
|
||||
PWND pWnd = NULL;
|
||||
DECLARE_RETURN(HDESK);
|
||||
|
||||
DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
|
||||
|
@ -1112,44 +1109,11 @@ NtUserCreateDesktop(
|
|||
Based on wine/server/window.c in get_desktop_window.
|
||||
*/
|
||||
|
||||
ClassName.Buffer = ((PWSTR)((ULONG_PTR)(WORD)(AtomMessage)));
|
||||
ClassName.Buffer = ((PWSTR)((ULONG_PTR)(WORD)(gpsi->atomSysClass[ICLS_HWNDMESSAGE])));
|
||||
ClassName.Length = 0;
|
||||
RtlZeroMemory(&MenuName, sizeof(MenuName));
|
||||
RtlZeroMemory(&WindowName, sizeof(WindowName));
|
||||
|
||||
wc.cbSize = sizeof(wc);
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = gpsi->apfnClientW.pfnMessageWindowProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = hModClient;
|
||||
wc.hIcon = NULL;
|
||||
wc.hCursor = NULL;
|
||||
wc.hbrBackground = 0;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = ClassName.Buffer;
|
||||
wc.hIconSm = NULL;
|
||||
|
||||
Class = IntCreateClass( &wc,
|
||||
&ClassName,
|
||||
&MenuName,
|
||||
NULL,
|
||||
FNID_MESSAGEWND,
|
||||
CSF_SYSTEMCLASS,
|
||||
NULL,
|
||||
pi);
|
||||
if (Class != NULL)
|
||||
{
|
||||
ASSERT(Class->System);
|
||||
Class->pclsNext = SystemClassList;
|
||||
(void)InterlockedExchangePointer((PVOID*)&SystemClassList,
|
||||
Class);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("!!! Registering Message system class failed!\n");
|
||||
}
|
||||
|
||||
pWnd = co_IntCreateWindowEx( 0,
|
||||
&ClassName,
|
||||
&WindowName,
|
||||
|
|
|
@ -303,6 +303,7 @@ IntCallWndProc
|
|||
co_HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, SameThread, (LPARAM)&CWP );
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
FASTCALL
|
||||
|
@ -1535,9 +1536,13 @@ co_IntSendMessageTimeoutSingle(HWND hWnd,
|
|||
RETURN( FALSE);
|
||||
}
|
||||
|
||||
Result = (ULONG_PTR)co_IntCallWindowProc(Window->Wnd->lpfnWndProc, !Window->Wnd->Unicode, hWnd, Msg, wParam,
|
||||
lParamPacked,lParamBufferSize);
|
||||
|
||||
Result = (ULONG_PTR)co_IntCallWindowProc( Window->Wnd->lpfnWndProc,
|
||||
!Window->Wnd->Unicode,
|
||||
hWnd,
|
||||
Msg,
|
||||
wParam,
|
||||
lParamPacked,
|
||||
lParamBufferSize);
|
||||
if(uResult)
|
||||
{
|
||||
*uResult = Result;
|
||||
|
@ -1744,18 +1749,10 @@ co_IntDoSendMessage(HWND hWnd,
|
|||
|
||||
IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
|
||||
|
||||
if (Window->Wnd->IsSystem)
|
||||
{
|
||||
Info.Proc = (!Info.Ansi ? Window->Wnd->lpfnWndProc : Window->Wnd->WndProcExtra);
|
||||
}
|
||||
else
|
||||
{
|
||||
Info.Ansi = !Window->Wnd->Unicode;
|
||||
Info.Proc = Window->Wnd->lpfnWndProc;
|
||||
}
|
||||
|
||||
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, &Result);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -195,7 +195,6 @@ IntAttachMonitor(IN PDEVOBJ *pGdiDevice,
|
|||
PMONITOR_OBJECT p;
|
||||
DPRINT("Additional monitor is beeing attached\n");
|
||||
for (p = gMonitorList; p->Next != NULL; p = p->Next)
|
||||
;
|
||||
{
|
||||
p->Next = Monitor;
|
||||
}
|
||||
|
|
|
@ -368,6 +368,10 @@ NtUserInitializeClientPfnArrays(
|
|||
RtlCopyMemory(&gpsi->apfnClientW, pfnClientW, sizeof(PFNCLIENT));
|
||||
RtlCopyMemory(&gpsi->apfnClientWorker, pfnClientWorker, sizeof(PFNCLIENTWORKER));
|
||||
|
||||
//// FIXME! HAX! Temporary until server side is finished.
|
||||
//// Copy the client side procs for now.
|
||||
RtlCopyMemory(&gpsi->aStoCidPfn, pfnClientW, sizeof(gpsi->aStoCidPfn));
|
||||
|
||||
hModClient = hmodUser;
|
||||
ClientPfnInit = TRUE;
|
||||
}
|
||||
|
|
|
@ -520,34 +520,6 @@ NtUserCallTwoParam(
|
|||
|
||||
case TWOPARAM_ROUTINE_REGISTERLOGONPROC:
|
||||
RETURN( (DWORD)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2));
|
||||
|
||||
case TWOPARAM_ROUTINE_ROS_REGSYSCLASSES:
|
||||
{
|
||||
DWORD Ret = 0;
|
||||
DWORD Count = Param1;
|
||||
PREGISTER_SYSCLASS RegSysClassArray = (PREGISTER_SYSCLASS)Param2;
|
||||
|
||||
if (Count != 0 && RegSysClassArray != NULL)
|
||||
{
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeArrayForRead(RegSysClassArray,
|
||||
sizeof(RegSysClassArray[0]),
|
||||
Count,
|
||||
2);
|
||||
|
||||
Ret = (DWORD)UserRegisterSystemClasses(Count,
|
||||
RegSysClassArray);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
SetLastNtError(_SEH2_GetExceptionCode());
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
|
||||
RETURN( Ret);
|
||||
}
|
||||
}
|
||||
DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
|
||||
Routine, Param1, Param2);
|
||||
|
|
|
@ -432,6 +432,7 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
|
|||
/* from now on no messages can be sent to this window anymore */
|
||||
Window->Status |= WINDOWSTATUS_DESTROYED;
|
||||
Wnd->state |= WNDS_DESTROYED;
|
||||
Wnd->fnid |= FNID_FREED;
|
||||
|
||||
/* don't remove the WINDOWSTATUS_DESTROYING bit */
|
||||
|
||||
|
@ -539,64 +540,148 @@ IntGetWindowBorderMeasures(PWINDOW_OBJECT Window, UINT *cx, UINT *cy)
|
|||
}
|
||||
}
|
||||
|
||||
static WNDPROC
|
||||
IntGetWindowProc(IN PWINDOW_OBJECT Window,
|
||||
IN BOOL Ansi)
|
||||
//
|
||||
// Same as User32:IntGetWndProc.
|
||||
//
|
||||
WNDPROC FASTCALL
|
||||
IntGetWindowProc(PWND pWnd,
|
||||
BOOL Ansi)
|
||||
{
|
||||
PWND Wnd = Window->Wnd;
|
||||
INT i;
|
||||
PCLS Class;
|
||||
WNDPROC gcpd, Ret = 0;
|
||||
|
||||
ASSERT(UserIsEnteredExclusive() == TRUE);
|
||||
|
||||
if (Wnd->IsSystem)
|
||||
Class = pWnd->pcls;
|
||||
|
||||
if (pWnd->state & WNDS_SERVERSIDEWINDOWPROC)
|
||||
{
|
||||
return (Ansi ? Wnd->WndProcExtra : Wnd->lpfnWndProc);
|
||||
for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
|
||||
{
|
||||
if (GETPFNSERVER(i) == pWnd->lpfnWndProc)
|
||||
{
|
||||
if (Ansi)
|
||||
Ret = GETPFNCLIENTA(i);
|
||||
else
|
||||
Ret = GETPFNCLIENTW(i);
|
||||
}
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
if (Class->fnid == FNID_EDIT)
|
||||
Ret = pWnd->lpfnWndProc;
|
||||
else
|
||||
{
|
||||
Ret = pWnd->lpfnWndProc;
|
||||
|
||||
if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
|
||||
{
|
||||
if (Ansi)
|
||||
{
|
||||
if (GETPFNCLIENTW(Class->fnid) == pWnd->lpfnWndProc)
|
||||
Ret = GETPFNCLIENTA(Class->fnid);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Ansi == Wnd->Unicode)
|
||||
{
|
||||
return Wnd->lpfnWndProc;
|
||||
if (GETPFNCLIENTA(Class->fnid) == pWnd->lpfnWndProc)
|
||||
Ret = GETPFNCLIENTW(Class->fnid);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Wnd->CallProc != NULL)
|
||||
{
|
||||
return GetCallProcHandle(Wnd->CallProc);
|
||||
}
|
||||
/* BUGBOY Comments: Maybe theres something Im not undestanding here, but why would a CallProc be created
|
||||
on a function that I thought is only suppose to return the current Windows Proc? */
|
||||
else
|
||||
{
|
||||
PCALLPROCDATA NewCallProc, CallProc;
|
||||
if ( Ret != pWnd->lpfnWndProc)
|
||||
return Ret;
|
||||
}
|
||||
if ( Ansi == !!(pWnd->state & WNDS_ANSIWINDOWPROC) )
|
||||
return Ret;
|
||||
|
||||
NewCallProc = UserFindCallProc(Wnd->pcls,
|
||||
Wnd->lpfnWndProc,
|
||||
Wnd->Unicode);
|
||||
if (NewCallProc == NULL)
|
||||
{
|
||||
NewCallProc = CreateCallProc(Wnd->head.pti->pDeskInfo,
|
||||
Wnd->lpfnWndProc,
|
||||
Wnd->Unicode,
|
||||
Wnd->head.pti->ppi);
|
||||
if (NewCallProc == NULL)
|
||||
{
|
||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
gcpd = (WNDPROC)UserGetCPD(
|
||||
pWnd,
|
||||
(Ansi ? UserGetCPDA2U : UserGetCPDU2A )|UserGetCPDWindow,
|
||||
(ULONG_PTR)Ret);
|
||||
|
||||
UserAddCallProcToClass(Wnd->pcls,
|
||||
NewCallProc);
|
||||
}
|
||||
|
||||
CallProc = Wnd->CallProc;
|
||||
Wnd->CallProc = NewCallProc;
|
||||
|
||||
return GetCallProcHandle((CallProc == NULL ? NewCallProc : CallProc));
|
||||
}
|
||||
}
|
||||
}
|
||||
return (gcpd ? gcpd : Ret);
|
||||
}
|
||||
|
||||
static WNDPROC
|
||||
IntSetWindowProc(PWND pWnd,
|
||||
WNDPROC NewWndProc,
|
||||
BOOL Ansi)
|
||||
{
|
||||
INT i;
|
||||
PCALLPROCDATA CallProc;
|
||||
PCLS Class;
|
||||
WNDPROC Ret, chWndProc = NULL;
|
||||
|
||||
// Retrieve previous window proc.
|
||||
Ret = IntGetWindowProc(pWnd, Ansi);
|
||||
|
||||
Class = pWnd->pcls;
|
||||
|
||||
if (IsCallProcHandle(NewWndProc))
|
||||
{
|
||||
CallProc = UserGetObject(gHandleTable, NewWndProc, otCallProc);
|
||||
if (CallProc)
|
||||
{ // Reset new WndProc.
|
||||
NewWndProc = CallProc->pfnClientPrevious;
|
||||
// Reset Ansi from CallProc handle. This is expected with wine "deftest".
|
||||
Ansi = !!(CallProc->wType & UserGetCPDU2A);
|
||||
}
|
||||
}
|
||||
// Switch from Client Side call to Server Side call if match. Ref: "deftest".
|
||||
for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
|
||||
{
|
||||
if (GETPFNCLIENTW(i) == NewWndProc)
|
||||
{
|
||||
chWndProc = GETPFNSERVER(i);
|
||||
break;
|
||||
}
|
||||
if (GETPFNCLIENTA(i) == NewWndProc)
|
||||
{
|
||||
chWndProc = GETPFNSERVER(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If match, set/reset to Server Side and clear ansi.
|
||||
if (chWndProc)
|
||||
{
|
||||
pWnd->lpfnWndProc = chWndProc;
|
||||
pWnd->Unicode = TRUE;
|
||||
pWnd->state &= ~WNDS_ANSIWINDOWPROC;
|
||||
pWnd->state |= WNDS_SERVERSIDEWINDOWPROC;
|
||||
}
|
||||
else
|
||||
{
|
||||
pWnd->Unicode = !Ansi;
|
||||
// Handle the state change in here.
|
||||
if (Ansi)
|
||||
pWnd->state |= WNDS_ANSIWINDOWPROC;
|
||||
else
|
||||
pWnd->state &= ~WNDS_ANSIWINDOWPROC;
|
||||
|
||||
if (pWnd->state & WNDS_SERVERSIDEWINDOWPROC)
|
||||
pWnd->state &= ~WNDS_SERVERSIDEWINDOWPROC;
|
||||
|
||||
if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
|
||||
{
|
||||
if (Ansi)
|
||||
{
|
||||
if (GETPFNCLIENTW(Class->fnid) == NewWndProc)
|
||||
chWndProc = GETPFNCLIENTA(Class->fnid);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GETPFNCLIENTA(Class->fnid) == NewWndProc)
|
||||
chWndProc = GETPFNCLIENTW(Class->fnid);
|
||||
}
|
||||
}
|
||||
// Now set the new window proc.
|
||||
pWnd->lpfnWndProc = (chWndProc ? chWndProc : NewWndProc);
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
// Move this to user space!
|
||||
BOOL FASTCALL
|
||||
IntGetWindowInfo(PWINDOW_OBJECT Window, PWINDOWINFO pwi)
|
||||
{
|
||||
|
@ -1026,7 +1111,7 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
|
|||
if (IntIsChildWindow(Wnd, WndNewParent))
|
||||
{
|
||||
SetLastWin32Error( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1582,8 +1667,16 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
|||
ParentWindowHandle = pti->Desktop->DesktopWindow;
|
||||
}
|
||||
|
||||
|
||||
if ( !(pti->ppi->W32PF_flags & W32PF_CLASSESREGISTERED ))
|
||||
{
|
||||
UserRegisterSystemClasses();
|
||||
}
|
||||
|
||||
OwnerWindowHandle = NULL;
|
||||
|
||||
DPRINT("co_IntCreateWindowEx %wZ\n", ClassName);
|
||||
|
||||
if (hWndParent == HWND_MESSAGE)
|
||||
{
|
||||
/*
|
||||
|
@ -1633,6 +1726,8 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
|||
|
||||
/* Check the class. */
|
||||
|
||||
DPRINT("Class %wZ\n", ClassName);
|
||||
|
||||
ClassAtom = IntGetClassAtom(ClassName,
|
||||
hInstance,
|
||||
ti->ppi,
|
||||
|
@ -1653,7 +1748,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
|||
SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS);
|
||||
RETURN((PWND)0);
|
||||
}
|
||||
|
||||
DPRINT("ClassAtom %x\n", ClassAtom);
|
||||
Class = IntReferenceClass(Class,
|
||||
ClassLink,
|
||||
pti->Desktop);
|
||||
|
@ -1683,6 +1778,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
|||
sizeof(WND) + Class->cbwndExtra);
|
||||
Window->Wnd->head.h = hWnd;
|
||||
Wnd = Window->Wnd;
|
||||
Wnd->fnid = 0;
|
||||
|
||||
Wnd->head.pti = ti;
|
||||
Wnd->head.rpdesk = pti->Desktop;
|
||||
|
@ -1747,27 +1843,68 @@ AllocErr:
|
|||
|
||||
Wnd->dwUserData = 0;
|
||||
|
||||
Wnd->IsSystem = Wnd->pcls->System;
|
||||
if (Wnd->pcls->CSF_flags & CSF_SERVERSIDEPROC)
|
||||
Wnd->state |= WNDS_SERVERSIDEWINDOWPROC;
|
||||
|
||||
/* BugBoy Comments: Comment below say that System classes are always created as UNICODE.
|
||||
In windows, creating a window with the ANSI version of CreateWindow sets the window
|
||||
to ansi as verified by testing with IsUnicodeWindow API.
|
||||
/* BugBoy Comments: Comment below say that System classes are always created
|
||||
as UNICODE. In windows, creating a window with the ANSI version of CreateWindow
|
||||
sets the window to ansi as verified by testing with IsUnicodeWindow API.
|
||||
|
||||
No where can I see in code or through testing does the window change back to ANSI
|
||||
after being created as UNICODE in ROS. I didnt do more testing to see what problems this would cause.*/
|
||||
// See NtUserDefSetText! We convert to Unicode all the time and never use Mix. (jt)
|
||||
if (Wnd->pcls->System)
|
||||
{
|
||||
/* NOTE: Always create a unicode window for system classes! */
|
||||
Wnd->Unicode = TRUE;
|
||||
No where can I see in code or through testing does the window change back
|
||||
to ANSI after being created as UNICODE in ROS. I didnt do more testing to
|
||||
see what problems this would cause.*/
|
||||
|
||||
// Set WndProc from Class.
|
||||
Wnd->lpfnWndProc = Wnd->pcls->lpfnWndProc;
|
||||
Wnd->WndProcExtra = Wnd->pcls->WndProcExtra;
|
||||
|
||||
// GetWindowProc, test for non server side default classes and set WndProc.
|
||||
if ( Wnd->pcls->fnid <= FNID_GHOST && Wnd->pcls->fnid >= FNID_BUTTON )
|
||||
{
|
||||
if (bUnicodeWindow)
|
||||
{
|
||||
if (GETPFNCLIENTA(Wnd->pcls->fnid) == Wnd->lpfnWndProc)
|
||||
Wnd->lpfnWndProc = GETPFNCLIENTW(Wnd->pcls->fnid);
|
||||
}
|
||||
else
|
||||
{
|
||||
Wnd->Unicode = Wnd->pcls->Unicode;
|
||||
Wnd->lpfnWndProc = Wnd->pcls->lpfnWndProc;
|
||||
Wnd->CallProc = NULL;
|
||||
if (GETPFNCLIENTW(Wnd->pcls->fnid) == Wnd->lpfnWndProc)
|
||||
Wnd->lpfnWndProc = GETPFNCLIENTA(Wnd->pcls->fnid);
|
||||
}
|
||||
}
|
||||
|
||||
// If not an Unicode caller, set Ansi creator bit.
|
||||
if (!bUnicodeWindow) Wnd->state |= WNDS_ANSICREATOR;
|
||||
|
||||
// Clone Class Ansi/Unicode proc type.
|
||||
if (Wnd->pcls->CSF_flags & CSF_ANSIPROC)
|
||||
{
|
||||
Wnd->state |= WNDS_ANSIWINDOWPROC;
|
||||
Wnd->Unicode = FALSE;
|
||||
}
|
||||
else
|
||||
{ /*
|
||||
It seems there can be both an Ansi creator and Unicode Class Window
|
||||
WndProc, unless the following overriding conditions occur:
|
||||
*/
|
||||
if ( !bUnicodeWindow &&
|
||||
( ClassAtom == gpsi->atomSysClass[ICLS_BUTTON] ||
|
||||
ClassAtom == gpsi->atomSysClass[ICLS_COMBOBOX] ||
|
||||
ClassAtom == gpsi->atomSysClass[ICLS_COMBOLBOX] ||
|
||||
ClassAtom == gpsi->atomSysClass[ICLS_DIALOG] ||
|
||||
ClassAtom == gpsi->atomSysClass[ICLS_EDIT] ||
|
||||
ClassAtom == gpsi->atomSysClass[ICLS_IME] ||
|
||||
ClassAtom == gpsi->atomSysClass[ICLS_LISTBOX] ||
|
||||
ClassAtom == gpsi->atomSysClass[ICLS_MDICLIENT] ||
|
||||
ClassAtom == gpsi->atomSysClass[ICLS_STATIC] ) )
|
||||
{ // Override Class and set the window Ansi WndProc.
|
||||
Wnd->state |= WNDS_ANSIWINDOWPROC;
|
||||
Wnd->Unicode = FALSE;
|
||||
}
|
||||
else
|
||||
{ // Set the window Unicode WndProc.
|
||||
Wnd->state &= ~WNDS_ANSIWINDOWPROC;
|
||||
Wnd->Unicode = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
Window->OwnerThread = PsGetCurrentThread();
|
||||
|
@ -2270,8 +2407,6 @@ AllocErr:
|
|||
else
|
||||
{
|
||||
UserAddCallProcToClass(Wnd->pcls, CallProc);
|
||||
Wnd->CallProc = CallProc;
|
||||
Wnd->IsSystem = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2435,6 +2570,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
|
|||
|
||||
if (!Wnd) return TRUE; // FIXME: Need to finish object rewrite or lock the thread when killing the window!
|
||||
|
||||
DPRINT("co_UserDestroyWindow \n");
|
||||
|
||||
/* Check for owner thread */
|
||||
if ((Window->OwnerThread != PsGetCurrentThread()))
|
||||
{
|
||||
|
@ -2557,8 +2694,6 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
@ -2992,8 +3127,6 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
|
|||
return WndAncestor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
@ -3222,8 +3355,6 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
|
|||
return( hWndOldParent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* NtUserSetParent
|
||||
*
|
||||
|
@ -3269,8 +3400,6 @@ CLEANUP:
|
|||
END_CLEANUP;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* UserGetShellWindow
|
||||
*
|
||||
|
@ -3493,9 +3622,6 @@ CLEANUP:
|
|||
END_CLEANUP;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
HWND FASTCALL
|
||||
UserGetWindow(HWND hWnd, UINT Relationship)
|
||||
{
|
||||
|
@ -3548,8 +3674,6 @@ UserGetWindow(HWND hWnd, UINT Relationship)
|
|||
return hWndResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* NtUserGetWindow
|
||||
*
|
||||
|
@ -3576,9 +3700,6 @@ CLEANUP:
|
|||
END_CLEANUP;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* NtUserGetWindowLong
|
||||
*
|
||||
|
@ -3638,8 +3759,7 @@ UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
|
|||
break;
|
||||
|
||||
case GWL_WNDPROC:
|
||||
Result = (LONG)IntGetWindowProc(Window,
|
||||
Ansi);
|
||||
Result = (LONG)IntGetWindowProc(Wnd, Ansi);
|
||||
break;
|
||||
|
||||
case GWL_HINSTANCE:
|
||||
|
@ -3676,9 +3796,6 @@ UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
|
|||
return Result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* NtUserGetWindowLong
|
||||
*
|
||||
|
@ -3706,102 +3823,6 @@ CLEANUP:
|
|||
END_CLEANUP;
|
||||
}
|
||||
|
||||
static WNDPROC
|
||||
IntSetWindowProc(PWINDOW_OBJECT Window,
|
||||
WNDPROC NewWndProc,
|
||||
BOOL Ansi)
|
||||
{
|
||||
WNDPROC Ret;
|
||||
PCALLPROCDATA CallProc;
|
||||
PWND Wnd = Window->Wnd;
|
||||
|
||||
/* resolve any callproc handle if possible */
|
||||
if (IsCallProcHandle(NewWndProc))
|
||||
{
|
||||
WNDPROC_INFO wpInfo;
|
||||
|
||||
if (UserGetCallProcInfo((HANDLE)NewWndProc,
|
||||
&wpInfo))
|
||||
{
|
||||
NewWndProc = wpInfo.WindowProc;
|
||||
/* FIXME - what if wpInfo.IsUnicode doesn't match Ansi? */
|
||||
}
|
||||
}
|
||||
|
||||
/* attempt to get the previous window proc */
|
||||
if (Wnd->IsSystem)
|
||||
{
|
||||
Ret = (Ansi ? Wnd->WndProcExtra : Wnd->lpfnWndProc);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Ansi == Wnd->Unicode)
|
||||
{
|
||||
Ret = Wnd->lpfnWndProc;
|
||||
}
|
||||
else
|
||||
{
|
||||
CallProc = UserFindCallProc(Wnd->pcls,
|
||||
Wnd->lpfnWndProc,
|
||||
Wnd->Unicode);
|
||||
if (CallProc == NULL)
|
||||
{
|
||||
CallProc = CreateCallProc(NULL,
|
||||
Wnd->lpfnWndProc,
|
||||
Wnd->Unicode,
|
||||
Wnd->head.pti->ppi);
|
||||
if (CallProc == NULL)
|
||||
{
|
||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UserAddCallProcToClass(Wnd->pcls,
|
||||
CallProc);
|
||||
}
|
||||
/* BugBoy Comments: Added this if else, see below comments */
|
||||
if (!Wnd->CallProc)
|
||||
{
|
||||
Ret = Wnd->lpfnWndProc;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ret = GetCallProcHandle(Wnd->CallProc);
|
||||
}
|
||||
|
||||
Wnd->CallProc = CallProc;
|
||||
|
||||
/* BugBoy Comments: Above sets the current CallProc for the
|
||||
window and below we set the Ret value to it.
|
||||
SetWindowLong for WNDPROC should return the previous proc
|
||||
Ret = GetCallProcHandle(Wnd->CallProc); */
|
||||
}
|
||||
}
|
||||
|
||||
if (Wnd->pcls->System)
|
||||
{
|
||||
/* check if the new procedure matches with the one in the
|
||||
window class. If so, we need to restore both procedures! */
|
||||
Wnd->IsSystem = (NewWndProc == Wnd->pcls->lpfnWndProc ||
|
||||
NewWndProc == Wnd->pcls->WndProcExtra);
|
||||
|
||||
if (Wnd->IsSystem)
|
||||
{
|
||||
Wnd->lpfnWndProc = Wnd->pcls->lpfnWndProc;
|
||||
Wnd->WndProcExtra = Wnd->pcls->WndProcExtra;
|
||||
Wnd->Unicode = !Ansi;
|
||||
return Ret;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(!Wnd->IsSystem);
|
||||
|
||||
/* update the window procedure */
|
||||
Wnd->lpfnWndProc = NewWndProc;
|
||||
Wnd->Unicode = !Ansi;
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
LONG FASTCALL
|
||||
|
@ -3835,7 +3856,17 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
|
|||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||
return( 0);
|
||||
}
|
||||
|
||||
OldValue = *((LONG *)((PCHAR)(Wnd + 1) + Index));
|
||||
/*
|
||||
if ( Index == DWLP_DLGPROC && Wnd->state & WNDS_DIALOGWINDOW)
|
||||
{
|
||||
OldValue = (LONG)IntSetWindowProc( Wnd,
|
||||
(WNDPROC)NewValue,
|
||||
Ansi);
|
||||
if (!OldValue) return 0;
|
||||
}
|
||||
*/
|
||||
*((LONG *)((PCHAR)(Wnd + 1) + Index)) = NewValue;
|
||||
}
|
||||
else
|
||||
|
@ -3873,8 +3904,13 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
|
|||
|
||||
case GWL_WNDPROC:
|
||||
{
|
||||
/* FIXME: should check if window belongs to current process */
|
||||
OldValue = (LONG)IntSetWindowProc(Window,
|
||||
if ( Wnd->head.pti->ppi != PsGetCurrentProcessWin32Process() ||
|
||||
Wnd->fnid & FNID_FREED)
|
||||
{
|
||||
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
||||
return( 0);
|
||||
}
|
||||
OldValue = (LONG)IntSetWindowProc(Wnd,
|
||||
(WNDPROC)NewValue,
|
||||
Ansi);
|
||||
break;
|
||||
|
@ -3914,8 +3950,6 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
|
|||
return( OldValue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* NtUserSetWindowLong
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue