From cdd092371095e78e7d10a366953b2ffacb1a1c60 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 12 Jan 1994 11:12:51 +0000 Subject: [PATCH] Release 0.6 Tue Jan 4 13:01:33 1994 David Metcalfe * [window/caret.c] Modified code to use system timer. Jan 9, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [windows/win.c] Windows create if required new XLIB MenuBar & CaptionBar. * [windows/defwnd.c] WM_CALCSIZE Move & Resize caption, menubar & scrollbars. (I'm not sure it's the good place for it, but it work...) * [loader/resource.c] optimize in FindResourceByNumber, make lseek() if next type ... * [controls/scroll.c] scrollbar buttons are now using system resources bitmaps. * [controls/caption.c] - new file ... captionbar showing title, close button with SysMenu, and other buttons using system resources bitmaps. * [controls/menu.c] New functions: SetMenuItemBitmaps() with 'glues', Make new version of LoadMenu() & ParseMenu(), ( put #define USE_POPUPMENU ). Implementation of MenuBar functions. * [sysres.dll] New bitmaps for system such OBM_CLOSE, OBM_MINIMIZE, OBM_UPARROWI. New SYSMENU menu, it don't work yet ! :-(( Tue Jan 11 05:27:45 1994 julliard@di.epfl.ch (Alexandre Julliard * [memory/atom.c] Fixed a bug that could cause atoms to be case-sensitive. * [misc/rect.c] Bug fix in SubtractRect(). * [objects/clipping.c] Bug fix when setting the clip mask to an empty region. * [windows/dce.c] Bug fix in ReleaseDC(). * [windows/dialog.c] Call AdjustWindowRectEx() before creating the dialog window. Added support for DS_MODALFRAME style. * [windows/event.c] Cleaned up event handling and removed old Xt stuff. Moved double-click handling to windows/message.c * [windows/focus.c] Bug fix: only set the X focus when the window is viewable. * [windows/graphics.c] Rewritten DrawReliefRect() to use brush instead of pen, and to use the system colors. * [windows/message.c] Implemented WM_NCHITTEST message sending, and non-client mouse messages. Cleaned up double-click handling, and removed the Xt code. * [windows/nonclient.c] (New file) Implemented AdjustWindowRect(). Implemented WM_NCCALCSIZE, WM_NCHITTEST and WM_NCPAINT handling. * [windows/painting.c] Added sending of the WM_NCPAINT message in BeginPaint(). * [windows/sysmetrics.c] [include/sysmetrics.h] (New files) Implemented system metrics. * [windows/win.c] Bug fix in setting the parent and owner in CreateWindow(). Removed the Xt code. * [windows/winpos.c] Added sending of the WM_NCPAINT message in SetWindowPos(). Removed the Xt code. --- ChangeLog | 88 +++- Makefile | 2 +- README | 8 + controls/Makefile | 3 +- controls/caption.c | 296 +++++++++++ controls/menu.c | 1117 ++++++++++++++++++++++++++++++++++++------ controls/scroll.c | 130 ++++- controls/widgets.c | 3 + debugger/info.c | 2 +- if1632/relay.c | 10 +- if1632/user.spec | 4 + include/caption.h | 17 + include/gdi.h | 7 +- include/menu.h | 9 +- include/sysmetrics.h | 55 +++ include/win.h | 8 +- include/windows.h | 136 ++++- include/wineopts.h | 11 + loader/resource.c | 65 ++- loader/wine.c | 120 +++-- memory/atom.c | 3 +- misc/Makefile | 2 +- misc/dos_fs.c | 2 +- misc/lstr.c | 2 +- misc/profile.c | 2 +- misc/rect.c | 8 +- misc/spy.c | 257 ++++++++++ misc/user.c | 6 +- misc/xt.c | 33 +- objects/brush.c | 2 - objects/clipping.c | 19 +- objects/dib.c | 2 +- objects/font.c | 3 - objects/gdiobj.c | 2 - objects/linedda.c | 2 +- objects/palette.c | 9 +- objects/pen.c | 3 - objects/text.c | 11 +- sysres.dll | Bin 86528 -> 108544 bytes test/widget.exe | Bin 306490 -> 310447 bytes windows/Makefile | 3 +- windows/caret.c | 75 +-- windows/dce.c | 14 +- windows/defwnd.c | 96 ++-- windows/dialog.c | 25 +- windows/event.c | 463 ++++++----------- windows/focus.c | 12 +- windows/graphics.c | 70 ++- windows/message.c | 174 ++++--- windows/nonclient.c | 461 +++++++++++++++++ windows/painting.c | 6 +- windows/sysmetrics.c | 81 +++ windows/win.c | 306 ++++-------- windows/winpos.c | 32 +- wine.ini | 37 +- 55 files changed, 3221 insertions(+), 1093 deletions(-) create mode 100644 controls/caption.c create mode 100644 include/caption.h create mode 100644 include/sysmetrics.h create mode 100644 include/wineopts.h create mode 100644 misc/spy.c create mode 100644 windows/nonclient.c create mode 100644 windows/sysmetrics.c diff --git a/ChangeLog b/ChangeLog index 151f65bfec9..5c2f74716ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,90 @@ +Tue Jan 4 13:01:33 1994 David Metcalfe + + * [window/caret.c] + Modified code to use system timer. + +Jan 9, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [windows/win.c] + Windows create if required new XLIB MenuBar & CaptionBar. + + * [windows/defwnd.c] + WM_CALCSIZE Move & Resize caption, menubar & scrollbars. + (I'm not sure it's the good place for it, but it work...) + + * [loader/resource.c] + optimize in FindResourceByNumber, make lseek() if next type ... + + * [controls/scroll.c] + scrollbar buttons are now using system resources bitmaps. + + * [controls/caption.c] - new file ... + captionbar showing title, close button with SysMenu, + and other buttons using system resources bitmaps. + + * [controls/menu.c] + New functions: SetMenuItemBitmaps() with 'glues', + Make new version of LoadMenu() & ParseMenu(), + ( put #define USE_POPUPMENU ). + Implementation of MenuBar functions. + + * [sysres.dll] + New bitmaps for system such OBM_CLOSE, OBM_MINIMIZE, OBM_UPARROWI. + New SYSMENU menu, it don't work yet ! :-(( + +Tue Jan 11 05:27:45 1994 julliard@di.epfl.ch (Alexandre Julliard + + * [memory/atom.c] + Fixed a bug that could cause atoms to be case-sensitive. + + * [misc/rect.c] + Bug fix in SubtractRect(). + + * [objects/clipping.c] + Bug fix when setting the clip mask to an empty region. + + * [windows/dce.c] + Bug fix in ReleaseDC(). + + * [windows/dialog.c] + Call AdjustWindowRectEx() before creating the dialog window. + Added support for DS_MODALFRAME style. + + * [windows/event.c] + Cleaned up event handling and removed old Xt stuff. + Moved double-click handling to windows/message.c + + * [windows/focus.c] + Bug fix: only set the X focus when the window is viewable. + + * [windows/graphics.c] + Rewritten DrawReliefRect() to use brush instead of pen, and + to use the system colors. + + * [windows/message.c] + Implemented WM_NCHITTEST message sending, and non-client + mouse messages. + Cleaned up double-click handling, and removed the Xt code. + + * [windows/nonclient.c] (New file) + Implemented AdjustWindowRect(). + Implemented WM_NCCALCSIZE, WM_NCHITTEST and WM_NCPAINT handling. + + * [windows/painting.c] + Added sending of the WM_NCPAINT message in BeginPaint(). + + * [windows/sysmetrics.c] [include/sysmetrics.h] (New files) + Implemented system metrics. + + * [windows/win.c] + Bug fix in setting the parent and owner in CreateWindow(). + Removed the Xt code. + + * [windows/winpos.c] + Added sending of the WM_NCPAINT message in SetWindowPos(). + Removed the Xt code. + +---------------------------------------------------------------------- Sun Jan 2 12:38:53 1994 David Metcalfe * [windows/class.c] @@ -101,7 +188,6 @@ Sat Jan 1 10:22:43 1994 Bob Amstadt (bob@pooh) * loader/wine.c: Added support for relocation types 5 and 6. ----------------------------------------------------------------------- Mon Dec 27 11:06:03 1993 Erik Bos (erik@trashcan.hacktic.nl) * [misc/comm.c] diff --git a/Makefile b/Makefile index 1f7221cbd49..21c7cab4a09 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ ###################################################################### # These variables are inherited by the sub-makefiles -DEBUGOPTS=-DUSE_XLIB +DEBUGOPTS= COPTS=-O2 -m486 INCLUDE_DIR=include LDFLAGS= diff --git a/README b/README index 1b090d42f7a..52863a7bf14 100644 --- a/README +++ b/README @@ -41,6 +41,14 @@ For example: to run Windows' solitaire: Have a nice game of solitaire, but be careful. Emulation isn't perfect. So, occassionally it will crash. +WHAT'S NEW with version 0.6: (see ChangeLog for details) + - Working towards elimination of Xt-dependent code. Thanks to + Alexandre and Martin. + - Other bug fixes. + - I added a rudimentary spy facility which can be turned + on from the wine.ini file. See the sample wine.ini + for details + WHAT'S NEW with version 0.5: (see ChangeLog for details) - Working towards elimination of Xt-dependent code. - StretchBlt() diff --git a/controls/Makefile b/controls/Makefile index 2f4c0812d01..520a1120766 100644 --- a/controls/Makefile +++ b/controls/Makefile @@ -1,6 +1,7 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR) -OBJS=menu.o widgets.o button.o scroll.o listbox.o combo.o static.o \ +OBJS = menu.o caption.o widgets.o button.o \ + scroll.o listbox.o combo.o static.o \ SmeMenuButto.o WinLabel.o WinCommand.o \ WinMenuButto.o diff --git a/controls/caption.c b/controls/caption.c new file mode 100644 index 00000000000..68283a77dee --- /dev/null +++ b/controls/caption.c @@ -0,0 +1,296 @@ +/* + * Interface code to CAPTION widget + * + * Copyright Martin Ayotte, 1994 + * + */ + +/* +#define DEBUG_CAPTION +*/ + +static char Copyright[] = "Copyright Martin Ayotte, 1994"; + +#include +#include +#include "windows.h" +#include "caption.h" +#include "heap.h" +#include "win.h" +#include +#include +#include + +HBITMAP hStdClose = (HBITMAP)NULL; +HBITMAP hStdCloseD = (HBITMAP)NULL; +HBITMAP hStdMinim = (HBITMAP)NULL; +HBITMAP hStdMinimD = (HBITMAP)NULL; +HBITMAP hStdMaxim = (HBITMAP)NULL; +HBITMAP hStdMaximD = (HBITMAP)NULL; +HMENU hStdSysMenu = (HMENU)NULL; + +LPHEADCAPTION CaptionBarGetWindowAndStorage(HWND hWnd, WND **wndPtr); +LPHEADCAPTION CaptionBarGetStorageHeader(HWND hWnd); +void SetMenuLogicalParent(HMENU hMenu, HWND hWnd); + + +/*********************************************************************** + * CaptionBarWndProc + */ +LONG CaptionBarWndProc( HWND hWnd, WORD message, WORD wParam, LONG lParam ) +{ + WORD wRet; + short x, y; + short width, height; + WND *wndPtr; + LPHEADCAPTION lphs; + PAINTSTRUCT ps; + HDC hDC; + HDC hMemDC; + BITMAP bm; + RECT rect; + char str[128]; + switch(message) + { + case WM_CREATE: + wndPtr = WIN_FindWndPtr(hWnd); + lphs = (LPHEADCAPTION)malloc(sizeof(HEADCAPTION)); + if (lphs == 0) { + printf("Bad Memory Alloc on CAPTIONBAR !\n"); + return 0; + } + memset(lphs, 0, sizeof(HEADCAPTION)); +#ifdef DEBUG_CAPTION + printf("CreateCaptionBarStruct %lX !\n", lphs); +#endif + *((LPHEADCAPTION *)&wndPtr->wExtra[1]) = lphs; + if (hStdClose == (HBITMAP)NULL) + hStdClose = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_CLOSE)); + lphs->hClose = hStdClose; + if (hStdMinim == (HBITMAP)NULL) + hStdMinim = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_REDUCE)); + lphs->hMinim = hStdMinim; + if (hStdMaxim == (HBITMAP)NULL) + hStdMaxim = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RESTORE)); + lphs->hMaxim = hStdMaxim; + if (hStdCloseD == (HBITMAP)NULL) + hStdCloseD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_CLOSE)); + if (hStdMinimD == (HBITMAP)NULL) + hStdMinimD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_REDUCED)); + if (hStdMaximD == (HBITMAP)NULL) + hStdMaximD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RESTORED)); + if (hStdSysMenu == (HBITMAP)NULL) + hStdSysMenu = LoadMenu((HINSTANCE)NULL, "SYSMENU"); + lphs->hSysMenu = hStdSysMenu; + printf("CaptionBar SYSMENU %04X !\n", lphs->hSysMenu); + if (lphs->hSysMenu == 0) lphs->hSysMenu = CreatePopupMenu(); + AppendMenu(lphs->hSysMenu, MF_STRING, 9999, "About &Wine ..."); + GetClientRect(hWnd, &rect); + CopyRect(&lphs->rectClose, &rect); + CopyRect(&lphs->rectMaxim, &rect); + lphs->rectClose.right = lphs->rectClose.left + + lphs->rectClose.bottom + lphs->rectClose.top; + lphs->rectMaxim.left = lphs->rectMaxim.right - + lphs->rectMaxim.bottom + lphs->rectMaxim.top; + CopyRect(&lphs->rectMinim, &lphs->rectMaxim); + if (lphs->hMaxim != 0) { + lphs->rectMinim.left = lphs->rectMaxim.bottom + lphs->rectMaxim.top; + lphs->rectMinim.right = lphs->rectMaxim.bottom + lphs->rectMaxim.top; + } + if (lphs->hClose == 0) lphs->rectClose.right = lphs->rectClose.left; + printf("CAPTION Close.right=%d Maxim.left=%d Minim.left=%d !\n", + lphs->rectClose.right, lphs->rectMaxim.left, lphs->rectMinim.left); + return 0; + case WM_DESTROY: + lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr); + if (lphs == 0) return 0; +#ifdef DEBUG_CAPTION + printf("CaptionBar WM_DESTROY %lX !\n", lphs); +#endif + DestroyMenu(lphs->hSysMenu); + free(lphs); + *((LPHEADCAPTION *)&wndPtr->wExtra[1]) = 0; + return 0; + case WM_COMMAND: +#ifdef DEBUG_CAPTION + printf("CaptionBar WM_COMMAND %04X %08X !\n", wParam, lParam); +#endif + lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr); + if (wParam == 9999) { + printf("CaptionBar Show 'About Wine ...' !\n"); + } + SendMessage(wndPtr->hwndParent, message, wParam, lParam); + break; + case WM_SIZE: + lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr); + width = LOWORD(lParam); + height = HIWORD(lParam); + if (lphs->hClose != 0) + SetRect(&lphs->rectClose, 0, 0, height, height); + if (lphs->hMinim != 0) { + if (lphs->hMaxim != 0) + SetRect(&lphs->rectMinim, width - 2 * height, 0, + width - height, height); + else + SetRect(&lphs->rectMinim, width - height, 0, width, height); + } + if (lphs->hMaxim != 0) + SetRect(&lphs->rectMaxim, width - height, 0, width, height); + break; + case WM_LBUTTONDOWN: + lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr); + SetCapture(hWnd); + x = LOWORD(lParam); + y = HIWORD(lParam); + hDC = GetDC(hWnd); + if (x > lphs->rectClose.left && x < lphs->rectClose.right) { + lphs->hClose = hStdCloseD; + InvalidateRect(hWnd, &lphs->rectClose, TRUE); + UpdateWindow(hWnd); + } + if (x > lphs->rectMinim.left && x < lphs->rectMinim.right) { + lphs->hMinim = hStdMinimD; + InvalidateRect(hWnd, &lphs->rectMinim, TRUE); + UpdateWindow(hWnd); + } + if (x > lphs->rectMaxim.left && x < lphs->rectMaxim.right && + lphs->hMaxim != 0) { + lphs->hMaxim = hStdMaximD; + InvalidateRect(hWnd, &lphs->rectMaxim, TRUE); + UpdateWindow(hWnd); + } + ReleaseDC(hWnd, hDC); + break; + case WM_LBUTTONUP: + lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr); + ReleaseCapture(); +#ifdef DEBUG_CAPTION + printf("CaptionBar WM_LBUTTONUP %lX !\n", lParam); +#endif + x = LOWORD(lParam); + y = HIWORD(lParam); + if (x > lphs->rectClose.left && x < lphs->rectClose.right) { + lphs->hClose = hStdClose; + InvalidateRect(hWnd, &lphs->rectClose, TRUE); + UpdateWindow(hWnd); + TrackPopupMenu(lphs->hSysMenu, TPM_LEFTBUTTON, 0, -20, + 0, wndPtr->hwndParent, (LPRECT)NULL); + SetMenuLogicalParent(lphs->hSysMenu, hWnd); + printf("CAPTION Pop the SYSMENU !\n"); + break; + } + if (x > lphs->rectMinim.left && x < lphs->rectMinim.right) { + SendMessage(wndPtr->hwndParent, WM_SYSCOMMAND, SC_MINIMIZE, 0L); + lphs->hMinim = hStdMinim; + InvalidateRect(hWnd, &lphs->rectMinim, TRUE); + UpdateWindow(hWnd); + printf("CAPTION Minimize Window !\n"); + break; + } + if (x > lphs->rectMaxim.left && x < lphs->rectMaxim.right) { + lphs->hMaxim = hStdMaxim; + InvalidateRect(hWnd, &lphs->rectMaxim, TRUE); + UpdateWindow(hWnd); + SendMessage(wndPtr->hwndParent, WM_SYSCOMMAND, SC_MAXIMIZE, 0L); + printf("CAPTION Maximize Window !\n"); + break; + } + break; + + case WM_LBUTTONDBLCLK: + lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr); +#ifdef DEBUG_CAPTION + printf("CaptionBar WM_LBUTTONDBLCLK %lX !\n", lParam); +#endif + x = LOWORD(lParam); + y = HIWORD(lParam); + if (x > lphs->rectClose.left && x < lphs->rectClose.right) { + SendMessage(wndPtr->hwndParent, WM_SYSCOMMAND, SC_CLOSE, 0L); + printf("CAPTION DoubleClick Close Window !\n"); + break; + } + break; + + case WM_KEYDOWN: + case WM_KEYUP: + case WM_CHAR: + lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr); + return(SendMessage(wndPtr->hwndParent, message, wParam, lParam)); + + case WM_PAINT: + GetWindowRect(hWnd, &rect); +#ifdef DEBUG_CAPTION + printf("CaptionBar WM_PAINT left=%d top=%d right=%d bottom=%d !\n", + rect.left, rect.top, rect.right, rect.bottom); +#endif + lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr); + hDC = BeginPaint(hWnd, &ps); + hMemDC = CreateCompatibleDC(hDC); + if (lphs->hClose != 0) { + GetObject(lphs->hClose, sizeof(BITMAP), (LPSTR)&bm); + SelectObject(hMemDC, lphs->hClose); + BitBlt(hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + } + if (lphs->hMinim != 0) { + GetObject(lphs->hMinim, sizeof(BITMAP), (LPSTR)&bm); + SelectObject(hMemDC, lphs->hMinim); + BitBlt(hDC, lphs->rectMinim.left, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + } + if (lphs->hMaxim != 0) { + GetObject(lphs->hMaxim, sizeof(BITMAP), (LPSTR)&bm); + SelectObject(hMemDC, lphs->hMaxim); + BitBlt(hDC, lphs->rectMaxim.left, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + } + DeleteDC(hMemDC); + GetClientRect(hWnd, &rect); + FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH)); + rect.left = lphs->rectClose.right; + rect.right = lphs->rectMinim.left; +#ifdef DEBUG_CAPTION + printf("CaptionBar WM_PAINT left=%d top=%d right=%d bottom=%d !\n", + rect.left, rect.top, rect.right, rect.bottom); +#endif + FillRect(hDC, &rect, GetStockObject(GRAY_BRUSH)); + if (GetWindowTextLength(wndPtr->hwndParent) > 0) { + GetWindowText(wndPtr->hwndParent, str, sizeof(str)); + width = GetTextExtent(hDC, str, strlen(str)); + DrawText(hDC, str, -1, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); + } + EndPaint(hWnd, &ps); + break; + default: + return DefWindowProc( hWnd, message, wParam, lParam ); + } +return(0); +} + + + +LPHEADCAPTION CaptionBarGetWindowAndStorage(HWND hWnd, WND **wndPtr) +{ + WND *Ptr; + LPHEADCAPTION lphs; + *(wndPtr) = Ptr = WIN_FindWndPtr(hWnd); + if (Ptr == 0) { + printf("Bad Window handle on CaptionBar !\n"); + return 0; + } + lphs = *((LPHEADCAPTION *)&Ptr->wExtra[1]); + return lphs; +} + + +LPHEADCAPTION CaptionBarGetStorageHeader(HWND hWnd) +{ + WND *wndPtr; + LPHEADCAPTION lphs; + wndPtr = WIN_FindWndPtr(hWnd); + if (wndPtr == 0) { + printf("Bad Window handle on CaptionBar !\n"); + return 0; + } + lphs = *((LPHEADCAPTION *)&wndPtr->wExtra[1]); + return lphs; +} + + diff --git a/controls/menu.c b/controls/menu.c index c1cd758484d..4a01b2fff4e 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -1,7 +1,11 @@ static char RCSId[] = "$Id$"; static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; +static char Copyright2[] = "Copyright Martin Ayotte, 1993"; +/* #define DEBUG_MENU +*/ +#define USE_POPUPMENU #include #include @@ -17,6 +21,9 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "bitmaps/check_bitmap" #include "bitmaps/nocheck_bitmap" +HBITMAP hStdCheck = 0; +HBITMAP hStdMnArrow = 0; + static LPMENUBAR firstMenu = NULL; static MENUITEM *parentItem; static MENUITEM *siblingItem; @@ -27,9 +34,19 @@ static Pixmap nocheckBitmap = XtUnspecifiedPixmap; LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd); LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr); +void StdDrawMenuBar(HWND hwnd); void StdDrawPopupMenu(HWND hwnd); -LPMENUITEM PopupMenuFindItem(HWND hwnd, int x, int y, WORD *lpRet); +LPMENUITEM MenuFindItem(HWND hwnd, int x, int y, WORD *lpRet); +LPMENUITEM MenuFindItemBySelKey(HWND hwnd, WORD key, WORD *lpRet); +void PopupMenuCalcSize(HWND hwnd); +void MenuBarCalcSize(HWND hwnd); LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos); +WORD GetSelectionKey(LPSTR str); +LPSTR GetShortCutString(LPSTR str); +WORD GetShortCutPos(LPSTR str); +BOOL HideAllSubPopupMenu(LPPOPUPMENU menu); +WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu); +void SetMenuLogicalParent(HMENU hMenu, HWND hWnd); /*********************************************************************** * PopupMenuWndProc @@ -40,7 +57,7 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) WORD wRet; short x, y; WND *wndPtr; - LPPOPUPMENU lppop; + LPPOPUPMENU lppop, lppop2; LPMENUITEM lpitem, lpitem2; HMENU hSubMenu; RECT rect; @@ -53,12 +70,30 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) #endif createStruct = (CREATESTRUCT *)lParam; lppop = (LPPOPUPMENU)createStruct->lpCreateParams; - if (lppop == 0) break; + if (lppop == NULL) break; wndPtr = WIN_FindWndPtr(hwnd); *((LPPOPUPMENU *)&wndPtr->wExtra[1]) = lppop; #ifdef DEBUG_MENU printf("PopupMenu WM_CREATE lppop=%08X !\n", lppop); #endif +/* + if (lppop->BarFlags == 0) { + PopupMenuCalcSize(hwnd); + printf("PopupMenu WM_CREATE Width=%d Height=%d !\n", + lppop->Width, lppop->Height); + SetWindowPos(hwnd, 0, 0, 0, lppop->Width + 2, lppop->Height, + SWP_NOZORDER | SWP_NOMOVE); + } + else { + MenuBarCalcSize(hwnd); + SetWindowPos(hwnd, 0, 0, -16, lppop->Width, lppop->Height, + SWP_NOZORDER); + } +*/ + if (hStdCheck == (HBITMAP)NULL) + hStdCheck = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_CHECK); + if (hStdMnArrow == (HBITMAP)NULL) + hStdMnArrow = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_MNARROW); return 0; case WM_DESTROY: lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); @@ -66,29 +101,56 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) printf("PopupMenu WM_DESTROY %lX !\n", lppop); #endif return 0; - + case WM_COMMAND: + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); +#ifdef DEBUG_MENU + printf("PopupMenu // push to lower parent WM_COMMAND !\n"); +#endif + if (lppop->hWndParent != (HWND)NULL) + SendMessage(lppop->hWndParent, WM_COMMAND, wParam, lParam); + else + SendMessage(lppop->ownerWnd, WM_COMMAND, wParam, lParam); + if (lppop->BarFlags == 0) ShowWindow(hwnd, SW_HIDE); + break; + case WM_SHOWWINDOW: + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (wParam == 0) { + HideAllSubPopupMenu(lppop); +#ifdef DEBUG_MENU + printf("PopupMenu WM_SHOWWINDOW -> HIDE!\n"); +#endif + break; + } + lppop->FocusedItem = (WORD)-1; + if (lppop->BarFlags == 0) { + PopupMenuCalcSize(hwnd); +#ifdef DEBUG_MENU + printf("PopupMenu WM_SHOWWINDOW Width=%d Height=%d !\n", + lppop->Width, lppop->Height); +#endif + SetWindowPos(hwnd, 0, 0, 0, lppop->Width + 2, lppop->Height, + SWP_NOZORDER | SWP_NOMOVE); + } + else { + MenuBarCalcSize(hwnd); +#ifdef DEBUG_MENU + printf("MenuBarMenu WM_SHOWWINDOW Width=%d Height=%d !\n", + lppop->Width, lppop->Height); +#endif + SetWindowPos(hwnd, 0, 0, -16, lppop->Width, lppop->Height, + SWP_NOZORDER); + } + break; case WM_LBUTTONDOWN: lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); SetCapture(hwnd); - lpitem = PopupMenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet); + lpitem = MenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet); +#ifdef DEBUG_MENU printf("PopupMenu WM_LBUTTONDOWN wRet=%d lpitem=%08X !\n", wRet, lpitem); - if (lpitem != NULL) { - lppop->FocusedItem = wRet; - if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && - ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { - hDC = GetDC(hwnd); - InvertRect(hDC, &lpitem->rect); - ReleaseDC(hwnd, hDC); - } - } - break; - case WM_LBUTTONUP: - lppop = PopupMenuGetStorageHeader(hwnd); - ReleaseCapture(); - lpitem = PopupMenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet); - printf("PopupMenu WM_LBUTTONUP wRet=%d lpitem=%08X !\n", wRet, lpitem); +#endif if (lpitem != NULL) { if (lppop->FocusedItem != (WORD)-1) { + HideAllSubPopupMenu(lppop); lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); if (((lpitem2->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && ((lpitem2->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { @@ -97,32 +159,79 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) ReleaseDC(hwnd, hDC); } } + lppop->FocusedItem = wRet; + if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + hDC = GetDC(hwnd); + InvertRect(hDC, &lpitem->rect); + ReleaseDC(hwnd, hDC); + } if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { hSubMenu = (HMENU)lpitem->item_id; - printf("ShowSubmenu hSubMenu=%04X !\n", hSubMenu); + lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); + if (lppop2 == NULL) break; + lppop2->hWndParent = hwnd; GetClientRect(hwnd, &rect); - x = rect.right; - GetWindowRect(hwnd, &rect); - x += rect.left; - TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, - x, rect.top + HIWORD(lParam), + if (lppop->BarFlags != 0) { + y = rect.bottom - rect.top; + TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, + lpitem->rect.left, 0, 0, lppop->ownerWnd, (LPRECT)NULL); + } + else { + x = rect.right; + GetWindowRect(hwnd, &rect); + x += rect.left; + TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, + x, lpitem->rect.top, + 0, lppop->ownerWnd, (LPRECT)NULL); + } + break; + } + } + break; + case WM_LBUTTONUP: + lppop = PopupMenuGetStorageHeader(hwnd); + ReleaseCapture(); + lpitem = MenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet); +#ifdef DEBUG_MENU + printf("PopupMenu WM_LBUTTONUP wRet=%d lpitem=%08X !\n", wRet, lpitem); +#endif + if (lpitem != NULL) { + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { break; } if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) { - SendMessage(lppop->ownerWnd, WM_COMMAND, lpitem->item_id, 0L); + ShowWindow(lppop->hWnd, SW_HIDE); + if (lppop->hWndParent != (HWND)NULL) + SendMessage(lppop->hWndParent, WM_COMMAND, + lpitem->item_id, 0L); + else + SendMessage(lppop->ownerWnd, WM_COMMAND, + lpitem->item_id, 0L); +#ifdef DEBUG_MENU printf("PopupMenu // SendMessage WM_COMMAND wParam=%d !\n", lpitem->item_id); - ShowWindow(lppop->hWnd, SW_HIDE); +#endif break; } } + if (lppop->FocusedItem != (WORD)-1) { + HideAllSubPopupMenu(lppop); + lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); + if (((lpitem2->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem2->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + hDC = GetDC(hwnd); + InvertRect(hDC, &lpitem2->rect); + ReleaseDC(hwnd, hDC); + } + } break; case WM_MOUSEMOVE: if ((wParam & MK_LBUTTON) != 0) { lppop = PopupMenuGetStorageHeader(hwnd); - lpitem = PopupMenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet); + lpitem = MenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet); if ((lpitem != NULL) && (lppop->FocusedItem != wRet)) { lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); hDC = GetDC(hwnd); @@ -130,9 +239,27 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) ((lpitem2->item_flags & MF_STRING) == MF_STRING)) { InvertRect(hDC, &lpitem2->rect); } + if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP) { + HideAllSubPopupMenu(lppop); + } lppop->FocusedItem = wRet; - printf("PopupMenu WM_MOUSEMOVE wRet=%d lpitem=%08X !\n", wRet, lpitem); - InvertRect(hDC, &lpitem->rect); + if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || + ((lpitem->item_flags & MF_STRING) == MF_STRING)) { + InvertRect(hDC, &lpitem->rect); + } + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { + hSubMenu = (HMENU)lpitem->item_id; + lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); + if (lppop2 == NULL) break; + if (lppop->BarFlags != 0) { + lppop2->hWndParent = hwnd; + GetClientRect(hwnd, &rect); + y = rect.bottom - rect.top; + TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, + lpitem->rect.left, 0, + 0, lppop->ownerWnd, (LPRECT)NULL); + } + } ReleaseDC(hwnd, hDC); } } @@ -140,13 +267,203 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) case WM_KEYDOWN: case WM_KEYUP: - case WM_CHAR: + if (lParam < 0L) break; lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); - return(SendMessage(wndPtr->hwndParent, message, wParam, lParam)); - + if (lppop->FocusedItem == (WORD)-1) { + if (wParam == VK_UP || wParam == VK_DOWN || + wParam == VK_LEFT || wParam == VK_RIGHT) { + hDC = GetDC(hwnd); + lppop->FocusedItem = 0; + lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); + if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || + ((lpitem->item_flags & MF_STRING) == MF_STRING)) { + InvertRect(hDC, &lpitem->rect); + } + ReleaseDC(hwnd, hDC); + } + break; + } + switch(wParam) { + case VK_UP: + if (lppop->BarFlags != 0) break; + if (lppop->FocusedItem < 1) break; + lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) + HideAllSubPopupMenu(lppop); + hDC = GetDC(hwnd); + if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || + ((lpitem->item_flags & MF_STRING) == MF_STRING)) { + InvertRect(hDC, &lpitem->rect); + } + lppop->FocusedItem--; + lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); + if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || + ((lpitem->item_flags & MF_STRING) == MF_STRING)) { + InvertRect(hDC, &lpitem->rect); + } + ReleaseDC(hwnd, hDC); + break; + case VK_DOWN: + if (lppop->BarFlags != 0) goto ProceedSPACE; + if (lppop->FocusedItem >= lppop->nItems - 1) break; + lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) + HideAllSubPopupMenu(lppop); + hDC = GetDC(hwnd); + if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || + ((lpitem->item_flags & MF_STRING) == MF_STRING)) { + InvertRect(hDC, &lpitem->rect); + } + lppop->FocusedItem++; + lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); + if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || + ((lpitem->item_flags & MF_STRING) == MF_STRING)) { + InvertRect(hDC, &lpitem->rect); + } + ReleaseDC(hwnd, hDC); + break; + case VK_LEFT: + if (lppop->BarFlags == 0) { + if (lppop->hWndParent != 0) + SendMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam); + break; + } + if (lppop->FocusedItem < 1) break; + lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) + HideAllSubPopupMenu(lppop); + hDC = GetDC(hwnd); + if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || + ((lpitem->item_flags & MF_STRING) == MF_STRING)) { + InvertRect(hDC, &lpitem->rect); + } + lppop->FocusedItem--; + lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); + if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || + ((lpitem->item_flags & MF_STRING) == MF_STRING)) { + InvertRect(hDC, &lpitem->rect); + } + ReleaseDC(hwnd, hDC); + break; + case VK_RIGHT: + if (lppop->BarFlags == 0) { + if (lppop->hWndParent != 0) + SendMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam); + break; + } + if (lppop->FocusedItem >= lppop->nItems - 1) break; + lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) + HideAllSubPopupMenu(lppop); + hDC = GetDC(hwnd); + if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || + ((lpitem->item_flags & MF_STRING) == MF_STRING)) { + InvertRect(hDC, &lpitem->rect); + } + lppop->FocusedItem++; + lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); + if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || + ((lpitem->item_flags & MF_STRING) == MF_STRING)) { + InvertRect(hDC, &lpitem->rect); + } + ReleaseDC(hwnd, hDC); + break; + case VK_RETURN: + case VK_SPACE: +ProceedSPACE: + printf("PopupMenu VK_SPACE !\n"); + lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { + hSubMenu = (HMENU)lpitem->item_id; + lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); + if (lppop2 == NULL) break; + lppop2->hWndParent = hwnd; + GetClientRect(hwnd, &rect); + if (lppop->BarFlags != 0) { + y = rect.bottom - rect.top; + TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, + lpitem->rect.left, 0, + 0, lppop->ownerWnd, (LPRECT)NULL); + } + else { + x = rect.right; + GetWindowRect(hwnd, &rect); + x += rect.left; + TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, + x, lpitem->rect.top, + 0, lppop->ownerWnd, (LPRECT)NULL); + } + break; + } + if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) { + ShowWindow(lppop->hWnd, SW_HIDE); + if (lppop->hWndParent != (HWND)NULL) + SendMessage(lppop->hWndParent, WM_COMMAND, + lpitem->item_id, 0L); + else + SendMessage(lppop->ownerWnd, WM_COMMAND, + lpitem->item_id, 0L); +#ifdef DEBUG_MENU + printf("PopupMenu // SendMessage WM_COMMAND wParam=%d !\n", + lpitem->item_id); +#endif + } + break; + } + break; + case WM_CHAR: + if (lParam < 0L) break; + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (wParam == VK_ESCAPE) { + if (lppop->hWndParent != 0) { + lppop2 = PopupMenuGetWindowAndStorage( + lppop->hWndParent, &wndPtr); + HideAllSubPopupMenu(lppop2); + break; + } + if (lppop->FocusedItem != (WORD)-1) { + lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); + hDC = GetDC(hwnd); + if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) || + ((lpitem2->item_flags & MF_STRING) == MF_STRING)) { + InvertRect(hDC, &lpitem2->rect); + } + ReleaseDC(hwnd, hDC); + lppop->FocusedItem = (WORD)-1; + } + } + if (wParam >= 'a' && wParam <= 'z') wParam -= 'a' - 'A'; + lpitem = MenuFindItemBySelKey(hwnd, wParam, &wRet); + if (lpitem != NULL) { + printf("Found wRet=%d !\n", wRet); + if (lppop->FocusedItem != (WORD)-1) { + lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); + if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP) + HideAllSubPopupMenu(lppop); + hDC = GetDC(hwnd); + if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) || + ((lpitem2->item_flags & MF_STRING) == MF_STRING)) { + InvertRect(hDC, &lpitem2->rect); + } + ReleaseDC(hwnd, hDC); + } + lppop->FocusedItem = wRet; + goto ProceedSPACE; + } + break; case WM_PAINT: - printf("PopupMenu WM_PAINT !\n"); - StdDrawPopupMenu(hwnd); + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop->BarFlags != 0) { + MenuBarCalcSize(hwnd); + printf("PopupMenu WM_PAINT Width=%d Height=%d !\n", + lppop->Width, lppop->Height); + StdDrawMenuBar(hwnd); + } + else{ + PopupMenuCalcSize(hwnd); + StdDrawPopupMenu(hwnd); + } break; default: return DefWindowProc( hwnd, message, wParam, lParam ); @@ -184,6 +501,14 @@ LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd) } +void SetMenuLogicalParent(HMENU hMenu, HWND hWnd) +{ + LPPOPUPMENU lppop; + lppop = (LPPOPUPMENU)GlobalLock(hMenu); + lppop->hWndParent = hWnd; +} + + void StdDrawPopupMenu(HWND hwnd) { WND *wndPtr; @@ -195,9 +520,11 @@ void StdDrawPopupMenu(HWND hwnd) HWND hWndParent; HDC hDC, hMemDC; RECT rect, rect2, rect3; + DWORD OldTextColor; + HFONT hOldFont; HBITMAP hBitMap; BITMAP bm; - UINT i; + UINT i, x; hDC = BeginPaint( hwnd, &ps ); if (!IsWindowVisible(hwnd)) { EndPaint( hwnd, &ps ); @@ -205,55 +532,82 @@ void StdDrawPopupMenu(HWND hwnd) } lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); if (lppop == NULL) goto EndOfPaint; - hBrush = SendMessage(lppop->ownerWnd, WM_CTLCOLOR, (WORD)hDC, - MAKELONG(hwnd, CTLCOLOR_LISTBOX)); - if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH); + hBrush = GetStockObject(WHITE_BRUSH); GetClientRect(hwnd, &rect); GetClientRect(hwnd, &rect2); FillRect(hDC, &rect, hBrush); + FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH)); if (lppop->nItems == 0) goto EndOfPaint; - lpitem = lppop->firstItem->next; + lpitem = lppop->firstItem; if (lpitem == NULL) goto EndOfPaint; for(i = 0; i < lppop->nItems; i++) { if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) { - rect2.bottom = rect2.top + 3; - CopyRect(&lpitem->rect, &rect2); - hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN)); + CopyRect(&rect2, &lpitem->rect); + hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN)); MoveTo(hDC, rect2.left, rect2.top + 1); LineTo(hDC, rect2.right, rect2.top + 1); SelectObject(hDC, hOldPen); - rect2.top += 3; } if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { - hBitMap = (HBITMAP)LOWORD(lpitem->item_text); - rect2.bottom = rect2.top + bm.bmHeight; - CopyRect(&lpitem->rect, &rect2); + hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); + CopyRect(&rect2, &lpitem->rect); hMemDC = CreateCompatibleDC(hDC); SelectObject(hMemDC, hBitMap); GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); BitBlt(hDC, rect2.left, rect2.top, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); DeleteDC(hMemDC); - rect2.top += bm.bmHeight; } if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { - rect2.bottom = rect2.top + 15; - CopyRect(&lpitem->rect, &rect2); - TextOut(hDC, rect2.left + 5, rect2.top + 2, - (char *)lpitem->item_text, strlen((char *)lpitem->item_text)); - rect2.top += 15; + hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); + if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED) + OldTextColor = SetTextColor(hDC, 0x00C0C0C0L); + else + OldTextColor = SetTextColor(hDC, 0x00000000L); + CopyRect(&rect3, &lpitem->rect); + InflateRect(&rect3, 0, -2); + if ((x = GetShortCutPos(lpitem->item_text)) != (WORD)-1) { + DrawText(hDC, lpitem->item_text, x, &rect3, + DT_LEFT | DT_VCENTER | DT_SINGLELINE); + DrawText(hDC, &lpitem->item_text[x], -1, &rect3, + DT_RIGHT | DT_VCENTER | DT_SINGLELINE); + } + else + DrawText(hDC, lpitem->item_text, -1, &rect3, + DT_LEFT | DT_VCENTER | DT_SINGLELINE); + SetTextColor(hDC, OldTextColor); + SelectObject(hDC, hOldFont); + CopyRect(&rect2, &lpitem->rect); } if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) { CopyRect(&rect3, &rect2); rect3.left = rect3.right - rect3.bottom + rect3.top; - InvertRect(hDC, &rect3); + hMemDC = CreateCompatibleDC(hDC); + if (lpitem->hCheckBit == 0) + SelectObject(hMemDC, hStdCheck); + else + SelectObject(hMemDC, lpitem->hCheckBit); + GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm); + BitBlt(hDC, rect3.left, rect3.top, + bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + DeleteDC(hMemDC); + printf("StdDrawPopupMenu // MF_CHECKED hStdCheck=%04X !\n", hStdCheck); + } + else { + if (lpitem->hUnCheckBit != 0) + SelectObject(hMemDC, lpitem->hUnCheckBit); } if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { CopyRect(&rect3, &rect2); rect3.left = rect3.right - rect3.bottom + rect3.top; - FillRect(hDC, &rect3, GetStockObject(BLACK_BRUSH)); + hMemDC = CreateCompatibleDC(hDC); + SelectObject(hMemDC, hStdMnArrow); + GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm); + BitBlt(hDC, rect3.left, rect3.top, + bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + DeleteDC(hMemDC); } if (lpitem->next == NULL) goto EndOfPaint; lpitem = (LPMENUITEM)lpitem->next; @@ -264,50 +618,244 @@ EndOfPaint: -LPMENUITEM PopupMenuFindItem(HWND hwnd, int x, int y, WORD *lpRet) +void StdDrawMenuBar(HWND hwnd) { WND *wndPtr; LPPOPUPMENU lppop; LPMENUITEM lpitem; - RECT rect, rect2; + PAINTSTRUCT ps; + HBRUSH hBrush; + HPEN hOldPen; + HWND hWndParent; + HDC hDC, hMemDC; + RECT rect, rect2, rect3; + HFONT hOldFont; HBITMAP hBitMap; BITMAP bm; - UINT i; + UINT i, textwidth; + hDC = BeginPaint( hwnd, &ps ); + if (!IsWindowVisible(hwnd)) { + EndPaint( hwnd, &ps ); + return; + } + hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); - if (lppop == NULL) return NULL; + if (lppop == NULL) goto EndOfPaint; + hBrush = GetStockObject(WHITE_BRUSH); GetClientRect(hwnd, &rect); - if (lppop->nItems == 0) return NULL; - lpitem = lppop->firstItem->next; - if (lpitem == NULL) return NULL; + FillRect(hDC, &rect, hBrush); + FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH)); + if (lppop->nItems == 0) goto EndOfPaint; + lpitem = lppop->firstItem; + if (lpitem == NULL) goto EndOfPaint; for(i = 0; i < lppop->nItems; i++) { - if (y < rect2.top) return NULL; - if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) { - rect2.bottom = rect2.top + 3; - rect2.top += 3; - } if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { - hBitMap = (HBITMAP)LOWORD(lpitem->item_text); + hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); + CopyRect(&rect2, &lpitem->rect); + hMemDC = CreateCompatibleDC(hDC); + SelectObject(hMemDC, hBitMap); GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); - rect2.bottom = rect2.top + bm.bmHeight; - rect2.top += bm.bmHeight; + BitBlt(hDC, rect2.left, rect2.top, + bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + DeleteDC(hMemDC); } if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { - rect2.bottom = rect2.top + 15; - rect2.top += 15; + CopyRect(&rect2, &lpitem->rect); + DrawText(hDC, lpitem->item_text, -1, &rect2, + DT_LEFT | DT_VCENTER | DT_SINGLELINE); } - if (y < rect2.bottom) { + if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) { + CopyRect(&rect3, &rect2); + rect3.left = rect3.right - rect3.bottom + rect3.top; + hMemDC = CreateCompatibleDC(hDC); + SelectObject(hMemDC, hStdCheck); + GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); + BitBlt(hDC, rect3.left, rect3.top, + bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + DeleteDC(hMemDC); + } + if (lpitem->next == NULL) goto EndOfPaint; + lpitem = (LPMENUITEM)lpitem->next; + } +EndOfPaint: + SelectObject(hDC, hOldFont); + EndPaint( hwnd, &ps ); +} + + + +LPMENUITEM MenuFindItem(HWND hwnd, int x, int y, WORD *lpRet) +{ + WND *wndPtr; + LPPOPUPMENU lppop; + LPMENUITEM lpitem; + UINT i; + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) return NULL; + if (lppop->nItems == 0) return NULL; + lpitem = lppop->firstItem; + for(i = 0; i < lppop->nItems; i++) { + if (lpitem == NULL) return NULL; +#ifdef DEBUG_MENUFINDITEM + printf("FindItem // left=%d top=%d right=%d bottom=%d\n", + lpitem->rect.left, lpitem->rect.top, + lpitem->rect.right, lpitem->rect.bottom); +#endif + if (x > lpitem->rect.left && x < lpitem->rect.right && + y > lpitem->rect.top && y < lpitem->rect.bottom) { if (lpRet != NULL) *lpRet = i; return lpitem; } - if (lpitem->next == NULL) return NULL; lpitem = (LPMENUITEM)lpitem->next; } return NULL; } +LPMENUITEM MenuFindItemBySelKey(HWND hwnd, WORD key, WORD *lpRet) +{ + WND *wndPtr; + LPPOPUPMENU lppop; + LPMENUITEM lpitem; + UINT i; + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) return NULL; + if (lppop->nItems == 0) return NULL; + lpitem = lppop->firstItem; + for(i = 0; i < lppop->nItems; i++) { + if (lpitem == NULL) return NULL; +#ifdef DEBUG_MENUFINDITEM + printf("FindItemBySelKey // key=%d lpitem->sel_key=%d\n", + key, lpitem->sel_key); +#endif + if (key == lpitem->sel_key) { + if (lpRet != NULL) *lpRet = i; + return lpitem; + } + lpitem = (LPMENUITEM)lpitem->next; + } + return NULL; +} + + +void PopupMenuCalcSize(HWND hwnd) +{ + WND *wndPtr; + LPPOPUPMENU lppop; + LPMENUITEM lpitem; + HDC hDC; + RECT rect; + HBITMAP hBitMap; + BITMAP bm; + HFONT hOldFont; + UINT i, OldWidth, TempWidth; + DWORD dwRet; + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) return; + if (lppop->nItems == 0) return; + hDC = GetDC(hwnd); + lppop->Width = 20; + hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); +CalcAGAIN: + OldWidth = lppop->Width; + SetRect(&rect, 1, 1, OldWidth, 0); + lpitem = lppop->firstItem; + for(i = 0; i < lppop->nItems; i++) { + if (lpitem == NULL) break; + rect.right = rect.left + lppop->Width; + if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) { + rect.bottom = rect.top + 3; + } + if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { + hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); + GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); + rect.bottom = rect.top + bm.bmHeight; + lppop->Width = max(lppop->Width, bm.bmWidth); + } + if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && + ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + dwRet = GetTextExtent(hDC, (char *)lpitem->item_text, + strlen((char *)lpitem->item_text)); + rect.bottom = rect.top + HIWORD(dwRet); + InflateRect(&rect, 0, 2); + TempWidth = LOWORD(dwRet); + if (GetShortCutPos(lpitem->item_text) != (WORD)-1) + TempWidth += 15; + lppop->Width = max(lppop->Width, TempWidth); + } + CopyRect(&lpitem->rect, &rect); + rect.top = rect.bottom; + lpitem = (LPMENUITEM)lpitem->next; + } + if (OldWidth < lppop->Width) goto CalcAGAIN; + lppop->Height = rect.bottom; +#ifdef DEBUG_MENUCALC + printf("PopupMenuCalcSize w=%d h=%d !\n", + lppop->Width, lppop->Height); +#endif + SelectObject(hDC, hOldFont); + ReleaseDC(0, hDC); +} + + + +void MenuBarCalcSize(HWND hwnd) +{ + WND *wndPtr; + LPPOPUPMENU lppop; + LPMENUITEM lpitem; + HDC hDC; + RECT rect; + HBITMAP hBitMap; + BITMAP bm; + HFONT hOldFont; + UINT i, OldHeight; + DWORD dwRet; + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) return; + if (lppop->nItems == 0) return; + hDC = GetDC(hwnd); + hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); + lppop->Height = 10; +CalcAGAIN: + OldHeight = lppop->Height; + SetRect(&rect, 1, 1, 0, OldHeight); + lpitem = lppop->firstItem; + for(i = 0; i < lppop->nItems; i++) { + if (lpitem == NULL) break; + rect.bottom = rect.top + lppop->Height; + if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { + hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); + GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); + rect.right = rect.left + bm.bmWidth; + lppop->Height = max(lppop->Height, bm.bmHeight); + } + if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && + ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + dwRet = GetTextExtent(hDC, (char *)lpitem->item_text, + strlen((char *)lpitem->item_text)); + rect.right = rect.left + LOWORD(dwRet) + 10; + lppop->Height = max(lppop->Height, HIWORD(dwRet) + 10); + } + CopyRect(&lpitem->rect, &rect); + rect.left = rect.right; + lpitem = (LPMENUITEM)lpitem->next; + } + if (OldHeight < lppop->Height) goto CalcAGAIN; + lppop->Width = rect.right; +#ifdef DEBUG_MENUCALC + printf("MenuBarCalcSize w=%d h=%d !\n", + lppop->Width, lppop->Height); +#endif + SelectObject(hDC, hOldFont); + ReleaseDC(hwnd, hDC); +} + + LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos) { @@ -316,14 +864,106 @@ LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos) if (menu == NULL) return NULL; lpitem = menu->firstItem; for (i = 0; i < menu->nItems; i++) { - if (lpitem->next == NULL) return NULL; - lpitem = (LPMENUITEM)lpitem->next; + if (lpitem == NULL) return NULL; if (i == nPos) return(lpitem); + lpitem = (LPMENUITEM)lpitem->next; } return NULL; } +WORD GetSelectionKey(LPSTR str) +{ + int i; + WORD sel_key; + for (i = 0; i < strlen(str); i++) { + if (str[i] == '&' && str[i + 1] != '&') + { + sel_key = str[i + 1]; + if (sel_key >= 'a' && sel_key <= 'z') sel_key -= 'a' - 'A'; +#ifdef DEBUG_MENU + printf("GetSelectionKey // %04X\n", sel_key); +#endif + return sel_key; + } + } +#ifdef DEBUG_MENU + printf("GetSelectionKey NULL \n"); +#endif + return 0; +} + + + +LPSTR GetShortCutString(LPSTR str) +{ + int i; + LPSTR str2; + for (i = 0; i < strlen(str); i++) { + if (str[i] == '\t' && str[i + 1] != '\t') + { + str2 = &str[i + 1]; +#ifdef DEBUG_MENU + printf("GetShortCutString // '%s' \n", str2); +#endif + return str2; + } + } +#ifdef DEBUG_MENU + printf("GetShortCutString NULL \n"); +#endif + return NULL; +} + + + +WORD GetShortCutPos(LPSTR str) +{ + int i; + for (i = 0; i < strlen(str); i++) { + if (str[i] == '\t' && str[i + 1] != '\t') + { +#ifdef DEBUG_MENU + printf("GetShortCutPos = %d \n", i); +#endif + return i; + } + } +#ifdef DEBUG_MENU + printf("GetShortCutString NULL \n"); +#endif + return -1; +} + + + +BOOL HideAllSubPopupMenu(LPPOPUPMENU menu) +{ + LPPOPUPMENU submenu; + LPMENUITEM lpitem; + BOOL someClosed = FALSE; + int i; + if (menu == NULL) return; + lpitem = menu->firstItem; + for (i = 0; i < menu->nItems; i++) { + if (lpitem == NULL) return; + if (lpitem->item_flags & MF_POPUP) { + submenu = (LPPOPUPMENU) GlobalLock((HMENU)lpitem->item_id); + if (submenu != NULL) { + if (IsWindowVisible(submenu->hWnd)) { + ShowWindow(submenu->hWnd, SW_HIDE); + someClosed = TRUE; + } + } + } + lpitem = (LPMENUITEM)lpitem->next; + } + return someClosed; +} + + +#ifdef USE_XTMENU + /********************************************************************** * MENU_CheckWidget */ @@ -802,7 +1442,8 @@ CheckMenu(HMENU hmenu, WORD item_id, WORD check_flags) else return MF_CHECKED; } - + + /********************************************************************** * LoadMenu */ @@ -867,12 +1508,36 @@ LoadMenu(HINSTANCE instance, char *menu_name) return GlobalHandleFromPointer(menu->firstItem); } +#endif + /********************************************************************** * CheckMenuItem [USER.154] */ BOOL CheckMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags) { + WND *wndPtr; + LPPOPUPMENU menu; + LPMENUITEM lpitem; + int i; +#ifdef DEBUG_MENU + printf("CheckMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags); +#endif + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) return FALSE; + lpitem = menu->firstItem; + for (i = 0; i < menu->nItems; i++) { + if (lpitem == NULL) break; + if (i == wItemID) { + if (wFlags && MF_CHECKED) + lpitem->item_flags |= MF_CHECKED; + else + lpitem->item_flags &= ((WORD)-1 ^ MF_CHECKED); + return(TRUE); + } + lpitem = (LPMENUITEM)lpitem->next; + } + return FALSE; } @@ -881,6 +1546,28 @@ BOOL CheckMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags) */ BOOL EnableMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags) { + WND *wndPtr; + LPPOPUPMENU menu; + LPMENUITEM lpitem; + int i; +#ifdef DEBUG_MENU + printf("EnableMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags); +#endif + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) return FALSE; + lpitem = menu->firstItem; + for (i = 0; i < menu->nItems; i++) { + if (lpitem == NULL) break; + if (i == wItemID) { + if (wFlags && MF_DISABLED) + lpitem->item_flags |= MF_DISABLED; + else + lpitem->item_flags &= ((WORD)-1 ^ MF_DISABLED); + return(TRUE); + } + lpitem = (LPMENUITEM)lpitem->next; + } + return FALSE; } @@ -902,7 +1589,8 @@ BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewIt if (menu == NULL) return FALSE; lpitem = menu->firstItem; for (i = 0; i < menu->nItems; i++) { - if (lpitem->next == NULL) break; + if (lpitem == NULL) break; + if (i == nPos) break; lpitem = (LPMENUITEM)lpitem->next; printf("InsertMenu // during loop items !\n"); } @@ -910,14 +1598,17 @@ BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewIt hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); if (hNewItem == 0) return FALSE; lpitem2 = (LPMENUITEM)GlobalLock(hNewItem); - if (lpitem2 == 0) { + if (lpitem2 == NULL) { GlobalFree(hNewItem); return FALSE; } lpitem2->item_flags = wFlags; lpitem2->item_id = wItemID; - if ((wFlags & MF_STRING) == MF_STRING) { + if (((wFlags & MF_BITMAP) != MF_BITMAP) && + ((wFlags & MF_MENUBREAK) != MF_MENUBREAK) && + ((wFlags & MF_STRING) != MF_SEPARATOR)) { lpitem2->item_text = lpNewItem; + lpitem2->sel_key = GetSelectionKey(lpitem2->item_text); } else lpitem2->item_text = lpNewItem; @@ -952,32 +1643,41 @@ BOOL AppendMenu(HMENU hMenu, WORD wFlags, WORD wItemID, LPSTR lpNewItem) menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) return FALSE; lpitem = menu->firstItem; - while (lpitem->next != NULL) { - lpitem = (LPMENUITEM)lpitem->next; - printf("AppendMenu // during loop items !\n"); - } - printf("AppendMenu // after loop items !\n"); + if (lpitem != NULL) { + while (lpitem->next != NULL) { + lpitem = (LPMENUITEM)lpitem->next; + } + } hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); if (hNewItem == 0) return FALSE; lpitem2 = (LPMENUITEM)GlobalLock(hNewItem); - if (lpitem2 == 0) { + if (lpitem2 == NULL) { GlobalFree(hNewItem); return FALSE; } lpitem2->item_flags = wFlags; lpitem2->item_id = wItemID; - if ((wFlags & MF_STRING) == MF_STRING) { + if (((wFlags & MF_BITMAP) != MF_BITMAP) && + ((wFlags & MF_MENUBREAK) != MF_MENUBREAK) && + ((wFlags & MF_STRING) != MF_SEPARATOR)) { lpitem2->item_text = lpNewItem; + lpitem2->sel_key = GetSelectionKey(lpitem2->item_text); + lpitem2->shortcut = GetShortCutString(lpitem2->item_text); } else lpitem2->item_text = lpNewItem; - lpitem->next = lpitem2; + if (lpitem == NULL) + menu->firstItem = lpitem2; + else + lpitem->next = lpitem2; lpitem2->prev = lpitem; lpitem2->next = NULL; lpitem2->child = NULL; lpitem2->parent = NULL; lpitem2->w = NULL; lpitem2->menu_w = NULL; + lpitem2->hCheckBit = (HBITMAP)NULL; + lpitem2->hUnCheckBit = (HBITMAP)NULL; menu->nItems++; return TRUE; } @@ -999,14 +1699,14 @@ BOOL RemoveMenu(HMENU hMenu, WORD nPos, WORD wFlags) if (menu == NULL) return FALSE; lpitem = menu->firstItem; for (i = 0; i < menu->nItems; i++) { - if (lpitem->next == NULL) break; - lpitem = (LPMENUITEM)lpitem->next; + if (lpitem == NULL) break; if (i == nPos) { lpitem->prev->next = lpitem->next; lpitem->next->prev = lpitem->prev; GlobalFree(HIWORD(lpitem)); return(TRUE); } + lpitem = (LPMENUITEM)lpitem->next; printf("RemoveMenu // during loop items !\n"); } printf("RemoveMenu // after loop items !\n"); @@ -1031,11 +1731,28 @@ BOOL DeleteMenu(HMENU hMenu, WORD nPos, WORD wFlags) */ BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem) { + WND *wndPtr; + LPPOPUPMENU menu; + LPMENUITEM lpitem; + int i; #ifdef DEBUG_MENU printf("ModifyMenu (%04X, %04X, %04X, %04X, %08X) !\n", hMenu, nPos, wFlags, wItemID, lpNewItem); #endif - return TRUE; + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) return FALSE; + lpitem = menu->firstItem; + for (i = 0; i < menu->nItems; i++) { + if (lpitem == NULL) break; + if (i == nPos) { + lpitem->item_flags = wFlags; + lpitem->item_id = wItemID; + lpitem->item_text = lpNewItem; + return(TRUE); + } + lpitem = (LPMENUITEM)lpitem->next; + } + return FALSE; } @@ -1056,52 +1773,92 @@ HMENU CreatePopupMenu() GlobalFree(hMenu); return 0; } - hItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); - if (hItem == 0) { - GlobalFree(hMenu); - return 0; - } menu->nItems = 0; - menu->firstItem = (LPMENUITEM)GlobalLock(hItem); + menu->firstItem = NULL; menu->ownerWnd = 0; menu->hWnd = 0; - - menu->firstItem->next = NULL; - menu->firstItem->prev = NULL; - menu->firstItem->child = NULL; - menu->firstItem->parent = NULL; - menu->firstItem->item_flags = 0; - menu->firstItem->item_id = 0; - menu->firstItem->item_text = NULL; - menu->firstItem->w = NULL; - menu->firstItem->menu_w = NULL; + menu->hWndParent = 0; + menu->MouseFlags = 0; + menu->BarFlags = 0; + menu->Width = 100; + menu->Height = 0; return hMenu; } /********************************************************************** - * TrackPopupMenu [USER.414] + * TrackPopupMenu [USER.416] */ BOOL TrackPopupMenu(HMENU hMenu, WORD wFlags, short x, short y, short nReserved, HWND hWnd, LPRECT lpRect) { WND *wndPtr; - LPPOPUPMENU menu; + LPPOPUPMENU lppop; #ifdef DEBUG_MENU printf("TrackPopupMenu (%04X, %04X, %d, %d, %04X, %04X, %08X) !\n", hMenu, wFlags, x, y, nReserved, hWnd, lpRect); +#endif + lppop = (LPPOPUPMENU) GlobalLock(hMenu); + if (lppop == NULL) return FALSE; + wndPtr = WIN_FindWndPtr(hWnd); + lppop->ownerWnd = hWnd; + if (lppop->hWnd == (HWND)NULL) { + lppop->hWnd = CreateWindow("POPUPMENU", "", WS_CHILD | WS_VISIBLE, + x, y, lppop->Width, lppop->Height, hWnd, 0, + wndPtr->hInstance, (LPSTR)lppop); + } + else { + ShowWindow(lppop->hWnd, SW_SHOW); + } + if (lppop->BarFlags == 0) { + PopupMenuCalcSize(lppop->hWnd); +#ifdef DEBUG_MENU + printf("TrackPopupMenu // x=%d y=%d Width=%d Height=%d\n", + x, y, lppop->Width, lppop->Height); +#endif + SetWindowPos(lppop->hWnd, 0, x, y, lppop->Width + 2, lppop->Height, + SWP_NOZORDER); + } + else { + MenuBarCalcSize(lppop->hWnd); +#ifdef DEBUG_MENU + printf("TrackMenuBar // x=%d y=%d Width=%d Height=%d\n", + x, y, lppop->Width, lppop->Height); +#endif + SetWindowPos(lppop->hWnd, 0, 0, -16, lppop->Width, lppop->Height, + SWP_NOZORDER); + } + return TRUE; +} + + +/********************************************************************** + * SetMenuItemBitmaps [USER.418] + */ +BOOL SetMenuItemBitmaps(HMENU hMenu, WORD nPos, WORD wFlags, + HBITMAP hNewCheck, HBITMAP hNewUnCheck) +{ + WND *wndPtr; + LPPOPUPMENU menu; + LPMENUITEM lpitem; + int i; +#ifdef DEBUG_MENU + printf("SetMenuItemBitmaps (%04X, %04X, %04X, %04X, %08X) !\n", + hMenu, nPos, wFlags, hNewCheck, hNewUnCheck); #endif menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) return FALSE; - wndPtr = WIN_FindWndPtr(hWnd); - menu->ownerWnd = hWnd; - if (menu->hWnd == NULL) { - menu->hWnd = CreateWindow("POPUPMENU", "", WS_CHILD | WS_VISIBLE, - x, y, 100, 150, hWnd, 0, wndPtr->hInstance, (LPSTR)menu); - } - else - ShowWindow(menu->hWnd, SW_SHOW); - return TRUE; + lpitem = menu->firstItem; + for (i = 0; i < menu->nItems; i++) { + if (lpitem == NULL) break; + if (i == nPos) { + lpitem->hCheckBit = hNewCheck; + lpitem->hUnCheckBit = hNewUnCheck; + return(TRUE); + } + lpitem = (LPMENUITEM)lpitem->next; + } + return FALSE; } @@ -1112,37 +1869,25 @@ HMENU CreateMenu() { HANDLE hItem; HMENU hMenu; - LPMENUBAR menu; + LPPOPUPMENU menu; #ifdef DEBUG_MENU - printf("CreateMenu !\n"); + printf("CreatePopupMenu !\n"); #endif - hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUBAR)); - menu = (LPMENUBAR) GlobalLock(hMenu); + hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU)); + menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) { GlobalFree(hMenu); return 0; } - hItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); - if (hItem == 0) { - GlobalFree(hMenu); - return 0; - } - menu->menuDescription = 0; menu->nItems = 0; - menu->parentWidget = NULL; - menu->firstItem = (LPMENUITEM) GlobalLock(hItem); + menu->firstItem = NULL; menu->ownerWnd = 0; - menu->menuBarWidget = NULL; - - menu->firstItem->next = NULL; - menu->firstItem->prev = NULL; - menu->firstItem->child = NULL; - menu->firstItem->parent = NULL; - menu->firstItem->item_flags = 0; - menu->firstItem->item_id = 0; - menu->firstItem->item_text = NULL; - menu->firstItem->w = NULL; - menu->firstItem->menu_w = NULL; + menu->hWnd = 0; + menu->hWndParent = 0; + menu->MouseFlags = 0; + menu->BarFlags = TRUE; + menu->Width = 100; + menu->Height = 0; return hMenu; } @@ -1162,7 +1907,7 @@ BOOL DestroyMenu(HMENU hMenu) if (lppop == NULL) return FALSE; if (lppop->hWnd) DestroyWindow (lppop->hWnd); lpitem = lppop->firstItem; - while (lpitem->next != NULL) { + while (lpitem != NULL) { #ifdef DEBUG_MENU printf("DestroyMenu (%04X) // during loop items !\n", hMenu); #endif @@ -1179,3 +1924,89 @@ BOOL DestroyMenu(HMENU hMenu) } +#ifdef USE_POPUPMENU + + +/********************************************************************** + * DrawMenuBar [USER.152] + */ +void DrawMenuBar(HWND hWnd) +{ + WND *wndPtr; +#ifdef DEBUG_MENU + printf("DrawMenuBar (%04X)\n", hWnd); +#endif + wndPtr = WIN_FindWndPtr(hWnd); + if (wndPtr != NULL && wndPtr->hWndMenuBar != 0) { + InvalidateRect(wndPtr->hWndMenuBar, NULL, TRUE); + UpdateWindow(wndPtr->hWndMenuBar); + } +} + + +/********************************************************************** + * LoadMenu [USER.152] + */ +HMENU LoadMenu(HINSTANCE instance, char *menu_name) +{ + HMENU hMenu; + HANDLE hMenu_desc; + MENU_HEADER *menu_desc; + +#ifdef DEBUG_MENU + printf("LoadMenu: instance %02x, menu '%s'\n", + instance, menu_name); +#endif + if (menu_name == NULL || + (hMenu_desc = RSC_LoadMenu(instance, menu_name)) == 0 || + (menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc)) == NULL) + { + return 0; + } + hMenu = CreateMenu(); + ParseMenuResource((WORD *) (menu_desc + 1), 0, hMenu); + + return hMenu; +} + + +WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu) +{ + WORD *item; + WORD *next_item; + HMENU hSubMenu; + int i; + + level++; + next_item = first_item; + i = 0; + do + { + i++; + item = next_item; + if (*item & MF_POPUP) + { + MENU_POPUPITEM *popup_item = (MENU_POPUPITEM *) item; + next_item = (WORD *) (popup_item->item_text + + strlen(popup_item->item_text) + 1); + hSubMenu = CreatePopupMenu(); + next_item = ParseMenuResource(next_item, level, hSubMenu); + AppendMenu(hMenu, popup_item->item_flags, + hSubMenu, popup_item->item_text); + } + else + { + MENU_NORMALITEM *normal_item = (MENU_NORMALITEM *) item; + next_item = (WORD *) (normal_item->item_text + + strlen(normal_item->item_text) + 1); + AppendMenu(hMenu, normal_item->item_flags, + normal_item->item_id, normal_item->item_text); + } + } + while (!(*item & MF_END)); + + return next_item; +} + +#endif + diff --git a/controls/scroll.c b/controls/scroll.c index 9cfa55010d1..439be8dc7ee 100644 --- a/controls/scroll.c +++ b/controls/scroll.c @@ -21,6 +21,15 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; #include #include +HBITMAP hUpArrow = 0; +HBITMAP hDnArrow = 0; +HBITMAP hLfArrow = 0; +HBITMAP hRgArrow = 0; +HBITMAP hUpArrowD = 0; +HBITMAP hDnArrowD = 0; +HBITMAP hLfArrowD = 0; +HBITMAP hRgArrowD = 0; + LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hwnd, WND **wndPtr); LPHEADSCROLL ScrollBarGetStorageHeader(HWND hwnd); void StdDrawScrollBar(HWND hwnd); @@ -34,9 +43,13 @@ LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) { WORD wRet; short x, y; + short width, height; WND *wndPtr; LPHEADSCROLL lphs; - RECT rect; + LPDRAWITEMSTRUCT lpdis; + HDC hMemDC; + BITMAP bm; + RECT rect; static RECT rectsel; switch(message) { @@ -45,6 +58,22 @@ LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) #ifdef DEBUG_SCROLL printf("ScrollBar Creation up=%X down=%X!\n", lphs->hWndUp, lphs->hWndDown); #endif + if (hUpArrow == (HBITMAP)NULL) + hUpArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_UPARROWI)); + if (hDnArrow == (HBITMAP)NULL) + hDnArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_DNARROWI)); + if (hLfArrow == (HBITMAP)NULL) + hLfArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_LFARROWI)); + if (hRgArrow == (HBITMAP)NULL) + hRgArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROWI)); + if (hUpArrowD == (HBITMAP)NULL) + hUpArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_UPARROWD)); + if (hDnArrowD == (HBITMAP)NULL) + hDnArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_DNARROWD)); + if (hLfArrowD == (HBITMAP)NULL) + hLfArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_LFARROWD)); + if (hRgArrowD == (HBITMAP)NULL) + hRgArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROWD)); return 0; case WM_DESTROY: lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr); @@ -129,15 +158,6 @@ LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) ReleaseCapture(); break; - case WM_KEYDOWN: - case WM_KEYUP: - case WM_CHAR: - lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr); - return(SendMessage(wndPtr->hwndParent, message, wParam, lParam)); - - case WM_PAINT: - StdDrawScrollBar(hwnd); - break; case WM_MOUSEMOVE: if ((wParam & MK_LBUTTON) != 0) { lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr); @@ -150,12 +170,88 @@ LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) x = (y * (lphs->MaxVal - lphs->MinVal) / lphs->MaxPix) + lphs->MinVal; #ifdef DEBUG_SCROLL - printf("WM_MOUSEMOVE val=%d pix=%d\n", x, y); + printf("Scroll WM_MOUSEMOVE val=%d pix=%d\n", x, y); #endif SendMessage(wndPtr->hwndParent, lphs->Direction, SB_THUMBTRACK, MAKELONG(x, hwnd)); } break; + case WM_KEYDOWN: + case WM_KEYUP: + case WM_CHAR: + lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr); + return(SendMessage(wndPtr->hwndParent, message, wParam, lParam)); + + case WM_SIZE: + lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr); + width = LOWORD(lParam); + height = HIWORD(lParam); + if (lphs->Direction == WM_VSCROLL) { + MoveWindow(lphs->hWndUp, 0, 0, width, width, TRUE); + MoveWindow(lphs->hWndDown, 0, height - width, width, width, TRUE); + } + else { + MoveWindow(lphs->hWndUp, 0, 0, height, height, TRUE); + MoveWindow(lphs->hWndDown, width - height, 0, height, height, TRUE); + } + break; + case WM_DRAWITEM: +#ifdef DEBUG_SCROLL + printf("Scroll WM_DRAWITEM w=%04X l=%08X\n", wParam, lParam); +#endif + lpdis = (LPDRAWITEMSTRUCT)lParam; + if (lpdis->CtlType == ODT_BUTTON && lpdis->itemAction == ODA_DRAWENTIRE) { + hMemDC = CreateCompatibleDC(lpdis->hDC); + if (lpdis->CtlID == 1) { + GetObject(hUpArrow, sizeof(BITMAP), (LPSTR)&bm); + SelectObject(hMemDC, hUpArrow); + BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + } + if (lpdis->CtlID == 2) { + GetObject(hDnArrow, sizeof(BITMAP), (LPSTR)&bm); + SelectObject(hMemDC, hDnArrow); + BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + } + if (lpdis->CtlID == 3) { + GetObject(hLfArrow, sizeof(BITMAP), (LPSTR)&bm); + SelectObject(hMemDC, hLfArrow); + BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + } + if (lpdis->CtlID == 4) { + GetObject(hRgArrow, sizeof(BITMAP), (LPSTR)&bm); + SelectObject(hMemDC, hRgArrow); + BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + } + DeleteDC(hMemDC); + } + if (lpdis->CtlType == ODT_BUTTON && lpdis->itemAction == ODA_SELECT) { + hMemDC = CreateCompatibleDC(lpdis->hDC); + if (lpdis->CtlID == 1) { + GetObject(hUpArrowD, sizeof(BITMAP), (LPSTR)&bm); + SelectObject(hMemDC, hUpArrowD); + BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + } + if (lpdis->CtlID == 2) { + GetObject(hDnArrowD, sizeof(BITMAP), (LPSTR)&bm); + SelectObject(hMemDC, hDnArrowD); + BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + } + if (lpdis->CtlID == 3) { + GetObject(hLfArrowD, sizeof(BITMAP), (LPSTR)&bm); + SelectObject(hMemDC, hLfArrowD); + BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + } + if (lpdis->CtlID == 4) { + GetObject(hRgArrowD, sizeof(BITMAP), (LPSTR)&bm); + SelectObject(hMemDC, hRgArrowD); + BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + } + DeleteDC(hMemDC); + } + break; + case WM_PAINT: + StdDrawScrollBar(hwnd); + break; default: return DefWindowProc( hwnd, message, wParam, lParam ); } @@ -274,10 +370,10 @@ int CreateScrollBarStruct(HWND hwnd) lphs->MaxPix = height - 3 * width; lphs->Direction = WM_VSCROLL; lphs->hWndUp = CreateWindow("BUTTON", "", - WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, + WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, 0, 0, width, width, hwnd, 1, wndPtr->hInstance, 0L); lphs->hWndDown = CreateWindow("BUTTON", "", - WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, + WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, 0, height - width, width, width, hwnd, 2, wndPtr->hInstance, 0L); } @@ -286,11 +382,11 @@ int CreateScrollBarStruct(HWND hwnd) lphs->MaxPix = width - 3 * height; lphs->Direction = WM_HSCROLL; lphs->hWndUp = CreateWindow("BUTTON", "", - WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, - 0, 0, height, height, hwnd, 0, wndPtr->hInstance, 0L); + WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, + 0, 0, height, height, hwnd, 3, wndPtr->hInstance, 0L); lphs->hWndDown = CreateWindow("BUTTON", "", - WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, - width - height, 0, height, height, hwnd, 0, + WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, + width - height, 0, height, height, hwnd, 4, wndPtr->hInstance, 0L); } if (lphs->MaxPix < 1) lphs->MaxPix = 1; diff --git a/controls/widgets.c b/controls/widgets.c index c88ac448a07..02d10b4dac7 100644 --- a/controls/widgets.c +++ b/controls/widgets.c @@ -17,6 +17,7 @@ LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ); LONG ListBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); LONG ComboBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); LONG PopupMenuWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG CaptionBarWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); static WNDCLASS WIDGETS_BuiltinClasses[] = @@ -33,6 +34,8 @@ static WNDCLASS WIDGETS_BuiltinClasses[] = 0, 0, 0, 0, NULL, "COMBOBOX" }, { CS_GLOBALCLASS, (LONG(*)())PopupMenuWndProc, 0, 8, 0, 0, 0, 0, NULL, "POPUPMENU" }, + { CS_GLOBALCLASS, (LONG(*)())CaptionBarWndProc, 0, 8, + 0, 0, 0, 0, NULL, "CAPTION" }, { CS_GLOBALCLASS, (LONG(*)())DefDlgProc, 0, DLGWINDOWEXTRA, 0, 0, 0, 0, NULL, DIALOG_CLASS_NAME } }; diff --git a/debugger/info.c b/debugger/info.c index 063447a025b..87aec59e6ca 100644 --- a/debugger/info.c +++ b/debugger/info.c @@ -172,7 +172,7 @@ void examine_memory(int addr, int count, char format){ pnt = (char *) addr; for(i=0; iexport_name) == 0 && - seg_off == 0x00972526 && - *ret_addr == 0x004700cd && - IF1632_Saved16_esp == 0x2526 && - IF1632_Saved16_ebp == 0x2534 && - IF1632_Saved16_ss == 0x0097) - printf("ACK!!\n"); - #ifdef DEBUG_STACK stack_p = (unsigned short *) seg_off; for (i = 0; i < 24; i++, stack_p++) diff --git a/if1632/user.spec b/if1632/user.spec index 86682f18c6e..24c3e249734 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -120,6 +120,7 @@ length 540 155 pascal EnableMenuItem(word word word) EnableMenuItem(1 2 3) 157 pascal GetMenu(word) GetMenu(1) 158 pascal SetMenu(word word) SetMenu(1 2) +160 pascal DrawMenuBar(word) DrawMenuBar(1) 163 pascal CreateCaret(word word word word) CreateCaret(1 2 3 4) 164 pascal DestroyCaret() DestroyCaret() 165 pascal SetCaretPos(word word) SetCaretPos(1 2) @@ -206,6 +207,8 @@ length 540 415 pascal CreatePopupMenu() CreatePopupMenu() 416 pascal TrackPopupMenu(word word word word word word ptr) TrackPopupMenu(1 2 3 4 5 6 7) +418 pascal SetMenuItemBitmaps(word word word word word) + SetMenuItemBitmaps(1 2 3 4 5) 420 pascal wsprintf(ptr ptr) wsprintf(1 2) 421 pascal wvsprintf(ptr ptr ptr) wvsprintf(1 2 3) 430 pascal lstrcmp(ptr ptr) lstrcmp(1 2) @@ -220,6 +223,7 @@ length 540 452 pascal CreateWindowEx(long ptr ptr long s_word s_word s_word s_word word word word ptr) CreateWindowEx(1 2 3 4 5 6 7 8 9 10 11 12) +454 pascal AdjustWindowRectEx(ptr long word long) AdjustWindowRectEx(1 2 3 4) 457 pascal DestroyIcon(word) DestroyIcon(1) 458 pascal DestroyCursor(word) DestroyCursor(1) 471 pascal lstrcmpi(ptr ptr) lstrcmpi(1 2) diff --git a/include/caption.h b/include/caption.h new file mode 100644 index 00000000000..0c951c398c1 --- /dev/null +++ b/include/caption.h @@ -0,0 +1,17 @@ +/* + * Caption Bar definitions + */ + + +typedef struct tagHEADCAPTION { + HBITMAP hClose; + HBITMAP hMinim; + HBITMAP hMaxim; + HMENU hSysMenu; + RECT rectClose; + RECT rectMinim; + RECT rectMaxim; +} HEADCAPTION; +typedef HEADCAPTION FAR* LPHEADCAPTION; + + diff --git a/include/gdi.h b/include/gdi.h index aade98d919f..b0771350d3d 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -282,7 +282,10 @@ extern HANDLE GDI_AllocObject( WORD, WORD ); extern BOOL GDI_FreeObject( HANDLE ); extern GDIOBJHDR * GDI_GetObjPtr( HANDLE, WORD ); -extern Display * XT_display; -extern Screen * XT_screen; +extern Display * XT_display; /* Will be removed */ +extern Screen * XT_screen; /* Will be removed */ + +extern Display * display; +extern Screen * screen; #endif /* GDI_H */ diff --git a/include/menu.h b/include/menu.h index edc0bec12b0..fa742406f76 100644 --- a/include/menu.h +++ b/include/menu.h @@ -13,7 +13,6 @@ #include #include -#include "windows.h" typedef struct tagMENUITEM { @@ -23,7 +22,9 @@ typedef struct tagMENUITEM struct tagMENUITEM *parent; WORD item_flags; WORD item_id; - char *item_text; + WORD sel_key; + char *shortcut; + char *item_text; Widget w; Widget menu_w; char menu_name[10]; @@ -46,11 +47,15 @@ typedef struct tagMENUBAR typedef struct tagPOPUPMENU { HWND hWnd; /* PopupMenu window handle */ + HWND hWndParent; /* Parent opupMenu window handle */ HWND ownerWnd; /* Owner window */ WORD nItems; /* Number of items on menu */ MENUITEM *firstItem; WORD FocusedItem; WORD MouseFlags; + WORD BarFlags; + WORD Width; + WORD Height; } POPUPMENU, *LPPOPUPMENU; typedef struct diff --git a/include/sysmetrics.h b/include/sysmetrics.h new file mode 100644 index 00000000000..186d2138875 --- /dev/null +++ b/include/sysmetrics.h @@ -0,0 +1,55 @@ +/* + * System metrics definitions + * + * Copyright 1994 Alexandre Julliard + */ + +#ifndef SYSMETRICS_H +#define SYSMETRICS_H + +#include "windows.h" + + + /* Constant system metrics */ +#define SYSMETRICS_CXVSCROLL 16 +#define SYSMETRICS_CYHSCROLL 16 +#define SYSMETRICS_CYCAPTION 20 +#define SYSMETRICS_CXBORDER 1 +#define SYSMETRICS_CYBORDER 1 +#define SYSMETRICS_CXDLGFRAME 4 +#define SYSMETRICS_CYDLGFRAME 4 +#define SYSMETRICS_CYVTHUMB 16 +#define SYSMETRICS_CXHTHUMB 16 +#define SYSMETRICS_CXICON 32 +#define SYSMETRICS_CYICON 32 +#define SYSMETRICS_CXCURSOR 32 +#define SYSMETRICS_CYCURSOR 32 +#define SYSMETRICS_CYMENU 18 +#define SYSMETRICS_CYVSCROLL 16 +#define SYSMETRICS_CXHSCROLL 16 +#define SYSMETRICS_CXMIN 100 +#define SYSMETRICS_CYMIN 28 +#define SYSMETRICS_CXSIZE 18 +#define SYSMETRICS_CYSIZE 18 +#define SYSMETRICS_CXMINTRACK 100 +#define SYSMETRICS_CYMINTRACK 28 +#define SYSMETRICS_CXICONSPACING 20 +#define SYSMETRICS_CYICONSPACING 20 + + /* Some non-constant system metrics */ +#define SYSMETRICS_CXSCREEN sysMetrics[SM_CXSCREEN] +#define SYSMETRICS_CYSCREEN sysMetrics[SM_CYSCREEN] +#define SYSMETRICS_CXFULLSCREEN sysMetrics[SM_CXFULLSCREEN] +#define SYSMETRICS_CYFULLSCREEN sysMetrics[SM_CYFULLSCREEN] +#define SYSMETRICS_SWAPBUTTON sysMetrics[SM_SWAPBUTTON] +#define SYSMETRICS_CXFRAME sysMetrics[SM_CXFRAME] +#define SYSMETRICS_CYFRAME sysMetrics[SM_CYFRAME] +#define SYSMETRICS_CXDOUBLECLK sysMetrics[SM_CXDOUBLECLK] +#define SYSMETRICS_CYDOUBLECLK sysMetrics[SM_CYDOUBLECLK] +#define SYSMETRICS_MENUDROPALIGNMENT sysMetrics[SM_MENUDROPALIGNMENT] + + +extern short sysMetrics[SM_CMETRICS]; + + +#endif diff --git a/include/win.h b/include/win.h index b90675db260..8bb8d5756f4 100644 --- a/include/win.h +++ b/include/win.h @@ -7,7 +7,7 @@ #ifndef WIN_H #define WIN_H -#include +#include #include "windows.h" #include "menu.h" @@ -40,11 +40,10 @@ typedef struct tagWND WORD wIDmenu; /* ID or hmenu (from CreateWindow) */ HANDLE hText; /* Handle of window text */ WORD flags; /* Misc. flags */ - Widget shellWidget; /* For top-level windows */ - Widget winWidget; /* For all windows */ - Widget compositeWidget;/* For top-level windows */ Window window; /* X window */ LPMENUBAR menuBarPtr; /* Menu bar */ + HWND hWndMenuBar; /* Menu bar */ + HWND hWndCaption; /* Caption bar */ WORD wExtra[1]; /* Window extra bytes */ } WND; @@ -54,6 +53,7 @@ typedef struct tagWND #define WIN_GOT_SIZEMSG 0x04 /* WM_SIZE has been sent to the window */ #define WIN_OWN_DC 0x08 /* Win class has style CS_OWNDC */ #define WIN_CLASS_DC 0x10 /* Win class has style CS_CLASSDC */ +#define WIN_DOUBLE_CLICKS 0x20 /* Win class has style CS_DBLCLKS */ /* Window functions */ WND *WIN_FindWndPtr( HWND hwnd ); diff --git a/include/windows.h b/include/windows.h index ae37d54da4e..7cfecdc2e66 100644 --- a/include/windows.h +++ b/include/windows.h @@ -238,6 +238,49 @@ typedef struct #define WVR_REDRAW (WVR_HREDRAW | WVR_VREDRAW) #define WVR_VALIDRECTS 0x0400 + /* WM_NCHITTEST return codes */ +#define HTERROR (-2) +#define HTTRANSPARENT (-1) +#define HTNOWHERE 0 +#define HTCLIENT 1 +#define HTCAPTION 2 +#define HTSYSMENU 3 +#define HTSIZE 4 +#define HTMENU 5 +#define HTHSCROLL 6 +#define HTVSCROLL 7 +#define HTMINBUTTON 8 +#define HTMAXBUTTON 9 +#define HTLEFT 10 +#define HTRIGHT 11 +#define HTTOP 12 +#define HTTOPLEFT 13 +#define HTTOPRIGHT 14 +#define HTBOTTOM 15 +#define HTBOTTOMLEFT 16 +#define HTBOTTOMRIGHT 17 +#define HTBORDER 18 +#define HTGROWBOX HTSIZE +#define HTREDUCE HTMINBUTTON +#define HTZOOM HTMAXBUTTON + + /* WM_SYSCOMMAND parameters */ +#define SC_SIZE 0xf000 +#define SC_MOVE 0xf010 +#define SC_MINIMIZE 0xf020 +#define SC_MAXIMIZE 0xf030 +#define SC_NEXTWINDOW 0xf040 +#define SC_PREVWINDOW 0xf050 +#define SC_CLOSE 0xf060 +#define SC_VSCROLL 0xf070 +#define SC_HSCROLL 0xf080 +#define SC_MOUSEMENU 0xf090 +#define SC_KEYMENU 0xf100 +#define SC_ARRANGE 0xf110 +#define SC_RESTORE 0xf120 +#define SC_TASKLIST 0xf130 +#define SC_SCREENSAVE 0xf140 +#define SC_HOTKEY 0xf150 /* Dialogs */ @@ -794,6 +837,8 @@ typedef METARECORD *PMETARECORD; #define SM_PENWINDOWS 41 #define SM_DBCSENABLED 42 +#define SM_CMETRICS 43 + /* Device-independent bitmaps */ typedef struct { BYTE rgbBlue, rgbGreen, rgbRed, rgbReserved; } RGBQUAD; @@ -1058,6 +1103,63 @@ typedef HANDLETABLE *LPHANDLETABLE; #define IDC_SIZEWE MAKEINTRESOURCE(32544) #define IDC_SIZENS MAKEINTRESOURCE(32545) +/* OEM Resource Ordinal Numbers */ +#define OBM_CLOSE 32754 +#define OBM_UPARROW 32753 +#define OBM_DNARROW 32752 +#define OBM_RGARROW 32751 +#define OBM_LFARROW 32750 +#define OBM_REDUCE 32749 +#define OBM_ZOOM 32748 +#define OBM_RESTORE 32747 +#define OBM_REDUCED 32746 +#define OBM_ZOOMD 32745 +#define OBM_RESTORED 32744 +#define OBM_UPARROWD 32743 +#define OBM_DNARROWD 32742 +#define OBM_RGARROWD 32741 +#define OBM_LFARROWD 32740 +#define OBM_MNARROW 32739 +#define OBM_COMBO 32738 +#define OBM_UPARROWI 32737 +#define OBM_DNARROWI 32736 +#define OBM_RGARROWI 32735 +#define OBM_LFARROWI 32734 + +#define OBM_OLD_CLOSE 32767 +#define OBM_SIZE 32766 +#define OBM_OLD_UPARROW 32765 +#define OBM_OLD_DNARROW 32764 +#define OBM_OLD_RGARROW 32763 +#define OBM_OLD_LFARROW 32762 +#define OBM_BTSIZE 32761 +#define OBM_CHECK 32760 +#define OBM_CHECKBOXES 32759 +#define OBM_BTNCORNERS 32758 +#define OBM_OLD_REDUCE 32757 +#define OBM_OLD_ZOOM 32756 +#define OBM_OLD_RESTORE 32755 + +#define OCR_NORMAL 32512 +#define OCR_IBEAM 32513 +#define OCR_WAIT 32514 +#define OCR_CROSS 32515 +#define OCR_UP 32516 +#define OCR_SIZE 32640 +#define OCR_ICON 32641 +#define OCR_SIZENWSE 32642 +#define OCR_SIZENESW 32643 +#define OCR_SIZEWE 32644 +#define OCR_SIZENS 32645 +#define OCR_SIZEALL 32646 +#define OCR_ICOCUR 32647 + +#define OIC_SAMPLE 32512 +#define OIC_HAND 32513 +#define OIC_QUES 32514 +#define OIC_BANG 32515 +#define OIC_NOTE 32516 + /* Stock GDI objects for GetStockObject() */ #define WHITE_BRUSH 0 @@ -1097,10 +1199,25 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE #define WM_NCCREATE 0x0081 #define WM_NCDESTROY 0x0082 -#define WM_NCCALCSIZE 0x0083 +#define WM_NCCALCSIZE 0x0083 +#define WM_NCHITTEST 0x0084 +#define WM_NCPAINT 0x0085 +#define WM_NCACTIVATE 0x0086 #define WM_GETDLGCODE 0x0087 + /* Non-client mouse messages */ +#define WM_NCMOUSEMOVE 0x00a0 +#define WM_NCLBUTTONDOWN 0x00a1 +#define WM_NCLBUTTONUP 0x00a2 +#define WM_NCLBUTTONDBLCLK 0x00a3 +#define WM_NCRBUTTONDOWN 0x00a4 +#define WM_NCRBUTTONUP 0x00a5 +#define WM_NCRBUTTONDBLCLK 0x00a6 +#define WM_NCMBUTTONDOWN 0x00a7 +#define WM_NCMBUTTONUP 0x00a8 +#define WM_NCMBUTTONDBLCLK 0x00a9 + /* Keyboard messages */ #define WM_KEYDOWN 0x0100 #define WM_KEYUP 0x0101 @@ -1115,6 +1232,7 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE #define WM_INITDIALOG 0x0110 #define WM_COMMAND 0x0111 +#define WM_SYSCOMMAND 0x0112 #define WM_TIMER 0x0113 #define WM_SYSTIMER 0x0118 @@ -1166,6 +1284,14 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE #define PM_REMOVE 0x0001 #define PM_NOYIELD 0x0002 +#define WM_SHOWWINDOW 0x0018 + +/* WM_SHOWWINDOW wParam codes */ +#define SW_PARENTCLOSING 1 +#define SW_OTHERMAXIMIZED 2 +#define SW_PARENTOPENING 3 +#define SW_OTHERRESTORED 4 + enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED, SW_MAXIMIZE, SW_SHOWNOACTIVATE, SW_SHOW, SW_MINIMIZE, SW_SHOWMINNOACTIVE, SW_SHOWNA, SW_RESTORE }; @@ -1284,9 +1410,7 @@ enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED, #define DT_NOPREFIX 2048 #define DT_INTERNAL 4096 - - - +/* Window Styles */ #define WS_OVERLAPPED 0x00000000L #define WS_POPUP 0x80000000L #define WS_CHILD 0x40000000L @@ -2022,7 +2146,7 @@ Fa(WORD,GetPolyFillMode,HDC,a) Fa(WORD,GetRelAbs,HDC,a) Fa(WORD,GetROP2,HDC,a) Fa(WORD,GetStretchBltMode,HDC,a) -Fa(int,GetSystemMetrics,short,a) +Fa(int,GetSystemMetrics,WORD,a) Fa(int,GetWindowTextLength,HWND,a) Fa(int,RestoreVisRgn,HDC,a) Fa(int,SaveDC,HDC,a) @@ -2347,7 +2471,7 @@ Fd(int,LoadString,HANDLE,a,WORD,b,LPSTR,c,int,d) Fd(int,MessageBox,HWND,a,LPSTR,b,LPSTR,c,WORD,d) Fd(int,SetScrollPos,HWND,a,int,b,int,c,BOOL,d) Fd(int,SetVoiceNote,int,a,int,b,int,c,int,d) -Fd(void,AdjustWindowRectEx,LPRECT,a,LONG,b,BOOL,c,DWORD,d) +Fd(void,AdjustWindowRectEx,LPRECT,a,DWORD,b,BOOL,c,DWORD,d) Fd(void,AnimatePalette,HPALETTE,a,WORD,b,WORD,c,LPPALETTEENTRY,d) Fd(void,CheckRadioButton,HWND,a,WORD,b,WORD,c,WORD,d) Fd(void,CreateCaret,HWND,a,HBITMAP,b,short,c,short,d) diff --git a/include/wineopts.h b/include/wineopts.h new file mode 100644 index 00000000000..6f3e66b81c5 --- /dev/null +++ b/include/wineopts.h @@ -0,0 +1,11 @@ +/* WINEOPTS.H + */ + +#ifndef WINEOPTS_H +#define WINEOPTS_H + +#include + +FILE *SpyFp; + +#endif /* WINEOPTS_H */ diff --git a/loader/resource.c b/loader/resource.c index 9d973058c68..da059d10b6f 100644 --- a/loader/resource.c +++ b/loader/resource.c @@ -153,6 +153,7 @@ FindResourceByNumber(struct resource_nameinfo_s *result_p, if (read(ResourceFd, &size_shift, sizeof(size_shift)) != sizeof(size_shift)) { + printf("FindResourceByNumber (%s) bad block size !\n", resource_id); return -1; } @@ -160,40 +161,38 @@ FindResourceByNumber(struct resource_nameinfo_s *result_p, * Find resource. */ typeinfo.type_id = 0xffff; - while (typeinfo.type_id != 0) - { + while (typeinfo.type_id != 0) { if (read(ResourceFd, &typeinfo, sizeof(typeinfo)) != - sizeof(typeinfo)) - { + sizeof(typeinfo)) { + printf("FindResourceByNumber (%X) bad typeinfo size !\n", resource_id); return -1; - } - if (typeinfo.type_id != 0) - { - for (i = 0; i < typeinfo.count; i++) - { - if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) != - sizeof(nameinfo)) - { - return -1; - } - -#if defined(DEBUG_RESOURCE) && defined(VERBOSE_DEBUG) - if (type_id == typeinfo.type_id) - { - printf("FindResource: type id = %d, resource id = %x\n", - type_id, nameinfo.id); - } + } +#ifdef DEBUG_RESOURCE + printf("FindResourceByNumber type=%X count=%d\n", + typeinfo.type_id, typeinfo.count); #endif - if ((type_id == -1 || typeinfo.type_id == type_id) && - nameinfo.id == resource_id) - { + if (typeinfo.type_id == 0) break; + if (typeinfo.type_id == type_id || type_id == -1) { + for (i = 0; i < typeinfo.count; i++) { + if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) != + sizeof(nameinfo)) { + printf("FindResourceByNumber (%X) bad nameinfo size !\n", resource_id); + return -1; + } +#ifdef DEBUG_RESOURCE + printf("FindResource: search type=%X id=%X // type=%X id=%X\n", + type_id, resource_id, typeinfo.type_id, nameinfo.id); +#endif + if (nameinfo.id == resource_id) { memcpy(result_p, &nameinfo, sizeof(nameinfo)); return size_shift; - } + } + } } - } - } - + else { + lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR); + } + } return -1; } @@ -243,7 +242,7 @@ FindResourceByName(struct resource_nameinfo_s *result_p, return -1; } #ifdef DEBUG_RESOURCE - printf("FindResourceByName typeinfo.type_id=%d type_id=%d\n", + printf("FindResourceByName typeinfo.type_id=%X type_id=%X\n", typeinfo.type_id, type_id); #endif if (typeinfo.type_id == 0) break; @@ -269,7 +268,7 @@ FindResourceByName(struct resource_nameinfo_s *result_p, lseek(ResourceFd, old_pos, SEEK_SET); name[nbytes] = '\0'; #ifdef DEBUG_RESOURCE - printf("FindResourceByName type_id=%d name='%s' resource_name='%s'\n", + printf("FindResourceByName type_id=%X name='%s' resource_name='%s'\n", typeinfo.type_id, name, resource_name); #endif if (strcasecmp(name, resource_name) == 0) @@ -281,7 +280,7 @@ FindResourceByName(struct resource_nameinfo_s *result_p, } else { lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR); - } + } } return -1; } @@ -681,9 +680,6 @@ LoadBitmap(HANDLE instance, LPSTR bmp_name) printf("LoadBitmap: instance = %04x, name = %08x\n", instance, bmp_name); #endif - printf("LoadBitmap: instance = %04x, name = %08x\n", - instance, bmp_name); - if (instance == (HANDLE)NULL) instance = hSysRes; if (!(hdc = GetDC(GetDesktopWindow()))) return 0; @@ -706,7 +702,6 @@ printf("before GlobalLock\n"); else if (*lp == sizeof(BITMAPINFOHEADER)) hbitmap = ConvertInfoBitmap( hdc, (BITMAPINFO *) lp ); else hbitmap = 0; -printf("LoadBitmap %04X\n", hbitmap); GlobalFree(rsc_mem); ReleaseDC( 0, hdc ); return hbitmap; diff --git a/loader/wine.c b/loader/wine.c index 60b606bbf4a..48c5e2b2f00 100644 --- a/loader/wine.c +++ b/loader/wine.c @@ -21,6 +21,9 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "dlls.h" #include "wine.h" #include "windows.h" +#include "wineopts.h" + +/* #define DEBUG_FIXUP */ extern int CallToInit16(unsigned long csip, unsigned long sssp, unsigned short ds); @@ -46,6 +49,8 @@ HINSTANCE hSysRes; static char *Extensions[] = { "dll", "exe", NULL }; static char *WinePath = NULL; +FILE *SpyFp = NULL; + /********************************************************************** * DebugPrintString */ @@ -110,6 +115,19 @@ HINSTANCE LoadImage(char *modulename) unsigned int status; char buffer[256]; + /* + * search file + */ + if (FindFile(buffer, sizeof(buffer), modulename, Extensions, WindowsPath) + ==NULL) + { + + + fprintf(stderr,"LoadImage: I can't find %s !\n",modulename); + return (HINSTANCE) NULL; + } + fprintf(stderr,"LoadImage: loading %s (%s)\n", modulename, buffer); + /* First allocate a spot to store the info we collect, and add it to * our linked list. */ @@ -124,20 +142,6 @@ HINSTANCE LoadImage(char *modulename) }; wpnt->next = NULL; - /* - * search file - */ - - if (FindFile(buffer, sizeof(buffer), modulename, Extensions, WindowsPath) - ==NULL) - { - char temp[256]; - - sprintf(temp,"LoadImage: I can't find %s !\n",modulename); - myerror(temp); - } - fprintf(stderr,"LoadImage: loading %s (%s)\n", modulename, buffer); - /* * Open file for reading. */ @@ -251,6 +255,31 @@ HINSTANCE LoadImage(char *modulename) return(wpnt->hinstance); } +/********************************************************************** + * ParseArgs + */ +void +ParseArgs(int argc, char **argv) +{ + if (argc < 2) + { + fprintf(stderr, "usage: %s [-spy FILENAME] FILENAME\n", argv[0]); + exit(1); + } + + Argc = argc - 1; + + for (Argv = argv + 1; **Argv == '-' && Argc > 0; Argv++) + { + if (strcmp(*Argv, "-spy") == 0) + { + if (strcmp(*(++Argv), "-") == 0) + SpyFp = stdout; + else + SpyFp = fopen(*Argv, "a"); + } + } +} /********************************************************************** * main @@ -260,6 +289,7 @@ _WinMain(int argc, char **argv) int segment; char *p; char *sysresname; + char filename[100]; char syspath[256]; char exe_path[256]; #ifdef WINESTAT @@ -269,15 +299,8 @@ _WinMain(int argc, char **argv) int cs_reg, ds_reg, ss_reg, ip_reg, sp_reg; int i; int rv; - - Argc = argc - 1; - Argv = argv + 1; - - if (argc < 2) - { - fprintf(stderr, "usage: %s FILENAME\n", argv[0]); - exit(1); - } + + ParseArgs(argc, argv); p = getenv("WINEPATH"); WinePath = malloc(256 + strlen(p)); @@ -285,27 +308,17 @@ _WinMain(int argc, char **argv) strcat(WinePath, ";"); strcat(WinePath, p); - LoadImage(argv[1]); - hSysRes = LoadImage("sysres.dll"); + LoadImage(Argv[0]); + + GetPrivateProfileString("wine", "SystemResources", "sysres.dll", + filename, sizeof(filename), + WINE_INI); + hSysRes = LoadImage(filename); if (hSysRes == (HINSTANCE)NULL) printf("Error Loading System Resources !!!\n"); else printf("System Resources Loaded // hSysRes='%04X'\n", hSysRes); - if(ran_out) exit(1); -#ifdef DEBUG - { - int dummy1, dummy2; - - GetEntryDLLName("USER", "INITAPP", &dummy1, &dummy2); - } - for(i=0; i<1024; i++) { - int j; - j = GetEntryPointFromOrdinal(wine_files, i); - if(j == 0) break; - fprintf(stderr," %d %x\n", i, j); - }; -#endif /* * Fixup references. */ @@ -442,8 +455,10 @@ FixupSegment(struct w_files * wpnt, int segment_num) seg = &seg_table[segment_num]; sel = &selector_table[segment_num]; - fprintf(stderr, "Segment fixups for %s, segment %d, selector %x\n", - wpnt->name, segment_num, (int) sel->base_addr >> 16); +#ifdef DEBUG_FIXUP + printf("Segment fixups for %s, segment %d, selector %x\n", + wpnt->name, segment_num, (int) sel->base_addr >> 16); +#endif if ((seg->seg_data_offset == 0) || !(seg->seg_flags & NE_SEGFLAGS_RELOC_DATA)) @@ -589,13 +604,6 @@ FixupSegment(struct w_files * wpnt, int segment_num) rep->target1, rep->target2); free(rep1); return -1; -#if 0 - sp = (unsigned short *) ((char *) sel->base_addr + rep->offset); - fprintf(stderr, " FIXUP ADDRESS %04.4x:%04.4x\n", - (int) sel->base_addr >> 16, rep->offset); - WineForceFail = 1; - continue; -#endif } /* @@ -619,6 +627,10 @@ FixupSegment(struct w_files * wpnt, int segment_num) { case NE_RADDR_OFFSET16: do { +#ifdef DEBUG_FIXUP + printf(" %04.4x:%04.4x:%04.4x OFFSET16\n", + (unsigned long) sp >> 16, (int) sp & 0xFFFF, *sp); +#endif next_addr = *sp; *sp = (unsigned short) address; if (additive == 2) @@ -631,6 +643,10 @@ FixupSegment(struct w_files * wpnt, int segment_num) case NE_RADDR_POINTER32: do { +#ifdef DEBUG_FIXUP + printf(" %04.4x:%04.4x:%04.4x POINTER32\n", + (unsigned long) sp >> 16, (int) sp & 0xFFFF, *sp); +#endif next_addr = *sp; *sp = (unsigned short) address; if (additive == 2) @@ -644,11 +660,15 @@ FixupSegment(struct w_files * wpnt, int segment_num) case NE_RADDR_SELECTOR: do { +#ifdef DEBUG_FIXUP + printf(" %04.4x:%04.4x:%04.4x SELECTOR\n", + (unsigned long) sp >> 16, (int) sp & 0xFFFF, *sp); +#endif next_addr = *sp; *sp = (unsigned short) selector; sp = (unsigned short *) ((char *) sel->base_addr + next_addr); - if (rep->relocation_type == NE_RELTYPE_INT1) break; - + if (rep->relocation_type == NE_RELTYPE_INT1) + break; } while (next_addr != 0xffff && !additive); diff --git a/memory/atom.c b/memory/atom.c index 1fd5f489f89..ad0345e8985 100644 --- a/memory/atom.c +++ b/memory/atom.c @@ -24,6 +24,7 @@ * integer atoms, use the "#1234" form. */ +#include #include #include @@ -90,7 +91,7 @@ static WORD ATOM_Hash( WORD entries, LPCSTR str, WORD len ) { WORD i, hash = 0; - for (i = 0; i < len; i++) hash ^= str[i] + i; + for (i = 0; i < len; i++) hash ^= toupper(str[i]) + i; return hash % entries; } diff --git a/misc/Makefile b/misc/Makefile index 8cdcee9ea77..6fa5c19a167 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -2,7 +2,7 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I../include OBJS=kernel.o user.o xt.o rect.o file.o sound.o emulate.o \ keyboard.o profile.o lstr.o exec.o message.o int1a.o int21.o \ - dos_fs.o comm.o + dos_fs.o comm.o spy.o default: misc.o diff --git a/misc/dos_fs.c b/misc/dos_fs.c index e0722741415..57aed8d6ebd 100644 --- a/misc/dos_fs.c +++ b/misc/dos_fs.c @@ -661,7 +661,7 @@ char *WineIniFileName(void) char *WinIniFileName() { - char name[256]; + static char name[256]; strcpy(name,GetDirectUnixFileName(WindowsDirectory)); strcat(name,"win.ini"); diff --git a/misc/lstr.c b/misc/lstr.c index 77e178cadbc..bd30f8804cb 100644 --- a/misc/lstr.c +++ b/misc/lstr.c @@ -52,7 +52,7 @@ LPSTR lstrcpyn(LPSTR target,LPCSTR source,int n) /* KERNEL.90 */ int lstrlen(LPCSTR str) { - strlen(str); + return strlen(str); } /* AnsiUpper USER.431 */ diff --git a/misc/profile.c b/misc/profile.c index 12d12fe2704..f150c9c4bee 100644 --- a/misc/profile.c +++ b/misc/profile.c @@ -125,7 +125,7 @@ static TSecHeader *load (char *file) if (c == ' ' || c == '\t') break; - if (c == '\n' || overflow) /* Abort Definition */ + if (c == '\n' || c == ';' || overflow) /* Abort Definition */ next = CharBuffer; if (c == '=' || overflow){ diff --git a/misc/rect.c b/misc/rect.c index 4fd7be4ec3c..6adc0a52748 100644 --- a/misc/rect.c +++ b/misc/rect.c @@ -152,8 +152,12 @@ BOOL SubtractRect( LPRECT dest, LPRECT src1, LPRECT src2 ) *dest = *src1; if (IntersectRect( &tmp, src1, src2 )) { - if (EqualRect( &tmp, dest )) SetRectEmpty( src1 ); - else if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom)) + if (EqualRect( &tmp, dest )) + { + SetRectEmpty( dest ); + return FALSE; + } + if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom)) { if (tmp.left == dest->left) dest->right = tmp.right; else if (tmp.right == dest->right) dest->left = tmp.left; diff --git a/misc/spy.c b/misc/spy.c new file mode 100644 index 00000000000..d45ebb2a2f3 --- /dev/null +++ b/misc/spy.c @@ -0,0 +1,257 @@ +/* SPY.C + * + * Copyright 1994, Bob Amstadt + */ + +#include +#include +#include "wineopts.h" +#include "windows.h" +#include "wine.h" + +#ifndef NOSPY + +#define SPY_MAX_MSGNUM 0x0210 + +const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = +{ + "WM_NULL", /* 0x00 */ + "WM_CREATE", + "WM_DESTROY", + "WM_MOVE", + "WM_UNUSED0", + "WM_SIZE", + "WM_ACTIVATE", + "WM_SETFOCUS", + "WM_KILLFOCUS", + "WM_UNUSED1", + "WM_ENABLE", + "WM_SETREDRAW", + "WM_SETTEXT", + "WM_GETTEXT", + "WM_GETTEXTLENGTH", + "WM_PAINT", + "WM_CLOSE", /* 0x10 */ + "WM_QUERYENDSESSION", + "WM_QUIT", + "WM_QUERYOPEN", + "WM_ERASEBKGND", + "WM_SYSCOLORCHANGE", + "WM_ENDSESSION", + "WM_UNUSED2", + "WM_SHOWWINDOW", + "WM_CTLCOLOR", + "WM_WININICHANGE", + "WM_DEVMODECHANGE", + "WM_ACTIVATEAPP", + "WM_FONTCHANGE", + "WM_TIMECHANGE", + "WM_CANCELMODE", + "WM_SETCURSOR", /* 0x20 */ + "WM_MOUSEACTIVATE", + "WM_CHILDACTIVATE", + "WM_QUEUESYNC", + "WM_GETMINMAXINFO", + "WM_UNUSED3", + "WM_PAINTICON", + "WM_ICONERASEBKGND", + "WM_NEXTDLGCTL", + "WM_UNUSED4", + "WM_SPOOLERSTATUS", + "WM_DRAWITEM", + "WM_MEASUREITEM", + "WM_DELETEITEM", + "WM_VKEYTOITEM", + "WM_CHARTOITEM", + "WM_SETFONT", /* 0x30 */ + "WM_GETFONT", NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x40 */ + NULL, NULL, NULL, NULL, NULL, NULL, + "WM_WINDOWPOSCHANGING", /* 0x0046 */ + "WM_WINDOWPOSCHANGED", /* 0x0047 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x0050 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x0060 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x0070 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + NULL, /* 0x0080 */ + "WM_NCCREATE", /* 0x0081 */ + "WM_NCDESTROY", /* 0x0082 */ + "WM_NCCALCSIZE", /* 0x0083 */ + NULL, NULL, NULL, + "WM_GETDLGCODE", /* 0x0087 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x0090 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x00A0 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x00B0 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x00C0 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x00D0 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x00E0 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x00F0 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + "WM_KEYDOWN", /* 0x0100 */ + "WM_KEYUP", /* 0x0101 */ + "WM_CHAR", /* 0x0102 */ + "WM_DEADCHAR", /* 0x0103 */ + "WM_SYSKEYDOWN", /* 0x0104 */ + "WM_SYSKEYUP", /* 0x0105 */ + "WM_SYSCHAR", /* 0x0106 */ + "WM_SYSDEADCHAR", /* 0x0107 */ + "WM_KEYLAST", /* 0x0108 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + "WM_INITDIALOG", /* 0x0110 */ + "WM_COMMAND", /* 0x0111 */ + NULL, + "WM_TIMER", /* 0x0113 */ + "WM_HSCROLL", /* 0x0114 */ + "WM_VSCROLL", /* 0x0115 */ + NULL, NULL, + "WM_SYSTIMER", /* 0x0118 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x0120 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x0130 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x0140 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x0150 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x0160 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x0170 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x0180 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x0190 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x01A0 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x01B0 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x01C0 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x01D0 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x01E0 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x01F0 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + "WM_MOUSEMOVE", /* 0x0200 */ + "WM_LBUTTONDOWN", /* 0x0201 */ + "WM_LBUTTONUP", /* 0x0202 */ + "WM_LBUTTONDBLCLK", /* 0x0203 */ + "WM_RBUTTONDOWN", /* 0x0204 */ + "WM_RBUTTONUP", /* 0x0205 */ + "WM_RBUTTONDBLCLK", /* 0x0206 */ + "WM_MBUTTONDOWN", /* 0x0207 */ + "WM_MBUTTONUP", /* 0x0208 */ + "WM_MBUTTONDBLCLK", /* 0x0209 */ + "WM_PARENTNOTIFY", /* 0x0210 */ +}; + +#endif /* NOSPY */ + +/********************************************************************** + * SpyMessage + */ +void SpyMessage(HWND hwnd, WORD msg, WORD wParam, LONG lParam) +{ +#ifndef NOSPY + if (SpyFp == NULL) + return; + + if (msg > SPY_MAX_MSGNUM || MessageTypeNames[msg] == NULL) + { + fprintf(SpyFp, "%04.4x %04.4x %04.4x %08.8x\n", + hwnd, msg, wParam, lParam); + } + else + { + fprintf(SpyFp, "%04.4x %20.20s %04.4x %08.8x\n", + hwnd, MessageTypeNames[msg], wParam, lParam); + } +#endif +} + +/********************************************************************** + * SpyInit + */ +void SpyInit(void) +{ + char filename[100]; + + if (SpyFp == NULL) + return; + + GetPrivateProfileString("spy", "file", "", filename, sizeof(filename), + WINE_INI); + + if (strcasecmp(filename, "CON") == 0) + SpyFp = stdout; + else if (strlen(filename)) + SpyFp = fopen(filename, "a"); + else + SpyFp = NULL; +} diff --git a/misc/user.c b/misc/user.c index 501448cd55d..d8e0596360a 100644 --- a/misc/user.c +++ b/misc/user.c @@ -16,6 +16,7 @@ MDESC *USER_Heap = NULL; extern BOOL ATOM_Init(); extern BOOL GDI_Init(); +extern void SYSMETRICS_Init(); /*********************************************************************** * USER_HeapInit @@ -40,13 +41,16 @@ USER_InitApp(int hInstance) { int queueSize; + SpyInit(); + /* Global atom table initialisation */ if (!ATOM_Init()) return 0; /* GDI initialisation */ if (!GDI_Init()) return 0; - /* Initialize system colors */ + /* Initialize system colors and metrics*/ + SYSMETRICS_Init(); SYSCOLOR_Init(); /* Create USER heap */ diff --git a/misc/xt.c b/misc/xt.c index a829a5b8429..44585210255 100644 --- a/misc/xt.c +++ b/misc/xt.c @@ -22,6 +22,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; Display * XT_display; Screen * XT_screen; +Display * display; +Screen * screen; XtAppContext XT_app_context; static Widget topLevelWidget; @@ -40,6 +42,8 @@ void main(int argc, char **argv) NULL ); XT_display = XtDisplay( topLevelWidget ); XT_screen = XtScreen( topLevelWidget ); + display = XtDisplay( topLevelWidget ); + screen = XtScreen( topLevelWidget ); DOS_InitFS(); Comm_Init(); @@ -68,32 +72,3 @@ DWORD GetTickCount() struct tms dummy; return (times(&dummy) * 1000) / HZ; } - - -int GetSystemMetrics( short index ) -{ - printf( "GetSystemMetrics: %d\n", index ); - switch(index) - { - case SM_CXSCREEN: - return DisplayWidth( XT_display, DefaultScreen( XT_display )); - - case SM_CYSCREEN: - return DisplayHeight( XT_display, DefaultScreen( XT_display )); - - default: - return 0; - } -} - -void AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu ) -{ - printf( "AdjustWindowRect: (%d,%d)-(%d,%d) %d %d\n", rect->left, rect->top, - rect->right, rect->bottom, style, menu ); -#ifdef USE_XLIB - rect->right += 8; - rect->bottom += 34; -#endif -} - - diff --git a/objects/brush.c b/objects/brush.c index 11a430bddc9..582349eca26 100644 --- a/objects/brush.c +++ b/objects/brush.c @@ -8,8 +8,6 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "gdi.h" -extern Display * XT_display; -extern Screen * XT_screen; #define NB_HATCH_STYLES 6 diff --git a/objects/clipping.c b/objects/clipping.c index 5776eb857d0..7504b12aeb3 100644 --- a/objects/clipping.c +++ b/objects/clipping.c @@ -20,15 +20,22 @@ void CLIPPING_SetDeviceClipping( DC * dc ) if (dc->w.hGCClipRgn) { RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(dc->w.hGCClipRgn, REGION_MAGIC); - XSetClipMask( XT_display, dc->u.x.gc, obj->region.pixmap ); - XSetClipOrigin( XT_display, dc->u.x.gc, - dc->w.DCOrgX + obj->region.box.left, - dc->w.DCOrgY + obj->region.box.top ); + if (obj->region.pixmap) + { + XSetClipMask( display, dc->u.x.gc, obj->region.pixmap ); + XSetClipOrigin( display, dc->u.x.gc, + dc->w.DCOrgX + obj->region.box.left, + dc->w.DCOrgY + obj->region.box.top ); + } + else /* Clip everything */ + { + XSetClipRectangles( display, dc->u.x.gc, 0, 0, NULL, 0, 0 ); + } } else { - XSetClipMask( XT_display, dc->u.x.gc, None ); - XSetClipOrigin( XT_display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY ); + XSetClipMask( display, dc->u.x.gc, None ); + XSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY ); } } diff --git a/objects/dib.c b/objects/dib.c index 735e449e001..15e3d09594b 100644 --- a/objects/dib.c +++ b/objects/dib.c @@ -44,7 +44,7 @@ XImage * DIB_DIBmpToImage( BITMAPINFOHEADER * bmp, void * bmpData ) XImage * image; int bytesPerLine = (bmp->biWidth * bmp->biBitCount + 31) / 32 * 4; - image = XCreateImage( XT_display, DefaultVisualOfScreen( XT_screen ), + image = XCreateImage( display, DefaultVisualOfScreen( screen ), bmp->biBitCount, ZPixmap, 0, bmpData, bmp->biWidth, bmp->biHeight, 32, bytesPerLine ); if (!image) return 0; diff --git a/objects/font.c b/objects/font.c index 10bc76b7b08..8345e0b1323 100644 --- a/objects/font.c +++ b/objects/font.c @@ -11,9 +11,6 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include #include "gdi.h" -extern Display * XT_display; -extern Screen * XT_screen; - /*********************************************************************** * FONT_MatchFont diff --git a/objects/gdiobj.c b/objects/gdiobj.c index cc539a49025..1b98fc8db81 100644 --- a/objects/gdiobj.c +++ b/objects/gdiobj.c @@ -8,8 +8,6 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "gdi.h" -extern Display * XT_display; -extern Screen * XT_screen; MDESC *GDI_Heap = NULL; diff --git a/objects/linedda.c b/objects/linedda.c index 6d8a1cfef84..e61290dab75 100644 --- a/objects/linedda.c +++ b/objects/linedda.c @@ -7,7 +7,7 @@ static char Copyright[] = "Copyright Bob Amstadt, 1993"; #include -#include "win.h" +#include "windows.h" /********************************************************************** * LineDDA (GDI.100) diff --git a/objects/palette.c b/objects/palette.c index 511cf3f0efb..f107a618d0c 100644 --- a/objects/palette.c +++ b/objects/palette.c @@ -18,9 +18,6 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "gdi.h" -extern Display * XT_display; -extern Screen * XT_screen; - extern Colormap COLOR_WinColormap; GDIOBJHDR * PALETTE_systemPalette; @@ -36,7 +33,7 @@ BOOL PALETTE_Init() HPALETTE hpalette; LOGPALETTE * palPtr; - size = DefaultVisual( XT_display, DefaultScreen(XT_display) )->map_entries; + size = DefaultVisual( display, DefaultScreen(display) )->map_entries; palPtr = malloc( sizeof(LOGPALETTE) + (size-1)*sizeof(PALETTEENTRY) ); if (!palPtr) return FALSE; palPtr->palVersion = 0x300; @@ -46,7 +43,7 @@ BOOL PALETTE_Init() for (i = 0; i < size; i++) { color.pixel = i; - XQueryColor( XT_display, COLOR_WinColormap, &color ); + XQueryColor( display, COLOR_WinColormap, &color ); palPtr->palPalEntry[i].peRed = color.red >> 8; palPtr->palPalEntry[i].peGreen = color.green >> 8; palPtr->palPalEntry[i].peBlue = color.blue >> 8; @@ -132,7 +129,7 @@ WORD GetNearestPaletteIndex( HPALETTE hpalette, COLORREF color ) palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC ); if (!palPtr) return 0; - if ((COLOR_WinColormap != DefaultColormapOfScreen(XT_screen)) && + if ((COLOR_WinColormap != DefaultColormapOfScreen(screen)) && (hpalette == STOCK_DEFAULT_PALETTE)) { if ((color & 0xffffff) == 0) return 0; /* Entry 0 is black */ diff --git a/objects/pen.c b/objects/pen.c index fa49ef3d2f0..a0a7ad78632 100644 --- a/objects/pen.c +++ b/objects/pen.c @@ -8,9 +8,6 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "gdi.h" -extern Display * XT_display; -extern Screen * XT_screen; - /*********************************************************************** * CreatePen (GDI.61) diff --git a/objects/text.c b/objects/text.c index 07aef5835c4..787b0f72737 100644 --- a/objects/text.c +++ b/objects/text.c @@ -6,15 +6,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; -#include -#include -#include -#include #include -#include "message.h" -#include "callback.h" -#include "win.h" #include "gdi.h" #define TAB 9 @@ -224,8 +217,8 @@ int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags ) if (flags & DT_SINGLELINE) { - if (flags & DT_VCENTER) y = (rect->top + rect->bottom - - size.cy) / 2; + if (flags & DT_VCENTER) y = rect->top + + (rect->bottom - rect->top) / 2 - size.cy / 2; else if (flags & DT_BOTTOM) y = rect->bottom - size.cy; } diff --git a/sysres.dll b/sysres.dll index 38c7ca909d2540ae5515dee73c18b4706a6d6a08..0a61ba9a491c21246805e04115b6c36566e65299 100755 GIT binary patch delta 9503 zcmeI2-)~e!6vyZ8ZrKHkTPiAGwM9#05^0+m ziNw|CYV*v`>1=g2!fHgGT3iR^KYr#vwk?aCiRhO}>`VZ*N2LBGe9GnMV0sakqCHPnH9I*cj8gtS389WdC z6Zk6dkKj7+58$i8--E9Ke+RAye+zB^e*>Nm{u+EO_$%;rJ{rf-XapYvF906}H-Wzd zUl0BQ+zbxDH-JaMH-gWCZvu~iTfqN-7lO|OKBuu2jng=>NJS~7e}ivP5#m$eCD1tu zz7_lz_%`qf@a^C~!Aq%%7FVY*T+3CKxC8tqbb7$Ctmm_R^%e{39)Peai~rQykZnd| zKX?cD9q=A-)D+yi~Lp5@{YywY;*UkM)ia;fxthRua9Lpeh|W8!GKfnnzKBWfpxp5ynAc8+buB zCpUmtrBgKE&=dz=?ua`{2z|^TIej)eVToki(#bd_HFdA4n8#cheHwFxT9AI0OGjx_47jz-9RwynM2B6{ zYzD}T?Nbvky~+rYBD9uVZ^&hlyY6#T5*E!xR%Z;`5DS!?e1>5$i4#*2Vp@79GiDZ{ zBy%JZBD0JThbtkv?CLOQY=};$WWX_I!{Pu%J{2L7Q3-_yRJhoE6BfiKT$hoOg3xV< zPNy897$6#t$A&n)hBC%qZ*bP^`k}>LUTj4Wtfh5do8njck>GJP;wv?}qD_s~KOY@U zdNrd-YS*73S?cK#|M)Zfx_>r!3v0z7II%Z1;FZ1w62^}#*_GK147V}4(fcKxREpOL z@~&x_f)?gmLzrHzh11ms_v4Yx{Se!Jh%6uOGa=JhiJV>1Y#v9nN;_1E@W@7J zrNFxD$@om_HZ@!*5-RR?8=jjRuD-D$x%sYic&?k=p2uVC=xec#C z$;o9nV&@;;ljuUs7xYYbo0Ze#Wtg0@;W5j|aHtZV%dQS{7#>evp#jGjd12+2D?NHV zmxvXfV++mqvL#8 zzx_)`dFoEs44oL@W(k(J{|VNJ7kB9 zq@$rvIRf2J3Bep=$#yE12On%%HkfZt48GWMgchl_b<_!e<+qOg-au*&|JZS-kK*Tw z$34KC(Y#Ho|D%3M%3uATQrN=H)9JjTgSj?HCV})mz_8!>9O@7)K;pvhmLjFmYX3IX?aCa2xoRycws60AM(XSh>k37|z zK-|6gf}eG$6!D@``1>{GK&dI*EUfVbgN2rZf@EwEjq2#G}W|f`_5fkr>C~}FT7_7Wb{`a zaq1znt$)iy4gEVCT3cJEuj+qf`@;5JTeN~X?(N#+HMc$M^{5{8g1VQbHQ4i_*(jht x?C5!d{+43R-D@_jPIcYAZ(Zz&*K#h}^2Zi*#b@54bGgF#bBxz-Zt)H+_!k-V`ZfRn delta 386 zcmXZYF=_%q6b9h;-psD+xEnWVY_<^M0anNXQfMED*jb1d@CFW;BCS}25JW_S0h?fo zG#+BH6ps>!Grv19%s2nc8y;he&~Ae7p2&&keQ8b(T=0?Gn%tsM*J>UQkTu9Uk6=|c@Z9~h5zm^A(t|* diff --git a/test/widget.exe b/test/widget.exe index ea5dc2f8bf328cb955a66477af23da5f561865ef..95413e0ec83f71550bdaf87c51da35d2fbff30b6 100755 GIT binary patch delta 25963 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 Oq??5tQP|pqkpBaTnX@_o delta 23072 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 diff --git a/windows/Makefile b/windows/Makefile index 30570a109c9..8ac8efab582 100644 --- a/windows/Makefile +++ b/windows/Makefile @@ -2,7 +2,8 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR) OBJS=class.o dc.o dce.o event.o message.o win.o timer.o graphics.o \ clipping.o mapping.o painting.o keyboard.o utility.o syscolor.o \ - defwnd.o defdlg.o dialog.o focus.o scroll.o caret.o winpos.o + defwnd.o defdlg.o dialog.o focus.o scroll.o caret.o winpos.o \ + sysmetrics.o nonclient.o default: windows.o diff --git a/windows/caret.c b/windows/caret.c index eb78dc80ec1..566e32179e5 100644 --- a/windows/caret.c +++ b/windows/caret.c @@ -6,12 +6,8 @@ static char Copyright[] = "Copyright David Metcalfe, 1993"; -#include - #include "windows.h" -extern XtAppContext XT_app_context; - typedef struct { HWND hwnd; @@ -23,49 +19,46 @@ typedef struct short height; COLORREF color; WORD timeout; - XtIntervalId xtid; + WORD timerid; } CARET; static CARET Caret; static BOOL LockCaret; -static void CARET_Callback(XtPointer data, XtIntervalId *xtid); -static void CARET_HideCaret(CARET *pCaret); +static WORD CARET_Callback(HWND hwnd, WORD msg, WORD timerid, LONG ctime); +static void CARET_HideCaret(); /***************************************************************** * CARET_Callback */ -static void CARET_Callback(XtPointer data, XtIntervalId *xtid) +static WORD CARET_Callback(HWND hwnd, WORD msg, WORD timerid, LONG ctime) { - CARET *pCaret = (CARET *)data; HDC hdc; HBRUSH hBrush; HRGN rgn; #ifdef DEBUG_CARET - printf("CARET_Callback: LockCaret=%d, hidden=%d, on=%d\n", - LockCaret, pCaret->hidden, pCaret->on); + printf("CARET_Callback: id=%d: LockCaret=%d, hidden=%d, on=%d\n", + timerid, LockCaret, Caret.hidden, Caret.on); #endif - if (!LockCaret && (!pCaret->hidden || pCaret->on)) + if (!LockCaret && (!Caret.hidden || Caret.on)) { - pCaret->on = (pCaret->on ? FALSE : TRUE); - hdc = GetDC(pCaret->hwnd); - hBrush = CreateSolidBrush(pCaret->color); + Caret.on = (Caret.on ? FALSE : TRUE); + hdc = GetDC(Caret.hwnd); + hBrush = CreateSolidBrush(Caret.color); SelectObject(hdc, (HANDLE)hBrush); SetROP2(hdc, R2_XORPEN); - rgn = CreateRectRgn(pCaret->x, pCaret->y, - pCaret->x + pCaret->width, - pCaret->y + pCaret->height); + rgn = CreateRectRgn(Caret.x, Caret.y, + Caret.x + Caret.width, + Caret.y + Caret.height); FillRgn(hdc, rgn, hBrush); DeleteObject((HANDLE)rgn); DeleteObject((HANDLE)hBrush); - ReleaseDC(pCaret->hwnd, hdc); + ReleaseDC(Caret.hwnd, hdc); } - - pCaret->xtid = XtAppAddTimeOut(XT_app_context, pCaret->timeout, - CARET_Callback, pCaret); + return 0; } @@ -73,24 +66,24 @@ static void CARET_Callback(XtPointer data, XtIntervalId *xtid) * CARET_HideCaret */ -static void CARET_HideCaret(CARET *pCaret) +static void CARET_HideCaret() { HDC hdc; HBRUSH hBrush; HRGN rgn; - pCaret->on = FALSE; - hdc = GetDC(pCaret->hwnd); - hBrush = CreateSolidBrush(pCaret->color); + Caret.on = FALSE; + hdc = GetDC(Caret.hwnd); + hBrush = CreateSolidBrush(Caret.color); SelectObject(hdc, (HANDLE)hBrush); SetROP2(hdc, R2_XORPEN); - rgn = CreateRectRgn(pCaret->x, pCaret->y, - pCaret->x + pCaret->width, - pCaret->y + pCaret->height); + rgn = CreateRectRgn(Caret.x, Caret.y, + Caret.x + Caret.width, + Caret.y + Caret.height); FillRgn(hdc, rgn, hBrush); DeleteObject((HANDLE)rgn); DeleteObject((HANDLE)hBrush); - ReleaseDC(pCaret->hwnd, hdc); + ReleaseDC(Caret.hwnd, hdc); } @@ -102,6 +95,7 @@ void CreateCaret(HWND hwnd, HBITMAP bitmap, short width, short height) { if (!hwnd) return; + /* if cursor already exists, destroy it */ /* if (Caret.hwnd) DestroyCaret(); @@ -131,8 +125,11 @@ void CreateCaret(HWND hwnd, HBITMAP bitmap, short width, short height) Caret.timeout = 750; LockCaret = FALSE; - Caret.xtid = XtAppAddTimeOut(XT_app_context, Caret.timeout, - CARET_Callback, &Caret); + Caret.timerid = SetSystemTimer(NULL, 0, Caret.timeout, CARET_Callback); + +#ifdef DEBUG_CARET + printf("CreateCaret: hwnd=%d, timerid=%d\n", hwnd, Caret.timerid); +#endif } @@ -144,10 +141,14 @@ void DestroyCaret() { /* if (!Caret.hwnd) return; */ - XtRemoveTimeOut(Caret.xtid); +#ifdef DEBUG_CARET + printf("DestroyCaret: timerid\n", Caret.timerid); +#endif + + KillSystemTimer(NULL, Caret.timerid); if (Caret.on) - CARET_HideCaret(&Caret); + CARET_HideCaret(); Caret.hwnd = 0; /* cursor marked as not existing */ } @@ -171,7 +172,7 @@ void SetCaretPos(short x, short y) LockCaret = TRUE; if (Caret.on) - CARET_HideCaret(&Caret); + CARET_HideCaret(); Caret.x = x; Caret.y = y; @@ -189,7 +190,7 @@ void HideCaret(HWND hwnd) LockCaret = TRUE; if (Caret.on) - CARET_HideCaret(&Caret); + CARET_HideCaret(); ++Caret.hidden; LockCaret = FALSE; @@ -221,7 +222,9 @@ void SetCaretBlinkTime(WORD msecs) { if (!Caret.hwnd) return; + KillSystemTimer(NULL, Caret.timerid); Caret.timeout = msecs; + Caret.timerid = SetSystemTimer(NULL, 0, Caret.timeout, CARET_Callback); } diff --git a/windows/dce.c b/windows/dce.c index 7b24f1d4d94..5aef283c7f7 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -15,8 +15,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #define NB_DCE 5 /* Number of DCEs created at startup */ -extern Display * XT_display; -extern Screen * XT_screen; +extern Display * display; static HANDLE firstDCE = 0; static HDC defaultDCstate = 0; @@ -159,11 +158,11 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) IntersectVisRect( hdc, 0, 0, dc->w.DCSizeX, dc->w.DCSizeY ); } } - else dc->u.x.drawable = DefaultRootWindow( XT_display ); + else dc->u.x.drawable = DefaultRootWindow( display ); if (flags & DCX_CLIPCHILDREN) - XSetSubwindowMode( XT_display, dc->u.x.gc, ClipByChildren ); - else XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors); + XSetSubwindowMode( display, dc->u.x.gc, ClipByChildren ); + else XSetSubwindowMode( display, dc->u.x.gc, IncludeInferiors); if ((flags & DCX_INTERSECTRGN) || (flags & DCX_EXCLUDERGN)) { @@ -216,7 +215,7 @@ HDC GetWindowDC( HWND hwnd ) int ReleaseDC( HWND hwnd, HDC hdc ) { HANDLE hdce; - DCE * dce; + DCE * dce = NULL; #ifdef DEBUG_DC printf( "ReleaseDC: %d %d\n", hwnd, hdc ); @@ -227,11 +226,12 @@ int ReleaseDC( HWND hwnd, HDC hdc ) if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return 0; if (dce->inUse && (dce->hdc == hdc)) break; } + if (!hdce) return 0; if (dce->type == DCE_CACHE_DC) { SetDCState( dce->hdc, defaultDCstate ); dce->inUse = FALSE; } - return (hdce != 0); + return 1; } diff --git a/windows/defwnd.c b/windows/defwnd.c index e2f9a397885..dc75bc1bcca 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -6,17 +6,19 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; -#ifndef USE_XLIB -#include -#include -#endif #include "windows.h" #include "win.h" #include "class.h" #include "user.h" -extern Display * XT_display; +extern Display * display; + +extern LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn ); +extern LONG NC_HandleNCCalcSize( HWND hwnd, NCCALCSIZE_PARAMS *params ); +extern LONG NC_HandleNCHitTest( HWND hwnd, POINT pt ); +extern LONG NC_HandleNCMouseMsg(HWND hwnd, WORD msg, WORD wParam, LONG lParam); + /*********************************************************************** * DefWindowProc (USER.107) @@ -26,6 +28,7 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) CLASS * classPtr; LPSTR textPtr; int len; + int tempwidth, tempheight; WND * wndPtr = WIN_FindWndPtr( hwnd ); #ifdef DEBUG_MESSAGE @@ -51,40 +54,19 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) } case WM_NCCALCSIZE: - { -#ifdef USE_XLIB - NCCALCSIZE_PARAMS *params = (NCCALCSIZE_PARAMS *)lParam; - if (wndPtr->dwStyle & WS_CHILD) - { - if (wndPtr->dwStyle & WS_BORDER) - { - params->rgrc[0].left += 1; /* SM_CXBORDER */ - params->rgrc[0].top += 1; /* SM_CYBORDER */ - params->rgrc[0].right -= 1; /* SM_CXBORDER */ - params->rgrc[0].bottom -= 1; /* SM_CYBORDER */ - } - } - else - { - params->rgrc[0].left += 4; /* SM_CXFRAME */ - params->rgrc[0].top += 30; /* SM_CYFRAME+SM_CYCAPTION */ - params->rgrc[0].right -= 4; /* SM_CXFRAME */ - params->rgrc[0].bottom -= 4; /* SM_CYFRAME */ - if (wndPtr->dwStyle & WS_VSCROLL) - { - params->rgrc[0].right -= 16; /* SM_CXVSCROLL */ - } - if (wndPtr->dwStyle & WS_HSCROLL) - { - params->rgrc[0].bottom += 16; /* SM_CYHSCROLL */ - } - } -#endif - return 0; - } - - case WM_CREATE: - return 0; + return NC_HandleNCCalcSize( hwnd, (NCCALCSIZE_PARAMS *)lParam ); + + case WM_NCPAINT: + return NC_HandleNCPaint( hwnd, (HRGN)wParam ); + + case WM_NCHITTEST: + return NC_HandleNCHitTest( hwnd, MAKEPOINT(lParam) ); + + case WM_NCLBUTTONDOWN: + case WM_NCLBUTTONUP: + case WM_NCLBUTTONDBLCLK: + case WM_NCMOUSEMOVE: + return NC_HandleNCMouseMsg( hwnd, msg, wParam, lParam ); case WM_NCDESTROY: { @@ -188,18 +170,42 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) strlen((LPSTR)lParam) + 1); textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText); strcpy(textPtr, (LPSTR)lParam); -#ifdef USE_XLIB - XStoreName( XT_display, wndPtr->window, textPtr ); -#else - if (wndPtr->shellWidget) - XtVaSetValues( wndPtr->shellWidget, XtNtitle, textPtr, NULL ); -#endif + XStoreName( display, wndPtr->window, textPtr ); return (0L); } case WM_SETCURSOR: if (wndPtr->hCursor != (HCURSOR)NULL) SetCursor(wndPtr->hCursor); return 0L; + case WM_SYSCOMMAND: + switch (wParam) + { + case SC_CLOSE: + ShowWindow(hwnd, SW_MINIMIZE); + printf("defdwndproc WM_SYSCOMMAND SC_CLOSE !\n"); + return SendMessage( hwnd, WM_CLOSE, 0, 0 ); + case SC_RESTORE: + ShowWindow(hwnd, SW_RESTORE); + break; + case SC_MINIMIZE: + ShowWindow(hwnd, SW_MINIMIZE); + printf("defdwndproc WM_SYSCOMMAND SC_MINIMIZE !\n"); + break; + case SC_MAXIMIZE: + ShowWindow(hwnd, SW_MAXIMIZE); + break; + } + break; + case WM_SYSKEYDOWN: + if (wParam == VK_MENU) { + printf("VK_MENU Pressed // hMenu=%04X !\n", GetMenu(hwnd)); + } + break; + case WM_SYSKEYUP: + if (wParam == VK_MENU) { + printf("VK_MENU Released // hMenu=%04X !\n", GetMenu(hwnd)); + } + break; } return 0; } diff --git a/windows/dialog.c b/windows/dialog.c index 83a03899566..6316e34c05b 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -184,11 +184,13 @@ HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate, HMENU hMenu; HFONT hFont = 0; HWND hwnd; + RECT rect; WND * wndPtr; int i; DLGTEMPLATE template; DLGCONTROLHEADER * header; DIALOGINFO * dlgInfo; + DWORD exStyle = 0; WORD xUnit = xBaseUnit; WORD yUnit = yBaseUnit; @@ -229,7 +231,7 @@ HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate, HFONT oldFont; HDC hdc; - hdc = GetDC(GetDesktopWindow()); + hdc = GetDC(0); oldFont = SelectObject( hdc, hFont ); GetTextMetrics( hdc, &tm ); SelectObject( hdc, oldFont ); @@ -241,14 +243,19 @@ HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate, /* Create dialog main window */ - hwnd = CreateWindow( template.className, template.caption, - template.header->style, - template.header->x * xUnit / 4, - template.header->y * yUnit / 8, - template.header->cx * xUnit / 4, - template.header->cy * yUnit / 8, - owner, hMenu, hInst, - NULL ); + rect.left = rect.top = 0; + rect.right = template.header->cx * xUnit / 4; + rect.bottom = template.header->cy * yUnit / 8; + if (template.header->style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME; + AdjustWindowRectEx( &rect, template.header->style, hMenu, exStyle ); + + hwnd = CreateWindowEx( exStyle, template.className, template.caption, + template.header->style, + rect.left + template.header->x * xUnit / 4, + rect.top + template.header->y * yUnit / 8, + rect.right - rect.left, rect.bottom - rect.top, + owner, hMenu, hInst, + NULL ); if (!hwnd) { if (hFont) DeleteObject( hFont ); diff --git a/windows/event.c b/windows/event.c index 5f3aa3d9e97..b2de49f5500 100644 --- a/windows/event.c +++ b/windows/event.c @@ -6,33 +6,23 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; -#include -#include -#include +#include #include "windows.h" #include "win.h" #include "class.h" +#include "message.h" #define NB_BUTTONS 3 /* Windows can handle 3 buttons */ -static WORD dblclick_time = 300; /* Max. time for a double click (milliseconds) */ -extern Display * XT_display; - - /* Event handlers */ -static void EVENT_expose(); -static void EVENT_key(); -static void EVENT_mouse_motion(); -static void EVENT_mouse_button(); -static void EVENT_structure(); -static void EVENT_focus_change(); -static void EVENT_enter_notify(); +extern Display * display; /* X context to associate a hwnd to an X window */ static XContext winContext = 0; /* State variables */ +static WORD ALTKeyState; static HWND captureWnd = 0; Window winHasCursor = 0; extern HWND hWndFocus; @@ -118,6 +108,17 @@ static char *event_names[] = }; #endif + /* Event handlers */ +static void EVENT_key( HWND hwnd, XKeyEvent *event ); +static void EVENT_ButtonPress( HWND hwnd, XButtonEvent *event ); +static void EVENT_ButtonRelease( HWND hwnd, XButtonEvent *event ); +static void EVENT_MotionNotify( HWND hwnd, XMotionEvent *event ); +static void EVENT_EnterNotify( HWND hwnd, XCrossingEvent *event ); +static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event ); +static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event ); +static void EVENT_Expose( HWND hwnd, XExposeEvent *event ); +static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event ); + /*********************************************************************** * EVENT_ProcessEvent @@ -128,117 +129,72 @@ void EVENT_ProcessEvent( XEvent *event ) { HWND hwnd; XPointer ptr; - Boolean cont_dispatch = TRUE; - XFindContext( XT_display, ((XAnyEvent *)event)->window, winContext, &ptr ); - hwnd = (HWND)ptr & 0xffff; + XFindContext( display, ((XAnyEvent *)event)->window, winContext, &ptr ); + hwnd = (HWND) (int)ptr; #ifdef DEBUG_EVENT - printf( "Got event %s for hwnd %d\n", - event_names[event->type], hwnd ); + printf( "Got event %s for hwnd %d\n", event_names[event->type], hwnd ); #endif switch(event->type) { - case Expose: - EVENT_expose( 0, hwnd, event, &cont_dispatch ); - break; + case KeyPress: + case KeyRelease: + EVENT_key( hwnd, (XKeyEvent*)event ); + break; + + case ButtonPress: + EVENT_ButtonPress( hwnd, (XButtonEvent*)event ); + break; - case KeyPress: - case KeyRelease: - EVENT_key( 0, hwnd, event, &cont_dispatch ); - break; + case ButtonRelease: + EVENT_ButtonRelease( hwnd, (XButtonEvent*)event ); + break; - case MotionNotify: - EVENT_mouse_motion( 0, hwnd, event, &cont_dispatch ); - break; + case MotionNotify: + EVENT_MotionNotify( hwnd, (XMotionEvent*)event ); + break; - case ButtonPress: - case ButtonRelease: - EVENT_mouse_button( 0, hwnd, event, &cont_dispatch ); - break; + case EnterNotify: + EVENT_EnterNotify( hwnd, (XCrossingEvent*)event ); + break; - case CirculateNotify: - case ConfigureNotify: - case MapNotify: - case UnmapNotify: - EVENT_structure( 0, hwnd, event, &cont_dispatch ); - break; + case FocusIn: + EVENT_FocusIn( hwnd, (XFocusChangeEvent*)event ); + break; - case FocusIn: - case FocusOut: - EVENT_focus_change( 0, hwnd, event, &cont_dispatch ); - break; + case FocusOut: + EVENT_FocusOut( hwnd, (XFocusChangeEvent*)event ); + break; - case EnterNotify: - EVENT_enter_notify( 0, hwnd, event, &cont_dispatch ); - break; + case Expose: + EVENT_Expose( hwnd, (XExposeEvent*)event ); + break; + + case ConfigureNotify: + EVENT_ConfigureNotify( hwnd, (XConfigureEvent*)event ); + break; #ifdef DEBUG_EVENT - default: - printf( "Unprocessed event %s for hwnd %d\n", - event_names[event->type], hwnd ); - break; -#endif + default: + printf( "Unprocessed event %s for hwnd %d\n", + event_names[event->type], hwnd ); + break; +#endif } } /*********************************************************************** - * EVENT_AddHandlers + * EVENT_RegisterWindow * - * Add the event handlers to the given window + * Associate an X window to a HWND. */ -#ifdef USE_XLIB -void EVENT_AddHandlers( Window w, int hwnd ) +void EVENT_RegisterWindow( Window w, HWND hwnd ) { if (!winContext) winContext = XUniqueContext(); - XSaveContext( XT_display, w, winContext, (XPointer)hwnd ); -} -#else -void EVENT_AddHandlers( Widget w, int hwnd ) -{ - XtAddEventHandler(w, ExposureMask, FALSE, - EVENT_expose, (XtPointer)hwnd ); - XtAddEventHandler(w, KeyPressMask | KeyReleaseMask, FALSE, - EVENT_key, (XtPointer)hwnd ); - XtAddEventHandler(w, PointerMotionMask, FALSE, - EVENT_mouse_motion, (XtPointer)hwnd ); - XtAddEventHandler(w, ButtonPressMask | ButtonReleaseMask, FALSE, - EVENT_mouse_button, (XtPointer)hwnd ); - XtAddEventHandler(w, StructureNotifyMask, FALSE, - EVENT_structure, (XtPointer)hwnd ); - XtAddEventHandler(w, FocusChangeMask, FALSE, - EVENT_focus_change, (XtPointer)hwnd ); - XtAddEventHandler(w, EnterWindowMask, FALSE, - EVENT_enter_notify, (XtPointer)hwnd ); -} -#endif - - -/*********************************************************************** - * EVENT_RemoveHandlers - * - * Remove the event handlers of the given window - */ -void EVENT_RemoveHandlers( Widget w, int hwnd ) -{ -#ifndef USE_XLIB - XtRemoveEventHandler(w, ExposureMask, FALSE, - EVENT_expose, (XtPointer)hwnd ); - XtRemoveEventHandler(w, KeyPressMask | KeyReleaseMask, FALSE, - EVENT_key, (XtPointer)hwnd ); - XtRemoveEventHandler(w, PointerMotionMask, FALSE, - EVENT_mouse_motion, (XtPointer)hwnd ); - XtRemoveEventHandler(w, ButtonPressMask | ButtonReleaseMask, FALSE, - EVENT_mouse_button, (XtPointer)hwnd ); - XtRemoveEventHandler(w, StructureNotifyMask, FALSE, - EVENT_structure, (XtPointer)hwnd ); - XtRemoveEventHandler(w, FocusChangeMask, FALSE, - EVENT_focus_change, (XtPointer)hwnd ); - XtRemoveEventHandler(w, EnterWindowMask, FALSE, - EVENT_enter_notify, (XtPointer)hwnd ); -#endif + XSaveContext( display, w, winContext, (XPointer)(int)hwnd ); } @@ -262,12 +218,9 @@ static WORD EVENT_XStateToKeyState( int state ) /*********************************************************************** - * EVENT_expose - * - * Handle a X expose event + * EVENT_Expose */ -static void EVENT_expose( Widget w, int hwnd, XExposeEvent *event, - Boolean *cont_dispatch ) +static void EVENT_Expose( HWND hwnd, XExposeEvent *event ) { RECT rect; WND * wndPtr = WIN_FindWndPtr( hwnd ); @@ -288,10 +241,8 @@ static void EVENT_expose( Widget w, int hwnd, XExposeEvent *event, * * Handle a X key event */ -static void EVENT_key( Widget w, int hwnd, XKeyEvent *event, - Boolean *cont_dispatch ) +static void EVENT_key( HWND hwnd, XKeyEvent *event ) { - MSG msg; char Str[24]; XComposeStatus cs; KeySym keysym; @@ -350,25 +301,20 @@ static void EVENT_key( Widget w, int hwnd, XKeyEvent *event, if (event->type == KeyPress) { - msg.hwnd = hwnd; - msg.message = WM_KEYDOWN; - msg.wParam = vkey; + if (vkey == VK_MENU) ALTKeyState = TRUE; keylp.lp1.count = 1; keylp.lp1.code = LOBYTE(event->keycode); keylp.lp1.extended = (extended ? 1 : 0); keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0); keylp.lp1.previous = (KeyDown ? 0 : 1); keylp.lp1.transition = 0; - msg.lParam = keylp.lp2; #ifdef DEBUG_KEY - printf(" wParam=%X, lParam=%lX\n", msg.wParam, msg.lParam); + printf(" wParam=%X, lParam=%lX\n", vkey, keylp.lp2 ); #endif - msg.time = event->time; - msg.pt.x = event->x & 0xffff; - msg.pt.y = event->y & 0xffff; - - hardware_event( hwnd, WM_KEYDOWN, vkey, keylp.lp2, - event->x & 0xffff, event->y & 0xffff, event->time, 0 ); + hardware_event( hwnd, ALTKeyState ? WM_SYSKEYDOWN : WM_KEYDOWN, + vkey, keylp.lp2, + event->x_root & 0xffff, event->y_root & 0xffff, + event->time, 0 ); KeyDown = TRUE; /* The key translation ought to take place in TranslateMessage(). @@ -378,218 +324,145 @@ static void EVENT_key( Widget w, int hwnd, XKeyEvent *event, */ if (count == 1) /* key has an ASCII representation */ { - msg.hwnd = hwnd; - msg.message = WM_CHAR; - msg.wParam = (WORD)Str[0]; - msg.lParam = keylp.lp2; #ifdef DEBUG_KEY - printf("WM_CHAR : wParam=%X\n", msg.wParam); + printf("WM_CHAR : wParam=%X\n", (WORD)Str[0] ); #endif - msg.time = event->time; - msg.pt.x = event->x & 0xffff; - msg.pt.y = event->y & 0xffff; PostMessage( hwnd, WM_CHAR, (WORD)Str[0], keylp.lp2 ); } } else { - msg.hwnd = hwnd; - msg.message = WM_KEYUP; - msg.wParam = vkey; + if (vkey == VK_MENU) ALTKeyState = FALSE; keylp.lp1.count = 1; keylp.lp1.code = LOBYTE(event->keycode); keylp.lp1.extended = (extended ? 1 : 0); keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0); keylp.lp1.previous = 1; keylp.lp1.transition = 1; - msg.lParam = keylp.lp2; #ifdef DEBUG_KEY - printf(" wParam=%X, lParam=%lX\n", msg.wParam, msg.lParam); + printf(" wParam=%X, lParam=%lX\n", vkey, keylp.lp2 ); #endif - msg.time = event->time; - msg.pt.x = event->x & 0xffff; - msg.pt.y = event->y & 0xffff; - - hardware_event( hwnd, WM_KEYUP, vkey, keylp.lp2, - event->x & 0xffff, event->y & 0xffff, event->time, 0 ); + hardware_event( hwnd, + ((ALTKeyState || vkey == VK_MENU) ? + WM_SYSKEYUP : WM_KEYUP), + vkey, keylp.lp2, + event->x_root & 0xffff, event->y_root & 0xffff, + event->time, 0 ); KeyDown = FALSE; } } /*********************************************************************** - * EVENT_mouse_motion - * - * Handle a X mouse motion event + * EVENT_MotionNotify */ -static void EVENT_mouse_motion( Widget w, int hwnd, XMotionEvent *event, - Boolean *cont_dispatch ) +static void EVENT_MotionNotify( HWND hwnd, XMotionEvent *event ) { - WND * wndPtr = WIN_FindWndPtr( hwnd ); - if (!wndPtr) return; - - /* Position must be relative to client area */ - event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left; - event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top; - - hardware_event( hwnd, WM_MOUSEMOVE, EVENT_XStateToKeyState( event->state ), - (event->x & 0xffff) | (event->y << 16), - event->x & 0xffff, event->y & 0xffff, + hardware_event( hwnd, WM_MOUSEMOVE, + EVENT_XStateToKeyState( event->state ), 0L, + event->x_root & 0xffff, event->y_root & 0xffff, event->time, 0 ); } /*********************************************************************** - * EVENT_mouse_button - * - * Handle a X mouse button event + * EVENT_ButtonPress */ -static void EVENT_mouse_button( Widget w, int hwnd, XButtonEvent *event, - Boolean *cont_dispatch ) +static void EVENT_ButtonPress( HWND hwnd, XButtonEvent *event ) { - static WORD messages[3][NB_BUTTONS] = - { - { WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN }, - { WM_LBUTTONUP, WM_MBUTTONUP, WM_RBUTTONUP }, - { WM_LBUTTONDBLCLK, WM_MBUTTONDBLCLK, WM_RBUTTONDBLCLK } - }; - static unsigned long lastClickTime[NB_BUTTONS] = { 0, 0, 0 }; - - int buttonNum, prevTime, type; + static WORD messages[NB_BUTTONS] = + { WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN }; + int buttonNum = event->button - 1; - WND * wndPtr = WIN_FindWndPtr( hwnd ); - if (!wndPtr) return; - - /* Position must be relative to client area */ - event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left; - event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top; - - buttonNum = event->button-1; - if (buttonNum >= NB_BUTTONS) return; - if (event->type == ButtonRelease) type = 1; - else - { /* Check if double-click */ - prevTime = lastClickTime[buttonNum]; - lastClickTime[buttonNum] = event->time; - if (event->time - prevTime < dblclick_time) - { - WND * wndPtr; - CLASS * classPtr; - if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return; - if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return; - type = (classPtr->wc.style & CS_DBLCLKS) ? 2 : 0; - } - else type = 0; - } - + if (buttonNum >= NB_BUTTONS) return; winHasCursor = event->window; - - hardware_event( hwnd, messages[type][buttonNum], - EVENT_XStateToKeyState( event->state ), - (event->x & 0xffff) | (event->y << 16), - event->x & 0xffff, event->y & 0xffff, + hardware_event( hwnd, messages[buttonNum], + EVENT_XStateToKeyState( event->state ), 0L, + event->x_root & 0xffff, event->y_root & 0xffff, event->time, 0 ); } /*********************************************************************** - * EVENT_structure - * - * Handle a X StructureNotify event + * EVENT_ButtonRelease */ -static void EVENT_structure( Widget w, int hwnd, XEvent *event, - Boolean *cont_dispatch ) +static void EVENT_ButtonRelease( HWND hwnd, XButtonEvent *event ) { - MSG msg; - - msg.hwnd = hwnd; - msg.time = GetTickCount(); - msg.pt.x = 0; - msg.pt.y = 0; + static const WORD messages[NB_BUTTONS] = + { WM_LBUTTONUP, WM_MBUTTONUP, WM_RBUTTONUP }; + int buttonNum = event->button - 1; - switch(event->type) - { - case ConfigureNotify: - { - HANDLE handle; - NCCALCSIZE_PARAMS *params; - XConfigureEvent * evt = (XConfigureEvent *)event; - WND * wndPtr = WIN_FindWndPtr( hwnd ); - if (!wndPtr) return; - wndPtr->rectWindow.left = evt->x; - wndPtr->rectWindow.top = evt->y; - wndPtr->rectWindow.right = evt->x + evt->width; - wndPtr->rectWindow.bottom = evt->y + evt->height; + if (buttonNum >= NB_BUTTONS) return; + winHasCursor = event->window; + hardware_event( hwnd, messages[buttonNum], + EVENT_XStateToKeyState( event->state ), 0L, + event->x_root & 0xffff, event->y_root & 0xffff, + event->time, 0 ); +} - /* Send WM_NCCALCSIZE message */ - handle = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) ); - params = (NCCALCSIZE_PARAMS *)GlobalLock( handle ); - params->rgrc[0] = wndPtr->rectWindow; - params->lppos = NULL; /* Should be WINDOWPOS struct */ - SendMessage( hwnd, WM_NCCALCSIZE, FALSE, params ); - wndPtr->rectClient = params->rgrc[0]; - PostMessage( hwnd, WM_MOVE, 0, - MAKELONG( wndPtr->rectClient.left, - wndPtr->rectClient.top )); - PostMessage( hwnd, WM_SIZE, SIZE_RESTORED, - MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left, - wndPtr->rectClient.bottom-wndPtr->rectClient.top)); - GlobalUnlock( handle ); - GlobalFree( handle ); - } - break; - - } + +/*********************************************************************** + * EVENT_ConfigureNotify + */ +static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event ) +{ + HANDLE handle; + NCCALCSIZE_PARAMS *params; + WND * wndPtr = WIN_FindWndPtr( hwnd ); + if (!wndPtr) return; + wndPtr->rectWindow.left = event->x; + wndPtr->rectWindow.top = event->y; + wndPtr->rectWindow.right = event->x + event->width; + wndPtr->rectWindow.bottom = event->y + event->height; + + /* Send WM_NCCALCSIZE message */ + handle = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) ); + params = (NCCALCSIZE_PARAMS *)GlobalLock( handle ); + params->rgrc[0] = wndPtr->rectWindow; + params->lppos = NULL; /* Should be WINDOWPOS struct */ + SendMessage( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)params ); + wndPtr->rectClient = params->rgrc[0]; + PostMessage( hwnd, WM_MOVE, 0, + MAKELONG( wndPtr->rectClient.left, wndPtr->rectClient.top )); + PostMessage( hwnd, WM_SIZE, SIZE_RESTORED, + MAKELONG( wndPtr->rectClient.right-wndPtr->rectClient.left, + wndPtr->rectClient.bottom-wndPtr->rectClient.top) ); + GlobalUnlock( handle ); + GlobalFree( handle ); } /********************************************************************** - * EVENT_focus_change - * - * Handle an X FocusChange event + * EVENT_FocusIn */ -static void EVENT_focus_change( Widget w, int hwnd, XEvent *event, - Boolean *cont_dispatch ) +static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event ) { - switch(event->type) - { - case FocusIn: - { - PostMessage( hwnd, WM_SETFOCUS, hwnd, 0 ); - hWndFocus = hwnd; - } - break; - - case FocusOut: - { - if (hWndFocus) - { - PostMessage( hwnd, WM_KILLFOCUS, hwnd, 0 ); - hWndFocus = 0; - } - } - } + PostMessage( hwnd, WM_SETFOCUS, hwnd, 0 ); + hWndFocus = hwnd; } /********************************************************************** - * EVENT_enter_notify - * - * Handle an X EnterNotify event + * EVENT_FocusOut */ -static void EVENT_enter_notify( Widget w, int hwnd, XCrossingEvent *event, - Boolean *cont_dispatch ) +static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event ) +{ + if (hWndFocus) + { + PostMessage( hwnd, WM_KILLFOCUS, hwnd, 0 ); + hWndFocus = 0; + } +} + + +/********************************************************************** + * EVENT_EnterNotify + */ +static void EVENT_EnterNotify( HWND hwnd, XCrossingEvent *event ) { if (captureWnd != 0) return; - winHasCursor = event->window; - - switch(event->type) - { - case EnterNotify: - PostMessage( hwnd, WM_SETCURSOR, hwnd, 0 ); - break; - } + PostMessage( hwnd, WM_SETCURSOR, hwnd, 0 ); } @@ -604,15 +477,9 @@ HWND SetCapture(HWND wnd) if (wnd_p == NULL) return 0; -#ifdef USE_XLIB - rv = XGrabPointer(XT_display, wnd_p->window, False, + rv = XGrabPointer(display, wnd_p->window, False, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeSync, None, None, CurrentTime); -#else - rv = XtGrabPointer(wnd_p->winWidget, False, - ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, - GrabModeAsync, GrabModeSync, None, None, CurrentTime); -#endif if (rv == GrabSuccess) { @@ -637,12 +504,7 @@ void ReleaseCapture() if (wnd_p == NULL) return; -#ifdef USE_XLIB - XUngrabPointer( XT_display, CurrentTime ); -#else - XtUngrabPointer(wnd_p->winWidget, CurrentTime); -#endif - + XUngrabPointer( display, CurrentTime ); captureWnd = 0; } @@ -653,24 +515,3 @@ HWND GetCapture() { return captureWnd; } - -/********************************************************************** - * SetDoubleClickTime (USER.20) - */ -void SetDoubleClickTime (WORD interval) -{ - if (interval == 0) - dblclick_time = 500; - else - dblclick_time = interval; -} - -/********************************************************************** - * GetDoubleClickTime (USER.21) - */ -WORD GetDoubleClickTime () -{ - return ((WORD)dblclick_time); -} - - diff --git a/windows/focus.c b/windows/focus.c index 639b2dfd85a..a2d2b8d75f8 100644 --- a/windows/focus.c +++ b/windows/focus.c @@ -27,13 +27,19 @@ HWND SetFocus(HWND hwnd) if (hwnd == 0) { - XSetInputFocus(XT_display, None, RevertToPointerRoot, CurrentTime); + XSetInputFocus(display, None, RevertToPointerRoot, CurrentTime); } else { + XWindowAttributes win_attr; wndPtr = WIN_FindWndPtr(hwnd); - XSetInputFocus(XT_display, wndPtr->window, - RevertToParent, CurrentTime); + + if (XGetWindowAttributes( display, wndPtr->window, &win_attr )) + { + if (win_attr.map_state == IsViewable) + XSetInputFocus(display, wndPtr->window, + RevertToParent, CurrentTime); + } } return hWndPrevFocus; diff --git a/windows/graphics.c b/windows/graphics.c index 9fd5d27a55f..c5e41b5a3d5 100644 --- a/windows/graphics.c +++ b/windows/graphics.c @@ -7,7 +7,9 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include +#include #include +#include #ifndef PI #define PI M_PI #endif @@ -412,49 +414,45 @@ void DrawFocusRect( HDC hdc, LPRECT rc ) } -/********************************************************************** - * Line (Not a MSWin Call) - */ -void Line(HDC hDC, int X1, int Y1, int X2, int Y2) -{ -MoveTo(hDC, X1, Y1); -LineTo(hDC, X2, Y2); -} - - /********************************************************************** * DrawReliefRect (Not a MSWin Call) */ - void DrawReliefRect(HDC hDC, RECT rect, int ThickNess, int Mode) +void DrawReliefRect( HDC hdc, RECT rect, int thickness, BOOL pressed ) { -HPEN hWHITEPen; -HPEN hDKGRAYPen; -HPEN hOldPen; -int OldColor; -rect.right--; rect.bottom--; -hDKGRAYPen = CreatePen(PS_SOLID, 1, 0x00808080L); -hWHITEPen = GetStockObject(WHITE_PEN); -hOldPen = SelectObject(hDC, hWHITEPen); -while(ThickNess > 0) { - if (Mode == 0) - SelectObject(hDC, hWHITEPen); - else - SelectObject(hDC, hDKGRAYPen); - Line(hDC, rect.left, rect.top, rect.right, rect.top); - Line(hDC, rect.left, rect.top, rect.left, rect.bottom + 1); - if (Mode == 0) - SelectObject(hDC, hDKGRAYPen); - else - SelectObject(hDC, hWHITEPen); - Line(hDC, rect.right, rect.bottom, rect.left, rect.bottom); - Line(hDC, rect.right, rect.bottom, rect.right, rect.top - 1); - InflateRect(&rect, -1, -1); - ThickNess--; + HBRUSH hbrushOld, hbrushShadow, hbrushHighlight; + int i; + + hbrushShadow = CreateSolidBrush( GetSysColor(COLOR_BTNSHADOW) ); + hbrushHighlight = CreateSolidBrush( GetSysColor(COLOR_BTNHIGHLIGHT) ); + + if (pressed) hbrushOld = SelectObject( hdc, hbrushShadow ); + else hbrushOld = SelectObject( hdc, hbrushHighlight ); + + for (i = 0; i < thickness; i++) + { + PatBlt( hdc, rect.left + i, rect.top, + 1, rect.bottom - rect.top - i, PATCOPY ); + PatBlt( hdc, rect.left, rect.top + i, + rect.right - rect.left - i, 1, PATCOPY ); } -SelectObject(hDC, hOldPen); -DeleteObject(hDKGRAYPen); + + if (pressed) hbrushOld = SelectObject( hdc, hbrushHighlight ); + else hbrushOld = SelectObject( hdc, hbrushShadow ); + + for (i = 0; i < thickness; i++) + { + PatBlt( hdc, rect.right - i - 1, rect.top + i, + 1, rect.bottom - rect.top - i, PATCOPY ); + PatBlt( hdc, rect.left + i, rect.bottom - i - 1, + rect.right - rect.left - i, 1, PATCOPY ); + } + + SelectObject( hdc, hbrushOld ); + DeleteObject( hbrushShadow ); + DeleteObject( hbrushHighlight ); } + /********************************************************************** * Polyline (GDI.37) */ diff --git a/windows/message.c b/windows/message.c index 09b49e7861c..3782a279e04 100644 --- a/windows/message.c +++ b/windows/message.c @@ -17,15 +17,15 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "message.h" #include "win.h" - +#include "wineopts.h" +#include "sysmetrics.h" #define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */ -extern BOOL TIMER_CheckTimer( DWORD *next ); /* timer.c */ - -extern Display * XT_display; -extern Screen * XT_screen; -extern XtAppContext XT_app_context; +extern BOOL TIMER_CheckTimer( DWORD *next ); /* timer.c */ +extern void EVENT_ProcessEvent( XEvent *event ); /* event.c */ + +extern Display * display; /* System message queue (for hardware events) */ static HANDLE hmemSysMsgQueue = 0; @@ -35,6 +35,10 @@ static MESSAGEQUEUE * sysMsgQueue = NULL; static HANDLE hmemAppMsgQueue = 0; static MESSAGEQUEUE * appMsgQueue = NULL; + /* Double-click time */ +static int doubleClickSpeed = 452; + + /*********************************************************************** * MSG_CreateMsgQueue * @@ -78,7 +82,8 @@ static HANDLE MSG_CreateMsgQueue( int size ) /*********************************************************************** * MSG_CreateSysMsgQueue * - * Create the system message queue. Must be called only once. + * Create the system message queue, and set the double-click speed. + * Must be called only once. */ BOOL MSG_CreateSysMsgQueue( int size ) { @@ -86,6 +91,7 @@ BOOL MSG_CreateSysMsgQueue( int size ) else if (size <= 0) size = 1; if (!(hmemSysMsgQueue = MSG_CreateMsgQueue( size ))) return FALSE; sysMsgQueue = (MESSAGEQUEUE *) GlobalLock( hmemSysMsgQueue ); + doubleClickSpeed = GetProfileInt( "windows", "DoubleClickSpeed", 452 ); return TRUE; } @@ -99,6 +105,8 @@ static int MSG_AddMsg( MESSAGEQUEUE * msgQueue, MSG * msg, DWORD extraInfo ) { int pos; + SpyMessage(msg->hwnd, msg->message, msg->wParam, msg->lParam); + if (!msgQueue) return FALSE; pos = msgQueue->nextFreeMessage; @@ -183,6 +191,93 @@ static void MSG_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos ) } +/*********************************************************************** + * MSG_TranslateMouseMsg + * + * Translate an mouse hardware event into a real mouse message. + * Actions performed: + * - Translate button down messages in double-clicks. + * - Send the WM_NCHITTEST message to find where the cursor is. + * - Translate the message into a non-client message, or translate + * the coordinates to client coordinates. + */ +static void MSG_TranslateMouseMsg( MSG *msg ) +{ + static DWORD lastClickTime = 0; + static WORD lastClickMsg = 0; + static POINT lastClickPos = { 0, 0 }; + + LONG hittest_result = SendMessage( msg->hwnd, WM_NCHITTEST, 0, + MAKELONG( msg->pt.x, msg->pt.y ) ); + + if ((msg->message == WM_LBUTTONDOWN) || + (msg->message == WM_RBUTTONDOWN) || + (msg->message == WM_MBUTTONDOWN)) + { + BOOL dbl_click = FALSE; + + /* Check for double-click */ + + if ((msg->message == lastClickMsg) && + (msg->time - lastClickTime < doubleClickSpeed) && + (abs(msg->pt.x - lastClickPos.x) < SYSMETRICS_CXDOUBLECLK/2) && + (abs(msg->pt.y - lastClickPos.y) < SYSMETRICS_CYDOUBLECLK/2)) + dbl_click = TRUE; + + if (dbl_click && (hittest_result == HTCLIENT)) + { + /* Check whether window wants the double click message. */ + WND * wndPtr = WIN_FindWndPtr( msg->hwnd ); + if (!wndPtr || !(wndPtr->flags & WIN_DOUBLE_CLICKS)) + dbl_click = FALSE; + } + + if (dbl_click) switch(msg->message) + { + case WM_LBUTTONDOWN: msg->message = WM_LBUTTONDBLCLK; break; + case WM_RBUTTONDOWN: msg->message = WM_RBUTTONDBLCLK; break; + case WM_MBUTTONDOWN: msg->message = WM_MBUTTONDBLCLK; break; + } + + lastClickTime = msg->time; + lastClickMsg = msg->message; + lastClickPos = msg->pt; + } + + msg->lParam = MAKELONG( msg->pt.x, msg->pt.y ); + if (hittest_result == HTCLIENT) + { + ScreenToClient( msg->hwnd, (LPPOINT)&msg->lParam ); + } + else + { + msg->wParam = hittest_result; + msg->message += WM_NCLBUTTONDOWN - WM_LBUTTONDOWN; + } +} + + +/********************************************************************** + * SetDoubleClickTime (USER.20) + */ +void SetDoubleClickTime( WORD interval ) +{ + if (interval == 0) + doubleClickSpeed = 500; + else + doubleClickSpeed = interval; +} + + +/********************************************************************** + * GetDoubleClickTime (USER.21) + */ +WORD GetDoubleClickTime() +{ + return (WORD)doubleClickSpeed; +} + + /*********************************************************************** * MSG_IncPaintCount */ @@ -233,6 +328,7 @@ void MSG_DecTimerCount( HANDLE hQueue ) * hardware_event * * Add an event to the system message queue. + * Note: the position is in screen coordinates. */ void hardware_event( HWND hwnd, WORD message, WORD wParam, LONG lParam, WORD xPos, WORD yPos, DWORD time, DWORD extraInfo ) @@ -325,24 +421,6 @@ BOOL GetInputState() } -#ifndef USE_XLIB -static XtIntervalId xt_timer = 0; - -/*********************************************************************** - * MSG_TimerCallback - */ -static void MSG_TimerCallback( XtPointer data, XtIntervalId * xtid ) -{ - DWORD nextExp; - TIMER_CheckTimer( &nextExp ); - if (nextExp != (DWORD)-1) - xt_timer = XtAppAddTimeOut( XT_app_context, nextExp, - MSG_TimerCallback, NULL ); - else xt_timer = 0; -} -#endif /* USE_XLIB */ - - /*********************************************************************** * MSG_PeekMessage */ @@ -351,9 +429,7 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd, { int pos, mask; DWORD nextExp; /* Next timer expiration time */ -#ifdef USE_XLIB XEvent event; -#endif if (first || last) { @@ -366,16 +442,11 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd, } else mask = QS_MOUSE | QS_KEY | QS_POSTMESSAGE | QS_TIMER | QS_PAINT; -#ifdef USE_XLIB - while (XPending( XT_display )) + while (XPending( display )) { - XNextEvent( XT_display, &event ); + XNextEvent( display, &event ); EVENT_ProcessEvent( &event ); } -#else - while (XtAppPending( XT_app_context )) - XtAppProcessEvent( XT_app_context, XtIMAll ); -#endif while(1) { @@ -432,6 +503,8 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd, msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo; if (flags & PM_REMOVE) MSG_RemoveMsg( sysMsgQueue, pos ); + if ((msg->message >= WM_MOUSEFIRST) && + (msg->message <= WM_MOUSELAST)) MSG_TranslateMouseMsg( msg ); break; } @@ -447,26 +520,16 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd, /* Finally handle WM_TIMER messages */ if ((msgQueue->status & QS_TIMER) && (mask & QS_TIMER)) - { - BOOL posted = TIMER_CheckTimer( &nextExp ); -#ifndef USE_XLIB - if (xt_timer) XtRemoveTimeOut( xt_timer ); - if (nextExp != (DWORD)-1) - xt_timer = XtAppAddTimeOut( XT_app_context, nextExp, - MSG_TimerCallback, NULL ); - else xt_timer = 0; -#endif - if (posted) continue; /* Restart the whole thing */ - } + if (TIMER_CheckTimer( &nextExp )) + continue; /* Restart the whole search */ /* Wait until something happens */ if (peek) return FALSE; -#ifdef USE_XLIB - if (!XPending( XT_display ) && (nextExp != -1)) + if (!XPending( display ) && (nextExp != -1)) { fd_set read_set; struct timeval timeout; - int fd = ConnectionNumber(XT_display); + int fd = ConnectionNumber(display); FD_ZERO( &read_set ); FD_SET( fd, &read_set ); timeout.tv_sec = nextExp / 1000; @@ -474,11 +537,8 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd, if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1) continue; /* On timeout or error, restart from the start */ } - XNextEvent( XT_display, &event ); + XNextEvent( display, &event ); EVENT_ProcessEvent( &event ); -#else - XtAppProcessEvent( XT_app_context, XtIMAll ); -#endif } /* We got a message */ @@ -529,7 +589,11 @@ BOOL PostMessage( HWND hwnd, WORD message, WORD wParam, LONG lParam ) */ LONG SendMessage( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) { - WND * wndPtr = WIN_FindWndPtr( hwnd ); + WND * wndPtr; + + SpyMessage(hwnd, msg, wParam, lParam); + + wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return 0; return CallWindowProc( wndPtr->lpfnWndProc, hwnd, msg, wParam, lParam ); } @@ -564,7 +628,7 @@ LONG DispatchMessage( LPMSG msg ) int painting; #ifdef DEBUG_MSG - printf( "Dispatch message hwnd=%08x msg=%d w=%d l=%d time=%u pt=%d,%d\n", + printf( "Dispatch message hwnd=%08x msg=0x%x w=%d l=%d time=%u pt=%d,%d\n", msg->hwnd, msg->message, msg->wParam, msg->lParam, msg->time, msg->pt.x, msg->pt.y ); #endif @@ -587,7 +651,7 @@ LONG DispatchMessage( LPMSG msg ) if (painting && (wndPtr->flags & WIN_NEEDS_BEGINPAINT)) { #ifdef DEBUG_WIN - printf( "BeginPaint not called on WM_PAINT!\n" ); + printf( "BeginPaint not called on WM_PAINT for hwnd %d!\n", msg->hwnd); #endif wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT; } diff --git a/windows/nonclient.c b/windows/nonclient.c new file mode 100644 index 00000000000..79f58937518 --- /dev/null +++ b/windows/nonclient.c @@ -0,0 +1,461 @@ +/* + * Non-client area window functions + * + * Copyright 1994 Alexandre Julliard + */ + +static char Copyright[] = "Copyright Alexandre Julliard, 1994"; + +#include "win.h" +#include "sysmetrics.h" + + +/*********************************************************************** + * NC_AdjustRect + * + * Compute the size of the window rectangle from the size of the + * client rectangle. + */ +static void NC_AdjustRect( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle ) +{ + if ((style & WS_DLGFRAME) && + ((exStyle & WS_EX_DLGMODALFRAME) || !(style & WS_BORDER))) + InflateRect( rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME ); + else if (style & WS_THICKFRAME) + InflateRect( rect, SYSMETRICS_CXFRAME, SYSMETRICS_CYFRAME ); + + if (style & WS_BORDER) + InflateRect( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER ); + + if ((style & WS_CAPTION) == WS_CAPTION) + rect->top -= SYSMETRICS_CYCAPTION - 1; + + if (menu) rect->top -= SYSMETRICS_CYMENU + 1; + + if (style & WS_VSCROLL) rect->right += SYSMETRICS_CXVSCROLL; + if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL; +} + + +/*********************************************************************** + * AdjustWindowRect (USER.102) + */ +void AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu ) +{ + AdjustWindowRectEx( rect, style, menu, 0 ); +} + + +/*********************************************************************** + * AdjustWindowRectEx (USER.454) + */ +void AdjustWindowRectEx( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle ) +{ + /* Correct the window style */ + + if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */ + style |= WS_CAPTION; + if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME; + +#ifdef DEBUG_NONCLIENT + printf( "AdjustWindowRectEx: (%d,%d)-(%d,%d) %08x %d %08x\n", + rect->left, rect->top, rect->right, rect->bottom, style, menu, exStyle ); +#endif + + NC_AdjustRect( rect, style, menu, exStyle ); +} + + +/*********************************************************************** + * NC_HandleNCCalcSize + * + * Handle a WM_NCCALCSIZE message. Called from DefWindowProc(). + */ +LONG NC_HandleNCCalcSize( HWND hwnd, NCCALCSIZE_PARAMS *params ) +{ + RECT tmpRect = { 0, 0, 0, 0 }; + BOOL hasMenu; + WND *wndPtr = WIN_FindWndPtr( hwnd ); + + if (!wndPtr) return 0; + + hasMenu = (!(wndPtr->dwStyle & WS_CHILD)) && (wndPtr->wIDmenu != 0); + + NC_AdjustRect( &tmpRect, wndPtr->dwStyle, hasMenu, wndPtr->dwExStyle ); + + params->rgrc[0].left -= tmpRect.left; + params->rgrc[0].top -= tmpRect.top; + params->rgrc[0].right -= tmpRect.right; + params->rgrc[0].bottom -= tmpRect.bottom; + return 0; +} + + +/*********************************************************************** + * NC_HandleNCHitTest + * + * Handle a WM_NCHITTEST message. Called from DefWindowProc(). + */ +LONG NC_HandleNCHitTest( HWND hwnd, POINT pt ) +{ + RECT rect; + WND *wndPtr = WIN_FindWndPtr( hwnd ); + if (!wndPtr) return HTERROR; + +#ifdef DEBUG_NONCLIENT + printf( "NC_HandleNCHitTest: hwnd=%x pt=%d,%d\n", hwnd, pt.x, pt.y ); +#endif + + if (hwnd == GetCapture()) return HTCLIENT; + GetWindowRect( hwnd, &rect ); + if (!PtInRect( &rect, pt )) return HTNOWHERE; + ScreenToClient( hwnd, &pt ); + GetClientRect( hwnd, &rect ); + + if (PtInRect( &rect, pt )) return HTCLIENT; + + /* Check vertical scroll bar */ + if (wndPtr->dwStyle & WS_VSCROLL) + { + rect.right += SYSMETRICS_CXVSCROLL; + if (PtInRect( &rect, pt )) return HTVSCROLL; + } + + /* Check horizontal scroll bar */ + if (wndPtr->dwStyle & WS_HSCROLL) + { + rect.bottom += SYSMETRICS_CYHSCROLL; + if (PtInRect( &rect, pt )) + { + /* Check size box */ + if ((wndPtr->dwStyle & WS_VSCROLL) && + (pt.x >= rect.right - SYSMETRICS_CXVSCROLL)) return HTSIZE; + return HTHSCROLL; + } + } + + /* Check menu */ + if ((!(wndPtr->dwStyle & WS_CHILD)) && (wndPtr->wIDmenu != 0)) + { + rect.top -= SYSMETRICS_CYMENU + 1; + if (PtInRect( &rect, pt )) return HTMENU; + } + + /* Check caption */ + if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION) + { + rect.top -= SYSMETRICS_CYCAPTION - 1; + if (PtInRect( &rect, pt )) + { + /* Check system menu */ + if ((wndPtr->dwStyle & WS_SYSMENU) && (pt.x <= SYSMETRICS_CXSIZE)) + return HTSYSMENU; + /* Check maximize box */ + if (wndPtr->dwStyle & WS_MAXIMIZEBOX) + rect.right -= SYSMETRICS_CXSIZE + 1; + if (pt.x >= rect.right) return HTMAXBUTTON; + /* Check minimize box */ + if (wndPtr->dwStyle & WS_MINIMIZEBOX) + rect.right -= SYSMETRICS_CXSIZE + 1; + if (pt.x >= rect.right) return HTMINBUTTON; + return HTCAPTION; + } + } + + /* Check non-sizing border */ + if (!(wndPtr->dwStyle & WS_THICKFRAME) || + ((wndPtr->dwStyle & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)) + return HTBORDER; + + /* Check top sizing border */ + if (pt.y < rect.top) + { + if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT; + if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT; + return HTTOP; + } + + /* Check bottom sizing border */ + if (pt.y >= rect.bottom) + { + if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT; + if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT; + return HTBOTTOM; + } + + /* Check left sizing border */ + if (pt.x < rect.left) + { + if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT; + if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT; + return HTLEFT; + } + + /* Check right sizing border */ + if (pt.x >= rect.right) + { + if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT; + if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT; + return HTRIGHT; + } + + /* Should never get here */ + return HTERROR; +} + + +/*********************************************************************** + * NC_DrawFrame + * + * Draw a window frame inside the given rectangle, and update the rectangle. + * The correct pen and brush must be selected in the DC. + */ +static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame ) +{ + short width, height, tmp; + + if (dlgFrame) + { + width = SYSMETRICS_CXDLGFRAME; + height = SYSMETRICS_CYDLGFRAME; + } + else + { + width = SYSMETRICS_CXFRAME - 1; + height = SYSMETRICS_CYFRAME - 1; + } + + /* Draw frame */ + PatBlt( hdc, rect->left, rect->top, + rect->right - rect->left, height, PATCOPY ); + PatBlt( hdc, rect->left, rect->top, + width, rect->bottom - rect->top, PATCOPY ); + PatBlt( hdc, rect->left, rect->bottom, + rect->right - rect->left, -height, PATCOPY ); + PatBlt( hdc, rect->right, rect->top, + -width, rect->bottom - rect->top, PATCOPY ); + + if (dlgFrame) + { + InflateRect( rect, -width, -height ); + return; + } + + /* Draw inner rectangle */ + MoveTo( hdc, rect->left+width, rect->top+height ); + LineTo( hdc, rect->right-width-1, rect->top+height ); + LineTo( hdc, rect->right-width-1, rect->bottom-height-1 ); + LineTo( hdc, rect->left+width, rect->bottom-height-1 ); + LineTo( hdc, rect->left+width, rect->top+height ); + + /* Draw the decorations */ + tmp = rect->top + SYSMETRICS_CYFRAME + SYSMETRICS_CYSIZE; + MoveTo( hdc, rect->left, tmp); + LineTo( hdc, rect->left+width, tmp ); + MoveTo( hdc, rect->right-width-1, tmp ); + LineTo( hdc, rect->right-1, tmp ); + + tmp = rect->bottom - 1 - SYSMETRICS_CYFRAME - SYSMETRICS_CYSIZE; + MoveTo( hdc, rect->left, tmp ); + LineTo( hdc, rect->left+width, tmp ); + MoveTo( hdc, rect->right-width-1, tmp ); + LineTo( hdc, rect->right-1, tmp ); + + tmp = rect->left + SYSMETRICS_CXFRAME + SYSMETRICS_CXSIZE; + MoveTo( hdc, tmp, rect->top ); + LineTo( hdc, tmp, rect->top+height ); + MoveTo( hdc, tmp, rect->bottom-height-1 ); + LineTo( hdc, tmp, rect->bottom-1 ); + + tmp = rect->right - 1 - SYSMETRICS_CXFRAME - SYSMETRICS_CYSIZE; + MoveTo( hdc, tmp, rect->top ); + LineTo( hdc, tmp, rect->top+height ); + MoveTo( hdc, tmp, rect->bottom-height-1 ); + LineTo( hdc, tmp, rect->bottom-1 ); + + InflateRect( rect, -width-1, -height-1 ); +} + + +/*********************************************************************** + * NC_DrawCaption + * + * Draw the window caption. + * The correct pen for the window frame must be selected in the DC. + */ +static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd, DWORD style ) +{ + RECT r; + HBRUSH hbrushCaption, hbrushButtons; + char buffer[256]; + + hbrushButtons = CreateSolidBrush( GetSysColor( COLOR_BTNFACE ) ); + hbrushCaption = CreateSolidBrush( GetSysColor( COLOR_ACTIVECAPTION ) ); + + MoveTo( hdc, rect->left, rect->bottom ); + LineTo( hdc, rect->right-1, rect->bottom ); + + /* We should probably use OEM bitmaps (OBM_*) here */ + if (style & WS_SYSMENU) + { + r = *rect; + r.right = r.left + SYSMETRICS_CYSIZE; + FillRect( hdc, &r, hbrushButtons ); + MoveTo( hdc, r.right, r.top ); + LineTo( hdc, r.right, r.bottom ); + rect->left += SYSMETRICS_CXSIZE + 1; + } + if (style & WS_MAXIMIZEBOX) + { + r = *rect; + r.left = r.right - SYSMETRICS_CXSIZE; + FillRect( hdc, &r, hbrushButtons ); + MoveTo( hdc, r.left-1, r.top ); + LineTo( hdc, r.left-1, r.bottom ); + DrawReliefRect( hdc, r, 2, 0 ); + rect->right -= SYSMETRICS_CXSIZE + 1; + } + if (style & WS_MINIMIZEBOX) + { + r = *rect; + r.left = r.right - SYSMETRICS_CXSIZE; + FillRect( hdc, &r, hbrushButtons ); + MoveTo( hdc, r.left-1, r.top ); + LineTo( hdc, r.left-1, r.bottom ); + DrawReliefRect( hdc, r, 2, 0 ); + rect->right -= SYSMETRICS_CXSIZE + 1; + } + + FillRect( hdc, rect, hbrushCaption ); + + if (GetWindowText( hwnd, buffer, 256 )) + { + SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) ); + SetBkMode( hdc, TRANSPARENT ); + DrawText( hdc, buffer, -1, rect, + DT_SINGLELINE | DT_CENTER | DT_VCENTER ); + } + + DeleteObject( hbrushButtons ); + DeleteObject( hbrushCaption ); +} + + +/*********************************************************************** + * NC_HandleNCPaint + * + * Handle a WM_NCPAINT message. Called from DefWindowProc(). + */ +LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn ) +{ + HDC hdc; + RECT rect; + HBRUSH hbrushBorder = 0; + HPEN hpenFrame = 0; + + WND *wndPtr = WIN_FindWndPtr( hwnd ); + +#ifdef DEBUG_NONCLIENT + printf( "NC_HandleNCPaint: %d %d\n", hwnd, hrgn ); +#endif + + if (!wndPtr || !hrgn) return 0; + if (!(wndPtr->dwStyle & (WS_BORDER | WS_DLGFRAME | WS_THICKFRAME))) + return 0; /* Nothing to do! */ + + if (hrgn == 1) hdc = GetDCEx( hwnd, 0, DCX_CACHE | DCX_WINDOW ); + else hdc = GetDCEx( hwnd, hrgn, DCX_CACHE | DCX_WINDOW | DCX_INTERSECTRGN); + if (!hdc) return 0; + if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left, + wndPtr->rectClient.top-wndPtr->rectWindow.top, + wndPtr->rectClient.right-wndPtr->rectWindow.left, + wndPtr->rectClient.bottom-wndPtr->rectWindow.top ) + == NULLREGION) + { + ReleaseDC( hwnd, hdc ); + return 0; + } + + rect.top = rect.left = 0; + rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left; + rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top; + + hpenFrame = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_WINDOWFRAME) ); + SelectObject( hdc, hpenFrame ); + hbrushBorder = CreateSolidBrush( GetSysColor(COLOR_ACTIVEBORDER) ); + SelectObject( hdc, hbrushBorder ); + + if ((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME)) + { + MoveTo( hdc, 0, 0 ); + LineTo( hdc, rect.right-1, 0 ); + LineTo( hdc, rect.right-1, rect.bottom-1 ); + LineTo( hdc, 0, rect.bottom-1 ); + LineTo( hdc, 0, 0 ); + InflateRect( &rect, -1, -1 ); + } + + if ((wndPtr->dwStyle & WS_DLGFRAME) && + ((wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) || + !(wndPtr->dwStyle & WS_BORDER))) NC_DrawFrame( hdc, &rect, TRUE ); + else if (wndPtr->dwStyle & WS_THICKFRAME) NC_DrawFrame(hdc, &rect, FALSE); + + if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION) + { + RECT r = rect; + rect.top += SYSMETRICS_CYSIZE + 1; + r.bottom = rect.top - 1; + if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) + { + HBRUSH hbrushWindow = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); + HBRUSH hbrushOld = SelectObject( hdc, hbrushWindow ); + PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1, PATCOPY ); + PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY ); + PatBlt( hdc, r.left, r.top, r.right-r.left, 1, PATCOPY ); + r.left++; + r.right--; + r.top++; + SelectObject( hdc, hbrushOld ); + DeleteObject( hbrushWindow ); + } + NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle ); + } + + if (wndPtr->dwStyle & (WS_VSCROLL | WS_HSCROLL)) + { + HBRUSH hbrushScroll = CreateSolidBrush( GetSysColor(COLOR_SCROLLBAR) ); + HBRUSH hbrushOld = SelectObject( hdc, hbrushScroll ); + if (wndPtr->dwStyle & WS_VSCROLL) + PatBlt( hdc, rect.right - SYSMETRICS_CXVSCROLL, rect.top, + SYSMETRICS_CXVSCROLL, rect.bottom-rect.top, PATCOPY ); + if (wndPtr->dwStyle & WS_HSCROLL) + PatBlt( hdc, rect.left, rect.bottom - SYSMETRICS_CYHSCROLL, + rect.right-rect.left, SYSMETRICS_CYHSCROLL, PATCOPY ); + SelectObject( hdc, hbrushOld ); + DeleteObject( hbrushScroll ); + } + + ReleaseDC( hwnd, hdc ); + if (hbrushBorder) DeleteObject( hbrushBorder ); + if (hpenFrame) DeleteObject( hpenFrame ); + return 0; +} + + +/*********************************************************************** + * NC_HandleNCMouseMsg + * + * Handle a non-client mouse message. Called from DefWindowProc(). + */ +LONG NC_HandleNCMouseMsg( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) +{ + switch(wParam) /* Hit test code */ + { + case HTSYSMENU: + if (msg == WM_NCLBUTTONDBLCLK) + return SendMessage( hwnd, WM_SYSCOMMAND, SC_CLOSE, lParam ); + break; + } + return 0; +} + diff --git a/windows/painting.c b/windows/painting.c index 5a8e60a0e11..2aeaba2f223 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -21,9 +21,12 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; */ HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) { + HRGN hrgnUpdate; WND * wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return 0; + hrgnUpdate = wndPtr->hrgnUpdate; /* Save update region */ + if (!(lps->hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate, DCX_INTERSECTRGN | DCX_USESTYLE ))) return 0; GetRgnBox( InquireVisRgn(lps->hdc), &lps->rcPaint ); @@ -35,7 +38,8 @@ HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) MSG_DecPaintCount( wndPtr->hmemTaskQ ); } wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT; - + + SendMessage( hwnd, WM_NCPAINT, hrgnUpdate, 0 ); if (!(wndPtr->flags & WIN_ERASE_UPDATERGN)) lps->fErase = TRUE; else lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 ); diff --git a/windows/sysmetrics.c b/windows/sysmetrics.c new file mode 100644 index 00000000000..bea45613500 --- /dev/null +++ b/windows/sysmetrics.c @@ -0,0 +1,81 @@ +/* + * System metrics functions + * + * Copyright 1994 Alexandre Julliard + */ + +static char Copyright[] = "Copyright Alexandre Julliard, 1994"; + +#include + +#include "sysmetrics.h" + + +short sysMetrics[SM_CMETRICS]; + +extern Display * display; + +/*********************************************************************** + * SYSMETRICS_Init + * + * Initialisation of the system metrics array. + */ +void SYSMETRICS_Init() +{ + sysMetrics[SM_CXSCREEN] = DisplayWidth( display, DefaultScreen(display) ); + sysMetrics[SM_CYSCREEN] = DisplayHeight( display, DefaultScreen(display) ); + sysMetrics[SM_CXVSCROLL] = SYSMETRICS_CXVSCROLL; + sysMetrics[SM_CYHSCROLL] = SYSMETRICS_CYHSCROLL; + sysMetrics[SM_CYCAPTION] = SYSMETRICS_CYCAPTION; + sysMetrics[SM_CXBORDER] = SYSMETRICS_CXBORDER; + sysMetrics[SM_CYBORDER] = SYSMETRICS_CYBORDER; + sysMetrics[SM_CXDLGFRAME] = SYSMETRICS_CXDLGFRAME; + sysMetrics[SM_CYDLGFRAME] = SYSMETRICS_CYDLGFRAME; + sysMetrics[SM_CYVTHUMB] = SYSMETRICS_CYVTHUMB; + sysMetrics[SM_CXHTHUMB] = SYSMETRICS_CXHTHUMB; + sysMetrics[SM_CXICON] = SYSMETRICS_CXICON; + sysMetrics[SM_CYICON] = SYSMETRICS_CYICON; + sysMetrics[SM_CXCURSOR] = SYSMETRICS_CXCURSOR; + sysMetrics[SM_CYCURSOR] = SYSMETRICS_CYCURSOR; + sysMetrics[SM_CYMENU] = SYSMETRICS_CYMENU; + sysMetrics[SM_CXFULLSCREEN] = sysMetrics[SM_CXSCREEN]; + sysMetrics[SM_CYFULLSCREEN] = sysMetrics[SM_CYSCREEN] - sysMetrics[SM_CYCAPTION]; + sysMetrics[SM_CYKANJIWINDOW] = 0; + sysMetrics[SM_MOUSEPRESENT] = 1; + sysMetrics[SM_CYVSCROLL] = SYSMETRICS_CYVSCROLL; + sysMetrics[SM_CXHSCROLL] = SYSMETRICS_CXHSCROLL; + sysMetrics[SM_DEBUG] = 0; + sysMetrics[SM_SWAPBUTTON] = 0; + sysMetrics[SM_RESERVED1] = 0; + sysMetrics[SM_RESERVED2] = 0; + sysMetrics[SM_RESERVED3] = 0; + sysMetrics[SM_RESERVED4] = 0; + sysMetrics[SM_CXMIN] = SYSMETRICS_CXMIN; + sysMetrics[SM_CYMIN] = SYSMETRICS_CYMIN; + sysMetrics[SM_CXSIZE] = SYSMETRICS_CXSIZE; + sysMetrics[SM_CYSIZE] = SYSMETRICS_CYSIZE; + sysMetrics[SM_CXFRAME] = GetProfileInt( "windows", "BorderWidth", 4 ); + sysMetrics[SM_CYFRAME] = sysMetrics[SM_CXFRAME]; + sysMetrics[SM_CXMINTRACK] = SYSMETRICS_CXMINTRACK; + sysMetrics[SM_CYMINTRACK] = SYSMETRICS_CYMINTRACK; + sysMetrics[SM_CXDOUBLECLK] = (GetProfileInt( "windows","DoubleClickWidth", 4) + 1) & ~1; + sysMetrics[SM_CYDOUBLECLK] = (GetProfileInt( "windows","DoubleClickHeight", 4) + 1) & ~1; + sysMetrics[SM_CXICONSPACING] = GetProfileInt( "desktop","IconSpacing", 75); + sysMetrics[SM_CYICONSPACING] = GetProfileInt( "desktop","IconVerticalSpacing", 72); + sysMetrics[SM_MENUDROPALIGNMENT] = GetProfileInt( "windows","MenuDropAlignment", 0 ); + sysMetrics[SM_PENWINDOWS] = 0; + sysMetrics[SM_DBCSENABLED] = 0; +} + + +/*********************************************************************** + * GetSystemMetrics (USER.179) + */ +int GetSystemMetrics( WORD index ) +{ + if (index >= SM_CMETRICS) return 0; + else return sysMetrics[index]; +} + + + diff --git a/windows/win.c b/windows/win.c index 8411e489860..810503cadb7 100644 --- a/windows/win.c +++ b/windows/win.c @@ -15,11 +15,13 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "win.h" #include "user.h" #include "dce.h" +#include "sysmetrics.h" -extern Display * XT_display; -extern Screen * XT_screen; +extern Display * display; extern Colormap COLOR_WinColormap; +extern void EVENT_RegisterWindow( Window w, HWND hwnd ); /* event.c */ + static HWND firstWindow = 0; /*********************************************************************** @@ -178,17 +180,22 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, CREATESTRUCT *createStruct; HANDLE hcreateStruct; int wmcreate; - short newwidth, newheight; + XSetWindowAttributes win_attr; + Window parentWindow; + int x_rel, y_rel; + LPPOPUPMENU lpbar; #ifdef DEBUG_WIN - printf( "CreateWindowEx: %s %s %d,%d %dx%d %08x\n", - className, windowName, x, y, width, height, style ); + printf( "CreateWindowEx: %d '%s' '%s' %d,%d %dx%d %08x %x\n", + exStyle, className, windowName, x, y, width, height, style, parent); #endif - if (x == CW_USEDEFAULT) x = 0; - if (y == CW_USEDEFAULT) y = 0; - if (width == CW_USEDEFAULT) width = 600; - if (height == CW_USEDEFAULT) height = 400; + if (x == CW_USEDEFAULT) x = y = 0; + if (width == CW_USEDEFAULT) + { + width = 600; + height = 400; + } if (width == 0) width = 1; if (height == 0) height = 1; @@ -201,11 +208,18 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, if (!parent) return 0; } else if (style & WS_CHILD) return 0; /* WS_CHILD needs a parent */ - + if (!(class = CLASS_FindClassByName( className, &classPtr ))) { printf("CreateWindow BAD CLASSNAME '%s' !\n", className); return 0; } + + /* Correct the window style */ + + if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */ + style |= WS_CAPTION | WS_CLIPSIBLINGS; + if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME; + /* Create the window structure */ hwnd = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra); @@ -217,8 +231,8 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, wndPtr->hwndNext = 0; wndPtr->hwndChild = 0; wndPtr->dwMagic = WND_MAGIC; - wndPtr->hwndParent = parent; - wndPtr->hwndOwner = parent; /* What else? */ + wndPtr->hwndParent = (style & WS_CHILD) ? parent : 0; + wndPtr->hwndOwner = (style & WS_CHILD) ? 0 : parent; wndPtr->hClass = class; wndPtr->hInstance = instance; wndPtr->rectWindow.left = x; @@ -239,9 +253,12 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, wndPtr->hCursor = 0; wndPtr->hWndVScroll = 0; wndPtr->hWndHScroll = 0; + wndPtr->hWndMenuBar = 0; + wndPtr->hWndCaption = 0; if (classPtr->wc.cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra ); + if (classPtr->wc.style & CS_DBLCLKS) wndPtr->flags |= WIN_DOUBLE_CLICKS; classPtr->cWindows++; /* Get class or window DC if needed */ @@ -261,156 +278,32 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, WIN_LinkWindow( hwnd, HWND_TOP ); - if (!strcasecmp(className, "COMBOBOX")) - { - height = 16; - } - -#ifdef USE_XLIB - { - XSetWindowAttributes win_attr; - Window parentWindow; - int x_rel, y_rel; - - win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | - PointerMotionMask | ButtonPressMask | - ButtonReleaseMask | StructureNotifyMask | - FocusChangeMask | EnterWindowMask; - win_attr.override_redirect = /*True*/ False; - win_attr.colormap = COLOR_WinColormap; - if (style & WS_CHILD) - { - parentWindow = parentPtr->window; - x_rel = x + parentPtr->rectClient.left-parentPtr->rectWindow.left; - y_rel = y + parentPtr->rectClient.top-parentPtr->rectWindow.top; - } - else - { - parentWindow = DefaultRootWindow( XT_display ); - x_rel = x; - y_rel = y; - } - wndPtr->window = XCreateWindow( XT_display, parentWindow, - x_rel, y_rel, width, height, 0, - CopyFromParent, InputOutput, - CopyFromParent, - CWEventMask | CWOverrideRedirect | - CWColormap, &win_attr ); - XStoreName( XT_display, wndPtr->window, windowName ); - } -#else - /* Create the widgets */ + /* Create the X window */ + win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | + PointerMotionMask | ButtonPressMask | + ButtonReleaseMask | StructureNotifyMask | + FocusChangeMask | EnterWindowMask; + win_attr.override_redirect = /*True*/ False; + win_attr.colormap = COLOR_WinColormap; if (style & WS_CHILD) { - wndPtr->shellWidget = 0; - if (style & (WS_BORDER | WS_DLGFRAME | WS_THICKFRAME)) - { - int borderCol = 0; - if (COLOR_WinColormap == DefaultColormapOfScreen(XT_screen)) - borderCol = BlackPixelOfScreen(XT_screen); - wndPtr->winWidget = XtVaCreateManagedWidget(className, - compositeWidgetClass, - parentPtr->winWidget, - XtNx, x, - XtNy, y, - XtNwidth, width, - XtNheight, height, - XtNborderColor, borderCol, - XtNmappedWhenManaged, FALSE, - NULL ); - } - else - { - wndPtr->winWidget = XtVaCreateManagedWidget(className, - compositeWidgetClass, - parentPtr->winWidget, - XtNx, x, - XtNy, y, - XtNwidth, width, - XtNheight, height, - XtNborderWidth, 0, - XtNmappedWhenManaged, FALSE, - NULL ); - } + parentWindow = parentPtr->window; + x_rel = x + parentPtr->rectClient.left - parentPtr->rectWindow.left; + y_rel = y + parentPtr->rectClient.top - parentPtr->rectWindow.top; } else { - wndPtr->shellWidget = XtVaAppCreateShell(windowName, - className, - topLevelShellWidgetClass, - XT_display, - XtNx, x, - XtNy, y, - XtNcolormap, COLOR_WinColormap, - XtNmappedWhenManaged, FALSE, - NULL ); - wndPtr->compositeWidget = XtVaCreateManagedWidget(className, - formWidgetClass, - wndPtr->shellWidget, - NULL ); -/* wndPtr->winWidget = wndPtr->compositeWidget; */ - wndPtr->winWidget = wndPtr->shellWidget; - if (wndPtr->wIDmenu == 0) - { - wndPtr->menuBarPtr = - MENU_CreateMenuBar(wndPtr->compositeWidget, - instance, hwnd, - classPtr->wc.lpszMenuName, - width); - if (wndPtr->menuBarPtr) - wndPtr->wIDmenu = - GlobalHandleFromPointer(wndPtr->menuBarPtr->firstItem); - } - else - { - wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget, - instance, hwnd, - wndPtr->wIDmenu, width); - } - - if (wndPtr->menuBarPtr != NULL) - { - wndPtr->winWidget = - XtVaCreateManagedWidget(className, - compositeWidgetClass, - wndPtr->compositeWidget, - XtNwidth, width, - XtNheight, height, - XtNfromVert, - wndPtr->menuBarPtr->menuBarWidget, - XtNvertDistance, 4, - NULL ); - } - else - { - wndPtr->winWidget = - XtVaCreateManagedWidget(className, - compositeWidgetClass, - wndPtr->compositeWidget, - XtNwidth, width, - XtNheight, height, - NULL ); - } + parentWindow = DefaultRootWindow( display ); + x_rel = x; + y_rel = y; } - if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget ); - if (wndPtr->compositeWidget) XtRealizeWidget( wndPtr->compositeWidget ); - XtRealizeWidget( wndPtr->winWidget ); - wndPtr->window = XtWindow( wndPtr->winWidget ); -#endif /* USE_XLIB */ - - if ((style & WS_VSCROLL) == WS_VSCROLL) { - newheight = height - (((style & WS_HSCROLL) == WS_HSCROLL) ? 16 : 0); - wndPtr->hWndVScroll = CreateWindow("SCROLLBAR", "", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_VERT, - width - 16, 0, 16, newheight, hwnd, 2, instance, 0L); - } - if ((style & WS_HSCROLL) == WS_HSCROLL) { - newwidth = width - (((style & WS_VSCROLL) == WS_VSCROLL) ? 16 : 0); - wndPtr->hWndHScroll = CreateWindow("SCROLLBAR", "", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_HORZ, - 0, height - 16, newwidth, 16, hwnd, 3, instance, 0L); - } + wndPtr->window = XCreateWindow(display, parentWindow, + x_rel, y_rel, width, height, 0, + CopyFromParent, InputOutput, CopyFromParent, + CWEventMask | CWOverrideRedirect | + CWColormap, &win_attr ); + XStoreName( display, wndPtr->window, windowName ); /* Send the WM_CREATE message */ @@ -452,30 +345,56 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, GlobalUnlock( hcreateStruct ); GlobalFree( hcreateStruct ); - + if (wmcreate == -1) { /* Abort window creation */ - if (parent) parentPtr->hwndChild = wndPtr->hwndNext; - else firstWindow = wndPtr->hwndNext; -#ifdef USE_XLIB - XDestroyWindow( XT_display, wndPtr->window ); -#else - if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget ); - else XtDestroyWidget( wndPtr->winWidget ); -#endif + WIN_UnlinkWindow( hwnd ); + XDestroyWindow( display, wndPtr->window ); if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce ); classPtr->cWindows--; USER_HEAP_FREE( hwnd ); return 0; } -#ifdef USE_XLIB - EVENT_AddHandlers( wndPtr->window, hwnd ); -#else - EVENT_AddHandlers( wndPtr->winWidget, hwnd ); -#endif + /* Create scrollbars */ + + if (windowName != NULL) SetWindowText(hwnd, windowName); + if ((style & WS_CAPTION) == WS_CAPTION) { + wndPtr->hWndCaption = CreateWindow("CAPTION", "", + WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, + 0, -20, width, 20, hwnd, 1, instance, 0L); + } + if (((style & WS_CHILD) != WS_CHILD) && (wndPtr->wIDmenu != 0)) { + lpbar = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu); + if (lpbar != NULL) { + lpbar->ownerWnd = hwnd; + wndPtr->hWndMenuBar = CreateWindow("POPUPMENU", "", + WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, + 0, 0, width, 20, hwnd, 2, instance, (LPSTR)lpbar); + } + } + if ((style & WS_VSCROLL) == WS_VSCROLL) + { + wndPtr->hWndVScroll = CreateWindow("SCROLLBAR", "", + WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_VERT, + wndPtr->rectClient.right-wndPtr->rectClient.left, 0, + SYSMETRICS_CXVSCROLL, + wndPtr->rectClient.bottom-wndPtr->rectClient.top, + hwnd, 3, instance, 0L); + } + if ((style & WS_HSCROLL) == WS_HSCROLL) + { + wndPtr->hWndHScroll = CreateWindow("SCROLLBAR", "", + WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_HORZ, + 0, wndPtr->rectClient.bottom-wndPtr->rectClient.top, + wndPtr->rectClient.right-wndPtr->rectClient.left, + SYSMETRICS_CYHSCROLL, + hwnd, 4, instance, 0L); + } + + EVENT_RegisterWindow( wndPtr->window, hwnd ); WIN_SendParentNotify( hwnd, wndPtr, WM_CREATE ); @@ -515,12 +434,7 @@ BOOL DestroyWindow( HWND hwnd ) /* Destroy the window */ -#ifdef USE_XLIB - XDestroyWindow( XT_display, wndPtr->window ); -#else - if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget ); - else XtDestroyWidget( wndPtr->winWidget ); -#endif + XDestroyWindow( display, wndPtr->window ); if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce ); classPtr->cWindows--; USER_HEAP_FREE( hwnd ); @@ -588,49 +502,7 @@ HMENU GetMenu( HWND hwnd ) */ BOOL SetMenu(HWND hwnd, HMENU hmenu) { -#ifdef USE_XLIB return FALSE; -#else - WND *wndPtr; - wndPtr = WIN_FindWndPtr(hwnd); - if (wndPtr == NULL) - return FALSE; - - if (wndPtr->dwStyle & WS_CHILD) return FALSE; - - if (wndPtr->menuBarPtr != NULL) - { - XtVaSetValues(wndPtr->winWidget, XtNfromVert, NULL, NULL); - MENU_CollapseMenu(wndPtr->menuBarPtr); - } - - wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget, - wndPtr->hInstance, hwnd, hmenu, - wndPtr->rectClient.right - - wndPtr->rectClient.left); - - if (wndPtr->menuBarPtr != NULL) - { - XtVaSetValues(wndPtr->winWidget, - XtNfromVert, wndPtr->menuBarPtr->menuBarWidget, - XtNvertDistance, 4, - NULL); - } - else - { - if (wndPtr->wIDmenu != 0) - { - wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget, - wndPtr->hInstance, hwnd, - wndPtr->wIDmenu, - wndPtr->rectClient.right - - wndPtr->rectClient.left); - } - return FALSE; - } - - return TRUE; -#endif /* USE_XLIB */ } diff --git a/windows/winpos.c b/windows/winpos.c index 0b474e2e3ea..884f411abfc 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -8,8 +8,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "win.h" -extern Display * XT_display; -extern Screen * XT_screen; +extern Display * display; /*********************************************************************** @@ -213,10 +212,8 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y, RECT newWindowRect, newClientRect; WND *wndPtr; int calcsize_result = 0; -#ifdef USE_XLIB XWindowChanges winChanges; int changeMask = 0; -#endif #ifdef DEBUG_WIN printf( "SetWindowPos: %d %d %d,%d %dx%d 0x%x\n", @@ -311,7 +308,7 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y, } /* Perform the moving and resizing */ -#ifdef USE_XLIB + if (!(winPos->flags & SWP_NOMOVE)) { WND * parentPtr; @@ -343,31 +340,28 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y, } changeMask |= CWStackMode; } - if (changeMask) XConfigureWindow( XT_display, wndPtr->window, + if (changeMask) XConfigureWindow( display, wndPtr->window, changeMask, &winChanges ); -#endif if (winPos->flags & SWP_SHOWWINDOW) { wndPtr->dwStyle |= WS_VISIBLE; -#ifdef USE_XLIB - XMapWindow( XT_display, wndPtr->window ); -#else - if (wndPtr->shellWidget) XtMapWidget( wndPtr->shellWidget ); - else XtMapWidget( wndPtr->winWidget ); -#endif + XMapWindow( display, wndPtr->window ); } else if (winPos->flags & SWP_HIDEWINDOW) { wndPtr->dwStyle &= ~WS_VISIBLE; -#ifdef USE_XLIB - XUnmapWindow( XT_display, wndPtr->window ); -#else - if (wndPtr->shellWidget) XtUnmapWidget( wndPtr->shellWidget ); - else XtUnmapWidget( wndPtr->winWidget ); -#endif + XUnmapWindow( display, wndPtr->window ); } + /* Send WM_NCPAINT message if needed */ + if ((winPos->flags & (SWP_FRAMECHANGED | SWP_SHOWWINDOW)) || + (!(winPos->flags & SWP_NOSIZE)) || + (!(winPos->flags & SWP_NOMOVE)) || + (!(winPos->flags & SWP_NOACTIVATE)) || + (!(winPos->flags & SWP_NOZORDER))) + SendMessage( hwnd, WM_NCPAINT, 1, 0L ); + /* Finally send the WM_WINDOWPOSCHANGED message */ wndPtr->rectWindow = newWindowRect; wndPtr->rectClient = newClientRect; diff --git a/wine.ini b/wine.ini index d9958bea4f0..a06ea5c372d 100644 --- a/wine.ini +++ b/wine.ini @@ -1,19 +1,32 @@ [drives] -a=/mnt/fd0 -c=/dos -d=/usr/windows -e=/home/bob/Wine/work -f=/home/bob/test +A=/mnt/fd0 +C=/dos +D=/usr/windows +E=/home/bob/Wine/work +F=/home/bob/test [wine] -windows=c:\windows -system=c:\windows\system -temp=c:\temp -path=c:\windows;c:\windows\system;e:\;e:\test;f:\ +Windows=c:\windows +System=c:\windows\system +Temp=c:\temp +Path=c:\windows;c:\windows\system;e:\;e:\test;f:\ +SystemResources=sysres.dll +; SystemResources= [serialports] -com1=/dev/cua0 -com2=/dev/cua1 +Com1=/dev/cua0 +Com2=/dev/cua1 [parallelports] -lpt1=/dev/lp0 +Lpt1=/dev/lp0 + +[spy] +;;;;; Uncomment the following line to activate spying to the console ;;;;; +;File=CON + +;;;;; Uncomment the following line to activate spying to the spy.log ;;;;; +;File=spy.log + +;;;;; The following options are not supported yet ;;;;; +;Include= +;Exclude=