Release 960428
Sun Apr 28 14:32:43 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [Makefile.in]
Subdir memory is now also compiled for Winelib, in order to get
the Win32 heap functions.
* [if1632/Makefile.in]
Renamed winprocs and winprocs32 to wprocs and wprocs32 to avoid
DLL names > 8 characters.
* [loader/builtin.c] (New file)
Grouped all built-in DLLs code in a single file.
* [memory/global.c]
Use the Win32 heap code instead of malloc() to allocate linear
memory. This will help test the heap code.
* [memory/local.c]
Fixed FreeSelector() to clear DS and ES correctly for huge blocks.
* [tools/build.c] [if1632/relay.c]
Removed 'id' directive in spec files. For relay debugging, the DLL
entry point is now computed from the CS:IP entry point address.
Added 'heap' directive to specifiy a local heap for the DLL. USER
and GDI heap are now created this way.
* [windows/class.c] [include/class.h]
Changed the class structure to use pointers instead of handles.
Changed Get/SetClassWord/Long to use a switch statement; this
allows changing the layout of the CLASS structure.
* [windows/win.c] [include/win.h]
Use a CLASS * instead of a handle for the window class.
Sat Apr 27 18:10:11 Martin von Loewis <loewis@informatik.hu-berlin.de>
* [if1632/kernel32.spec] [memory/global.c]
[win32/memory.c] [win32/process.c]
GetProcessAffinityMask,GlobalLock,IsBadReadPtr,IsBadWritePtr,
LocalLock,SetThreadAffinityMask: new relays.
* [win32/cursoricon32.c]
Return same handle if a cursor is loaded multiple times.
Sat Apr 27 15:13:37 1996 Bang Jun Young <bangjy@nownuri.nowcom.co.kr>
* [resources/sysres_Ko.rc]
Added support for Korean [Ko] language.
Fri Apr 26 00:49:05 1996 Huw D. M. Davies <h.davies1@physics.oxford.ac.uk>
* [objects/dc.c] [objects/font.c]
Fixed problem with SaveDC()/RestoreDC() and font cache 'used' count.
* [objects/metafile.c] [objects/dcvalues.c]
Fixed broken SetTextAlign() on metafiles.
* [objects/metafile.c]
Delete objects in handle table at end of PlayMetaFile().
Wed Apr 24 19:21:01 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [if1632/ver.spec] [misc/ver.c] [include/ver.h] (New files)
VER.DLL (partially) implemented (VerFindFile,VerInstallFile)
[If it doesn't work for you, use -dll -ver and report it to me]
* [if1632/user32.spec] [if1632/kernel32.spec] [if1632/shell.spec]
[if1632/shell32.spec] [misc/ole2nls.c] [windows/message.c]
[windows/graphics.c]
Simple win32 functions, where we can just use the win16 counterpart.
Misc. stubs.
* [misc/lstr.c]
Someone reported a _lstrlen(NULL). NULL is a valid argument. Fixed.
* [misc/registry.c]
Some alloclens were off by 1, one double fclose() fixed.
Requesting value 0 of a key with no values returns an error
(should we always return a made up value NULL? what does win3.1?)
Tue Apr 23 17:00:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>
* [misc/shell.c]
Implemented FindEnvironmentString(), DoEnvironmentSubst(),
ExtractIcon(), InternalExtractIcon() and ExtractAssociatedIcon().
* [misc/user.c]
Do extensive cleanup on application exit.
* [windows/hook.c] [windows/win.c] [windows/class.c]
Added miscellaneous cleanup routines.
* [controls/menu.c]
More efficient popup menu window handling.
Mon Apr 22 21:35:22 1996 Albrecht Kleine <kleine@ak.sax.de>
* [include/windows.h][objects/oembitmap.c][include/bitmaps/obm_trtype]
Added "TT-bitmap" for later usage in a ChooseFont() ownerdraw combobox.
diff --git a/windows/class.c b/windows/class.c
index 04a05df..1a97140 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -15,11 +15,10 @@
#include "ldt.h"
#include "toolhelp.h"
#include "stddebug.h"
-/* #define DEBUG_CLASS */
#include "debug.h"
-static HCLASS firstClass = 0;
+static CLASS *firstClass = NULL;
/***********************************************************************
@@ -27,25 +26,26 @@
*
* Dump the content of a class structure to stderr.
*/
-void CLASS_DumpClass( HCLASS hClass )
+void CLASS_DumpClass( CLASS *ptr )
{
- CLASS *ptr;
char className[80];
int i;
- if (!(ptr = CLASS_FindClassPtr( hClass )))
+ if (((CLASS *)USER_HEAP_LIN_ADDR(ptr->self) != ptr) ||
+ (ptr->wMagic != CLASS_MAGIC))
{
- fprintf( stderr, "%04x is not a class handle\n", hClass );
+ fprintf( stderr, "%p is not a class\n", ptr );
return;
}
+
GlobalGetAtomName( ptr->atomName, className, sizeof(className) );
- fprintf( stderr, "Class %04x:\n", hClass );
+ fprintf( stderr, "Class %p:\n", ptr );
fprintf( stderr,
- "next=%04x name=%04x '%s' style=%04x wndProc=%08lx\n"
+ "next=%p name=%04x '%s' style=%04x wndProc=%08lx\n"
"inst=%04x hdce=%04x icon=%04x cursor=%04x bkgnd=%04x\n"
"clsExtra=%d winExtra=%d #windows=%d\n",
- ptr->hNext, ptr->atomName, className, ptr->wc.style,
+ ptr->next, ptr->atomName, className, ptr->wc.style,
(DWORD)ptr->wc.lpfnWndProc, ptr->wc.hInstance, ptr->hdce,
ptr->wc.hIcon, ptr->wc.hCursor, ptr->wc.hbrBackground,
ptr->wc.cbClsExtra, ptr->wc.cbWndExtra, ptr->cWindows );
@@ -67,67 +67,94 @@
*/
void CLASS_WalkClasses(void)
{
- HCLASS hClass = firstClass;
CLASS *ptr;
char className[80];
- fprintf( stderr, "Class Name Style WndProc\n" );
- while (hClass)
+ fprintf( stderr, " Class Name Style WndProc\n" );
+ for (ptr = firstClass; ptr; ptr = ptr->next)
{
- if (!(ptr = CLASS_FindClassPtr( hClass )))
- {
- fprintf( stderr, "*** Bad class %04x in list\n", hClass );
- return;
- }
GlobalGetAtomName( ptr->atomName, className, sizeof(className) );
- fprintf( stderr, "%04x %-20.20s %04x %08lx\n",
- hClass, className, ptr->wc.style, (DWORD)ptr->wc.lpfnWndProc);
- hClass = ptr->hNext;
+ fprintf( stderr, "%08lx %-20.20s %04x %08lx\n", (DWORD)ptr, className,
+ ptr->wc.style, (DWORD)ptr->wc.lpfnWndProc );
}
fprintf( stderr, "\n" );
}
/***********************************************************************
+ * CLASS_FreeClass
+ *
+ * Free a class structure.
+ */
+static void CLASS_FreeClass( CLASS *classPtr )
+{
+ CLASS **ppClass;
+
+ /* Remove the class from the linked list */
+
+ for (ppClass = &firstClass; *ppClass; ppClass = &(*ppClass)->next)
+ if (*ppClass == classPtr) break;
+ if (!*ppClass)
+ {
+ fprintf(stderr, "ERROR: Class list corrupted\n" );
+ return;
+ }
+ *ppClass = classPtr->next;
+
+ /* Delete the class */
+
+ if (classPtr->hdce) DCE_FreeDCE( classPtr->hdce );
+ if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground );
+ GlobalDeleteAtom( classPtr->atomName );
+ if (HIWORD(classPtr->wc.lpszMenuName))
+ USER_HEAP_FREE( (HANDLE)classPtr->wc.lpszMenuName );
+ USER_HEAP_FREE( classPtr->self );
+}
+
+
+/***********************************************************************
+ * CLASS_FreeModuleClasses
+ */
+void CLASS_FreeModuleClasses( HMODULE hModule )
+{
+ CLASS *ptr, *next;
+
+ for (ptr = firstClass; ptr; ptr = next)
+ {
+ next = ptr->next;
+ if (ptr->wc.hInstance == hModule) CLASS_FreeClass( ptr );
+ }
+}
+
+
+/***********************************************************************
* CLASS_FindClassByName
*
- * Return a handle and a pointer to the class.
- * 'ptr' can be NULL if the pointer is not needed.
+ * Return a pointer to the class.
*/
-HCLASS CLASS_FindClassByName( SEGPTR name, HINSTANCE hinstance, CLASS **ptr )
+CLASS *CLASS_FindClassByName( SEGPTR name, HINSTANCE hinstance )
{
ATOM atom;
- HCLASS class;
- CLASS * classPtr;
+ CLASS * class;
if (!(atom = GlobalFindAtom( name ))) return 0;
/* First search task-specific classes */
- for (class = firstClass; (class); class = classPtr->hNext)
+ for (class = firstClass; (class); class = class->next)
{
- classPtr = (CLASS *) USER_HEAP_LIN_ADDR(class);
- if (classPtr->wc.style & CS_GLOBALCLASS) continue;
- if ((classPtr->atomName == atom) &&
- ( (hinstance==(HINSTANCE)0xffff) ||
- (hinstance == classPtr->wc.hInstance) ) )
- {
- if (ptr) *ptr = classPtr;
- return class;
- }
+ if (class->wc.style & CS_GLOBALCLASS) continue;
+ if ((class->atomName == atom) &&
+ ((hinstance==(HINSTANCE)0xffff) ||
+ (hinstance == class->wc.hInstance))) return class;
}
/* Then search global classes */
- for (class = firstClass; (class); class = classPtr->hNext)
+ for (class = firstClass; (class); class = class->next)
{
- classPtr = (CLASS *) USER_HEAP_LIN_ADDR(class);
- if (!(classPtr->wc.style & CS_GLOBALCLASS)) continue;
- if (classPtr->atomName == atom)
- {
- if (ptr) *ptr = classPtr;
- return class;
- }
+ if (!(class->wc.style & CS_GLOBALCLASS)) continue;
+ if (class->atomName == atom) return class;
}
return 0;
@@ -135,28 +162,12 @@
/***********************************************************************
- * CLASS_FindClassPtr
- *
- * Return a pointer to the CLASS structure corresponding to a HCLASS.
- */
-CLASS * CLASS_FindClassPtr( HCLASS hclass )
-{
- CLASS * ptr;
-
- if (!hclass) return NULL;
- ptr = (CLASS *) USER_HEAP_LIN_ADDR( hclass );
- if (ptr->wMagic != CLASS_MAGIC) return NULL;
- return ptr;
-}
-
-
-/***********************************************************************
* RegisterClass (USER.57)
*/
ATOM RegisterClass( LPWNDCLASS class )
{
- CLASS * newClass, * prevClassPtr;
- HCLASS handle, prevClass;
+ CLASS * newClass, * prevClass;
+ HCLASS handle;
int classExtra;
dprintf_class( stddeb, "RegisterClass: wndproc=%08lx hinst=%04x name='%s' background %04x\n",
@@ -171,15 +182,14 @@
class->hInstance = GetExePtr( class->hInstance );
/* Check if a class with this name already exists */
- prevClass = CLASS_FindClassByName( class->lpszClassName,
- class->hInstance, &prevClassPtr );
+ prevClass = CLASS_FindClassByName( class->lpszClassName, class->hInstance);
if (prevClass)
{
/* Class can be created only if it is local and */
/* if the class with the same name is global. */
if (class->style & CS_GLOBALCLASS) return 0;
- if (!(prevClassPtr->wc.style & CS_GLOBALCLASS)) return 0;
+ if (!(prevClass->wc.style & CS_GLOBALCLASS)) return 0;
}
/* Create class */
@@ -188,7 +198,8 @@
handle = USER_HEAP_ALLOC( sizeof(CLASS) + classExtra );
if (!handle) return 0;
newClass = (CLASS *) USER_HEAP_LIN_ADDR( handle );
- newClass->hNext = firstClass;
+ newClass->self = handle;
+ newClass->next = firstClass;
newClass->wMagic = CLASS_MAGIC;
newClass->cWindows = 0;
newClass->wc = *class;
@@ -216,7 +227,7 @@
}
if (classExtra) memset( newClass->wExtra, 0, classExtra );
- firstClass = handle;
+ firstClass = newClass;
return newClass->atomName;
}
@@ -226,40 +237,16 @@
*/
BOOL UnregisterClass( SEGPTR className, HANDLE hinstance )
{
- HANDLE class, prevClass;
- CLASS * classPtr, * prevClassPtr;
-
+ CLASS *classPtr;
+
hinstance = GetExePtr( hinstance );
+
/* Check if we can remove this class */
- class = CLASS_FindClassByName( className, hinstance, &classPtr );
- if (!class) return FALSE;
+ if (!(classPtr = CLASS_FindClassByName( className, hinstance )))
+ return FALSE;
if ((classPtr->wc.hInstance != hinstance) || (classPtr->cWindows > 0))
return FALSE;
-
- /* Remove the class from the linked list */
- if (firstClass == class) firstClass = classPtr->hNext;
- else
- {
- for (prevClass = firstClass; prevClass; prevClass=prevClassPtr->hNext)
- {
- prevClassPtr = (CLASS *) USER_HEAP_LIN_ADDR(prevClass);
- if (prevClassPtr->hNext == class) break;
- }
- if (!prevClass)
- {
- fprintf(stderr, "ERROR: Class list corrupted\n" );
- return FALSE;
- }
- prevClassPtr->hNext = classPtr->hNext;
- }
-
- /* Delete the class */
- if (classPtr->hdce) DCE_FreeDCE( classPtr->hdce );
- if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground );
- GlobalDeleteAtom( classPtr->atomName );
- if (HIWORD(classPtr->wc.lpszMenuName))
- USER_HEAP_FREE( (HANDLE)classPtr->wc.lpszMenuName );
- USER_HEAP_FREE( class );
+ CLASS_FreeClass( classPtr );
return TRUE;
}
@@ -269,7 +256,24 @@
*/
WORD GetClassWord( HWND hwnd, short offset )
{
- return (WORD)GetClassLong( hwnd, offset );
+ WND * wndPtr;
+
+ if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+ if (offset >= 0)
+ return *(WORD *)(((char *)wndPtr->class->wExtra) + offset);
+ switch(offset)
+ {
+ case GCW_HBRBACKGROUND: return wndPtr->class->wc.hbrBackground;
+ case GCW_HCURSOR: return wndPtr->class->wc.hCursor;
+ case GCW_HICON: return wndPtr->class->wc.hIcon;
+ case GCW_HMODULE: return wndPtr->class->wc.hInstance;
+ case GCW_CBWNDEXTRA: return wndPtr->class->wc.cbWndExtra;
+ case GCW_CBCLSEXTRA: return wndPtr->class->wc.cbClsExtra;
+ case GCW_STYLE: return wndPtr->class->wc.style;
+ case GCW_ATOM: return wndPtr->class->atomName;
+ }
+ fprintf(stderr, "Warning: invalid offset %d for GetClassWord()\n", offset);
+ return 0;
}
@@ -278,13 +282,26 @@
*/
WORD SetClassWord( HWND hwnd, short offset, WORD newval )
{
- CLASS * classPtr;
WND * wndPtr;
WORD *ptr, retval = 0;
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
- if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
- ptr = (WORD *)(((char *)classPtr->wExtra) + offset);
+ if (offset >= 0) ptr = (WORD *)(((char *)wndPtr->class->wExtra) + offset);
+ else switch(offset)
+ {
+ case GCW_HBRBACKGROUND: ptr = &wndPtr->class->wc.hbrBackground; break;
+ case GCW_HCURSOR: ptr = &wndPtr->class->wc.hCursor; break;
+ case GCW_HICON: ptr = &wndPtr->class->wc.hIcon; break;
+ case GCW_HMODULE: ptr = &wndPtr->class->wc.hInstance; break;
+ case GCW_CBWNDEXTRA: ptr = &wndPtr->class->wc.cbWndExtra; break;
+ case GCW_CBCLSEXTRA: ptr = &wndPtr->class->wc.cbClsExtra; break;
+ case GCW_STYLE: ptr = &wndPtr->class->wc.style; break;
+ case GCW_ATOM: ptr = &wndPtr->class->atomName; break;
+ default:
+ fprintf( stderr, "Warning: invalid offset %d for SetClassWord()\n",
+ offset);
+ return 0;
+ }
retval = *ptr;
*ptr = newval;
return retval;
@@ -296,12 +313,18 @@
*/
LONG GetClassLong( HWND hwnd, short offset )
{
- CLASS * classPtr;
WND * wndPtr;
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
- if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
- return *(LONG *)(((char *)classPtr->wExtra) + offset);
+ if (offset >= 0)
+ return *(WORD *)(((char *)wndPtr->class->wExtra) + offset);
+ switch(offset)
+ {
+ case GCL_MENUNAME: return (LONG)wndPtr->class->wc.lpszMenuName;
+ case GCL_WNDPROC: return (LONG)wndPtr->class->wc.lpfnWndProc;
+ }
+ fprintf(stderr, "Warning: invalid offset %d for GetClassLong()\n", offset);
+ return 0;
}
@@ -310,13 +333,20 @@
*/
LONG SetClassLong( HWND hwnd, short offset, LONG newval )
{
- CLASS * classPtr;
WND * wndPtr;
LONG *ptr, retval = 0;
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
- if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
- ptr = (LONG *)(((char *)classPtr->wExtra) + offset);
+ if (offset >= 0) ptr = (LONG *)(((char *)wndPtr->class->wExtra) + offset);
+ else switch(offset)
+ {
+ case GCL_MENUNAME: ptr = (LONG*)&wndPtr->class->wc.lpszMenuName; break;
+ case GCL_WNDPROC: ptr = (LONG*)&wndPtr->class->wc.lpfnWndProc; break;
+ default:
+ fprintf( stderr, "Warning: invalid offset %d for SetClassLong()\n",
+ offset);
+ return 0;
+ }
retval = *ptr;
*ptr = newval;
return retval;
@@ -329,14 +359,12 @@
int GetClassName(HWND hwnd, LPSTR lpClassName, short maxCount)
{
WND *wndPtr;
- CLASS *classPtr;
/* FIXME: We have the find the correct hInstance */
dprintf_class(stddeb,"GetClassName(%04x,%p,%d)\n",hwnd,lpClassName,maxCount);
if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
- if (!(classPtr = CLASS_FindClassPtr(wndPtr->hClass))) return 0;
- return GlobalGetAtomName(classPtr->atomName, lpClassName, maxCount);
+ return GlobalGetAtomName( wndPtr->class->atomName, lpClassName, maxCount );
}
@@ -353,7 +381,7 @@
hInstance = GetExePtr( hInstance );
- if (!(CLASS_FindClassByName( name, hInstance, &classPtr))) return FALSE;
+ if (!(classPtr = CLASS_FindClassByName( name, hInstance ))) return FALSE;
if (hInstance && (hInstance != classPtr->wc.hInstance)) return FALSE;
memcpy(lpWndClass, &(classPtr->wc), sizeof(WNDCLASS));
@@ -366,7 +394,7 @@
*/
BOOL ClassFirst( CLASSENTRY *pClassEntry )
{
- pClassEntry->wNext = firstClass;
+ pClassEntry->wNext = 1;
return ClassNext( pClassEntry );
}
@@ -376,12 +404,19 @@
*/
BOOL ClassNext( CLASSENTRY *pClassEntry )
{
- CLASS *classPtr = (CLASS *) USER_HEAP_LIN_ADDR( pClassEntry->wNext );
- if (!classPtr) return FALSE;
+ int i;
+ CLASS *class = firstClass;
- pClassEntry->hInst = classPtr->wc.hInstance;
- pClassEntry->wNext = classPtr->hNext;
- GlobalGetAtomName( classPtr->atomName, pClassEntry->szClassName,
+ if (!pClassEntry->wNext) return FALSE;
+ for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next;
+ if (!class)
+ {
+ pClassEntry->wNext = 0;
+ return FALSE;
+ }
+ pClassEntry->hInst = class->wc.hInstance;
+ pClassEntry->wNext++;
+ GlobalGetAtomName( class->atomName, pClassEntry->szClassName,
sizeof(pClassEntry->szClassName) );
return TRUE;
}