Commit d2e1c1a4 authored by Alexandre Julliard's avatar Alexandre Julliard

Release 960309

Fri Mar 8 19:07:18 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [configure.in] Quote '[' and ']' in the test program for the strength-reduce bug. This should work much better... * [files/file.c] Augmented DOS_FILE structure. Most internal functions now return a DOS_FILE* instead of a Unix handle. Added a local file array to replace the PDB list upon startup, to allow using file I/O functions before the first task is created. Added FILE_SetDateTime() and FILE_Sync() functions. * [loader/module.c] Use the DOS file I/O functions in MODULE_LoadExeHeader(). * [objects/bitblt.c] Use visible region instead of GC clip region to clip source area. This fixes the card drawing bug in freecell. * [objects/region.c] Fixed CombineRgn() to allow src and dest regions to be the same. Fri Mar 8 16:32:23 1996 Frans van Dorsselaer <dorssel@rulhm1.leidenuniv.nl> * [controls/EDIT.TODO] Updated so it reflects the current status. * [controls/edit.c] Implemented internal EDIT_WordBreakProc(). Implemented ES_READONLY. Implemented WM_LBUTTONDBLCLK to select whole words. Fixed a lot of types in the function definitions. Wed Mar 6 19:55:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu> * [debugger/info.c] Added "walk window" command to walk window list. * [windows/mdi.c] Added proper(?) WM_MDISETMENU message handling. Wed Mar 6 09:27:12 1996 Martin von Loewis <loewis@informatik.hu-berlin.de> * [if1632/callback.c][if1632/relay32.c] RELAY32_CallWindowProcConvStruct: new function. * [win32/struct32.c][win32/Makefile.in][win32/param.c][win32/user32.c] struct32.c: new file. Moved all structure conversions into that file PARAM32_POINT32to16,MSG16to32,USER32_RECT32to16: renamed to STRUCT32_POINT32to16, ... WIN32_POINT,WIN32_MSG,WIN32_RECT,WIN32_PAINTSTRUCT: renamed to POINT32, ... New conversion functions for NCCALCSIZE_PARAMS, WINDOWPOS, CREATESTRUCT. * [include/windows.h][misc/exec.c] WINHELP, MULTIKEYHELP, HELPWININFO: new structures WinHelp: Reimplemented. Thanks to Peter Balch (100710.2566@compuserve.com) for his valuable research. * [win32/winprocs.c] WIN32_CallWindowProcTo16: new function, call in USER32_DefWindowProcA,... Mon Mar 4 23:22:40 1996 Jim Peterson <jspeter@birch.ee.vt.edu> * [include/wintypes.h] Added "#define __export". * [objects/bitblt.c] Put in a few hacks to make bitblt-ing work when upside-down and/or mirrored. BITBLT_StretchImage should really be checked over thoroughly. * [programs/progman/main.c] Added "#include <resource.h>" for definition of HAVE_WINE_CONSTRUCTOR. * [rc/parser.h] [rc/parser.l] [rc/parser.y] [rc/winerc.c] Eliminated shift/reduce conflict in style definition. Added crude error message support: "stdin:%d: parse error before '%s'". Implemented string table support to the best of my ability (it works with LoadString() calls). * [windows/nonclient.c] Fixed bug in NC_DoSizeMove() that made system menu pop up when title bar of non-iconized window was clicked (checked for iconization). Mon Mar 04 20:55:19 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de> * [if1632/lzexpand.spec] [if1632/relay.c] [include/lzexpand.h][misc/lzexpand.c] LZEXPAND.DLL added. Sun Mar 03 18:10:22 1996 Albrecht Kleine <kleine@ak.sax.de> * [windows/win.c] Prevent usage of invalid HWNDs in WIN_EnumChildWin(), this prevents too early termination of EnumChildWindows().
parent 02ed4c23
This is release 960302 of Wine the MS Windows emulator. This is still a
This is release 960309 of Wine the MS Windows emulator. This is still a
developer's only release. There are many bugs and many unimplemented API
features. Most applications still do not work.
Patches should be submitted to "julliard@lrc.epfl.ch". Please don't
forget to include a ChangeLog entry.
WHAT'S NEW with Wine-960302: (see ChangeLog for details)
- Program manager clone using Winelib.
- Support for Esperanto language.
- Some scrollbar fixes.
- Edit control improvements.
WHAT'S NEW with Wine-960309: (see ChangeLog for details)
- More edit control improvements.
- Help begins to work.
- Internal LZEXPAND.DLL.
- Lots of bug fixes.
See the README file in the distribution for installation instructions.
......@@ -18,10 +17,10 @@ Because of lags created by using mirror, this message may reach you before
the release is available at the ftp sites. The sources will be available
from the following locations:
sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960302.tar.gz
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960302.tar.gz
ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960302.tar.gz
aris.com:/pub/linux/ALPHA/Wine/development/Wine-960302.tar.gz
sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960309.tar.gz
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960309.tar.gz
ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960309.tar.gz
aris.com:/pub/linux/ALPHA/Wine/development/Wine-960309.tar.gz
It should also be available from any site that mirrors tsx-11 or sunsite.
......
----------------------------------------------------------------------
Fri Mar 8 19:07:18 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [configure.in]
Quote '[' and ']' in the test program for the strength-reduce
bug. This should work much better...
* [files/file.c]
Augmented DOS_FILE structure. Most internal functions now return a
DOS_FILE* instead of a Unix handle.
Added a local file array to replace the PDB list upon startup, to
allow using file I/O functions before the first task is created.
Added FILE_SetDateTime() and FILE_Sync() functions.
* [loader/module.c]
Use the DOS file I/O functions in MODULE_LoadExeHeader().
* [objects/bitblt.c]
Use visible region instead of GC clip region to clip source
area. This fixes the card drawing bug in freecell.
* [objects/region.c]
Fixed CombineRgn() to allow src and dest regions to be the same.
Fri Mar 8 16:32:23 1996 Frans van Dorsselaer <dorssel@rulhm1.leidenuniv.nl>
* [controls/EDIT.TODO]
Updated so it reflects the current status.
* [controls/edit.c]
Implemented internal EDIT_WordBreakProc().
Implemented ES_READONLY.
Implemented WM_LBUTTONDBLCLK to select whole words.
Fixed a lot of types in the function definitions.
Wed Mar 6 19:55:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>
* [debugger/info.c]
Added "walk window" command to walk window list.
* [windows/mdi.c]
Added proper(?) WM_MDISETMENU message handling.
Wed Mar 6 09:27:12 1996 Martin von Loewis <loewis@informatik.hu-berlin.de>
* [if1632/callback.c][if1632/relay32.c]
RELAY32_CallWindowProcConvStruct: new function.
* [win32/struct32.c][win32/Makefile.in][win32/param.c][win32/user32.c]
struct32.c: new file. Moved all structure conversions into that file
PARAM32_POINT32to16,MSG16to32,USER32_RECT32to16:
renamed to STRUCT32_POINT32to16, ...
WIN32_POINT,WIN32_MSG,WIN32_RECT,WIN32_PAINTSTRUCT: renamed to
POINT32, ...
New conversion functions for NCCALCSIZE_PARAMS, WINDOWPOS,
CREATESTRUCT.
* [include/windows.h][misc/exec.c]
WINHELP, MULTIKEYHELP, HELPWININFO: new structures
WinHelp: Reimplemented. Thanks to Peter Balch
(100710.2566@compuserve.com) for his valuable research.
* [win32/winprocs.c]
WIN32_CallWindowProcTo16: new function, call in
USER32_DefWindowProcA,...
Mon Mar 4 23:22:40 1996 Jim Peterson <jspeter@birch.ee.vt.edu>
* [include/wintypes.h]
Added "#define __export".
* [programs/progman/main.c]
Added "#include <resource.h>" for definition of HAVE_WINE_CONSTRUCTOR.
* [rc/parser.h] [rc/parser.l] [rc/parser.y] [rc/winerc.c]
Eliminated shift/reduce conflict in style definition.
Added crude error message support: "stdin:%d: parse error before '%s'".
Implemented string table support to the best of my ability (it works
with LoadString() calls).
* [windows/nonclient.c]
Fixed bug in NC_DoSizeMove() that made system menu pop up when title
bar of non-iconized window was clicked (checked for iconization).
Mon Mar 04 20:55:19 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [if1632/lzexpand.spec] [if1632/relay.c]
[include/lzexpand.h][misc/lzexpand.c]
LZEXPAND.DLL added.
Sun Mar 03 18:10:22 1996 Albrecht Kleine <kleine@ak.sax.de>
* [windows/win.c]
Prevent usage of invalid HWNDs in WIN_EnumChildWin(),
this prevents too early termination of EnumChildWindows().
----------------------------------------------------------------------
Sat Mar 2 18:19:06 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [controls/scroll.c]
......
......@@ -5,28 +5,7 @@ If you want to contribute code to Wine, read the DEVELOPER-HINTS. The
primary source of information to developers is the ChangeLog (next to
the source, of course).
1. make: No rule to make target foo/foo.o. Stop.
This frequently happens when a prior attempt to make foo.o failed.
In the current setup, make does not terminate then, but continues and
realises the problem later on. 'make' again and watch the output. Be
sure to analyze the problem before you report it to the newsgroup.
2. What are these questions in Configure?
- Emulator/Library: You need an emulator when you want to run MS-Win
binaries. You need a library when you want to compile the source code
of a Windows program.
- Language: Wine can present the system menu in multiple languages. Select
one of English, German, or Norwegian here.
- Inter-process communication: Allows setting up a DDE conversation
between different instances of Wine. Only really useful when
building Wine as a library.
- Malloc debugging: When enabled, the mtrace and mcheck GNU libc functions
are called. You might want to set the MALLOC_TRACE environment variable
to a trace file name. If your system supports another way of malloc
debugging, feel free to add it.
- Config file: Sets the Wine environment. See README for details.
3. BAR.EXE used to work, but does not work anymore
1. BAR.EXE used to work, but does not work anymore
Look at the ChangeLog to see what files have been changed. Try to undo
the particular patch and go partially back to the previous version. If
you have any suspicions, report them to the author or to the newsgroup.
......
......@@ -1473,11 +1473,11 @@ cat > conftest.$ac_ext <<EOF
#include "confdefs.h"
int main(void) {
static int Array3;
static int Array[3];
unsigned int B = 3;
int i;
for(i=0; i<B; i++) Arrayi = i - 3;
exit( Array1 != -2 );
for(i=0; i<B; i++) Array[i] = i - 3;
exit( Array[1] != -2 );
}
EOF
eval $ac_link
......
......@@ -52,11 +52,11 @@ then
AC_CACHE_CHECK( "for gcc strength-reduce bug", ac_cv_c_gcc_strength_bug,
AC_TRY_RUN([
int main(void) {
static int Array[3];
static int Array[[3]];
unsigned int B = 3;
int i;
for(i=0; i<B; i++) Array[i] = i - 3;
exit( Array[1] != -2 );
for(i=0; i<B; i++) Array[[i]] = i - 3;
exit( Array[[1]] != -2 );
}],
ac_cv_c_gcc_strength_bug="no",
ac_cv_c_gcc_strength_bug="yes",
......
......@@ -8,12 +8,8 @@
- ES_LOWERCASE and ES_UPPERCASE.
- ES_PASSWORD and EM_PASSWORDCHAR.
- ES_OEMCONVERT. Probably won't do anything very much.
- ES_READONLY.
- ES_WANTRETURN and Ctrl-Enter to move to next line when this
functionality is enabled.
......@@ -21,3 +17,17 @@
entered text as well as deleted text. You can also undo an undo.
- Add word wrap - this is a very big change!
I'm doing a rewrite on edit.c. Please e-mail me if you want
to work on edit.c as well, so we can synchronize.
Bugs in the current version, known to me:
- An empty document still contains "\r\n"
- UNDO is unstable (incomplete, and it can cause a segfault)
- WM_LBUTTONDBLCLK lets you select whole words, but doesn't set
the caret at the end of the selection
- Scrolling (left-right) works, but the scrollbar doesn't
Frans van Dorsselaer
dorssel@rulhm1.LeidenUniv.nl
......@@ -435,7 +435,7 @@ static void SCROLL_DrawInterior( HWND hwnd, HDC hdc, int nBar, RECT *rect,
InflateRect( &r, -1, -1 );
GRAPH_DrawReliefRect( hdc, &r, 1, 2, FALSE );
if ((hwndTracking == hwnd) && (nBarTracking == nBar))
SCROLL_DrawMovingThumb( hdc, &rect, vertical, arrowSize, uTrackingPos);
SCROLL_DrawMovingThumb( hdc, rect, vertical, arrowSize, uTrackingPos);
}
......
......@@ -34,7 +34,8 @@ int yyerror(char *);
}
%token CONT STEP LIST NEXT QUIT HELP BACKTRACE INFO STACK SEGMENTS REGS
%token ENABLE DISABLE BREAK DELETE SET MODE PRINT EXAM DEFINE ABORT
%token ENABLE DISABLE BREAK DELETE SET MODE PRINT EXAM DEFINE ABORT WALK
%token WND QUEUE
%token NO_SYMBOL EOL
%token SYMBOLFILE
......@@ -93,6 +94,8 @@ int yyerror(char *);
}
| DELETE BREAK NUM EOL { DEBUG_DelBreakpoint( $3 ); }
| BACKTRACE EOL { DEBUG_BackTrace(); }
| WALK WND EOL { DEBUG_InitWalk(); DEBUG_WndWalk( NULL ); }
| WALK WND NUM EOL { DEBUG_InitWalk(); DEBUG_WndWalk( $3 ); }
| infocmd
| x_command
| print_command
......@@ -180,6 +183,8 @@ x_command:
| INFO BREAK EOL { DEBUG_InfoBreakpoints(); }
| INFO SEGMENTS EOL { LDT_Print( 0, -1 ); }
| INFO SEGMENTS expr EOL { LDT_Print( SELECTOR_TO_ENTRY($3), 1 ); }
| INFO WND expr EOL { DEBUG_WndDump( $3 ); }
| INFO QUEUE expr EOL { DEBUG_QueueDump( $3 ); }
%%
......
......@@ -90,6 +90,9 @@ enable|enabl|enab|ena { return ENABLE;}
disable|disabl|disab|disa|dis { return DISABLE; }
delete|delet|dele|del { return DELETE; }
quit|qui|qu|q { return QUIT; }
walk|w { return WALK; }
queue|queu|que { return QUEUE; }
window|windo|wind|win|wnd { return WND; }
x { return EXAM; }
help|hel|he|"?" { return HELP; }
......
......@@ -7,8 +7,190 @@
#include <stdio.h>
#include <stdlib.h>
#include "global.h"
#include "user.h"
#include "class.h"
#include "win.h"
#include "message.h"
#include "spy.h"
#include "debugger.h"
int iWndIndent = 0;
extern char lpstrSpyMessageIndent[]; /* from misc/spy.c */
/***********************************************************************
* DEBUG_InitWalk
*/
void DEBUG_InitWalk(void)
{
fprintf(stderr,"%-24.24s %-6.6s %-17.17s %-8.8s %s\n",
"HWND / WNDPTR","hQueue","Class Name", "Style", "WndProc");
lpstrSpyMessageIndent[0]='\0';
}
/***********************************************************************
* DEBUG_WndWalk
*
*/
void DEBUG_WndWalk(HWND hStart)
{
WND* wndPtr;
CLASS* classPtr;
char className[0x10];
int i;
if( !hStart )
hStart = GetDesktopHwnd();
wndPtr = WIN_FindWndPtr(hStart);
if( !wndPtr )
{ fprintf(stderr, "Invalid window handle: %04x\n", hStart);
return; }
i = strlen(lpstrSpyMessageIndent);
/* 0x10 bytes are always reserved at the end of lpstrSpyMessageIndent */
sprintf(lpstrSpyMessageIndent + i,"%04x %08x",hStart, (unsigned) wndPtr);
classPtr = CLASS_FindClassPtr(wndPtr->hClass);
if(classPtr)
GlobalGetAtomName(classPtr->atomName ,className, 0x10);
else
strcpy(className,"<BAD>");
fprintf(stderr,"%-24.24s %-6.4x %-17.17s %08x %04x:%04x\n",
lpstrSpyMessageIndent,
wndPtr->hmemTaskQ,
className,
(unsigned) wndPtr->dwStyle,
HIWORD(wndPtr->lpfnWndProc),
LOWORD(wndPtr->lpfnWndProc));
lpstrSpyMessageIndent[i] = '\0';
if( wndPtr->hwndChild )
{
/* walk children */
hStart = wndPtr->hwndChild;
wndPtr = WIN_FindWndPtr(hStart);
iWndIndent ++;
if( iWndIndent < SPY_MAX_INDENTLEVEL - 0x10 )
{
lpstrSpyMessageIndent[iWndIndent - 1] = ' ';
lpstrSpyMessageIndent[iWndIndent] = '\0';
}
while( wndPtr )
{
DEBUG_WndWalk(hStart);
hStart = wndPtr->hwndNext;
wndPtr = WIN_FindWndPtr(hStart);
}
if( hStart )
fprintf(stderr, "%s%s"NPFMT"\n", lpstrSpyMessageIndent,
"<BAD>", hStart);
if( iWndIndent )
{
iWndIndent--;
if( iWndIndent < SPY_MAX_INDENTLEVEL - 0x10 )
lpstrSpyMessageIndent[iWndIndent] = '\0';
}
}
}
/***********************************************************************
* DEBUG_WndDump
*
*/
void DEBUG_WndDump(HWND hWnd)
{
WND* wnd;
char* lpWndText = NULL;
wnd = WIN_FindWndPtr(hWnd);
if( !wnd )
{ fprintf(stderr, "Invalid window handle: %04x\n", hWnd);
return; }
if( wnd->hText )
lpWndText = (LPSTR) USER_HEAP_LIN_ADDR( wnd->hText );
fprintf( stderr, "next: %12.4x\n"
"child: %10.4x\n"
"parent: %10.4x\n"
"owner: %10.4x\n"
"hClass: %10.4x\n"
"hInst: %10.4x\n"
"clientRect: %i,%i - %i,%i\n"
"windowRect: %i,%i - %i,%i\n"
"hRgnUpdate: %6.4x\n"
"hLastPopup: %6.4x\n"
"Style: %10.8x\n"
"StyleEx: %9.8x\n"
"hDCE: %10.4x\n"
"hVscroll: %8.4x\n"
"hHscroll: %8.4x\n"
"menuID: %10.4x\n"
"hText: %10.4x (\"%s\")\n"
"flags: %10.4x\n",
wnd->hwndNext, wnd->hwndChild,wnd->hwndParent,
wnd->hwndOwner,wnd->hClass,wnd->hInstance,
wnd->rectClient.left, wnd->rectClient.top,
wnd->rectClient.right, wnd->rectClient.bottom,
wnd->rectWindow.left, wnd->rectWindow.top,
wnd->rectWindow.right, wnd->rectWindow.bottom,
wnd->hrgnUpdate, wnd->hwndLastActive,
(unsigned) wnd->dwStyle, (unsigned) wnd->dwExStyle,
wnd->hdce, wnd->hVScroll, wnd->hHScroll,
wnd->wIDmenu, wnd->hText, (lpWndText)?lpWndText:"NULL",
wnd->flags);
}
/***********************************************************************
* DEBUG_QueueDump
*
*/
void DEBUG_QueueDump(HQUEUE hQ)
{
MESSAGEQUEUE* pq;
if( !hQ || IsBadReadPtr((SEGPTR)MAKELONG( 0, GlobalHandleToSel(hQ)),
sizeof(MESSAGEQUEUE)) )
{
fprintf(stderr, "Invalid queue handle: "NPFMT"\n", hQ);
return;
}
pq = (MESSAGEQUEUE*) GlobalLock( hQ );
fprintf(stderr,"next: %12.4x Intertask SendMessage:\n"
"hTask: %11.4x ----------------------\n"
"msgSize: %9.4x hWnd: %10.4x\n"
"msgCount: %8.4x msg: %11.4x\n"
"msgNext: %9.4x wParam: %8.4x\n"
"msgFree: %9.4x lParam: %8.8x\n"
"qSize: %11.4x lRet: %10.8x\n"
"wWinVer: %9.4x ISMH: %10.4x\n"
"paints: %10.4x hSendTask: %5.4x\n"
"timers: %10.4x hPrevSend: %5.4x\n"
"wakeBits: %8.4x\n"
"wakeMask: %8.4x\n"
"hCurHook: %8.4x\n",
pq->next, pq->hTask, pq->msgSize, pq->hWnd,
pq->msgCount, pq->msg, pq->nextMessage, pq->wParam,
pq->nextFreeMessage, (unsigned)pq->lParam, pq->queueSize,
(unsigned)pq->SendMessageReturn, pq->wWinVersion, pq->InSendMessageHandle,
pq->wPaintCount, pq->hSendingTask, pq->wTimerCount,
pq->hPrevSendingTask, pq->status, pq->wakeMask, pq->hCurHook);
}
/***********************************************************************
* DEBUG_Print
......@@ -108,8 +290,10 @@ void DEBUG_Help(void)
" step next",
" mode [16,32] print <expr>",
" set <reg> = <expr> set *<addr> = <expr>",
" walk [wnd] <expr> dump [wnd, queue] <expr>",
" info [reg,stack,break,segments] bt",
" symbolfile <filename> define <identifier> <addr>",
" list <addr> ",
"",
"The 'x' command accepts repeat counts and formats (including 'i') in the",
"same way that gdb does.",
......@@ -143,7 +327,7 @@ void DEBUG_List( DBG_ADDR *addr, int count )
{
DEBUG_PrintAddress( addr, dbg_mode );
fprintf( stderr, ": " );
if (!DBG_CHECK_READ_PTR( addr, 1 )) break;
if (!DBG_CHECK_READ_PTR( addr, 1 )) return;
DEBUG_Disasm( addr );
fprintf (stderr, "\n");
}
......
......@@ -259,9 +259,9 @@ static int DOSFS_Match( const char *mask, const char *name )
*
* Convert a Unix time in the DOS date/time format.
*/
void DOSFS_ToDosDateTime( time_t *unixtime, WORD *pDate, WORD *pTime )
void DOSFS_ToDosDateTime( time_t unixtime, WORD *pDate, WORD *pTime )
{
struct tm *tm = localtime( unixtime );
struct tm *tm = localtime( &unixtime );
if (pTime)
*pTime = (tm->tm_hour << 11) + (tm->tm_min << 5) + (tm->tm_sec / 2);
if (pDate)
......@@ -652,12 +652,11 @@ int DOSFS_FindNext( const char *path, const char *mask, int drive,
if ((attr & ~(FA_UNUSED | FA_ARCHIVE | FA_RDONLY)) == FA_LABEL)
{
time_t now = time(NULL);
if (skip) return 0;
strcpy( entry->name, DRIVE_GetLabel( drive ) );
entry->attr = FA_LABEL;
entry->size = 0;
DOSFS_ToDosDateTime( &now, &entry->date, &entry->time );
DOSFS_ToDosDateTime( time(NULL), &entry->date, &entry->time );
return 1;
}
......
......@@ -2,11 +2,33 @@ TOPSRC = @top_srcdir@
MODULE = if1632
DLLS16 = commdlg.spec compobj.spec ddeml.spec gdi.spec kernel.spec \
keyboard.spec mmsystem.spec mouse.spec ole2.spec ole2conv.spec \
ole2disp.spec ole2nls.spec ole2prox.spec olecli.spec olesvr.spec \
shell.spec sound.spec storage.spec stress.spec system.spec \
toolhelp.spec user.spec win87em.spec winprocs.spec winsock.spec
DLLS16 = \
commdlg.spec \
compobj.spec \
ddeml.spec \
gdi.spec \
kernel.spec \
keyboard.spec \
lzexpand.spec \
mmsystem.spec \
mouse.spec \
ole2.spec \
ole2conv.spec \
ole2disp.spec \
ole2nls.spec \
ole2prox.spec \
olecli.spec \
olesvr.spec \
shell.spec \
sound.spec \
storage.spec \
stress.spec \
system.spec \
toolhelp.spec \
user.spec \
win87em.spec \
winprocs.spec \
winsock.spec
DLLS32 = advapi32.spec comctl32.spec comdlg32.spec gdi32.spec kernel32.spec \
ole32.spec shell32.spec user32.spec winprocs32.spec winspool.spec
......
......@@ -38,7 +38,7 @@ LONG CallWindowProc( WNDPROC func, HWND hwnd, WORD message,
if(!a->win32)
fprintf(stderr,"Where is the Win32 callback?\n");
if (UsesLParamPtr(message))
return RELAY32_CallWindowProc(a->win32,hwnd,message,wParam,lParam ? PTR_SEG_TO_LIN(lParam): 0);
return RELAY32_CallWindowProcConvStruct(a->win32,hwnd,message,wParam,lParam);
else
return RELAY32_CallWindowProc(a->win32,hwnd,message,wParam,lParam);
}
......
name lzexpand
id 26
1 pascal LZCopy(word word) LZCopy
2 pascal16 LZOpenFile(ptr ptr word) LZOpenFile
3 pascal16 LZInit(word) LZInit
4 pascal LZSeek(word long word) LZSeek
5 pascal16 LZRead(word segptr word) LZRead
6 pascal16 LZClose(word) LZClose
7 pascal16 LZStart() LZStart
8 pascal CopyLZFile(word word) CopyLZFile
9 pascal16 LZDone() LZDone
10 pascal16 GetExpandedName(ptr ptr) GetExpandedName
#11 WEP
#12 ___EXPORTEDSTUB
......@@ -52,7 +52,8 @@ struct dll_table_s dll_builtin_table[N_BUILTINS] =
DLL_ENTRY_NOTUSED(COMPOBJ),
DLL_ENTRY_NOTUSED(STORAGE),
DLL_ENTRY(WINPROCS),
DLL_ENTRY_NOTUSED(DDEML)
DLL_ENTRY_NOTUSED(DDEML),
DLL_ENTRY(LZEXPAND)
};
/* don't forget to increase N_BUILTINS in dlls.h if you add a dll */
......
......@@ -17,7 +17,10 @@
#include "pe_image.h"
#include "peexe.h"
#include "relay32.h"
#include "struct32.h"
#include "stackframe.h"
#include "xmalloc.h"
#include "ldt.h"
#include "stddebug.h"
#include "debug.h"
......@@ -124,7 +127,7 @@ LONG RELAY32_CallWindowProc( WNDPROC func, int hwnd, int message,
int wParam, int lParam )
{
int ret;
__asm__ (
__asm__ (
"push %1;"
"push %2;"
"push %3;"
......@@ -136,6 +139,68 @@ __asm__ (
return ret;
}
LONG RELAY32_CallWindowProcConvStruct( WNDPROC func, int hwnd, int message,
int wParam, LPARAM lParam16)
{
WINDOWPOS32 wp;
union {
MINMAXINFO32 mmi;
NCCALCSIZE_PARAMS32 nccs;
CREATESTRUCT32 cs;
} st;
CREATESTRUCT *lpcs;
LONG result;
void *lParam;
if(!lParam16)
return RELAY32_CallWindowProc(func,hwnd,message,wParam,(int)lParam16);
lParam = PTR_SEG_TO_LIN(lParam16);
switch(message) {
case WM_GETMINMAXINFO:
STRUCT32_MINMAXINFO16to32(lParam,&st.mmi);
result=RELAY32_CallWindowProc(func,hwnd,message,wParam,(int)&st.mmi);
STRUCT32_MINMAXINFO32to16(&st.mmi,lParam);
return result;
case WM_WINDOWPOSCHANGING:
case WM_WINDOWPOSCHANGED:
STRUCT32_WINDOWPOS16to32(lParam,&wp);
result=RELAY32_CallWindowProc(func,hwnd,message,wParam,(int)&wp);
STRUCT32_WINDOWPOS32to16(&wp,lParam);
return result;
case WM_NCCALCSIZE:
STRUCT32_NCCALCSIZE16to32Flat(lParam,&st.nccs);
if(((NCCALCSIZE_PARAMS*)lParam)->lppos) {
STRUCT32_WINDOWPOS16to32(((NCCALCSIZE_PARAMS*)lParam)->lppos,&wp);
st.nccs.lppos=&wp;
} else
st.nccs.lppos= 0;
result=RELAY32_CallWindowProc(func,hwnd,message,wParam,(int)&st.nccs);
STRUCT32_NCCALCSIZE32to16Flat(&st.nccs,lParam);
if(((NCCALCSIZE_PARAMS*)lParam)->lppos)
STRUCT32_WINDOWPOS32to16(&wp,((NCCALCSIZE_PARAMS*)lParam)->lppos);
return result;
case WM_NCCREATE:
lpcs = (CREATESTRUCT*)lParam;
STRUCT32_CREATESTRUCT16to32(lParam,&st.cs);
st.cs.lpszName = HIWORD(lpcs->lpszName) ?
PTR_SEG_TO_LIN(lpcs->lpszName) : (char*)lpcs->lpszName;
st.cs.lpszClass = HIWORD(lpcs->lpszClass) ?
PTR_SEG_TO_LIN(lpcs->lpszClass) : (char*)lpcs->lpszClass;
result=RELAY32_CallWindowProc(func,hwnd,message,wParam,(int)&st.cs);
STRUCT32_CREATESTRUCT32to16(&st.cs,lParam);
lpcs->lpszName = HIWORD(st.cs.lpszName) ?
MAKE_SEGPTR(st.cs.lpszName) : (SEGPTR)st.cs.lpszName;
lpcs->lpszClass = HIWORD(st.cs.lpszClass) ?
MAKE_SEGPTR(st.cs.lpszClass) : (SEGPTR)st.cs.lpszClass;
return result;
case WM_GETTEXT:
case WM_SETTEXT:
return RELAY32_CallWindowProc(func,hwnd,message,wParam,(int)lParam);
default:
fprintf(stderr,"No conversion function for message %d\n",message);
}
return RELAY32_CallWindowProc(func,hwnd,message,wParam,(int)lParam);
}
void RELAY32_MakeFakeModule(WIN32_builtin*dll)
{
NE_MODULE *pModule;
......
......@@ -89,6 +89,10 @@ extern void DEBUG_Print( const DBG_ADDR *addr, int count, char format );
extern void DEBUG_PrintAddress( const DBG_ADDR *addr, int addrlen );
extern void DEBUG_Help(void);
extern void DEBUG_List( DBG_ADDR *addr, int count );
extern void DEBUG_InitWalk(void);
extern void DEBUG_WndWalk( HWND );
extern void DEBUG_WndDump( HWND );
extern void DEBUG_QueueDump( HQUEUE );
/* debugger/memory.c */
extern BOOL DEBUG_IsBadReadPtr( const DBG_ADDR *address, int size );
......
......@@ -54,8 +54,9 @@ DECLARE_DLL(COMPOBJ)
DECLARE_DLL(STORAGE)
DECLARE_DLL(WINPROCS)
DECLARE_DLL(DDEML)
DECLARE_DLL(LZEXPAND)
#define N_BUILTINS 25
#define N_BUILTINS 26
extern struct dll_table_s dll_builtin_table[];
......
......@@ -25,7 +25,7 @@ typedef struct
#define IS_END_OF_NAME(ch) (!(ch) || ((ch) == '/') || ((ch) == '\\'))
extern void DOSFS_ToDosDateTime( time_t *unixtime, WORD *pDate, WORD *pTime );
extern void DOSFS_ToDosDateTime( time_t unixtime, WORD *pDate, WORD *pTime );
extern const char *DOSFS_ToDosFCBFormat( const char *name );
extern const char *DOSFS_ToDosDTAFormat( const char *name );
extern const char *DOSFS_IsDevice( const char *name );
......
......@@ -10,21 +10,21 @@
#include "windows.h"
extern void FILE_SetDosError(void);
extern int FILE_GetUnixTaskHandle( HFILE handle );
extern void FILE_CloseAllFiles( HANDLE hPDB );
extern int FILE_Open( LPCSTR path, int mode );
extern int FILE_Create( LPCSTR path, int mode, int unique );
extern int FILE_Stat( LPCSTR unixName, BYTE *pattr, DWORD *psize,
WORD *pdate, WORD *ptime );
extern int FILE_GetDateTime( HFILE hFile, WORD *pdate, WORD *ptime,
BOOL refresh );
extern int FILE_SetDateTime( HFILE hFile, WORD date, WORD time );
extern int FILE_Fstat( HFILE hFile, BYTE *pattr, DWORD *psize,
WORD *pdate, WORD *ptime );
extern int FILE_Sync( HFILE hFile );
extern int FILE_Unlink( LPCSTR path );
extern int FILE_MakeDir( LPCSTR path );
extern int FILE_RemoveDir( LPCSTR path );
extern HFILE FILE_Dup( HFILE hFile );
extern HFILE FILE_Dup2( HFILE hFile1, HFILE hFile2 );
extern int FILE_OpenFile( LPCSTR name, OFSTRUCT *ofs, UINT mode );
extern LONG FILE_Read( HFILE hFile, LPSTR buffer, LONG count );
extern LONG FILE_Read( HFILE hFile, void *buffer, LONG count );
extern INT _lcreat_uniq( LPCSTR path, INT attr );
#endif /* __WINE_FILE_H */
/* Includefile for the decompression library, lzexpand
*
* Copyright 1996 Marcus Meissner
*/
LONG LZCopy(HFILE,HFILE);
HFILE LZOpenFile(LPCSTR,LPOFSTRUCT,UINT);
HFILE LZInit(HFILE);
LONG LZSeek(HFILE,LONG,INT);
INT LZRead(HFILE,SEGPTR,WORD);
void LZClose(HFILE);
INT LZStart(void);
LONG CopyLZFile(HFILE,HFILE);
void LZDone(void);
INT GetExpandedName(LPCSTR,LPSTR);
#define LZERROR_BADINHANDLE 0xFFFF /* -1 */
#define LZERROR_BADOUTHANDLE 0xFFFE /* -2 */
#define LZERROR_READ 0xFFFD /* -3 */
#define LZERROR_WRITE 0xFFFC /* -4 */
#define LZERROR_GLOBALLOC 0xFFFB /* -5 */
#define LZERROR_GLOBLOCK 0xFFFA /* -6 */
#define LZERROR_BADVALUE 0xFFF9 /* -7 */
#define LZERROR_UNKNOWNALG 0xFFF8 /* -8 */
......@@ -7,6 +7,7 @@
#ifndef _RELAY32_H
#define _RELAY32_H
#include "pe_image.h"
#include "struct32.h"
void RELAY32_Unimplemented(char *dll, int item);
WIN32_builtin *RELAY32_GetBuiltinDLL(char *name);
......@@ -27,41 +28,10 @@ typedef struct tagWNDCLASSA{
char* lpszClassName;
}WNDCLASSA;
struct WIN32_POINT{
LONG x;
LONG y;
};
struct WIN32_MSG{
DWORD hwnd;
DWORD message;
DWORD wParam;
DWORD lParam;
DWORD time;
struct WIN32_POINT pt;
};
struct WIN32_RECT{
LONG left;
LONG top;
LONG right;
LONG bottom;
};
struct WIN32_PAINTSTRUCT{
DWORD hdc;
DWORD fErase;
struct WIN32_RECT rcPaint;
DWORD fRestore;
DWORD fIncUpdate;
BYTE rgbReserved[32];
};
ATOM USER32_RegisterClassA(WNDCLASSA *);
LRESULT USER32_DefWindowProcA(DWORD hwnd,DWORD msg,DWORD wParam,DWORD lParam);
BOOL USER32_GetMessageA(struct WIN32_MSG* lpmsg,DWORD hwnd,DWORD min,DWORD max);
HDC USER32_BeginPaint(DWORD hwnd,struct WIN32_PAINTSTRUCT *lpps);
BOOL USER32_EndPaint(DWORD hwnd,struct WIN32_PAINTSTRUCT *lpps);
BOOL USER32_GetMessageA(MSG32* lpmsg,DWORD hwnd,DWORD min,DWORD max);
HDC USER32_BeginPaint(DWORD hwnd,PAINTSTRUCT32 *lpps);
BOOL USER32_EndPaint(DWORD hwnd,PAINTSTRUCT32 *lpps);
#endif
......@@ -12,6 +12,9 @@
#define SPY_RESULT_OK 0x0000
#define SPY_RESULT_INVALIDHWND 0x0001
#define SPY_MAX_MSGNUM WM_USER
#define SPY_MAX_INDENTLEVEL 64
extern void EnterSpyMessage( int, HWND, WORD, WORD, LONG);
extern void ExitSpyMessage( int, HWND, WORD, LONG);
extern void SpyInit( void);
......
/* Structure definitions for Win32 -- used only internally */
#ifndef _STRUCT32_H
#define _STRUCT32_H
#include "handle32.h"
typedef struct tagRECT32
{
......@@ -10,8 +11,8 @@ typedef struct tagRECT32
LONG bottom;
} RECT32;
void USER32_RECT32to16(const RECT32*,RECT*);
void USER32_RECT16to32(const RECT*,RECT32*);
void STRUCT32_RECT32to16(const RECT32*,RECT*);
void STRUCT32_RECT16to32(const RECT*,RECT32*);
typedef struct tagPOINT32
{
......@@ -25,9 +26,21 @@ typedef struct tagSIZE32
LONG cy;
} SIZE32;
void PARAM32_POINT32to16(const POINT32*,POINT*);
void PARAM32_POINT16to32(const POINT*,POINT32*);
void PARAM32_SIZE16to32(const SIZE* p16, SIZE32* p32);
void STRUCT32_POINT32to16(const POINT32*,POINT*);
void STRUCT32_POINT16to32(const POINT*,POINT32*);
void STRUCT32_SIZE16to32(const SIZE* p16, SIZE32* p32);
typedef struct tagMINMAXINFO32
{
POINT32 ptReserved;
POINT32 ptMaxSize;
POINT32 ptMaxPosition;
POINT32 ptMinTrackSize;
POINT32 ptMaxTrackSize;
} MINMAXINFO32;
void STRUCT32_MINMAXINFO32to16(const MINMAXINFO32*,MINMAXINFO*);
void STRUCT32_MINMAXINFO16to32(const MINMAXINFO*,MINMAXINFO32*);
typedef struct {
DWORD style;
......@@ -51,4 +64,72 @@ typedef struct {
#define CW_USEDEFAULT32 0x80000000
typedef struct tagMSG32
{
DWORD hwnd;
DWORD message;
DWORD wParam;
DWORD lParam;
DWORD time;
POINT32 pt;
} MSG32;
void STRUCT32_MSG16to32(MSG *msg16,MSG32 *msg32);
void STRUCT32_MSG32to16(MSG32 *msg32,MSG *msg16);
typedef struct tagPAINTSTRUCT32
{
DWORD hdc;
DWORD fErase;
RECT32 rcPaint;
DWORD fRestore;
DWORD fIncUpdate;
BYTE rgbReserved[32];
} PAINTSTRUCT32;
typedef struct tagWINDOWPOS32
{
DWORD hwnd;
DWORD hwndInsertAfter;
LONG x;
LONG y;
LONG cx;
LONG cy;
DWORD flags;
} WINDOWPOS32;
void STRUCT32_WINDOWPOS32to16(const WINDOWPOS32*,WINDOWPOS*);
void STRUCT32_WINDOWPOS16to32(const WINDOWPOS*,WINDOWPOS32*);
typedef struct tagNCCALCSIZE_PARAMS32
{
RECT32 rgrc[3];
WINDOWPOS32 *lppos;
} NCCALCSIZE_PARAMS32;
void STRUCT32_NCCALCSIZE32to16Flat(const NCCALCSIZE_PARAMS32*,
NCCALCSIZE_PARAMS*);
void STRUCT32_NCCALCSIZE16to32Flat(const NCCALCSIZE_PARAMS* from,
NCCALCSIZE_PARAMS32* to);
typedef struct tagCREATESTRUCT32
{
DWORD lpCreateParams;
DWORD hInstance;
DWORD hMenu;
DWORD hwndParent;
LONG cy;
LONG cx;
LONG y;
LONG x;
LONG style;
LPSTR lpszName;
LPSTR lpszClass;
DWORD dwExStyle;
} CREATESTRUCT32;
typedef CREATESTRUCT32 CREATESTRUCTA;
void STRUCT32_CREATESTRUCT32to16(const CREATESTRUCT32*,CREATESTRUCT*);
void STRUCT32_CREATESTRUCT16to32(const CREATESTRUCT*,CREATESTRUCT32*);
#endif
......@@ -2553,6 +2553,32 @@ typedef struct {
WORD wMilliseconds;
} SYSTEMTIME, *LPSYSTEMTIME;
/* WinHelp internal structure */
typedef struct {
WORD size;
WORD command;
LONG data;
LONG reserved;
WORD ofsFilename;
WORD ofsData;
} WINHELP,*LPWINHELP;
typedef struct {
UINT mkSize;
BYTE mkKeyList;
BYTE szKeyPhrase[1];
} MULTIKEYHELP, *LPMULTIKEYHELP;
typedef struct {
WORD wStructSize;
WORD x;
WORD y;
WORD dx;
WORD dy;
WORD wMax;
char rgchMember[2];
} HELPWININFO, *LPHELPWININFO;
#define HELP_CONTEXT 0x0001
#define HELP_QUIT 0x0002
#define HELP_INDEX 0x0003
......
......@@ -143,6 +143,7 @@ typedef FARPROC HOOKPROC;
#define _near
#define PASCAL
#define _pascal
#define __export
#define VOID void
#define WINAPI PASCAL
#define CALLBACK PASCAL
......
WINElib resources: a proposal
One of the current issues with WINElib is the inadequate support for accessing
resources by name. I propose the following technique (which I have already
begun to implement) to allow this:
An internal table of resource entries is provided along with a registering
function for adding a resource to this table. 'winerc' should construct
*.c files much the same way as it does now with the inclusion of a single
static 'constructor' function that registers the associated resources with
the internal mechanism like so:
static void DoIt() __attribute__ ((constructor));
static void DoIt()
{
LIBRES_RegisterResource(hello3_MENU_MAIN__bytes,
sizeof(hello3_MENU_MAIN__bytes),
"MAIN",
RT_MENU);
LIBRES_RegisterResource(hello3_DIALOG_DIADEMO__bytes,
sizeof(hello3_DIALOG_DIADEMO__bytes),
"DIADEMO",
RT_DIALOG);
... etc. ...
}
The internal table can then be searched for the resource by name.
The only potential drawback I've determined so far is this technique's
reliance on gcc's 'constructor' attribute, which disallows compilation with
some other compiler. However, I'm guessing that WINE is already heavily
dependent on gcc, so this is probably not too much of a factor.
Any comments/suggestions/criticisms will be greatly appreciated.
Thank you,
--Jim
......@@ -411,7 +411,7 @@ HINSTANCE MODULE_CreateInstance( HMODULE hModule, LOADPARAMS *params )
/***********************************************************************
* MODULE_LoadExeHeader
*/
HMODULE MODULE_LoadExeHeader( int fd, OFSTRUCT *ofs )
HMODULE MODULE_LoadExeHeader( HFILE hFile, OFSTRUCT *ofs )
{
struct mz_header_s mz_header;
struct ne_header_s ne_header;
......@@ -427,15 +427,15 @@ HMODULE MODULE_LoadExeHeader( int fd, OFSTRUCT *ofs )
((fastload && ((offset) >= fastload_offset) && \
((offset)+(size) <= fastload_offset+fastload_length)) ? \
(memcpy( buffer, fastload+(offset)-fastload_offset, (size) ), TRUE) : \
(lseek( fd, mz_header.ne_offset+(offset), SEEK_SET), \
read( fd, (buffer), (size) ) == (size)))
(_llseek( hFile, mz_header.ne_offset+(offset), SEEK_SET), \
FILE_Read( hFile, (buffer), (size) ) == (size)))
lseek( fd, 0, SEEK_SET );
if ((read( fd, &mz_header, sizeof(mz_header) ) != sizeof(mz_header)) ||
_llseek( hFile, 0, SEEK_SET );
if ((FILE_Read(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
(mz_header.mz_magic != MZ_SIGNATURE)) return (HMODULE)11; /* invalid exe */
lseek( fd, mz_header.ne_offset, SEEK_SET );
if (read( fd, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
_llseek( hFile, mz_header.ne_offset, SEEK_SET );
if (FILE_Read( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
return (HMODULE)11; /* invalid exe */
if (ne_header.ne_magic == PE_SIGNATURE) return (HMODULE)21; /* win32 exe */
......@@ -477,8 +477,8 @@ HMODULE MODULE_LoadExeHeader( int fd, OFSTRUCT *ofs )
fastload_offset, fastload_length );
if ((fastload = (char *)malloc( fastload_length )) != NULL)
{
lseek( fd, mz_header.ne_offset + fastload_offset, SEEK_SET );
if (read( fd, fastload, fastload_length ) != fastload_length)
_llseek( hFile, mz_header.ne_offset + fastload_offset, SEEK_SET );
if (FILE_Read( hFile, fastload, fastload_length ) != fastload_length)
{
free( fastload );
fastload = NULL;
......@@ -572,8 +572,8 @@ HMODULE MODULE_LoadExeHeader( int fd, OFSTRUCT *ofs )
hModule, FALSE, FALSE, FALSE );
if (!pModule->nrname_handle) return (HMODULE)11; /* invalid exe */
buffer = GlobalLock( pModule->nrname_handle );
lseek( fd, ne_header.nrname_tab_offset, SEEK_SET );
if (read( fd, buffer, ne_header.nrname_tab_length )
_llseek( hFile, ne_header.nrname_tab_offset, SEEK_SET );
if (FILE_Read( hFile, buffer, ne_header.nrname_tab_length )
!= ne_header.nrname_tab_length) return (HMODULE)11; /* invalid exe */
}
else pModule->nrname_handle = 0;
......@@ -925,7 +925,8 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
LOADPARAMS *params = (LOADPARAMS *)paramBlock;
#ifndef WINELIB
WORD *pModRef, *pDLLs;
int i, fd;
HFILE hFile;
int i;
hModule = MODULE_FindModule( name );
......@@ -936,7 +937,7 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
/* Try to load the built-in first if not disabled */
if ((hModule = MODULE_LoadBuiltin( name, FALSE ))) return hModule;
if ((fd = FILE_OpenFile( name, &ofs, OF_READ )) == -1)
if ((hFile = OpenFile( name, &ofs, OF_READ )) == HFILE_ERROR)
{
/* Now try the built-in even if disabled */
if ((hModule = MODULE_LoadBuiltin( name, TRUE )))
......@@ -949,17 +950,20 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
/* Create the module structure */
hModule = MODULE_LoadExeHeader( fd, &ofs );
hModule = MODULE_LoadExeHeader( hFile, &ofs );
if (hModule < 32)
{
/* FIXME: Hack because PE_LoadModule is recursive */
int fd = dup( FILE_GetUnixHandle(hFile) );
_lclose( hFile );
if (hModule == 21) hModule = PE_LoadModule( fd, &ofs, paramBlock );
close(fd);
close( fd );
if (hModule < 32)
fprintf( stderr, "LoadModule: can't load '%s', error=%d\n",
name, hModule );
return hModule;
}
close( fd );
_lclose( hFile );
pModule = (NE_MODULE *)GlobalLock( hModule );
/* Allocate the segments for this module */
......@@ -1017,6 +1021,7 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
if (pModule->flags & NE_FFLAGS_SELFLOAD)
{
int fd;
/* Handle self loading modules */
SEGTABLEENTRY * pSegTable = (SEGTABLEENTRY *) NE_SEG_TABLE(pModule);
SELFLOADHEADER *selfloadheader;
......@@ -1069,6 +1074,8 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
IF1632_Stack32_base = WIN16_GlobalLock(hInitialStack32);
}
/* FIXME: we probably need a DOS handle here */
fd = MODULE_OpenFile( hModule );
CallTo16_word_ww (selfloadheader->BootApp,
pModule->self_loading_sel, hModule, fd);
/* some BootApp procs overwrite the selector of dgroup */
......
......@@ -74,6 +74,7 @@ BOOL NE_LoadSegment( HMODULE hModule, WORD segnum )
oldselector = pSeg->selector;
IF1632_Saved16_ss = pModule->self_loading_sel;
IF1632_Saved16_sp = 0xFF00;
/* FIXME: we probably need to pass a DOS file handle here */
newselector = CallTo16_word_www(selfloadheader->LoadAppSeg,
pModule->self_loading_sel, hModule, fd, segnum);
if (newselector != oldselector) {
......
......@@ -11,6 +11,7 @@ C_SRCS = \
escape.c \
keyboard.c \
lstr.c \
lzexpand.c \
main.c \
network.c \
ole2.c \
......
......@@ -116,27 +116,75 @@ BOOL ExitWindows( DWORD dwReturnCode, WORD wReserved )
*/
BOOL WinHelp(HWND hWnd, LPSTR lpHelpFile, WORD wCommand, DWORD dwData)
{
char str[256];
dprintf_exec(stddeb,"WinHelp(%s, %u, %lu)\n",
lpHelpFile, wCommand, dwData);
switch(wCommand) {
case 0:
case HELP_HELPONHELP:
GetWindowsDirectory(str, sizeof(str));
strcat(str, "\\winhelp.exe winhelp.hlp");
dprintf_exec(stddeb,"'%s'\n", str);
break;
case HELP_INDEX:
GetWindowsDirectory(str, sizeof(str));
strcat(str, "\\winhelp.exe ");
strcat(str, lpHelpFile);
dprintf_exec(stddeb,"'%s'\n", str);
break;
case HELP_QUIT:
return TRUE;
default:
static WORD WM_WINHELP=0;
HWND hDest;
char szBuf[20];
LPWINHELP lpwh;
HANDLE hwh;
void *data=0;
int size,dsize,nlen;
if (wCommand != HELP_QUIT) /* FIXME */
if(WinExec("winhelp.exe -x",SW_SHOWNORMAL)<=32)
return FALSE;
/* FIXME: Should be directed yield, to let winhelp open the window */
Yield();
if(!WM_WINHELP) {
strcpy(szBuf,"WM_WINHELP");
WM_WINHELP=RegisterWindowMessage(MAKE_SEGPTR(szBuf));
if(!WM_WINHELP)
return FALSE;
}
WinExec(str, SW_SHOWNORMAL);
return(TRUE);
strcpy(szBuf,"MS_WINHELP");
hDest = FindWindow(MAKE_SEGPTR(szBuf),0);
if(!hDest)
return FALSE;
switch(wCommand)
{
case HELP_CONTEXT:
case HELP_CONTENTS:
case HELP_SETCONTENTS:
case HELP_CONTEXTPOPUP:
case HELP_FORCEFILE:
case HELP_HELPONHELP:
case HELP_QUIT:
dsize=0;
break;
case HELP_KEY:
case HELP_PARTIALKEY:
case HELP_COMMAND:
data = PTR_SEG_TO_LIN(dwData);
dsize = strlen(data)+1;
break;
case HELP_MULTIKEY:
data = PTR_SEG_TO_LIN(dwData);
dsize = ((LPMULTIKEYHELP)data) -> mkSize;
break;
case HELP_SETWINPOS:
data = PTR_SEG_TO_LIN(dwData);
dsize = ((LPHELPWININFO)data) -> wStructSize;
break;
default:
fprintf(stderr,"Unknown help command %d\n",wCommand);
return FALSE;
}
if(lpHelpFile)
nlen = strlen(lpHelpFile)+1;
else
nlen = 0;
size = sizeof(WINHELP) + nlen + dsize;
hwh = GlobalAlloc(0,size);
lpwh = GlobalLock(hwh);
lpwh->size = size;
lpwh->command = wCommand;
if(nlen) {
lpwh->ofsFilename = sizeof(WINHELP);
strcpy(((char*)lpwh) + sizeof(WINHELP),lpHelpFile);
}
if(dsize) {
memcpy(((char*)lpwh)+sizeof(WINHELP)+nlen,data,dsize);
lpwh->ofsData = sizeof(WINHELP)+nlen;
} else
lpwh->ofsData = 0;
GlobalUnlock(hwh);
return SendMessage(hDest,WM_WINHELP,hWnd,hwh);
}
This diff is collapsed. Click to expand it.
......@@ -15,9 +15,6 @@
#include "debug.h"
#include "spy.h"
#define SPY_MAX_MSGNUM WM_USER
#define SPY_MAX_INDENTLEVEL 64
const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] =
{
"WM_NULL", /* 0x00 */
......@@ -130,7 +127,7 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] =
"WM_NCMBUTTONDBLCLK", /* 0x00A9 */
NULL, NULL, NULL, NULL, NULL, NULL,
/* 0x00B0 */
/* 0x00B0 - Win32 Edit controls */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
......@@ -142,11 +139,11 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] =
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 0x00E0 */
/* 0x00E0 - Win32 Scrollbars */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 0x00F0 */
/* 0x00F0 - Win32 Buttons */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
......@@ -186,7 +183,7 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] =
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 0x0140 */
/* 0x0140 - Win32 Comboboxes */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
......@@ -198,11 +195,11 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] =
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 0x0170 */
/* 0x0170 - Win32 Static controls */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 0x0180 */
/* 0x0180 - Win32 Listboxes */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
......@@ -398,7 +395,7 @@ static BOOL SpyFilters [SPY_MAX_MSGNUM+1];
static BOOL SpyIncludes[SPY_MAX_MSGNUM+1];
static int iSpyMessageIndentLevel = 0;
static char lpstrSpyMessageIndent[SPY_MAX_INDENTLEVEL];
char lpstrSpyMessageIndent[SPY_MAX_INDENTLEVEL]; /* referenced in debugger/info.c */
static char *lpstrSpyMessageFromWine = "Wine";
static char lpstrSpyMessageFromTask[10];
static char *lpstrSpyMessageFromSelf = "self";
......@@ -501,8 +498,11 @@ void ExitSpyMessage(int iFlag, HWND hWnd, WORD msg, LONG lReturn)
if( !SpyIncludes[wCheckMsg] || SpyFilters[wCheckMsg]) return;
iSpyMessageIndentLevel--;
lpstrSpyMessageIndent[iSpyMessageIndentLevel]='\0';
if( iSpyMessageIndentLevel )
{
iSpyMessageIndentLevel--;
lpstrSpyMessageIndent[iSpyMessageIndentLevel]='\0';
}
switch(iFlag)
{
......
......@@ -519,7 +519,7 @@ static void INT21_ChangeDir(struct sigcontext_struct *context)
char *dirname = PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context));
dprintf_int(stddeb,"int21: changedir %s\n", dirname);
if (dirname[1] == ':')
if (dirname[0] && (dirname[1] == ':'))
{
drive = toupper(dirname[0]) - 'A';
dirname += 2;
......@@ -599,28 +599,6 @@ static int INT21_FindNext(struct sigcontext_struct *context)
}
static int INT21_SetFileDateTime(struct sigcontext_struct *context)
{
fprintf( stderr, "INT21_SetFileDateTime: not implemented yet.\n" );
return 1;
#if 0
char *filename;
struct utimbuf filetime;
/* FIXME: Argument isn't the name of the file in DS:DX,
but the file handle in BX */
filename = DOSFS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS_reg(context),
DX_reg(context)),TRUE );
filetime.actime = 0L;
filetime.modtime = filetime.actime;
utime(filename, &filetime);
RESET_CFLAG(context);
#endif
}
static int INT21_CreateTempFile(struct sigcontext_struct *context)
{
static int counter = 0;
......@@ -1429,16 +1407,18 @@ void DOS3Call( struct sigcontext_struct context )
case 0x57: /* FILE DATE AND TIME */
switch (AL_reg(&context))
{
case 0x00:
if (!FILE_Fstat( BX_reg(&context), NULL, NULL,
&DX_reg(&context), &CX_reg(&context) ))
case 0x00: /* Get */
if (!FILE_GetDateTime( BX_reg(&context), &DX_reg(&context),
&CX_reg(&context), TRUE ))
{
AX_reg(&context) = DOS_ExtendedError;
SET_CFLAG(&context);
}
break;
case 0x01:
if (!INT21_SetFileDateTime(&context))
case 0x01: /* Set */
if (!FILE_SetDateTime( BX_reg(&context), DX_reg(&context),
CX_reg(&context) ))
{
AX_reg(&context) = DOS_ExtendedError;
SET_CFLAG(&context);
......@@ -1566,9 +1546,8 @@ void DOS3Call( struct sigcontext_struct context )
case 0x68: /* "FFLUSH" - COMMIT FILE */
case 0x6a: /* COMMIT FILE */
if (fsync( FILE_GetUnixTaskHandle( BX_reg(&context) )) == -1)
if (!FILE_Sync( BX_reg(&context) ))
{
FILE_SetDosError();
AX_reg(&context) = DOS_ExtendedError;
SET_CFLAG(&context);
}
......
......@@ -54,6 +54,9 @@ void INT_Int2fHandler( struct sigcontext_struct context )
INT_BARF( &context, 0x2f );
}
break;
case 0xb7: /* append */
AL_reg(&context) = 0; /* not installed */
break;
default:
INT_BARF( &context, 0x2f );
break;
......
......@@ -667,13 +667,13 @@ static void BITBLT_StretchImage( XImage *srcImage, XImage *dstImage,
{
yinc = ((int)heightSrc << 16) / heightDst;
ydst = visRectDst->top;
ysrc = yinc * ydst;
ysrc = yinc * ydst + (vswap ? heightSrc<<16 : 0);
}
else
{
yinc = ((int)heightDst << 16) / heightSrc;
ysrc = visRectSrc->top;
ydst = yinc * ysrc;
ydst = yinc * ysrc - (vswap ? (heightDst-1)<<16 : 0);
}
while(vstretch ? (ydst < visRectDst->bottom) : (ysrc < visRectSrc->bottom))
......@@ -685,7 +685,8 @@ static void BITBLT_StretchImage( XImage *srcImage, XImage *dstImage,
/* Stretch or shrink it */
if (hstretch)
BITBLT_StretchRow( rowSrc, rowDst, visRectDst->left,
BITBLT_StretchRow( rowSrc, rowDst, visRectDst->left +
(hswap ? widthDst : 0),
visRectDst->right-visRectDst->left, xinc, mode);
else BITBLT_ShrinkRow( rowSrc, rowDst, visRectSrc->left,
visRectSrc->right-visRectSrc->left, xinc, mode);
......@@ -714,7 +715,7 @@ static void BITBLT_StretchImage( XImage *srcImage, XImage *dstImage,
/* Store the destination row */
pixel = rowDst + visRectDst->right - 1;
pixel = rowDst + visRectDst->right - 1 + (hswap ? widthDst : 0);
if (vswap)
y = visRectDst->bottom - (vstretch ? ydst : ydst >> 16);
else
......@@ -972,7 +973,8 @@ static BOOL BITBLT_GetVisRectangles( DC *dcDst, short xDst, short yDst,
if (!dcSrc) return TRUE;
SetRect( &tmpRect, xSrc, ySrc, xSrc + widthSrc, ySrc + heightSrc );
GetRgnBox( dcSrc->w.hGCClipRgn, &clipRect );
/* Apparently the clip region is only for output, so use hVisRgn here */
GetRgnBox( dcSrc->w.hVisRgn, &clipRect );
OffsetRect( &clipRect, dcSrc->w.DCOrgX, dcSrc->w.DCOrgY );
if (!IntersectRect( visRectSrc, &tmpRect, &clipRect )) return FALSE;
......
......@@ -361,9 +361,11 @@ BOOL EqualRgn( HRGN rgn1, HRGN rgn2 )
*/
static int REGION_CopyRegion( RGNOBJ *src, RGNOBJ *dest )
{
Region tmprgn;
if (src->xrgn)
{
Region tmprgn = XCreateRegion();
if (src->xrgn == dest->xrgn) return COMPLEXREGION;
tmprgn = XCreateRegion();
if (!dest->xrgn) dest->xrgn = XCreateRegion();
XUnionRegion( tmprgn, src->xrgn, dest->xrgn );
XDestroyRegion( tmprgn );
......@@ -401,11 +403,14 @@ BOOL REGION_FrameRgn( HRGN hDest, HRGN hSrc, int x, int y )
/***********************************************************************
* CombineRgn (GDI.451)
*
* The behavior is correct even if src and dest regions are the same.
*/
INT CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode )
{
RGNOBJ *destObj, *src1Obj, *src2Obj;
Region destrgn;
dprintf_region(stddeb, "CombineRgn: "NPFMT","NPFMT" -> "NPFMT" mode=%x\n",
hSrc1, hSrc2, hDest, mode );
......@@ -445,29 +450,32 @@ INT CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode )
/* Perform the operation with the two X regions */
if (!destObj->xrgn) destObj->xrgn = XCreateRegion();
if (!(destrgn = XCreateRegion())) return ERROR;
switch(mode)
{
case RGN_AND:
XIntersectRegion( src1Obj->xrgn, src2Obj->xrgn, destObj->xrgn );
XIntersectRegion( src1Obj->xrgn, src2Obj->xrgn, destrgn );
break;
case RGN_OR:
XUnionRegion( src1Obj->xrgn, src2Obj->xrgn, destObj->xrgn );
XUnionRegion( src1Obj->xrgn, src2Obj->xrgn, destrgn );
break;
case RGN_XOR:
XXorRegion( src1Obj->xrgn, src2Obj->xrgn, destObj->xrgn );
XXorRegion( src1Obj->xrgn, src2Obj->xrgn, destrgn );
break;
case RGN_DIFF:
XSubtractRegion( src1Obj->xrgn, src2Obj->xrgn, destObj->xrgn );
XSubtractRegion( src1Obj->xrgn, src2Obj->xrgn, destrgn );
break;
default:
XDestroyRegion( destrgn );
return ERROR;
}
if (destObj->xrgn) XDestroyRegion( destObj->xrgn );
destObj->xrgn = destrgn;
if (XEmptyRegion(destObj->xrgn))
{
XDestroyRegion( destObj->xrgn );
destObj->xrgn = 0;
return NULLREGION;
}
else return COMPLEXREGION;
return COMPLEXREGION;
}
......@@ -9,6 +9,7 @@
#include "license.h"
#include "progman.h"
#ifdef WINELIB
#include <resource.h>
#include <options.h>
#include <shell.h>
#endif
......
......@@ -91,6 +91,8 @@ gen_res *make_menu(gen_res*);
gen_res *add_resource(gen_res*,gen_res*);
void add_str_tbl_elm(int,char*);
void create_output(gen_res*);
void set_out_file(char*);
......
......@@ -10,6 +10,8 @@
#include <stdlib.h>
#include "parser.h"
#include "y.tab.h"
int line_number=1;
%}
%%
ACCELERATORS return ACCELERATORS;
......@@ -70,7 +72,8 @@ VIRTKEY return VIRTKEY;
[A-Za-z][A-Za-z_0-9]* yylval.str=strdup(yytext);return IDENT;
\"[^"]*\" yylval.str=parse_c_string(yytext);return STRING;
\'[^']*\' yylval.str=strdup(yytext+1);return SINGLE_QUOTED;
[ \t\n\r] ;
\n { line_number++; }
[ \t\r] ;
. return yytext[0];
%%
......
......@@ -5,6 +5,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include "parser.h"
#include "windows.h"
%}
......@@ -29,7 +30,7 @@
%type <res> iconinfo menu menu_body item_definitions rcdata raw_data raw_elements
%type <res> stringtable strings versioninfo
%type <num> acc_options item_options
%type <style> style optional_style
%type <style> style style_elm optional_style
%%
resource_file: resources {create_output($1);}
......@@ -48,6 +49,11 @@ resource: NUMBER resource_definition
{$$=$2;$$->n.s_name=$1;$$->n_type=1;
if(verbose)fprintf(stderr,"Got %s %s\n",get_typename($2),$1);
}
| stringtable
{$$=$1; /* <-- should be NULL */
if(verbose)fprintf(stderr,"Got STRINGTABLE\n");
}
;
/* get the value for a single resource*/
resource_definition: accelerators {$$=$1;}
......@@ -58,8 +64,8 @@ resource_definition: accelerators {$$=$1;}
| icon {$$=$1;}
| menu {$$=$1;}
| rcdata {$$=$1;}
| stringtable {$$=$1;}
| versioninfo {$$=$1;}
;
/* have to use tBEGIN because BEGIN is predefined */
accelerators: ACCELERATORS tBEGIN events tEND {$$=$3;$$->type=acc;}
......@@ -190,20 +196,27 @@ raw_elements: SINGLE_QUOTED {$$=hex_to_raw($1,new_res());}
stringtable: STRINGTABLE load_and_memoption tBEGIN strings tEND
{$$=$4;}
strings: {$$=0;}|
NUMBER STRING strings {$$=0;}
NUMBER STRING strings {$$=0;add_str_tbl_elm($1,$2);}
versioninfo: VERSIONINFO NOT_SUPPORTED {$$=0;}
/* NOT x | NOT y | a | b means (a|b)& ~x & ~y
NOT is used to disable default styles */
style: NUMBER {$$=new_style();$$->or=$1;}
style: {$$=new_style();}
| style_elm {$$=$1;}
| style_elm '|' style
{$$=$1;$$->or|=$3->or;$$->and&=$3->and;free($3);}
style_elm: NUMBER {$$=new_style();$$->or=$1;}
| NOT NUMBER {$$=new_style();$$->and=~($2);}
| '(' style ')' {$$=$2;}
| style '|' style {$$=$1;$$->or|=$3->or;$$->and&=$3->and;}
%%
extern int line_number;
extern char* yytext;
int yyerror(char *s)
{
puts(s);
fprintf(stderr,"stdin:%d: %s before '%s'\n",line_number,s,yytext);
return 0;
}
......@@ -505,8 +505,70 @@ gen_res *make_menu(gen_res* res)
/* link top-level resources */
gen_res *add_resource(gen_res* first,gen_res *rest)
{
if(first)
{
first->next=rest;
return first;
}
else
return rest;
}
typedef struct str_tbl_elm{
int group;
struct str_tbl_elm *next;
char* strings[16];
} str_tbl_elm;
str_tbl_elm* string_table=NULL; /* sorted by group */
void add_str_tbl_elm(int id,char* str)
{
int group=(id>>4)+1;
int idx=id & 0x000f;
str_tbl_elm** elm=&string_table;
while(*elm && (*elm)->group<group) elm=&(*elm)->next;
if(!*elm || (*elm)->group!=group)
{
str_tbl_elm* new=xmalloc(sizeof(str_tbl_elm));
new->group=group;
new->next=*elm;
*elm=new;
}
(*elm)->strings[idx]=str;
}
gen_res* add_string_table(gen_res* t)
{
str_tbl_elm* ste;
int size,i;
gen_res* res;
unsigned char* p;
char* q;
if(!string_table) return t;
for(ste=string_table; ste; ste=ste->next)
{
for(size=0,i=0; i<16; i++)
size += ste->strings[i] ? strlen(ste->strings[i])+1 : 1;
res=new_res();
while(res->space<size)res=grow(res);
res->type=str;
res->n.i_name=ste->group;
res->n_type=0;
res->size=size;
for(p=res->res,i=0; i<16; i++)
if((q=ste->strings[i])==NULL)
*p++ = 0;
else
{
*p++ = strlen(q);
while(*q) *p++ = *q++;
}
t=add_resource(res,t);
}
return t;
}
char *get_typename(gen_res* t)
......@@ -543,6 +605,7 @@ void create_output(gen_res* top)
{
gen_res *it;
top=add_string_table(top);
fprintf( header, "/* %s\n"
" * This file is automatically generated. Do not edit!\n"
......@@ -563,6 +626,7 @@ void create_output(gen_res* top)
" * This file is automatically generated. Do not edit!\n"
" */\n\n"
"#include \"%s\"\n", sname, hname );
for(it=top;it;it=it->next)
{
int i;
......
......@@ -18,6 +18,7 @@ C_SRCS = \
process.c \
resource.c \
string32.c \
struct32.c \
thread.c \
time.c \
user32.c \
......
......@@ -13,19 +13,6 @@
#include "stddebug.h"
#include "debug.h"
void PARAM32_POINT32to16(const POINT32* p32,POINT* p16)
{
p16->x = p32->x;
p16->y = p32->y;
}
void PARAM32_SIZE16to32(const SIZE* p16, SIZE32* p32)
{
p32->cx = p16->cx;
p32->cy = p16->cy;
}
/****************************************************************
* MoveToEx (GDI32.254)
*/
......@@ -35,7 +22,7 @@ BOOL WIN32_MoveToEx(HDC hdc,int x,int y,POINT32* p32)
if (p32 == NULL)
return MoveToEx(hdc,x,y,(POINT *)NULL);
else {
PARAM32_POINT32to16(p32,&p);
STRUCT32_POINT32to16(p32,&p);
return MoveToEx(hdc,x,y,&p);
}
}
......@@ -47,7 +34,7 @@ BOOL WIN32_GetTextExtentPointA(HDC hdc, LPCTSTR str, int length, SIZE32* lpsize)
BOOL retval;
retval = GetTextExtentPoint(hdc, str, length, &s);
PARAM32_SIZE16to32(&s, lpsize);
STRUCT32_SIZE16to32(&s, lpsize);
return retval;
}
/*
* Win32 structure conversion functions
*
* Copyright 1996 Martin von Loewis
*/
#include <stdio.h>
#include "windows.h"
#include "winerror.h"
#include "struct32.h"
#include "stddebug.h"
#include "debug.h"
void STRUCT32_POINT32to16(const POINT32* p32,POINT* p16)
{
p16->x = p32->x;
p16->y = p32->y;
}
void STRUCT32_POINT16to32(const POINT* p16,POINT32* p32)
{
p32->x = p16->x;
p32->y = p16->y;
}
void STRUCT32_SIZE16to32(const SIZE* p16, SIZE32* p32)
{
p32->cx = p16->cx;
p32->cy = p16->cy;
}
void STRUCT32_MSG16to32(MSG *msg16,MSG32 *msg32)
{
msg32->hwnd=(DWORD)msg16->hwnd;
msg32->message=msg16->message;
msg32->wParam=msg16->wParam;
msg32->lParam=msg16->lParam;
msg32->time=msg16->time;
msg32->pt.x=msg16->pt.x;
msg32->pt.y=msg16->pt.y;
}
void STRUCT32_MSG32to16(MSG32 *msg32,MSG *msg16)
{
msg16->hwnd=(HWND)msg32->hwnd;
msg16->message=msg32->message;
msg16->wParam=msg32->wParam;
msg16->lParam=msg32->lParam;
msg16->time=msg32->time;
msg16->pt.x=msg32->pt.x;
msg16->pt.y=msg32->pt.y;
}
void STRUCT32_RECT32to16(const RECT32* r32,RECT *r16)
{
r16->left = r32->left;
r16->right = r32->right;
r16->top = r32->top;
r16->bottom = r32->bottom;
}
void STRUCT32_RECT16to32(const RECT* r16,RECT32 *r32)
{
r32->left = r16->left;
r32->right = r16->right;
r32->top = r16->top;
r32->bottom = r16->bottom;
}
void STRUCT32_MINMAXINFO32to16(const MINMAXINFO32 *from,MINMAXINFO *to)
{
STRUCT32_POINT32to16(&from->ptReserved,&to->ptReserved);
STRUCT32_POINT32to16(&from->ptMaxSize,&to->ptMaxSize);
STRUCT32_POINT32to16(&from->ptMaxPosition,&to->ptMaxPosition);
STRUCT32_POINT32to16(&from->ptMinTrackSize,&to->ptMinTrackSize);
STRUCT32_POINT32to16(&from->ptMaxTrackSize,&to->ptMaxTrackSize);
}
void STRUCT32_MINMAXINFO16to32(const MINMAXINFO *from,MINMAXINFO32 *to)
{
STRUCT32_POINT16to32(&from->ptReserved,&to->ptReserved);
STRUCT32_POINT16to32(&from->ptMaxSize,&to->ptMaxSize);
STRUCT32_POINT16to32(&from->ptMaxPosition,&to->ptMaxPosition);
STRUCT32_POINT16to32(&from->ptMinTrackSize,&to->ptMinTrackSize);
STRUCT32_POINT16to32(&from->ptMaxTrackSize,&to->ptMaxTrackSize);
}
void STRUCT32_WINDOWPOS32to16(const WINDOWPOS32* from,WINDOWPOS* to)
{
to->hwnd=from->hwnd;
to->hwndInsertAfter=from->hwndInsertAfter;
to->x=from->x;
to->y=from->y;
to->cx=from->cx;
to->flags=from->flags;
}
void STRUCT32_WINDOWPOS16to32(const WINDOWPOS* from,WINDOWPOS32* to)
{
to->hwnd=from->hwnd;
to->hwndInsertAfter=from->hwndInsertAfter;
to->x=from->x;
to->y=from->y;
to->cx=from->cx;
to->flags=from->flags;
}
void STRUCT32_NCCALCSIZE32to16Flat(const NCCALCSIZE_PARAMS32* from,
NCCALCSIZE_PARAMS* to)
{
STRUCT32_RECT32to16(from->rgrc,to->rgrc);
STRUCT32_RECT32to16(from->rgrc+1,to->rgrc+1);
STRUCT32_RECT32to16(from->rgrc+2,to->rgrc+2);
}
void STRUCT32_NCCALCSIZE16to32Flat(const NCCALCSIZE_PARAMS* from,
NCCALCSIZE_PARAMS32* to)
{
STRUCT32_RECT16to32(from->rgrc,to->rgrc);
STRUCT32_RECT16to32(from->rgrc+1,to->rgrc+1);
STRUCT32_RECT16to32(from->rgrc+2,to->rgrc+2);
}
/* The strings are not copied */
void STRUCT32_CREATESTRUCT32to16(const CREATESTRUCT32* from,CREATESTRUCT* to)
{
to->lpCreateParams = (LPVOID)from->lpCreateParams;
to->hInstance = from->hInstance;
to->hMenu = from->hMenu;
to->hwndParent = from->hwndParent;
to->cy = from->cy;
to->cx = from->cx;
to->y = from->y;
to->style = from->style;
to->dwExStyle = from->dwExStyle;
}
void STRUCT32_CREATESTRUCT16to32(const CREATESTRUCT* from,CREATESTRUCT32 *to)
{
to->lpCreateParams = (DWORD)from->lpCreateParams;
to->hInstance = from->hInstance;
to->hMenu = from->hMenu;
to->hwndParent = from->hwndParent;
to->cy = from->cy;
to->cx = from->cx;
to->y = from->y;
to->style = from->style;
to->dwExStyle = from->dwExStyle;
}
......@@ -24,45 +24,6 @@
#include "debug.h"
#include "stddebug.h"
/* Structure copy functions */
static void MSG16to32(MSG *msg16,struct WIN32_MSG *msg32)
{
msg32->hwnd=(DWORD)msg16->hwnd;
msg32->message=msg16->message;
msg32->wParam=msg16->wParam;
msg32->lParam=msg16->lParam;
msg32->time=msg16->time;
msg32->pt.x=msg16->pt.x;
msg32->pt.y=msg16->pt.y;
}
static void MSG32to16(struct WIN32_MSG *msg32,MSG *msg16)
{
msg16->hwnd=(HWND)msg32->hwnd;
msg16->message=msg32->message;
msg16->wParam=msg32->wParam;
msg16->lParam=msg32->lParam;
msg16->time=msg32->time;
msg16->pt.x=msg32->pt.x;
msg16->pt.y=msg32->pt.y;
}
void USER32_RECT32to16(const RECT32* r32,RECT *r16)
{
r16->left = r32->left;
r16->right = r32->right;
r16->top = r32->top;
r16->bottom = r32->bottom;
}
void USER32_RECT16to32(const RECT* r16,RECT32 *r32)
{
r32->left = r16->left;
r32->right = r16->right;
r32->top = r16->top;
r32->bottom = r16->bottom;
}
/***********************************************************************
* RegisterClassA (USER32.426)
*/
......@@ -113,19 +74,19 @@ ATOM USER32_RegisterClassA(WNDCLASSA* wndclass)
/***********************************************************************
* GetMessageA (USER32.269)
*/
BOOL USER32_GetMessageA(struct WIN32_MSG* lpmsg,DWORD hwnd,DWORD min,DWORD max)
BOOL USER32_GetMessageA(MSG32* lpmsg,DWORD hwnd,DWORD min,DWORD max)
{
BOOL ret;
MSG msg;
ret=GetMessage(MAKE_SEGPTR(&msg),(HWND)hwnd,min,max);
MSG16to32(&msg,lpmsg);
STRUCT32_MSG16to32(&msg,lpmsg);
return ret;
}
/***********************************************************************
* BeginPaint (USER32.9)
*/
HDC USER32_BeginPaint(DWORD hwnd,struct WIN32_PAINTSTRUCT *lpps)
HDC USER32_BeginPaint(DWORD hwnd,PAINTSTRUCT32 *lpps)
{
PAINTSTRUCT ps;
HDC ret;
......@@ -144,7 +105,7 @@ HDC USER32_BeginPaint(DWORD hwnd,struct WIN32_PAINTSTRUCT *lpps)
/***********************************************************************
* EndPaint (USER32.175)
*/
BOOL USER32_EndPaint(DWORD hwnd,struct WIN32_PAINTSTRUCT *lpps)
BOOL USER32_EndPaint(DWORD hwnd,PAINTSTRUCT32 *lpps)
{
PAINTSTRUCT ps;
ps.hdc=(HDC)lpps->hdc;
......@@ -162,23 +123,23 @@ BOOL USER32_EndPaint(DWORD hwnd,struct WIN32_PAINTSTRUCT *lpps)
/***********************************************************************
* DispatchMessageA (USER32.140)
*/
LONG USER32_DispatchMessageA(struct WIN32_MSG* lpmsg)
LONG USER32_DispatchMessageA(MSG32* lpmsg)
{
MSG msg;
LONG ret;
MSG32to16(lpmsg,&msg);
STRUCT32_MSG32to16(lpmsg,&msg);
ret=DispatchMessage(&msg);
MSG16to32(&msg,lpmsg);
STRUCT32_MSG16to32(&msg,lpmsg);
return ret;
}
/***********************************************************************
* TranslateMessage (USER32.555)
*/
BOOL USER32_TranslateMessage(struct WIN32_MSG* lpmsg)
BOOL USER32_TranslateMessage(MSG32* lpmsg)
{
MSG msg;
MSG32to16(lpmsg,&msg);
STRUCT32_MSG32to16(lpmsg,&msg);
return TranslateMessage(&msg);
}
......@@ -256,7 +217,7 @@ BOOL USER32_InvalidateRect(HWND hWnd,const RECT32 *lpRect,BOOL bErase)
if (lpRect == NULL)
InvalidateRect(hWnd, (RECT *)NULL, bErase);
else {
USER32_RECT32to16(lpRect,&r);
STRUCT32_RECT32to16(lpRect,&r);
InvalidateRect(hWnd,&r,bErase);
}
/* FIXME: Return meaningful value */
......@@ -269,7 +230,7 @@ BOOL USER32_InvalidateRect(HWND hWnd,const RECT32 *lpRect,BOOL bErase)
int USER32_DrawTextA(HDC hdc,LPCSTR lpStr,int count,RECT32* r32,UINT uFormat)
{
RECT r;
USER32_RECT32to16(r32,&r);
STRUCT32_RECT32to16(r32,&r);
return DrawText(hdc,lpStr,count,&r,uFormat);
}
......@@ -280,7 +241,7 @@ BOOL USER32_GetClientRect(HWND hwnd,RECT32 *r32)
{
RECT r;
GetClientRect(hwnd,&r);
USER32_RECT16to32(&r,r32);
STRUCT32_RECT16to32(&r,r32);
/* FIXME: return value */
return 0;
}
......
......@@ -146,30 +146,28 @@ static BOOL DCE_GetVisRect( WND *wndPtr, BOOL clientArea, RECT *lprect )
static HRGN DCE_ClipWindows( HWND hwndStart, HWND hwndEnd,
HRGN hrgn, int xoffset, int yoffset )
{
HRGN hrgnTmp = 0, hrgnNew = 0;
HRGN hrgnNew;
WND *wndPtr;
if (!hwndStart) return hrgn;
if (!(hrgnNew = CreateRectRgn( 0, 0, 0, 0 )))
{
if (hrgn) DeleteObject( hrgn );
return 0;
}
for (; hwndStart != hwndEnd; hwndStart = wndPtr->hwndNext)
{
hrgnTmp = hrgnNew = 0;
wndPtr = WIN_FindWndPtr( hwndStart );
if (!(wndPtr->dwStyle & WS_VISIBLE)) continue;
if (!(hrgnTmp = CreateRectRgn( 0, 0, 0, 0 ))) break;
if (!(hrgnNew = CreateRectRgn( wndPtr->rectWindow.left + xoffset,
wndPtr->rectWindow.top + yoffset,
wndPtr->rectWindow.right + xoffset,
wndPtr->rectWindow.bottom + yoffset )))
break;
if (!CombineRgn( hrgnTmp, hrgn, hrgnNew, RGN_DIFF )) break;
DeleteObject( hrgn );
DeleteObject( hrgnNew );
hrgn = hrgnTmp;
SetRectRgn( hrgnNew, wndPtr->rectWindow.left + xoffset,
wndPtr->rectWindow.top + yoffset,
wndPtr->rectWindow.right + xoffset,
wndPtr->rectWindow.bottom + yoffset );
if (!CombineRgn( hrgn, hrgn, hrgnNew, RGN_DIFF )) break;
}
if (hwndStart != hwndEnd) /* something went wrong */
{
if (hrgnTmp) DeleteObject( hrgnTmp );
if (hrgnNew) DeleteObject( hrgnNew );
DeleteObject( hrgnNew );
if (hrgn) DeleteObject( hrgn );
return 0;
}
......@@ -380,14 +378,8 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
if ((flags & DCX_INTERSECTRGN) || (flags & DCX_EXCLUDERGN))
{
HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
if (hrgn)
{
CombineRgn( hrgn, hrgnVisible, hrgnClip,
(flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
DeleteObject( hrgnVisible );
hrgnVisible = hrgn;
}
CombineRgn( hrgnVisible, hrgnVisible, hrgnClip,
(flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
}
SelectVisRgn( hdc, hrgnVisible );
DeleteObject( hrgnVisible );
......
......@@ -659,6 +659,9 @@ void DrawFocusRect( HDC hdc, const RECT* rc )
oldDrawMode = SetROP2(hdc, R2_XORPEN);
oldBkMode = SetBkMode(hdc, TRANSPARENT);
/* Hack: make sure the XORPEN operation has an effect */
dc->u.x.pen.pixel = (1 << screenDepth) - 1;
if (DC_SetupGCForPen( dc ))
XDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + left, dc->w.DCOrgY + top,
......
......@@ -20,6 +20,7 @@
#include <string.h>
#include <stdio.h>
#include <math.h>
#include "xmalloc.h"
#include "windows.h"
#include "win.h"
#include "nonclient.h"
......@@ -117,7 +118,7 @@ static BOOL MDI_MenuDeleteItem(WND* clientWnd, HWND hWndChild )
MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
WND *wndPtr = WIN_FindWndPtr(hWndChild);
LPSTR lpWndText;
INT index = 0,id,n;
UINT index = 0,id,n;
if( !clientInfo->nActiveChildren ||
!clientInfo->hWindowMenu ) return 0;
......@@ -198,17 +199,71 @@ HWND MDI_GetWindow(WND *clientWnd, HWND hWnd, WORD wTo )
/**********************************************************************
* MDISetMenu
* FIXME: This is not complete.
*/
HMENU MDISetMenu(HWND hwnd, BOOL fRefresh, HMENU hmenuFrame, HMENU hmenuWindow)
{
dprintf_mdi(stddeb, "WM_MDISETMENU: "NPFMT" %04x "NPFMT" "NPFMT"\n", hwnd, fRefresh, hmenuFrame, hmenuWindow);
if (!fRefresh) {
WND *w = WIN_FindWndPtr(hwnd);
MDICLIENTINFO *ci;
dprintf_mdi(stddeb, "WM_MDISETMENU: "NPFMT" %04x "NPFMT" "NPFMT"\n",
hwnd, fRefresh, hmenuFrame, hmenuWindow);
ci = (MDICLIENTINFO *) w->wExtra;
if (!fRefresh)
{
HWND hwndFrame = GetParent(hwnd);
HMENU oldFrameMenu = GetMenu(hwndFrame);
SetMenu(hwndFrame, hmenuFrame);
return oldFrameMenu;
}
if( ci->flagChildMaximized && hmenuFrame && hmenuFrame!=oldFrameMenu )
MDI_RestoreFrameMenu(w->hwndParent, ci->flagChildMaximized );
if( hmenuWindow && hmenuWindow!=ci->hWindowMenu )
{
/* delete menu items from ci->hWindowMenu
* and add them to hmenuWindow */
INT i = GetMenuItemCount(ci->hWindowMenu) - 1;
INT pos = GetMenuItemCount(hmenuWindow) + 1;
AppendMenu(hmenuWindow,MF_SEPARATOR,0,(SEGPTR)0);
if( ci->nActiveChildren )
{
INT j = i - ci->nActiveChildren + 1;
char buffer[100];
UINT id,state;
for( ; i >= j ; i-- )
{
id = GetMenuItemID(ci->hWindowMenu,i );
state = GetMenuState(ci->hWindowMenu,i,MF_BYPOSITION);
GetMenuString(ci->hWindowMenu, i, buffer, 100, MF_BYPOSITION);
DeleteMenu(ci->hWindowMenu, i , MF_BYPOSITION);
InsertMenu(hmenuWindow, pos, MF_BYPOSITION | MF_STRING,
id, MAKE_SEGPTR(buffer));
CheckMenuItem(hmenuWindow ,pos , MF_BYPOSITION | (state & MF_CHECKED));
}
}
/* remove separator */
DeleteMenu(ci->hWindowMenu, i, MF_BYPOSITION);
ci->hWindowMenu = hmenuWindow;
}
if( hmenuFrame && hmenuFrame!=oldFrameMenu)
{
SetMenu(hwndFrame, hmenuFrame);
if( ci->flagChildMaximized )
MDI_AugmentFrameMenu(ci,
w->hwndParent, ci->flagChildMaximized );
return oldFrameMenu;
}
}
return 0;
}
......@@ -236,11 +291,12 @@ HWND MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPARAM lParam )
HWND hwnd;
WORD wIDmenu = ci->idFirstChild + ci->nActiveChildren;
int spacing;
char chDef = '\0';
char* lpstrDef="junk!";
/*
* Create child window
*/
cs->style &= (WS_MINIMIZE | WS_MAXIMIZE | WS_HSCROLL | WS_VSCROLL);
/* The child windows should probably */
......@@ -250,8 +306,10 @@ HWND MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPARAM lParam )
cs->y = ci->nActiveChildren * spacing;
/* this menu is needed to set a check mark in MDI_ChildActivate */
AppendMenu(ci->hWindowMenu ,MF_STRING ,wIDmenu, MAKE_SEGPTR(&chDef) );
AppendMenu(ci->hWindowMenu ,MF_STRING ,wIDmenu, MAKE_SEGPTR(lpstrDef) );
ci->nActiveChildren++;
hwnd = CreateWindow( cs->szClass, cs->szTitle,
WS_CHILD | WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS |
WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU |
......@@ -262,12 +320,14 @@ HWND MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPARAM lParam )
if (hwnd)
{
ci->nActiveChildren++;
MDI_MenuModifyItem(w ,hwnd);
dprintf_mdi(stddeb, "MDICreateChild: created child - "NPFMT"\n",hwnd);
}
else
{
ci->nActiveChildren--;
DeleteMenu(ci->hWindowMenu,wIDmenu,MF_BYCOMMAND);
}
return hwnd;
}
......@@ -373,7 +433,7 @@ HWND MDIDestroyChild(WND *w_parent, MDICLIENTINFO *ci, HWND parent,
ci->nActiveChildren--;
/* WM_MDISETMENU ? */
dprintf_mdi(stddeb,"MDIDestroyChild: child destroyed - "NPFMT"\n",child);
if (flagDestroy)
{
......@@ -499,22 +559,8 @@ MDIWCL* MDI_BuildWCL(WND* clientWnd, int* iTotal)
childWnd = WIN_FindWndPtr( listTop->hChild );
while( childWnd && childWnd->hwndNext )
{
listNext = (MDIWCL*)malloc(sizeof(MDIWCL));
listNext = (MDIWCL*)xmalloc(sizeof(MDIWCL));
if( !listNext )
{
/* quit gracefully */
listNext = listTop->prev;
while( listTop )
{
listNext = listTop->prev;
free(listTop);
listTop = listNext;
}
dprintf_mdi(stddeb,"MDICascade: allocation failed\n");
return NULL;
}
if( (childWnd->dwStyle & WS_DISABLED) ||
(childWnd->dwStyle & WS_MINIMIZE) ||
!(childWnd->dwStyle & WS_VISIBLE) )
......@@ -921,6 +967,7 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
ci->hWindowMenu = ccs->hWindowMenu;
ci->idFirstChild = ccs->idFirstChild;
ci->flagChildMaximized = 0;
ci->nActiveChildren = 0;
ci->hFrameTitle = frameWnd->hText;
ci->sbStop = 0;
ci->self = hwnd;
......@@ -937,6 +984,8 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
NC_HandleNCCalcSize(hwnd, (NCCALCSIZE_PARAMS*) &rect);
w->rectClient = rect;
dprintf_mdi(stddeb,"MDI: Client created - hwnd = "NPFMT", idFirst = %u\n",hwnd,ci->idFirstChild);
return 0;
case WM_DESTROY:
......
......@@ -1075,9 +1075,9 @@ static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT pt )
SendMessage( hwnd, WM_EXITSIZEMOVE, 0, 0 );
SendMessage( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
/* Single click brings up the system menu */
/* Single click brings up the system menu when iconized */
if (!moved)
if (!moved && (wndPtr->dwStyle & WS_MINIMIZE))
{
NC_TrackSysMenu( hwnd, hdc, pt );
return;
......
......@@ -133,7 +133,7 @@ HBRUSH GetControlBrush( HWND hwnd, HDC hdc, WORD control )
*/
BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
{
HRGN tmpRgn, hrgn;
HRGN hrgn;
RECT rectClient;
WND * wndPtr;
......@@ -159,13 +159,10 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
{
if (wndPtr->hrgnUpdate) /* Is there already an update region? */
{
tmpRgn = CreateRectRgn( 0, 0, 0, 0 );
if ((hrgn = hrgnUpdate) == 0)
hrgn = CreateRectRgnIndirect( rectUpdate ? rectUpdate :
&rectClient );
CombineRgn( tmpRgn, wndPtr->hrgnUpdate, hrgn, RGN_OR );
DeleteObject( wndPtr->hrgnUpdate );
wndPtr->hrgnUpdate = tmpRgn;
CombineRgn( wndPtr->hrgnUpdate, wndPtr->hrgnUpdate, hrgn, RGN_OR );
if (!hrgnUpdate) DeleteObject( hrgn );
}
else /* No update region yet */
......@@ -197,17 +194,14 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
}
else
{
tmpRgn = CreateRectRgn( 0, 0, 0, 0 );
if ((hrgn = hrgnUpdate) == 0)
hrgn = CreateRectRgnIndirect( rectUpdate );
if (CombineRgn( tmpRgn, wndPtr->hrgnUpdate,
if (CombineRgn( wndPtr->hrgnUpdate, wndPtr->hrgnUpdate,
hrgn, RGN_DIFF ) == NULLREGION)
{
DeleteObject( tmpRgn );
tmpRgn = 0;
DeleteObject( wndPtr->hrgnUpdate );
wndPtr->hrgnUpdate = 0;
}
DeleteObject( wndPtr->hrgnUpdate );
wndPtr->hrgnUpdate = tmpRgn;
if (!hrgnUpdate) DeleteObject( hrgn );
}
if (!wndPtr->hrgnUpdate) /* No more update region */
......
......@@ -182,16 +182,10 @@ void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT rect, LPRECT clipRect)
HRGN hrgnInv = SCROLL_TraceChildren(hwnd,dx,dy,DCX_CLIPCHILDREN |
DCX_CLIPSIBLINGS );
if( hrgnInv )
{
HRGN hrgnCombine = CreateRectRgn(0,0,0,0);
CombineRgn(hrgnCombine,hrgnInv,hrgnUpdate,RGN_OR);
dprintf_scroll(stddeb,"ScrollWindow: hrgnComb="NPFMT" hrgnInv="NPFMT" hrgnUpd="NPFMT"\n",
hrgnCombine,hrgnInv,hrgnUpdate);
DeleteObject(hrgnUpdate); DeleteObject(hrgnInv);
hrgnUpdate = hrgnCombine;
}
{
CombineRgn(hrgnUpdate,hrgnInv,hrgnUpdate,RGN_OR);
DeleteObject(hrgnInv);
}
RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW);
}
......
......@@ -306,7 +306,7 @@ HWND CreateWindowEx( DWORD exStyle, SEGPTR className, SEGPTR windowName,
{
HANDLE class, hwnd;
CLASS *classPtr;
WND *wndPtr, *parentWndPtr;
WND *wndPtr;
POINT maxSize, maxPos, minTrack, maxTrack;
CREATESTRUCT createStruct;
int wmcreate;
......@@ -1207,13 +1207,17 @@ BOOL EnumTaskWindows( HTASK hTask, WNDENUMPROC lpEnumFunc, LPARAM lParam )
static BOOL WIN_EnumChildWin(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
{
WND *wndPtr;
HWND hwndN,hwndCh;
while (hwnd)
{
if (!(wndPtr=WIN_FindWndPtr(hwnd))) return 0;
hwndN=wndPtr->hwndNext; /* storing hwnd is a way to avoid.. */
hwndCh=wndPtr->hwndChild; /* ..side effects after wndenumprc */
if (!CallEnumWindowsProc( wndenumprc, hwnd, lParam )) return 0;
if (!WIN_EnumChildWin(wndPtr->hwndChild, wndenumprc, lParam)) return 0;
hwnd=wndPtr->hwndNext;
if (IsWindow(hwndCh)) /* to prevent too early termination */
if (!WIN_EnumChildWin(hwndCh, wndenumprc, lParam)) return 0;
hwnd=hwndN;
}
return 1;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment