Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

922 lines
29 KiB

/*++
*
* WOW v1.0
*
* Copyright (c) 1991, Microsoft Corporation
*
* WUCLASS.C
* WOW32 16-bit User API support
*
* History:
* Created 07-Mar-1991 by Jeff Parsons (jeffpar)
--*/
#include "precomp.h"
#pragma hdrstop
MODNAME(wuclass.c);
extern HANDLE ghInstanceUser32;
extern WORD gUser16hInstance;
/*++
BOOL GetClassInfo(<hInstance>, <lpClassName>, <lpWndClass>)
HANDLE <hInstance>;
LPSTR <lpClassName>;
LPWNDCLASS <lpWndClass>;
The %GetClassInfo% function retrieves information about a window class. The
<hInstance> parameter identifies the instance of the application that
created the class, and the <lpClassName> parameter identifies the window
class. If the function locates the specified window class, it copies the
%WNDCLASS% data used to register the window class to the %WNDCLASS%
structure pointed to by the <lpWndClass> parameter.
<hInstance>
Identifies the instance of the application that created the class. To
retrieve information on classes defined by Windows (such as buttons or
list boxes), set hInstance to NULL.
<lpClassName>
Points to a null-terminated string that contains the name of the
class to find. If the high-order word of this parameter is NULL, the
low-order word is assumed to be a value returned by the
%MAKEINTRESOURCE% macro used when the class was created.
<lpWndClass>
Points to the %WNDCLASS% structure that will receive the class
information.
The return value is TRUE if the function found a matching class and
successfully copied the data; the return value is FALSE if the function did
not find a matching class.
The %lpszClassName%, %lpszMenuName%, and %hInstance% members of the
%WNDCLASS% structure are <not> set by this function. The menu name is
not stored internally and cannot be returned. The class name is already
known since it is passed to this function. The %GetClassInfo% function
returns all other fields with the values used when the class was
registered.
--*/
ULONG FASTCALL WU32GetClassInfo(PVDMFRAME pFrame)
{
ULONG ul;
PSZ psz2, pszClass;
WNDCLASS t3;
register PGETCLASSINFO16 parg16;
WORD w;
HINSTANCE hInst;
PWC pwc = NULL;
PWNDCLASS16 pwc16;
CHAR szAtomName[WOWCLASS_ATOM_NAME];
GETARGPTR(pFrame, sizeof(GETCLASSINFO16), parg16);
GETPSZIDPTR(parg16->f2, psz2);
if ( HIWORD(psz2) == 0 ) {
pszClass = szAtomName;
GetAtomName( (ATOM)psz2, pszClass, WOWCLASS_ATOM_NAME );
} else {
pszClass = psz2;
}
// map hInst user16 to hMod user32
if(parg16->f1 == gUser16hInstance) {
hInst = ghInstanceUser32;
}
else {
hInst = HMODINST32(parg16->f1);
}
ul = GETBOOL16(GetClassInfo(hInst, pszClass, &t3));
// This fine piece of hackery mimicks the difference between the class list
// search algorithms in Win3.1 & SUR. Essentially SUR checks the private,
// public, and global class lists while Win3.1 only checks the private and
// global lists. Note we are striving for Win3.1 compatibility here -- not
// always the logical thing! Finding an existing *stale* class breaks some
// apps! Bug #31269 a-craigj, GerardoB
// Restrict this hack to PageMaker 50a for now
if(CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_FAKECLASSINFOFAIL) {
if(ul && hInst) {
// if this class wasn't registered by this app, AND it's not a global
// class, then it must have come from the public list and this app
// wouldn't know about it on Win3.1 -- so lie and say it doesn't exist!
// Note: The high word is the *hModule* which is what Win3.1 AND NT save
// with the class internally (not the hInstance!)
if((HIWORD(t3.hInstance) != HIWORD(hInst)) && !(t3.style & CS_GLOBALCLASS)) {
WOW32WARNMSGF(0,("\nWOW:GetClassInfo force failure hack:\n class = '%s' wc.hInstance = %X app_hInst = %X\n\n", pszClass, t3.hInstance, hInst));
ul = 0;
}
}
}
if (ul) {
//
// If the class is a 'standard' class, replace the class proc
// with a thunk proc
//
GETVDMPTR(parg16->f3, sizeof(WNDCLASS16), pwc16);
STOREWORD(pwc16->style, t3.style);
if (!WOW32_stricmp(pszClass, "edit")) {
STOREWORD(pwc16->style, (FETCHWORD(pwc16->style) & ~CS_GLOBALCLASS));
}
STOREDWORD(pwc16->vpfnWndProc, 0);
// if this class was registered by WOW
if (IsWOWProc (t3.lpfnWndProc)) {
//Unmark the proc and restore the high bits from rpl field
UnMarkWOWProc (t3.lpfnWndProc,pwc16->vpfnWndProc);
STORESHORT(pwc16->cbClsExtra, t3.cbClsExtra );
} else {
pwc16->vpfnWndProc = GetThunkWindowProc((DWORD)t3.lpfnWndProc, pszClass, NULL, NULL);
STORESHORT(pwc16->cbClsExtra, t3.cbClsExtra);
}
#ifdef OLD_WAY
if (parg16->f1 ||
!(pwc16->vpfnWndProc = GetThunkWindowProc((DWORD)t3.lpfnWndProc, pszClass, NULL, NULL))) {
pwc = FindClass16(pszClass, (HINST16)parg16->f1);
STOREDWORD(pwc16->vpfnWndProc, pwc->vpfnWndProc);
}
#endif
STORESHORT(pwc16->cbWndExtra, t3.cbWndExtra);
// Win3.1 copies the hInst passed in by the app into the WNDCLASS struct
// unless hInst == NULL, in which case they copy user's hInst
if((!parg16->f1) || (t3.hInstance == ghInstanceUser32)) {
w = gUser16hInstance;
} else {
w = VALIDHMOD(t3.hInstance);
if(w != BOGUSGDT) {
w = parg16->f1;
}
}
STOREWORD(pwc16->hInstance, w);
w = GETHICON16(t3.hIcon); STOREWORD(pwc16->hIcon, w);
w = GETHCURSOR16(t3.hCursor); STOREWORD(pwc16->hCursor, w);
w = ((ULONG)t3.hbrBackground > COLOR_ENDCOLORS) ?
GETHBRUSH16(t3.hbrBackground) : (WORD)t3.hbrBackground;
STOREWORD(pwc16->hbrBackground, w);
// These are strange assignments. We don't keep the class name or
// menu name in 16-bit memory. For class name, USER32 just returns
// the value which is passed as the second parameter, which works
// MOST of the time; we do the same. For the menu name, USER32 just
// returns the value which was passed when the class was registered.
// There are some situations where these psz's might go out of scope
// and no longer be valid when the application attempts to use them.
// IF YOU EVER FIND AN APPLICATION WHICH GETS THE WRONG
// THING AND IT FAILS BECAUSE OF IT, SOME NASTY HACKING WILL HAVE
// TO BE DONE AND IT SHOULD BE DONE IN USER32 ALSO...
// -BobDay
//
if ( pwc = FindClass16(pszClass, (HINST16)parg16->f1)) {
STOREDWORD(pwc16->vpszMenuName, pwc->vpszMenu);
} else {
STOREDWORD(pwc16->vpszMenuName, 0 );
}
STOREDWORD(pwc16->vpszClassName, parg16->f2);
FLUSHVDMPTR(parg16->f3, sizeof(WNDCLASS16), pwc16);
FREEVDMPTR(pwc16);
}
FREEPSZIDPTR(psz2);
FREEARGPTR(parg16);
RETURN(ul);
}
/*++
LONG GetClassLong(<hwnd>, <nIndex>)
HWND <hwnd>;
int <nIndex>;
The %GetClassLong% function retrieves the long value specified by the
<nIndex> parameter from the %WNDCLASS% structure of the window specified by
the <hwnd> parameter.
<hwnd>
Identifies the window.
<nIndex>
Specifies the byte offset of the value to be retrieved. It can also
be the following value:
GCL_WNDPROC
Retrieves a long pointer to the window function.
GCL_MENUNAME
Retrieves a long pointer to the menu name.
The return value specifies the value retrieved from the %WNDCLASS%
structure.
To access any extra four-byte values allocated when the window-class
structure was created, use a positive byte offset as the index specified by
the <nIndex> parameter. The first four-byte value in the extra space is at
offset zero, the next four-byte value is at offset 4, and so on.
--*/
ULONG FASTCALL WU32GetClassLong(PVDMFRAME pFrame)
{
ULONG ul;
INT iOffset;
HWND hwnd;
register PWW pww;
register PWC pwc;
register PGETCLASSLONG16 parg16;
GETARGPTR(pFrame, sizeof(GETCLASSLONG16), parg16);
// Make sure Win32 didn't change offsets for GCL constants
#if (GCL_WNDPROC != (-24) || GCL_MENUNAME != (-8))
#error Win16/Win32 GCL constants differ
#endif
// Make sure the 16-bit app is requesting allowable offsets
iOffset = INT32(parg16->f2);
WOW32ASSERT(iOffset >= 0 ||
iOffset == GCL_WNDPROC ||
iOffset == GCL_MENUNAME);
hwnd = HWND32(parg16->f1);
switch (iOffset) {
case GCL_WNDPROC:
{
DWORD dwProc32;
dwProc32 = GetClassLong(hwnd, iOffset);
if ( IsWOWProc (dwProc32)) {
if ( HIWORD(dwProc32) == WNDPROC_HANDLE ) {
//
// Class has a window proc which is really a handle
// to a proc. This happens when there is some
// unicode to ansi transition or vice versa.
//
pww = FindPWW( hwnd);
if ( pww == NULL ) {
ul = 0;
} else {
ul = GetThunkWindowProc(dwProc32,NULL,pww,hwnd);
}
} else {
//
// Class already has a 16:16 address
//
//Unmark the proc and restore the high bits from rpl field
UnMarkWOWProc (dwProc32,ul);
}
} else {
//
// Class has a 32-bit proc, return an allocated thunk
//
pww = FindPWW(hwnd);
if ( pww == NULL ) {
ul = 0;
} else {
ul = GetThunkWindowProc(dwProc32,NULL,pww,hwnd);
}
}
}
break;
case GCL_MENUNAME:
if (pwc = FindPWC(hwnd)) {
ul = pwc->vpszMenu;
} else {
ul = 0;
}
break;
case GCL_CBCLSEXTRA:
ul = GetClassLong(hwnd, GCL_CBCLSEXTRA);
break;
default:
ul = GetClassLong(hwnd, iOffset);
break;
}
FREEARGPTR(parg16);
RETURN(ul);
}
/*++
WORD GetClassWord(<hwnd>, <nIndex>)
HWND <hwnd>;
int <nIndex>;
The %GetClassWord% function retrieves the word that is specified by the
<nIndex> parameter from the %WNDCLASS% structure of the window specified by
the <hwnd> parameter.
<hwnd>
Identifies the window.
<nIndex>
Specifies the byte offset of the value to be retrieved. It can also
be one of the following values:
GCL_CBCLSEXTRA
Tells how many bytes of additional class information you have. For
information on how to access this memory, see the following "Comments"
section.
GCL_CBWNDEXTRA
Tells how many bytes of additional window information you have. For
information on how to access this memory, see the following<>Comments
section.
GCL_HBRBACKGROUND
Retrieves a handle to the background brush.
GCL_HCURSOR
Retrieves a handle to the cursor.
GCL_HICON
Retrieves a handle to the icon.
GCL_HMODULE
Retrieves a handle to the module.
GCL_STYLE
Retrieves the window-class style bits.
The return value specifies the value retrieved from the %WNDCLASS%
structure.
To access any extra two-byte values allocated when the window-class
structure was created, use a positive byte offset as the index specified by
the <nIndex> parameter, starting at zero for the first two-byte value in the
extra space, 2 for the next two-byte value and so on.
--*/
ULONG FASTCALL WU32GetClassWord(PVDMFRAME pFrame)
{
ULONG ul;
HWND hwnd;
INT iOffset;
register PGETCLASSWORD16 parg16;
GETARGPTR(pFrame, sizeof(GETCLASSWORD16), parg16);
// Make sure Win32 didn't change offsets
#if (GCL_HBRBACKGROUND != (-10) || GCL_HCURSOR != (-12) || GCL_HICON != (-14) || GCL_HMODULE != (-16) || GCL_CBWNDEXTRA != (-18) || GCL_CBCLSEXTRA != (-20) || GCL_STYLE != (-26))
#error Win16/Win32 class-word constants differ
#endif
// Make sure the 16-bit app is requesting allowable offsets
// (It's just assertion code, so it doesn't have to be pretty! -JTP)
iOffset = INT32(parg16->f2);
WOW32ASSERT(iOffset >= 0 ||
iOffset == GCL_HBRBACKGROUND ||
iOffset == GCL_HCURSOR ||
iOffset == GCL_HICON ||
iOffset == GCL_HMODULE ||
iOffset == GCL_CBWNDEXTRA ||
iOffset == GCL_CBCLSEXTRA ||
iOffset == GCL_STYLE ||
iOffset == GCW_ATOM);
hwnd = HWND32(parg16->f1);
switch(iOffset) {
case GCL_HBRBACKGROUND:
ul = GetClassLong(hwnd, iOffset);
if (ul > COLOR_ENDCOLORS)
ul = GETHBRUSH16(ul);
break;
case GCL_HCURSOR:
ul = GETHCURSOR16((HAND32)GetClassLong(hwnd, iOffset));
break;
case GCL_HICON:
ul = GETHICON16((HAND32)GetClassLong(hwnd, iOffset));
break;
case GCL_HMODULE:
ul = GetGCL_HMODULE(hwnd);
break;
case GCL_CBWNDEXTRA:
case GCL_STYLE:
ul = GetClassLong(hwnd, iOffset);
break;
case GCL_CBCLSEXTRA:
ul = GetClassLong(hwnd, GCL_CBCLSEXTRA);
break;
default:
ul = GetClassWord(hwnd, iOffset);
break;
}
FREEARGPTR(parg16);
RETURN(ul);
}
/*++
BOOL RegisterClass(<lpWndClass>)
LPWNDCLASS <lpWndClass>;
The %RegisterClass% function registers a window class for subsequent use in
calls to the %CreateWindow% function. The window class has the attributes
defined by the contents of the structure pointed to by the <lpWndClass>
parameter. If two classes with the same name are registered, the second
attempt fails and the information for that class is ignored.
<lpWndClass>
Points to a %WNDCLASS% structure. The structure must be filled with
the appropriate class attributes before being passed to the function.
See the following "Comments" section for details.
The return value specifies whether the window class is registered. It is
TRUE if the class is registered. Otherwise, it is FALSE.
The callback function must use the Pascal calling conventions and must be
declared %FAR%.
Callback Function:
BOOL FAR PASCAL <WndProc>(<hwnd>, <wMsg>, <wParam>, <lParam>)
HWND <hwnd>;
WORD <wMsg>;
WORD<wParam>;
DWORD<lParam>;
<WndProc> is a placeholder for the application-supplied function name. The
actual name must be exported by including it in an %EXPORTS% statement in
the application's module-definition file.
<wMsg>
Specifies the message number.
<wParam>
Specifies additional message-dependent information.
<lParam>
Specifies additional message-dependent information.
The window function returns the result of the message processing. The
possible return values depend on the actual message sent.
--*/
ULONG FASTCALL WU32RegisterClass(PVDMFRAME pFrame)
{
ULONG ul;
WNDCLASS t1;
VPSZ vpszMenu;
PSZ pszMenu;
PSZ pszClass;
register PREGISTERCLASS16 parg16;
CHAR szAtomName[WOWCLASS_ATOM_NAME];
WC wc;
GETARGPTR(pFrame, sizeof(REGISTERCLASS16), parg16);
GETWNDCLASS16(parg16->vpWndClass, &t1);
// Fix up the window words for apps that have hardcode values and did not
// use the value from GetClassInfo when superclassing system proc.
// Some items have been expanded from a WORD to a DWORD bug 22014
// t1.cbWndExtra = (t1.cbWndExtra + 3) & ~3;
vpszMenu = (VPSZ)t1.lpszMenuName;
if (HIWORD(t1.lpszMenuName) != 0) {
GETPSZPTR(t1.lpszMenuName, pszMenu);
t1.lpszMenuName = pszMenu;
}
if (HIWORD(t1.lpszClassName) == 0) {
pszClass = szAtomName;
GetAtomName( (ATOM)t1.lpszClassName, pszClass, WOWCLASS_ATOM_NAME);
} else {
GETPSZPTR(t1.lpszClassName, pszClass);
}
t1.lpszClassName = pszClass;
ul = 0;
wc.vpszMenu = vpszMenu;
wc.iClsExtra = 0;
wc.hMod16 = WOWGetProcModule16((DWORD)t1.lpfnWndProc);
// mark the proc as WOW proc and save the high bits in the RPL
MarkWOWProc(t1.lpfnWndProc,t1.lpfnWndProc);
// Validate hbrBackground, because apps can pass an invalid handle.
// The GetGDI32 returns a non-null value even if h16 is invalid.
//
// if hbrBackground is not valid we set it to NULL if the apps
// ExpWinVer is < 3.1. This behaviour is identical to WIN31 behaviour.
//
// We need to do this validation here because USER32 will fail
// RegisterClass() if hbrBackground is not valid.
//
// known culprits: QuickCase:W (that comes with QcWin)
// class "iconbutton".
if ((DWORD)t1.hbrBackground > (DWORD)(COLOR_ENDCOLORS) &&
GetObjectType(t1.hbrBackground) != OBJ_BRUSH) {
if ((WORD)W32GetExpWinVer((HANDLE) LOWORD(t1.hInstance) ) < 0x030a)
t1.hbrBackground = (HBRUSH)NULL;
}
ul = GETBOOL16((pfnOut.pfnRegisterClassWOWA)(&t1, (DWORD *)&wc));
if (!ul) {
LOGDEBUG(LOG_ALWAYS,("WOW: RegisterClass failed (\"%s\")\n", (LPSZ)pszClass));
// WOW32ASSERT(ul);
}
FREEPSZPTR(pszClass);
FREEPSZPTR(pszMenu);
FREEARGPTR(parg16);
RETURN(ul);
}
/*++
LONG SetClassLong(<hwnd>, <nIndex>, <dwNewLong>)
HWND <hwnd>;
int <nIndex>;
DWORD <dwNewLong>;
The %SetClassLong% function replaces the long value specified by the
<nIndex> parameter in the %WNDCLASS% structure of the window specified by
the <hwnd> parameter.
<hwnd>
Identifies the window.
<nIndex>
Specifies the byte offset of the word to be changed. It can also
be one of the following values:
GCL_MENUNAME
Sets a new long pointer to the menu
GCL_WNDPROC
Sets a new long pointer to the window function.
<dwNewLong>
Specifies the replacement value.
The return value specifies the previous value of the specified long
integer.
If the %SetClassLong% function and GCL_WNDPROC index are used to set a
window function, the given function must have the window-function form and
be exported in the module-definition file. See the %RegisterClass% function
earlier in this chapter for details.
Calling %SetClassLong% with the GCL_WNDPROC index creates a subclass of the
window class that affects all windows subsequently created with the class.
See Chapter 1, Window Manager Interface Functions, for more information on
window subclassing. An application should not attempt to create a window
subclass for standard Windows controls such as combo boxes and buttons.
To access any extra two-byte values allocated when the window-class
structure was created, use a positive byte offset as the index specified by
the <nIndex> parameter, starting at zero for the first two-byte value in the
extra space, 2 for the next two-byte value and so on.
--*/
ULONG FASTCALL WU32SetClassLong(PVDMFRAME pFrame)
{
ULONG ul;
INT iOffset;
PSZ pszMenu;
register PWC pwc;
register PSETCLASSLONG16 parg16;
GETARGPTR(pFrame, sizeof(SETCLASSLONG16), parg16);
// Make sure Win32 didn't change offsets for GCL constants
#if (GCL_MENUNAME != (-8) || GCL_WNDPROC != (-24))
#error Win16/Win32 GCL constants differ
#endif
// Make sure the 16-bit app is requesting allowable offsets
iOffset = INT32(parg16->f2);
WOW32ASSERT(iOffset >= 0 ||
iOffset == GCL_WNDPROC ||
iOffset == GCL_MENUNAME);
ul = 0;
switch (iOffset) {
case GCL_WNDPROC:
{
DWORD dwWndProc32Old;
DWORD dwWndProc32New;
PWW pww;
// Look to see if the new 16:16 proc is a thunk for a 32-bit proc.
dwWndProc32New = IsThunkWindowProc(LONG32(parg16->f3), NULL );
if ( dwWndProc32New != 0 ) {
//
// They are attempting to set the window proc to an existing
// 16-bit thunk that is really just a thunk for a 32-bit
// routine. We can just set it back to the 32-bit routine.
//
dwWndProc32Old = SetClassLong(HWND32(parg16->f1), GCL_WNDPROC, (LONG)dwWndProc32New);
} else {
//
// They are attempting to set it to a real 16:16 proc.
//
LONG l;
l = LONG32(parg16->f3);
// mark the proc as WOW proc and save the high bits in the RPL
MarkWOWProc (l,l);
dwWndProc32Old = SetClassLong(HWND32(parg16->f1), GCL_WNDPROC, l);
}
if ( IsWOWProc (dwWndProc32Old)) {
if ( HIWORD(dwWndProc32Old) == WNDPROC_HANDLE ) {
//
// If the return value is a handle, then just thunk it.
//
pww = FindPWW(HWND32(parg16->f1));
if ( pww == NULL ) {
ul = 0;
} else {
ul = GetThunkWindowProc(dwWndProc32Old, NULL, pww, HWND32(parg16->f1));
}
} else {
//
// Previous proc was a 16:16 proc
// Unmark the proc and restore the high bits from rpl field
UnMarkWOWProc (dwWndProc32Old,ul);
}
} else {
//
// Previous proc was a 32-bit proc, use an allocated thunk
//
pww = FindPWW(HWND32(parg16->f1));
if ( pww == NULL ) {
ul = 0;
} else {
ul = GetThunkWindowProc(dwWndProc32Old, NULL, pww, HWND32(parg16->f1));
}
}
}
break;
case GCL_MENUNAME:
if (pwc = FindPWC(HWND32(parg16->f1))) {
ul = pwc->vpszMenu;
GETPSZPTR(parg16->f3, pszMenu);
SETWC(HWND32(parg16->f1), GCL_WOWMENUNAME, parg16->f3);
SetClassLong(HWND32(parg16->f1), GCL_MENUNAME, (LONG)pszMenu);
FREEPSZPTR(pszMenu);
}
break;
case GCL_CBCLSEXTRA:
// apps shouldn't do this but of course some do!
// (see GCW_CBCLSEXTRA notes in thunk for RegisterClass())
WOW32WARNMSG(0, ("WOW:SetClassLong(): app changing cbClsExtra!"));
// only allow this to be set by classes registered via WOW
if(IsWOWProc (GetClassLong(HWND32(parg16->f1), GCL_WNDPROC))) {
/*
* The hard stuff is now done in User. FritzS
*/
ul = SetClassLong(HWND32(parg16->f1), iOffset, WORD32(parg16->f3));
break;
}
else {
ul = 0; // no can do for non-WOW classes
}
break;
default:
ul = SetClassLong(HWND32(parg16->f1), iOffset, LONG32(parg16->f3));
break;
}
FREEARGPTR(parg16);
RETURN(ul);
}
/*++
WORD SetClassWord(<hwnd>, <nIndex>, <wNewWord>)
HWND <hwnd>;
int <nIndex>;
WORD <wNewWord>;
The %SetClassWord% function replaces the word specified by the <nIndex>
parameter in the %WNDCLASS% structure of the window specified by the <hwnd>
parameter.
<hwnd>
Identifies the window.
<nIndex>
Specifies the byte offset of the word to be changed. It can also
be one of the following values:
GCL_CBCLSEXTRA
Sets two new bytes of additional window-class data.
GCL_CBWNDEXTRA
Sets two new bytes of additional window-class data.
GCL_HBRBACKGROUND
Sets a new handle to a background brush.
GCL_HCURSOR
Sets a new handle to a cursor.
GCL_HICON
Sets a new handle to an icon.
GCL_STYLE
Sets a new style bit for the window class.
<wNewWord>
Specifies the replacement value.
The return value specifies the previous value of the specified word.
The %SetClassWord% function should be used with care. For example, it is
possible to change the background color for a class by using %SetClassWord%,
but this change does not cause all windows belonging to the class to be
repainted immediately.
To access any extra four-byte values allocated when the window-class
structure was created, use a positive byte offset as the index specified by
the <nIndex> parameter, starting at zero for the first four-byte value in
the extra space, 4 for the next four-byte value and so on.
--*/
ULONG FASTCALL WU32SetClassWord(PVDMFRAME pFrame)
{
ULONG ul;
HWND hwnd;
INT iOffset;
register PSETCLASSWORD16 parg16;
GETARGPTR(pFrame, sizeof(SETCLASSWORD16), parg16);
// Make sure Win32 didn't change offsets
#if (GCL_HBRBACKGROUND != (-10) || GCL_HCURSOR != (-12) || GCL_HICON != (-14) || GCL_CBWNDEXTRA != (-18) || GCL_CBCLSEXTRA != (-20) || GCL_STYLE != (-26))
#error Win16/Win32 GCW constants differ
#endif
// Make sure the 16-bit app is requesting allowable offsets
// (It's just assertion code, so it doesn't have to be pretty! -JTP)
iOffset = INT32(parg16->f2);
WOW32ASSERT(iOffset >= 0 ||
iOffset == GCL_HBRBACKGROUND ||
iOffset == GCL_HCURSOR ||
iOffset == GCL_HICON ||
iOffset == GCL_CBWNDEXTRA ||
iOffset == GCL_CBCLSEXTRA ||
iOffset == GCL_STYLE)
hwnd = HWND32(parg16->f1);
ul = WORD32(parg16->f3);
switch(iOffset) {
case GCL_HBRBACKGROUND:
if (ul > COLOR_ENDCOLORS)
ul = (LONG) HBRUSH32(ul);
ul = SetClassLong(hwnd, iOffset, (LONG) ul);
if (ul > COLOR_ENDCOLORS)
ul = GETHBRUSH16(ul);
break;
case GCL_HCURSOR:
ul = GETHCURSOR16(SetClassLong(hwnd, iOffset, (LONG)HCURSOR32(ul)));
break;
case GCL_HICON:
ul = GETHICON16(SetClassLong(hwnd, iOffset, (LONG)HICON32(ul)));
break;
case GCL_HMODULE:
ul = 0; // not allowed to set this
break;
case GCL_CBWNDEXTRA:
case GCL_STYLE:
ul = SetClassLong(hwnd, iOffset, (LONG)ul);
break;
case GCL_CBCLSEXTRA:
// apps shouldn't do this but of course some do!
// (see GCW_CBCLSEXTRA notes in thunk for RegisterClass())
WOW32WARNMSG(0, ("WOW:SetClassWord(): app changing cbClsExtra!"));
// only allow this to be set by classes registered via WOW
if(IsWOWProc (GetClassLong(hwnd, GCL_WNDPROC))) {
ul = SetClassLong(hwnd, GCL_CBCLSEXTRA, (LONG)ul);
/*
* The hard work is now done in User. FritzS
*/
}
else {
ul = 0; // no can do for non-WOW classes
}
break;
default:
ul = SetClassWord(hwnd, iOffset, (WORD)ul);
break;
}
FREEARGPTR(parg16);
RETURN(ul);
}
/*++
BOOL UnregisterClass(<lpClassName>, <hInstance>)
The %UnregisterClass% function removes the window class specified by
<lpClassName> from the window-class table, freeing the storage required for
the class.
<lpClassName>
Points to a null-terminated string containing the class name. This class
name must have been previously registered by calling the RegisterClass
function with a valid hInstance field in the %WNDCLASS% structure
parameter. Predefined classes, such as dialog-box controls, may not be
unregistered.
<hInstance>
Identifies the instance of the module that created the class.
The return value is TRUE if the function successfully removed the window
class from the window-class table. It is FALSE if the class could not be
found or if a window exists that was created with the class.
Before using this function, destroy all windows created with the specified
class.
--*/
#if 0 // intthunk
ULONG FASTCALL WU32UnregisterClass(PVDMFRAME pFrame)
{
ULONG ul;
PSZ pszClass;
register PUNREGISTERCLASS16 parg16;
GETARGPTR(pFrame, sizeof(UNREGISTERCLASS16), parg16);
GETPSZIDPTR(parg16->vpszClass, pszClass);
ul = GETBOOL16(UnregisterClass(
pszClass,
HMODINST32(parg16->hInstance)
));
FREEPSZIDPTR(pszClass);
FREEARGPTR(parg16);
RETURN(ul);
}
#endif