From 940d58c2013dfe6afc3d9081185cd73b1c069d2e Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 16 Sep 1994 09:24:37 +0000 Subject: [PATCH] Release 940912 Thu Aug 25 15:24:36 EDT 1994 * [include/win.h] Removed seperate X window for icon, added icon width,height. * [include/windows.h] Commented out the old SW_xxx emum and added defines since they aren't enumerated. * [windows/dce.c] Removed some older IsIconic checks from GetDCEx(), functionality is now in nonclient and generic wine window handling code. Lots of thanks to Alexandre Julliard all the hints and help... * [windows/defwnd.c] Removed call to NC_HandleNCPaintIcon() under case WM_PAINTICON, WM_PAINTICON now calls NC_HandleNCPaint. * [windows/event.c] Removed IsIconic checks. * [windows/icon.c] Removed everything in this file for now... could be used later. Icon functionality is now handled by the generic wine windows handling functions. * [windows/mdi.c] Added a ShowWindow in MDIRestoreChild(). MDI child windows now show up when deiconified. Removed IsIconic checks. * [windows/message.c] Removed old icon routines from hardware_event(). * [windows/nonclient.c] Changed NC_HandleNCCalcSize() so it doesn't change the size of an icon window. Made NC_InternalNCHitTest() on an Iconic window always return HTCAPTION. Made NC_HandleNCLButtonDblClk() on an Iconic window always send a SC_RESTORE message. * [windows/painting.c] Changed RedrawWindow() so it doesn't redraw an iconic window unless it has to (no icon for this class). * [windows/win.c] Removed creation of seperate icon window from CreateWindowEx(). * [windows/winpos.c] Added saving and restoring of window rectangle during iconification/deiconification to ShowWindow(). Added functions to recursively hide and show children... called by ShowWindow during iconification/deiconification. Sat, 27 Aug 1994 18:47:34 +0100 (MET DST) micky@marie.physik.tu-berlin.de (Michael Patra) * [windows/message.c] WaitMessage(): Fixed handling of wm_timer-messages * [miscemu/int21.c] FindNextFCB(): Rewritten to support other functions than just returning the volume label * [misc/file.c] OpenFile(): Fix in handling of OF_CREATE Wed Aug 24 19:40:42 PDT 1994 Andrew Lagodzinski (andrew@netcom.com) * [if1632/user.spec] Added SetParent. * [windows/win.c] Added SetParent. Fri Aug 19 16:37:00 1994 Thomas Sandford * [loader/selector.c] Many changes throughout file to correct handling of shared memory function return codes. FreeBSD and SunOS shm functions return -1 not 0 on error. If Linux is different, these changes will have to be backed out. CleanupSelectors(): this is a new (internal) call to free up all selectors (and shm handles/memory) for use on exit. * [include/segmem.h] Change comment to reflect new use of shm_key * [misc/main.c] called_at_exit(): add call to CleanupSelectors() Mon Aug 22 18:19:25 1994 Alexandre Julliard (julliard@lamisun.epfl.ch) * [controls/button.c] Use OBM_CHECKBOXES to draw check boxes with correct colors. Fixed bug with WM_SETTEXT handling. A few drawing optimisations. * [controls/menu.c] Implemented correct \t and \a handling in menu items. Implemented help items (flush right) on menu bar. Added WM_ENTERMENULOOP and WM_EXITMENULOOP messages. * [controls/static.c] Fixed SS_ICON controls and implemented STM_SETICON message handling. * [controls/widget.c] Set cursor to IDC_ARROW for built-in classes. * [include/options.h] [misc/main.c] Backing store is now off by default. * [objects/region.c] Use X regions for rectangle and polygon regions: *major* speed improvement. * [windows/dialog.c] Fixed the fix for integer ids in controls. SS_ICON controls in dialogs should work now. Implemented DS_ABSALIGN style. * [windows/graphics.c] Implemented InvertRgn(). New internal function GRAPH_DrawBitmap() to draw bitmaps faster than with CreateCompatibleDC() + BitBlt(). * [windows/message.c] Determining the window for a mouse message is now done at GetMessage() time. Modified PeekMessage() handling to avoid needlessly flushing the output queue. * [windows/timer.c] Check for restart of a timer (SetTimer call with the same hwnd and id than an existing timer). --- ChangeLog | 136 ++++++++++ controls/button.c | 495 ++++++++++++------------------------ controls/desktop.c | 20 +- controls/menu.c | 269 ++++++++++---------- controls/static.c | 81 +++--- controls/widgets.c | 9 +- if1632/Imakefile | 2 +- if1632/gdi.spec | 2 +- if1632/user.spec | 2 +- include/bitmaps/check_boxes | 26 ++ include/gdi.h | 2 + include/menu.h | 14 +- include/msdos.h | 12 + include/options.h | 4 +- include/segmem.h | 2 +- include/win.h | 13 +- include/windows.h | 28 +- loader/selector.c | 52 +++- misc/file.c | 2 +- misc/main.c | 11 +- miscemu/int21.c | 71 ++++-- objects/bitmap.c | 9 +- objects/clipping.c | 7 +- objects/region.c | 403 ++++++++++++++++++----------- windows/dce.c | 24 +- windows/defwnd.c | 7 +- windows/dialog.c | 30 +-- windows/event.c | 7 - windows/graphics.c | 58 +++++ windows/icon.c | 186 -------------- windows/mdi.c | 7 +- windows/message.c | 140 ++++++---- windows/nonclient.c | 188 ++++++-------- windows/painting.c | 8 + windows/timer.c | 20 +- windows/win.c | 73 +++--- windows/winpos.c | 99 +++++++- 37 files changed, 1348 insertions(+), 1171 deletions(-) create mode 100644 include/bitmaps/check_boxes diff --git a/ChangeLog b/ChangeLog index e7dfebddcb1..1e09a069e22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,139 @@ +---------------------------------------------------------------------- +Thu Aug 25 15:24:36 EDT 1994 + + * [include/win.h] + Removed seperate X window for icon, added icon width,height. + + * [include/windows.h] + Commented out the old SW_xxx emum and added defines since + they aren't enumerated. + + * [windows/dce.c] + Removed some older IsIconic checks from GetDCEx(), functionality + is now in nonclient and generic wine window handling code. + Lots of thanks to Alexandre Julliard all the hints and + help... + + * [windows/defwnd.c] + Removed call to NC_HandleNCPaintIcon() under case WM_PAINTICON, + WM_PAINTICON now calls NC_HandleNCPaint. + + * [windows/event.c] + Removed IsIconic checks. + + * [windows/icon.c] + Removed everything in this file for now... could be used later. + Icon functionality is now handled by the generic wine windows + handling functions. + + * [windows/mdi.c] + Added a ShowWindow in MDIRestoreChild(). MDI child windows now + show up when deiconified. Removed IsIconic checks. + + * [windows/message.c] + Removed old icon routines from hardware_event(). + + * [windows/nonclient.c] + Changed NC_HandleNCCalcSize() so it doesn't change the size + of an icon window. Made NC_InternalNCHitTest() on an Iconic + window always return HTCAPTION. Made NC_HandleNCLButtonDblClk() + on an Iconic window always send a SC_RESTORE message. + + * [windows/painting.c] + Changed RedrawWindow() so it doesn't redraw an iconic window + unless it has to (no icon for this class). + + * [windows/win.c] + Removed creation of seperate icon window from CreateWindowEx(). + + * [windows/winpos.c] + Added saving and restoring of window rectangle during + iconification/deiconification to ShowWindow(). Added + functions to recursively hide and show children... called + by ShowWindow during iconification/deiconification. + +Sat, 27 Aug 1994 18:47:34 +0100 (MET DST) micky@marie.physik.tu-berlin.de (Michael Patra) + + * [windows/message.c] + WaitMessage(): Fixed handling of wm_timer-messages + + * [miscemu/int21.c] + FindNextFCB(): Rewritten to support other functions than just + returning the volume label + + * [misc/file.c] + OpenFile(): Fix in handling of OF_CREATE + +Wed Aug 24 19:40:42 PDT 1994 Andrew Lagodzinski (andrew@netcom.com) + + * [if1632/user.spec] + Added SetParent. + + * [windows/win.c] + Added SetParent. + +Fri Aug 19 16:37:00 1994 Thomas Sandford + + * [loader/selector.c] + Many changes throughout file to correct handling of shared memory + function return codes. FreeBSD and SunOS shm functions return + -1 not 0 on error. If Linux is different, these changes + will have to be backed out. + CleanupSelectors(): this is a new (internal) call to free + up all selectors (and shm handles/memory) for use on exit. + + * [include/segmem.h] + Change comment to reflect new use of shm_key + + * [misc/main.c] + called_at_exit(): add call to CleanupSelectors() + +Mon Aug 22 18:19:25 1994 Alexandre Julliard (julliard@lamisun.epfl.ch) + + * [controls/button.c] + Use OBM_CHECKBOXES to draw check boxes with correct colors. + Fixed bug with WM_SETTEXT handling. + A few drawing optimisations. + + * [controls/menu.c] + Implemented correct \t and \a handling in menu items. + Implemented help items (flush right) on menu bar. + Added WM_ENTERMENULOOP and WM_EXITMENULOOP messages. + + * [controls/static.c] + Fixed SS_ICON controls and implemented STM_SETICON message + handling. + + * [controls/widget.c] + Set cursor to IDC_ARROW for built-in classes. + + * [include/options.h] [misc/main.c] + Backing store is now off by default. + + * [objects/region.c] + Use X regions for rectangle and polygon regions: *major* speed + improvement. + + * [windows/dialog.c] + Fixed the fix for integer ids in controls. SS_ICON controls in + dialogs should work now. + Implemented DS_ABSALIGN style. + + * [windows/graphics.c] + Implemented InvertRgn(). + New internal function GRAPH_DrawBitmap() to draw bitmaps faster + than with CreateCompatibleDC() + BitBlt(). + + * [windows/message.c] + Determining the window for a mouse message is now done at + GetMessage() time. + Modified PeekMessage() handling to avoid needlessly flushing the + output queue. + + * [windows/timer.c] + Check for restart of a timer (SetTimer call with the same hwnd and + id than an existing timer). + ---------------------------------------------------------------------- Tue Aug 9 23:58:29 MET DST 1994 diff --git a/controls/button.c b/controls/button.c index a5d39469446..7e2d99e1b5b 100644 --- a/controls/button.c +++ b/controls/button.c @@ -12,15 +12,19 @@ static char Copyright2[] = "Copyright David Metcalfe, 1993"; #include "user.h" #include "syscolor.h" -LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam); -static BOOL pressed; +LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam); #define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \ SendMessage(GetParent(hWndCntrl), WM_COMMAND, \ GetDlgCtrlID(hWndCntrl), MAKELPARAM(hWndCntrl, wNotifyCode)); #define DIM(array) ((sizeof array)/(sizeof array[0])) +extern BOOL GRAPH_DrawBitmap( HDC hdc, HBITMAP hbitmap, int xdest, int ydest, + int xsrc, int ysrc, int width, int height, + int rop ); /* windows/graphics.c */ +extern void DEFWND_SetText( HWND hwnd, LPSTR text ); /* windows/defwnd.c */ + static LONG PB_Paint(HWND hWnd); static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam); static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam); @@ -54,136 +58,60 @@ static LONG OB_KillFocus(HWND hWnd); typedef struct { - LONG (*paintfn)(); - LONG (*lButtonDownfn)(); - LONG (*lButtonUpfn)(); - LONG (*lButtonDblClkfn)(); - LONG (*killFocusfn)(); - LONG (*setCheckfn)(); - LONG (*getCheckfn)(); + LONG (*paintfn)( HWND ); + LONG (*lButtonDownfn)( HWND, WORD, LONG ); + LONG (*lButtonUpfn)( HWND, WORD, LONG ); + LONG (*lButtonDblClkfn)( HWND, WORD, LONG ); + LONG (*killFocusfn)( HWND ); + LONG (*setCheckfn)( HWND, WORD ); + LONG (*getCheckfn)( HWND ); } BTNFN; #define MAX_BTN_TYPE 12 static BTNFN btnfn[MAX_BTN_TYPE] = { - { - (LONG(*)())PB_Paint, /* BS_PUSHBUTTON */ - (LONG(*)())PB_LButtonDown, - (LONG(*)())PB_LButtonUp, - (LONG(*)())PB_LButtonDblClk, - (LONG(*)())PB_KillFocus, - (LONG(*)())NULL, - (LONG(*)())NULL - }, - { - (LONG(*)())PB_Paint, /* BS_DEFPUSHBUTTON */ - (LONG(*)())PB_LButtonDown, - (LONG(*)())PB_LButtonUp, - (LONG(*)())PB_LButtonDblClk, - (LONG(*)())PB_KillFocus, - (LONG(*)())NULL, - (LONG(*)())NULL - }, - { - (LONG(*)())CB_Paint, /* BS_CHECKBOX */ - (LONG(*)())CB_LButtonDown, - (LONG(*)())CB_LButtonUp, - (LONG(*)())CB_LButtonDblClk, - (LONG(*)())CB_KillFocus, - (LONG(*)())CB_SetCheck, - (LONG(*)())CB_GetCheck - }, - { - (LONG(*)())CB_Paint, /* BS_AUTOCHECKBOX */ - (LONG(*)())CB_LButtonDown, - (LONG(*)())CB_LButtonUp, - (LONG(*)())CB_LButtonDblClk, - (LONG(*)())CB_KillFocus, - (LONG(*)())CB_SetCheck, - (LONG(*)())CB_GetCheck - }, - { - (LONG(*)())RB_Paint, /* BS_RADIOBUTTON */ - (LONG(*)())RB_LButtonDown, - (LONG(*)())RB_LButtonUp, - (LONG(*)())RB_LButtonDblClk, - (LONG(*)())RB_KillFocus, - (LONG(*)())RB_SetCheck, - (LONG(*)())RB_GetCheck - }, - { - (LONG(*)())CB_Paint, /* BS_3STATE */ - (LONG(*)())CB_LButtonDown, - (LONG(*)())CB_LButtonUp, - (LONG(*)())CB_LButtonDblClk, - (LONG(*)())CB_KillFocus, - (LONG(*)())CB_SetCheck, - (LONG(*)())CB_GetCheck - }, - { - (LONG(*)())CB_Paint, /* BS_AUTO3STATE */ - (LONG(*)())CB_LButtonDown, - (LONG(*)())CB_LButtonUp, - (LONG(*)())CB_LButtonDblClk, - (LONG(*)())CB_KillFocus, - (LONG(*)())CB_SetCheck, - (LONG(*)())CB_GetCheck - }, - { - (LONG(*)())GB_Paint, /* BS_GROUPBOX */ - (LONG(*)())NULL, - (LONG(*)())NULL, - (LONG(*)())NULL, - (LONG(*)())NULL, - (LONG(*)())NULL, - (LONG(*)())NULL - }, - { - (LONG(*)())UB_Paint, /* BS_USERBUTTON */ - (LONG(*)())UB_LButtonDown, - (LONG(*)())UB_LButtonUp, - (LONG(*)())NULL, - (LONG(*)())UB_KillFocus, - (LONG(*)())NULL, - (LONG(*)())NULL - }, - { - (LONG(*)())RB_Paint, /* BS_AUTORADIOBUTTON */ - (LONG(*)())RB_LButtonDown, - (LONG(*)())RB_LButtonUp, - (LONG(*)())RB_LButtonDblClk, - (LONG(*)())RB_KillFocus, - (LONG(*)())RB_SetCheck, - (LONG(*)())RB_GetCheck - }, - { - (LONG(*)())NULL, /* Not defined */ - (LONG(*)())NULL, - (LONG(*)())NULL, - (LONG(*)())NULL, - (LONG(*)())NULL, - (LONG(*)())NULL, - (LONG(*)())NULL - }, - { - (LONG(*)())OB_Paint, /* BS_OWNERDRAW */ - (LONG(*)())OB_LButtonDown, - (LONG(*)())OB_LButtonUp, - (LONG(*)())NULL, - (LONG(*)())OB_KillFocus, - (LONG(*)())NULL, - (LONG(*)())NULL - }, + /* BS_PUSHBUTTON */ + { PB_Paint, PB_LButtonDown, PB_LButtonUp, PB_LButtonDblClk, + PB_KillFocus, NULL, NULL }, + /* BS_DEFPUSHBUTTON */ + { PB_Paint, PB_LButtonDown, PB_LButtonUp, PB_LButtonDblClk, + PB_KillFocus, NULL, NULL }, + /* BS_CHECKBOX */ + { CB_Paint, CB_LButtonDown, CB_LButtonUp, CB_LButtonDblClk, + CB_KillFocus, CB_SetCheck, CB_GetCheck }, + /* BS_AUTOCHECKBOX */ + { CB_Paint, CB_LButtonDown, CB_LButtonUp, CB_LButtonDblClk, + CB_KillFocus, CB_SetCheck, CB_GetCheck }, + /* BS_RADIOBUTTON */ + { RB_Paint, RB_LButtonDown, RB_LButtonUp, RB_LButtonDblClk, + RB_KillFocus, RB_SetCheck, RB_GetCheck }, + /* BS_3STATE */ + { CB_Paint, CB_LButtonDown, CB_LButtonUp, CB_LButtonDblClk, + CB_KillFocus, CB_SetCheck, CB_GetCheck }, + /* BS_AUTO3STATE */ + { CB_Paint, CB_LButtonDown, CB_LButtonUp, CB_LButtonDblClk, + CB_KillFocus, CB_SetCheck, CB_GetCheck }, + /* BS_GROUPBOX */ + { GB_Paint, NULL, NULL, NULL, NULL, NULL, NULL }, + /* BS_USERBUTTON */ + { UB_Paint, UB_LButtonDown, UB_LButtonUp, NULL, UB_KillFocus, NULL, NULL }, + /* BS_AUTORADIOBUTTON */ + { RB_Paint, RB_LButtonDown, RB_LButtonUp, RB_LButtonDblClk, + RB_KillFocus, RB_SetCheck, RB_GetCheck }, + /* Not defined */ + { NULL, NULL, NULL, NULL, NULL, NULL, NULL }, + /* BS_OWNERDRAW */ + { OB_Paint, OB_LButtonDown, OB_LButtonUp, NULL, OB_KillFocus, NULL, NULL } }; +static HBITMAP hbitmapCheckBoxes = 0; +static WORD checkBoxWidth = 0, checkBoxHeight = 0; + LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam) { LONG lResult = 0; - HDC hDC; - RECT rc; - WND *wndPtr = WIN_FindWndPtr(hWnd); LONG style = wndPtr->dwStyle & 0x0000000F; @@ -197,12 +125,20 @@ LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam) break; case WM_CREATE: + if (!hbitmapCheckBoxes) + { + BITMAP bmp; + hbitmapCheckBoxes = LoadBitmap( 0, MAKEINTRESOURCE(OBM_CHECKBOXES) ); + GetObject( hbitmapCheckBoxes, sizeof(bmp), (LPSTR)&bmp ); + checkBoxWidth = bmp.bmWidth / 4; + checkBoxHeight = bmp.bmHeight / 3; + } + if (style < 0L || style >= (LONG)DIM(btnfn)) lResult = -1L; else { (WORD)(*(wndPtr->wExtra)) = 0; - pressed = FALSE; lResult = 0L; } break; @@ -227,6 +163,12 @@ LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam) (btnfn[style].lButtonDblClkfn)(hWnd, wParam, lParam); break; + case WM_SETTEXT: + DEFWND_SetText( hWnd, (LPSTR)lParam ); + InvalidateRect( hWnd, NULL, FALSE ); + UpdateWindow( hWnd ); + return 0; + case WM_SETFOCUS: break; @@ -270,76 +212,71 @@ static LONG PB_Paint(HWND hWnd) hDC = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &rc); - if (pressed) + if (GetCapture() == hWnd) DrawPressedPushButton(hDC, hWnd, rc); else DrawRaisedPushButton(hDC, hWnd, rc); EndPaint(hWnd, &ps); + return 0; } static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam) { SetFocus(hWnd); SetCapture(hWnd); - pressed = TRUE; InvalidateRect(hWnd, NULL, FALSE); UpdateWindow(hWnd); + return 0; } static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) { RECT rc; - pressed = FALSE; ReleaseCapture(); GetClientRect(hWnd, &rc); if (PtInRect(&rc, MAKEPOINT(lParam))) NOTIFY_PARENT(hWnd, BN_CLICKED); InvalidateRect(hWnd, NULL, FALSE); UpdateWindow(hWnd); + return 0; } static LONG PB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam) { - RECT rc; - - GetClientRect(hWnd, &rc); - if (PtInRect(&rc, MAKEPOINT(lParam))) - NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED); + NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED); + return 0; } static LONG PB_KillFocus(HWND hWnd) { - pressed = FALSE; InvalidateRect(hWnd, NULL, FALSE); UpdateWindow(hWnd); + return 0; } static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc) { HPEN hOldPen; HBRUSH hOldBrush; - HRGN rgn1, rgn2, rgn; + HRGN rgn; int len; - static char text[50+1]; + char *text; POINT points[6]; DWORD dwTextSize; int delta; TEXTMETRIC tm; + WND *wndPtr = WIN_FindWndPtr( hButton ); hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowFrame); hOldBrush = (HBRUSH)SelectObject(hDC, sysColorObjects.hbrushBtnFace); SetBkMode(hDC, TRANSPARENT); - - rgn = CreateRectRgn(0, 0, 0, 0); - rgn1 = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom); - - SendMessage(GetParent(hButton), WM_CTLCOLOR, (WORD)hDC, - MAKELPARAM(hButton, CTLCOLOR_BTN)); + SetTextColor( hDC, GetSysColor(COLOR_BTNTEXT) ); Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom); /* draw button label, if any: */ - len = GetWindowText(hButton, text, sizeof text); + text = USER_HEAP_ADDR( wndPtr->hText ); + len = strlen(text); if (len >= 1) { rc.left--; rc.bottom--; DrawText(hDC, text, len, &rc, @@ -359,9 +296,8 @@ static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc) points[4].y = rc.top+1; points[5].x = rc.left+2; points[5].y = rc.top+1; - rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE); - CombineRgn(rgn, rgn1, rgn2, RGN_AND); - FillRgn(hDC, rgn2, sysColorObjects.hbrushBtnHighlight); + rgn = CreatePolygonRgn(points, DIM(points), ALTERNATE); + FillRgn(hDC, rgn, sysColorObjects.hbrushBtnHighlight); /* draw button shadow: */ points[0].x = rc.left+2; @@ -376,9 +312,8 @@ static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc) points[4].y = rc.top; points[5].x = rc.right-1; points[5].y = rc.bottom; - rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE); - CombineRgn(rgn, rgn1, rgn2, RGN_AND); - FillRgn(hDC, rgn2, sysColorObjects.hbrushBtnShadow); + rgn = CreatePolygonRgn(points, DIM(points), ALTERNATE); + FillRgn(hDC, rgn, sysColorObjects.hbrushBtnShadow); /* do we have the focus? */ if (len >= 1 && GetFocus() == hButton) { @@ -393,8 +328,6 @@ static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc) SelectObject(hDC, (HANDLE)hOldPen); SelectObject(hDC, (HANDLE)hOldBrush); - DeleteObject((HANDLE)rgn1); - DeleteObject((HANDLE)rgn2); DeleteObject((HANDLE)rgn); } @@ -404,18 +337,16 @@ static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc) HPEN hOldPen; HBRUSH hOldBrush; int len; - static char text[50+1]; + char *text; DWORD dwTextSize; int delta; TEXTMETRIC tm; + WND *wndPtr = WIN_FindWndPtr( hButton ); hOldBrush = (HBRUSH)SelectObject(hDC, sysColorObjects.hbrushBtnFace); hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowFrame); SetBkMode(hDC, TRANSPARENT); - - /* give parent a chance to alter parameters: */ - SendMessage(GetParent(hButton), WM_CTLCOLOR, (WORD)hDC, - MAKELPARAM(hButton, CTLCOLOR_BTN)); + SetTextColor( hDC, GetSysColor(COLOR_BTNTEXT) ); Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom); /* draw button shadow: */ @@ -424,7 +355,8 @@ static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc) PatBlt(hDC, rc.left+1, rc.top+1, rc.right-rc.left-2, 1, PATCOPY ); /* draw button label, if any: */ - len = GetWindowText(hButton, text, sizeof text); + text = USER_HEAP_ADDR( wndPtr->hText ); + len = strlen(text); if (len >= 1) { rc.top++; rc.left++; DrawText(hDC, text, len, &rc, @@ -454,13 +386,11 @@ static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc) static LONG CB_Paint(HWND hWnd) { PAINTSTRUCT ps; - RECT rc, rc3; + RECT rc; HDC hDC; - HPEN hOldPen; - HBRUSH hBrush, hGrayBrush; + HBRUSH hBrush; int textlen, delta; char *text; - HANDLE hText; TEXTMETRIC tm; SIZE size; WND *wndPtr = WIN_FindWndPtr(hWnd); @@ -468,44 +398,23 @@ static LONG CB_Paint(HWND hWnd) hDC = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &rc); - hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowText); - hGrayBrush = (HBRUSH)GetStockObject(LTGRAY_BRUSH); - hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC, MAKELPARAM(hWnd, CTLCOLOR_BTN)); FillRect(hDC, &rc, hBrush); - textlen = GetWindowTextLength(hWnd); - hText = USER_HEAP_ALLOC(0, textlen+1); - text = USER_HEAP_ADDR(hText); - GetWindowText(hWnd, text, textlen+1); + text = USER_HEAP_ADDR( wndPtr->hText ); + textlen = strlen( text ); GetTextMetrics(hDC, &tm); - delta = (rc.bottom - rc.top - tm.tmHeight) >> 1; - Rectangle(hDC, 0, rc.top + delta, tm.tmHeight, tm.tmHeight + delta); - if (pressed) - Rectangle(hDC, 1, rc.top + delta + 1, tm.tmHeight - 1, - tm.tmHeight + delta - 1); - switch ((WORD)(*(wndPtr->wExtra))) - { - case 1: - MoveTo(hDC, 0, rc.top + delta); - LineTo(hDC, tm.tmHeight - 1, tm.tmHeight + delta - 1); - MoveTo(hDC, 0, tm.tmHeight + delta - 1); - LineTo(hDC, tm.tmHeight - 1, rc.top + delta); - break; + GRAPH_DrawBitmap( hDC, hbitmapCheckBoxes, + rc.left, rc.top + delta, + ((GetCapture() == hWnd) ? 2*checkBoxWidth : 0) + + (wndPtr->wExtra[0] ? checkBoxWidth : 0), + ((wndPtr->wExtra[0] == 2) ? 2*checkBoxHeight : 0), + checkBoxWidth, checkBoxHeight, SRCCOPY ); - case 2: - rc3.left = 1; - rc3.top = rc.top + delta + 1; - rc3.right = tm.tmHeight - 1; - rc3.bottom = tm.tmHeight + delta - 1; - FillRect(hDC, &rc3, hGrayBrush); - break; - } - - rc.left = tm.tmHeight + tm.tmAveCharWidth / 2; + rc.left = checkBoxWidth + tm.tmAveCharWidth / 2; DrawText(hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER); /* do we have the focus? */ @@ -519,53 +428,30 @@ static LONG CB_Paint(HWND hWnd) DrawFocusRect(hDC, &rc); } - SelectObject(hDC, hOldPen); - USER_HEAP_FREE(hText); EndPaint(hWnd, &ps); + return 0; } static LONG CB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam) { RECT rc; - HDC hDC; - TEXTMETRIC tm; - int delta; - hDC = GetDC(hWnd); - GetTextMetrics(hDC, &tm); - ReleaseDC(hWnd, hDC); GetClientRect(hWnd, &rc); - delta = (rc.bottom - rc.top - tm.tmHeight) >> 1; - rc.top += delta; - rc.bottom = tm.tmHeight + delta; - if (PtInRect(&rc, MAKEPOINT(lParam))) - { - SetFocus(hWnd); - SetCapture(hWnd); - pressed = TRUE; - InvalidateRect(hWnd, NULL, FALSE); - UpdateWindow(hWnd); - } + SetFocus(hWnd); + SetCapture(hWnd); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + return 0; } static LONG CB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) { RECT rc; - HDC hDC; - TEXTMETRIC tm; - int delta; WND *wndPtr = WIN_FindWndPtr(hWnd); LONG style; - pressed = FALSE; ReleaseCapture(); - hDC = GetDC(hWnd); - GetTextMetrics(hDC, &tm); - ReleaseDC(hWnd, hDC); GetClientRect(hWnd, &rc); - delta = (rc.bottom - rc.top - tm.tmHeight) >> 1; - rc.top += delta; - rc.bottom = tm.tmHeight + delta; if (PtInRect(&rc, MAKEPOINT(lParam))) { @@ -604,31 +490,20 @@ static LONG CB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) } InvalidateRect(hWnd, NULL, FALSE); UpdateWindow(hWnd); + return 0; } static LONG CB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam) { - RECT rc; - HDC hDC; - TEXTMETRIC tm; - int delta; - - hDC = GetDC(hWnd); - GetTextMetrics(hDC, &tm); - ReleaseDC(hWnd, hDC); - GetClientRect(hWnd, &rc); - delta = (rc.bottom - rc.top - tm.tmHeight) >> 1; - rc.top += delta; - rc.bottom = tm.tmHeight + delta; - if (PtInRect(&rc, MAKEPOINT(lParam))) - NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED); + NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED); + return 0; } static LONG CB_KillFocus(HWND hWnd) { - pressed = FALSE; InvalidateRect(hWnd, NULL, FALSE); UpdateWindow(hWnd); + return 0; } static LONG CB_SetCheck(HWND hWnd, WORD wParam) @@ -637,10 +512,14 @@ static LONG CB_SetCheck(HWND hWnd, WORD wParam) if ((WORD)(*(wndPtr->wExtra)) != wParam) { + RECT rect; + GetClientRect( hWnd, &rect ); + rect.right = rect.left + checkBoxWidth; /* Only invalidate check-box */ (WORD)(*(wndPtr->wExtra)) = wParam; - InvalidateRect(hWnd, NULL, FALSE); + InvalidateRect(hWnd, &rect, FALSE); UpdateWindow(hWnd); } + return 0; } static LONG CB_GetCheck(HWND hWnd) @@ -662,11 +541,9 @@ static LONG RB_Paint(HWND hWnd) PAINTSTRUCT ps; RECT rc; HDC hDC; - HPEN hOldPen; - HBRUSH hBrush, hOldBrush; + HBRUSH hBrush; int textlen, delta; char *text; - HANDLE hText; TEXTMETRIC tm; SIZE size; WND *wndPtr = WIN_FindWndPtr(hWnd); @@ -674,37 +551,23 @@ static LONG RB_Paint(HWND hWnd) hDC = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &rc); - hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowText); - hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC, MAKELPARAM(hWnd, CTLCOLOR_BTN)); FillRect(hDC, &rc, hBrush); - textlen = GetWindowTextLength(hWnd); - hText = USER_HEAP_ALLOC(0, textlen+1); - text = USER_HEAP_ADDR(hText); - GetWindowText(hWnd, text, textlen+1); GetTextMetrics(hDC, &tm); - delta = (rc.bottom - rc.top - tm.tmHeight) >> 1; - Ellipse(hDC, 0, rc.top + delta, tm.tmHeight, tm.tmHeight + delta); - if (pressed) - Ellipse(hDC, 1, rc.top + delta + 1, tm.tmHeight - 1, - tm.tmHeight + delta - 1); + GRAPH_DrawBitmap( hDC, hbitmapCheckBoxes, + rc.left, rc.top + delta, + ((GetCapture() == hWnd) ? 2*checkBoxWidth : 0) + + (wndPtr->wExtra[0] ? checkBoxWidth : 0), checkBoxHeight, + checkBoxWidth, checkBoxHeight, SRCCOPY ); - if ((WORD)(*(wndPtr->wExtra)) == 1) - { - hBrush = CreateSolidBrush( GetNearestColor(hDC, GetSysColor(COLOR_WINDOWTEXT))); - hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBrush); - Ellipse(hDC, 3, rc.top + delta + 3, tm.tmHeight - 3, - tm.tmHeight + delta -3); - SelectObject(hDC, (HANDLE)hOldBrush); - DeleteObject((HANDLE)hBrush); - } - - rc.left = tm.tmHeight + tm.tmAveCharWidth / 2; + text = USER_HEAP_ADDR( wndPtr->hText ); + textlen = strlen( text ); + rc.left = checkBoxWidth + tm.tmAveCharWidth / 2; DrawText(hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER); - + /* do we have the focus? */ if (GetFocus() == hWnd) { @@ -716,53 +579,31 @@ static LONG RB_Paint(HWND hWnd) DrawFocusRect(hDC, &rc); } - SelectObject(hDC, hOldPen ); - USER_HEAP_FREE(hText); EndPaint(hWnd, &ps); + return 0; } static LONG RB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam) { RECT rc; - HDC hDC; - TEXTMETRIC tm; - int delta; - hDC = GetDC(hWnd); - GetTextMetrics(hDC, &tm); - ReleaseDC(hWnd, hDC); GetClientRect(hWnd, &rc); - delta = (rc.bottom - rc.top - tm.tmHeight) >> 1; - rc.top += delta; - rc.bottom = tm.tmHeight + delta; - if (PtInRect(&rc, MAKEPOINT(lParam))) - { - SetFocus(hWnd); - SetCapture(hWnd); - pressed = TRUE; - InvalidateRect(hWnd, NULL, FALSE); - UpdateWindow(hWnd); - } + if (GetFocus() != hWnd) SetFocus(hWnd); + else rc.right = rc.left + checkBoxWidth; + SetCapture(hWnd); + InvalidateRect(hWnd, &rc, FALSE); + UpdateWindow(hWnd); + return 0; } static LONG RB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) { RECT rc; - HDC hDC; - TEXTMETRIC tm; - int delta; WND *wndPtr = WIN_FindWndPtr(hWnd); LONG style; - pressed = FALSE; ReleaseCapture(); - hDC = GetDC(hWnd); - GetTextMetrics(hDC, &tm); - ReleaseDC(hWnd, hDC); GetClientRect(hWnd, &rc); - delta = (rc.bottom - rc.top - tm.tmHeight) >> 1; - rc.top += delta; - rc.bottom = tm.tmHeight + delta; if (PtInRect(&rc, MAKEPOINT(lParam))) { @@ -771,33 +612,24 @@ static LONG RB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) (WORD)(*(wndPtr->wExtra)) = 1; NOTIFY_PARENT(hWnd, BN_CLICKED); } - InvalidateRect(hWnd, NULL, FALSE); + rc.right = rc.left + checkBoxWidth; + InvalidateRect(hWnd, &rc, FALSE); UpdateWindow(hWnd); + return 0; } + static LONG RB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam) { - RECT rc; - HDC hDC; - TEXTMETRIC tm; - int delta; - - hDC = GetDC(hWnd); - GetTextMetrics(hDC, &tm); - ReleaseDC(hWnd, hDC); - GetClientRect(hWnd, &rc); - delta = (rc.bottom - rc.top - tm.tmHeight) >> 1; - rc.top += delta; - rc.bottom = tm.tmHeight + delta; - if (PtInRect(&rc, MAKEPOINT(lParam))) - NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED); + NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED); + return 0; } static LONG RB_KillFocus(HWND hWnd) { - pressed = FALSE; InvalidateRect(hWnd, NULL, FALSE); UpdateWindow(hWnd); + return 0; } static LONG RB_SetCheck(HWND hWnd, WORD wParam) @@ -806,10 +638,14 @@ static LONG RB_SetCheck(HWND hWnd, WORD wParam) if ((WORD)(*(wndPtr->wExtra)) != wParam) { + RECT rc; + GetClientRect( hWnd, &rc ); + rc.right = rc.left + checkBoxWidth; (WORD)(*(wndPtr->wExtra)) = wParam; - InvalidateRect(hWnd, NULL, FALSE); + InvalidateRect(hWnd, &rc, FALSE); UpdateWindow(hWnd); } + return 0; } static LONG RB_GetCheck(HWND hWnd) @@ -831,39 +667,38 @@ static LONG GB_Paint(HWND hWnd) PAINTSTRUCT ps; RECT rc; HDC hDC; - HPEN hOldPen; HBRUSH hBrush; - int textlen; char *text; - HANDLE hText; SIZE size; + WND *wndPtr = WIN_FindWndPtr( hWnd ); hDC = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &rc); - hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowText); - + SelectObject( hDC, sysColorObjects.hpenWindowFrame ); hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC, MAKELPARAM(hWnd, CTLCOLOR_BTN)); FillRect(hDC, &rc, hBrush); - textlen = GetWindowTextLength(hWnd); - hText = USER_HEAP_ALLOC(0, textlen+1); - text = USER_HEAP_ADDR(hText); - GetWindowText(hWnd, text, textlen+1); - GetTextExtentPoint(hDC, text, textlen, &size); + text = USER_HEAP_ADDR( wndPtr->hText ); + GetTextExtentPoint(hDC, text, strlen(text), &size); + + MoveTo( hDC, 8, 5 ); + LineTo( hDC, rc.left, 5 ); + LineTo( hDC, rc.left, rc.bottom-1 ); + LineTo( hDC, rc.right-1, rc.bottom-1 ); + LineTo( hDC, rc.right-1, 5 ); + LineTo( hDC, rc.left + size.cx + 12, 5 ); - rc.top = 5; - Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom); rc.left = 10; rc.top = 0; rc.right = rc.left + size.cx + 1; rc.bottom = size.cy; - DrawText(hDC, text, textlen, &rc, DT_SINGLELINE); + SetTextColor( hDC, GetSysColor(COLOR_WINDOWTEXT) ); + DrawText(hDC, text, -1, &rc, DT_SINGLELINE ); - SelectObject(hDC, hOldPen ); - USER_HEAP_FREE(hText); EndPaint(hWnd, &ps); + return 0; } @@ -892,19 +727,16 @@ static LONG UB_Paint(HWND hWnd) DrawFocusRect(hDC, &rc); EndPaint(hWnd, &ps); + return 0; } static LONG UB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam) { - RECT rc; - SetFocus(hWnd); SetCapture(hWnd); - GetClientRect(hWnd, &rc); - if (PtInRect(&rc, MAKEPOINT(lParam))) - NOTIFY_PARENT(hWnd, BN_HILITE); InvalidateRect(hWnd, NULL, FALSE); UpdateWindow(hWnd); + return 0; } static LONG UB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) @@ -920,12 +752,14 @@ static LONG UB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) } InvalidateRect(hWnd, NULL, FALSE); UpdateWindow(hWnd); + return 0; } static LONG UB_KillFocus(HWND hWnd) { InvalidateRect(hWnd, NULL, FALSE); UpdateWindow(hWnd); + return 0; } @@ -955,33 +789,31 @@ static LONG OB_Paint(HWND hWnd) SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis); USER_HEAP_FREE(hDis); EndPaint(hWnd, &ps); + return 0; } static LONG OB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam) { HDC hDC; - RECT rc; HANDLE hDis; LPDRAWITEMSTRUCT lpdis; WND *wndPtr = WIN_FindWndPtr(hWnd); SetFocus(hWnd); SetCapture(hWnd); hDC = GetDC(hWnd); - GetClientRect(hWnd, &rc); - if (PtInRect(&rc, MAKEPOINT(lParam))) - NOTIFY_PARENT(hWnd, BN_CLICKED); - GetClientRect(hWnd, &rc); + NOTIFY_PARENT(hWnd, BN_CLICKED); hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT)); lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis); lpdis->hDC = hDC; lpdis->itemID = 0; - CopyRect(&lpdis->rcItem, &rc); + GetClientRect( hWnd, &lpdis->rcItem ); lpdis->CtlID = wndPtr->wIDmenu; lpdis->CtlType = ODT_BUTTON; lpdis->itemAction = ODA_SELECT; SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis); USER_HEAP_FREE(hDis); ReleaseDC(hWnd, hDC); + return 0; } static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) @@ -996,7 +828,6 @@ static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) GetClientRect(hWnd, &rc); if (PtInRect(&rc, MAKEPOINT(lParam))) NOTIFY_PARENT(hWnd, BN_CLICKED); - GetClientRect(hWnd, &rc); hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT)); lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis); lpdis->hDC = hDC; @@ -1008,11 +839,13 @@ static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis); USER_HEAP_FREE(hDis); ReleaseDC(hWnd, hDC); + return 0; } static LONG OB_KillFocus(HWND hWnd) { InvalidateRect(hWnd, NULL, FALSE); UpdateWindow(hWnd); + return 0; } diff --git a/controls/desktop.c b/controls/desktop.c index e1f5d7f16c2..40451777403 100644 --- a/controls/desktop.c +++ b/controls/desktop.c @@ -8,11 +8,15 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1994"; #include #include +#include #include #include "win.h" #include "desktop.h" #include "prototypes.h" +extern BOOL GRAPH_DrawBitmap( HDC hdc, HBITMAP hbitmap, int xdest, int ydest, + int xsrc, int ysrc, int width, int height, + int rop ); /* graphics.c */ /*********************************************************************** * DESKTOP_LoadBitmap @@ -85,17 +89,15 @@ static LONG DESKTOP_DoEraseBkgnd( HWND hwnd, HDC hdc, DESKTOPINFO *infoPtr ) if (infoPtr->hbitmapWallPaper) { int x, y; - HDC hdcmem; - hdcmem = CreateCompatibleDC( hdc ); - SelectObject( hdcmem, infoPtr->hbitmapWallPaper ); if (infoPtr->fTileWallPaper) { for (y = 0; y < rect.bottom; y += infoPtr->bitmapSize.cy) for (x = 0; x < rect.right; x += infoPtr->bitmapSize.cx) - BitBlt( hdc, x, y, - infoPtr->bitmapSize.cx, infoPtr->bitmapSize.cy, - hdcmem, 0, 0, SRCCOPY ); + GRAPH_DrawBitmap( hdc, infoPtr->hbitmapWallPaper, + x, y, 0, 0, + infoPtr->bitmapSize.cx, + infoPtr->bitmapSize.cy, SRCCOPY ); } else { @@ -103,10 +105,10 @@ static LONG DESKTOP_DoEraseBkgnd( HWND hwnd, HDC hdc, DESKTOPINFO *infoPtr ) y = (rect.top + rect.bottom - infoPtr->bitmapSize.cy) / 2; if (x < 0) x = 0; if (y < 0) y = 0; - BitBlt( hdc, x, y, infoPtr->bitmapSize.cx, infoPtr->bitmapSize.cy, - hdcmem, 0, 0, SRCCOPY ); + GRAPH_DrawBitmap( hdc, infoPtr->hbitmapWallPaper, x, y, 0, 0, + infoPtr->bitmapSize.cx, infoPtr->bitmapSize.cy, + SRCCOPY ); } - DeleteDC( hdcmem ); } return 1; diff --git a/controls/menu.c b/controls/menu.c index 0f791c757c3..16e515de6a7 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -38,6 +38,9 @@ static BOOL fEndMenuCalled = FALSE; /* Space between 2 menu bar items */ #define MENU_BAR_ITEMS_SPACE 16 + /* Minimum width of a tab character */ +#define MENU_TAB_SPACE 8 + /* Height of a separator item */ #define SEPARATOR_HEIGHT 5 @@ -52,6 +55,9 @@ static BOOL fEndMenuCalled = FALSE; extern void NC_DrawSysButton(HWND hwnd, HDC hdc, BOOL down); /* nonclient.c */ extern void CURSOR_SetWinCursor( HWND hwnd, HCURSOR hcursor ); /* cursor.c */ +extern BOOL GRAPH_DrawBitmap( HDC hdc, HBITMAP hbitmap, int xdest, int ydest, + int xsrc, int ysrc, int width, int height, + int rop ); /* graphics.c */ extern HINSTANCE hSysRes; @@ -59,9 +65,6 @@ static HMENU hSysMenu = 0; static HBITMAP hStdCheck = 0; static HBITMAP hStdMnArrow = 0; -WORD GetSelectionKey(LPSTR str); -LPSTR GetShortCutString(LPSTR str); -int GetShortCutPos(LPSTR str); HMENU CopySysMenu(); WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu); @@ -225,9 +228,14 @@ static WORD MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu, WORD key ) menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu ); lpitem = (MENUITEM *) USER_HEAP_ADDR( menu->hItems ); + key = toupper(key); for (i = 0; i < menu->nItems; i++, lpitem++) { - if (toupper(key) == lpitem->sel_key) return i; + if (IS_STRING_ITEM(lpitem->item_flags)) + { + char *p = strchr( lpitem->item_text, '&' ); + if (p && (p[1] != '&') && (toupper(p[1]) == key)) return i; + } } menuchar = SendMessage( hwndOwner, WM_MENUCHAR, key, MAKELONG( menu->wFlags, hmenu ) ); @@ -242,11 +250,14 @@ static WORD MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu, WORD key ) * * Calculate the size of the menu item and store it in lpitem->rect. */ -static void MENU_CalcItemSize( HDC hdc, LPMENUITEM lpitem, +static void MENU_CalcItemSize( HDC hdc, LPMENUITEM lpitem, HWND hwndOwner, int orgX, int orgY, BOOL menuBar ) { DWORD dwSize; + char *p; + SetRect( &lpitem->rect, orgX, orgY, orgX, orgY ); + lpitem->xTab = 0; if (lpitem->item_flags & MF_SEPARATOR) { @@ -264,8 +275,7 @@ static void MENU_CalcItemSize( HDC hdc, LPMENUITEM lpitem, if (lpitem->item_flags & MF_BITMAP) { BITMAP bm; - HBITMAP hbitmap = (HBITMAP)LOWORD((LONG)lpitem->item_text); - GetObject(hbitmap, sizeof(BITMAP), (LPSTR)&bm); + GetObject( (HBITMAP)lpitem->hText, sizeof(BITMAP), (LPSTR)&bm ); lpitem->rect.right += bm.bmWidth; lpitem->rect.bottom += bm.bmHeight; return; @@ -273,10 +283,26 @@ static void MENU_CalcItemSize( HDC hdc, LPMENUITEM lpitem, /* If we get here, then it is a text item */ - if (menuBar) lpitem->rect.right += MENU_BAR_ITEMS_SPACE; dwSize = GetTextExtent( hdc, lpitem->item_text, strlen(lpitem->item_text)); lpitem->rect.right += LOWORD(dwSize); lpitem->rect.bottom += max( HIWORD(dwSize), SYSMETRICS_CYMENU ); + + if (menuBar) lpitem->rect.right += MENU_BAR_ITEMS_SPACE; + else if ((p = strchr( lpitem->item_text, '\t' )) != NULL) + { + /* Item contains a tab (only meaningful in popup menus) */ + lpitem->xTab = check_bitmap_width + MENU_TAB_SPACE + + LOWORD( GetTextExtent( hdc, lpitem->item_text, + (int)(p - lpitem->item_text) )); + lpitem->rect.right += MENU_TAB_SPACE; + } + else + { + if (strchr( lpitem->item_text, '\b' )) + lpitem->rect.right += MENU_TAB_SPACE; + lpitem->xTab = lpitem->rect.right - check_bitmap_width + - arrow_bitmap_width; + } } @@ -285,11 +311,12 @@ static void MENU_CalcItemSize( HDC hdc, LPMENUITEM lpitem, * * Calculate the size of a popup menu. */ -static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop ) +static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop, HWND hwndOwner ) { LPMENUITEM items, lpitem; HDC hdc; - int start, i, orgX, orgY, maxX; + int start, i; + int orgX, orgY, maxX, maxTab, maxTabWidth; lppop->Width = lppop->Height = 0; if (lppop->nItems == 0) return; @@ -301,19 +328,30 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop ) lpitem = &items[start]; orgX = maxX; orgY = 0; + maxTab = maxTabWidth = 0; /* Parse items until column break or end of menu */ for (i = start; i < lppop->nItems; i++, lpitem++) { if ((i != start) && (lpitem->item_flags & (MF_MENUBREAK | MF_MENUBARBREAK))) break; - MENU_CalcItemSize( hdc, lpitem, orgX, orgY, FALSE ); + MENU_CalcItemSize( hdc, lpitem, hwndOwner, orgX, orgY, FALSE ); maxX = max( maxX, lpitem->rect.right ); orgY = lpitem->rect.bottom; + if (lpitem->xTab) + { + maxTab = max( maxTab, lpitem->xTab ); + maxTabWidth = max(maxTabWidth,lpitem->rect.right-lpitem->xTab); + } } /* Finish the column (set all items to the largest width found) */ - while (start < i) items[start++].rect.right = maxX; + maxX = max( maxX, maxTab + maxTabWidth ); + for (lpitem = &items[start]; start < i; start++, lpitem++) + { + lpitem->rect.right = maxX; + if (lpitem->xTab) lpitem->xTab = maxTab; + } lppop->Height = max( lppop->Height, orgY ); } @@ -327,10 +365,11 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop ) * * Calculate the size of the menu bar. */ -static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, LPPOPUPMENU lppop ) +static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, LPPOPUPMENU lppop, + HWND hwndOwner ) { LPMENUITEM lpitem, items; - int start, i, orgX, orgY, maxY; + int start, i, orgX, orgY, maxY, helpPos; if ((lprect == NULL) || (lppop == NULL)) return; if (lppop->nItems == 0) return; @@ -343,6 +382,7 @@ static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, LPPOPUPMENU lppop ) lppop->Height = 0; maxY = lprect->top; start = 0; + helpPos = -1; while (start < lppop->nItems) { lpitem = &items[start]; @@ -352,9 +392,10 @@ static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, LPPOPUPMENU lppop ) /* Parse items until line break or end of menu */ for (i = start; i < lppop->nItems; i++, lpitem++) { + if ((helpPos == -1) && (lpitem->item_flags & MF_HELP)) helpPos = i; if ((i != start) && (lpitem->item_flags & (MF_MENUBREAK | MF_MENUBARBREAK))) break; - MENU_CalcItemSize( hdc, lpitem, orgX, orgY, TRUE ); + MENU_CalcItemSize( hdc, lpitem, hwndOwner, orgX, orgY, TRUE ); if (lpitem->rect.right > lprect->right) { if (i != start) break; @@ -370,6 +411,23 @@ static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, LPPOPUPMENU lppop ) lprect->bottom = maxY; lppop->Height = lprect->bottom - lprect->top; + + /* Flush right all items between the MF_HELP and the last item */ + /* (if several lines, only move the last line) */ + if (helpPos != -1) + { + lpitem = &items[lppop->nItems-1]; + orgY = lpitem->rect.top; + orgX = lprect->right; + for (i = lppop->nItems - 1; i >= helpPos; i--, lpitem--) + { + if (lpitem->rect.top != orgY) break; /* Other line */ + if (lpitem->rect.right >= orgX) break; /* Too far right already */ + lpitem->rect.left += orgX - lpitem->rect.right; + lpitem->rect.right = orgX; + orgX = lpitem->rect.left; + } + } } @@ -406,6 +464,7 @@ static void MENU_DrawMenuItem( HDC hdc, LPMENUITEM lpitem, SelectObject( hdc, sysColorObjects.hpenWindowFrame ); MoveTo( hdc, rect.left, rect.top + SEPARATOR_HEIGHT/2 ); LineTo( hdc, rect.right, rect.top + SEPARATOR_HEIGHT/2 ); + return; } /* Setup colors */ @@ -433,40 +492,29 @@ static void MENU_DrawMenuItem( HDC hdc, LPMENUITEM lpitem, if (lpitem->item_flags & MF_CHECKED) { - HDC hMemDC = CreateCompatibleDC( hdc ); - if (lpitem->hCheckBit == 0) SelectObject(hMemDC, hStdCheck); - else SelectObject(hMemDC, lpitem->hCheckBit); - BitBlt( hdc, rect.left, - (rect.top + rect.bottom - check_bitmap_height) / 2, - check_bitmap_width, check_bitmap_height, - hMemDC, 0, 0, SRCCOPY ); - DeleteDC( hMemDC ); + GRAPH_DrawBitmap(hdc, lpitem->hCheckBit ? lpitem->hCheckBit : + hStdCheck, rect.left, + (rect.top+rect.bottom-check_bitmap_height) / 2, + 0, 0, check_bitmap_width, check_bitmap_height, + SRCCOPY); } - else /* Not checked */ + else if (lpitem->hUnCheckBit != 0) /* Not checked */ { - if (lpitem->hUnCheckBit != 0) - { - HDC hMemDC = CreateCompatibleDC( hdc ); - SelectObject(hMemDC, lpitem->hUnCheckBit); - BitBlt( hdc, rect.left, - (rect.top + rect.bottom - check_bitmap_height) / 2, - check_bitmap_width, check_bitmap_height, - hMemDC, 0, 0, SRCCOPY ); - DeleteDC( hMemDC ); - } + GRAPH_DrawBitmap(hdc, lpitem->hUnCheckBit, rect.left, + (rect.top+rect.bottom-check_bitmap_height) / 2, + 0, 0, check_bitmap_width, check_bitmap_height, + SRCCOPY); } /* Draw the popup-menu arrow */ if (lpitem->item_flags & MF_POPUP) { - HDC hMemDC = CreateCompatibleDC( hdc ); - SelectObject(hMemDC, hStdMnArrow); - BitBlt( hdc, rect.right-arrow_bitmap_width-1, - (rect.top + rect.bottom - arrow_bitmap_height) / 2, - arrow_bitmap_width, arrow_bitmap_height, - hMemDC, 0, 0, SRCCOPY ); - DeleteDC(hMemDC); + GRAPH_DrawBitmap( hdc, hStdMnArrow, + rect.right-arrow_bitmap_width-1, + (rect.top+rect.bottom-arrow_bitmap_height) / 2, + 0, 0, arrow_bitmap_width, arrow_bitmap_height, + SRCCOPY ); } rect.left += check_bitmap_width; @@ -477,33 +525,43 @@ static void MENU_DrawMenuItem( HDC hdc, LPMENUITEM lpitem, if (lpitem->item_flags & MF_BITMAP) { - HBITMAP hbitmap = (HBITMAP)LOWORD((LONG)lpitem->item_text); - HDC hMemDC = CreateCompatibleDC( hdc ); - SelectObject( hMemDC, hbitmap ); - BitBlt( hdc, rect.left, rect.top, - rect.right-rect.left, rect.bottom-rect.top, - hMemDC, 0, 0, SRCCOPY ); - DeleteDC( hMemDC ); + GRAPH_DrawBitmap( hdc, (HBITMAP)lpitem->hText, rect.left, rect.top, + 0, 0, rect.right-rect.left, rect.bottom-rect.top, + SRCCOPY ); return; } /* No bitmap - process text if present */ else if ((lpitem->item_text) != ((char *) NULL)) { - int x = GetShortCutPos(lpitem->item_text); + register int i; + if (menuBar) { rect.left += MENU_BAR_ITEMS_SPACE / 2; rect.right -= MENU_BAR_ITEMS_SPACE / 2; + i = strlen( lpitem->item_text ); } - if (x != -1) + else { - DrawText( hdc, lpitem->item_text, x, &rect, - DT_LEFT | DT_VCENTER | DT_SINGLELINE ); - DrawText( hdc, lpitem->item_text + x, -1, &rect, - DT_RIGHT | DT_VCENTER | DT_SINGLELINE ); + for (i = 0; lpitem->item_text[i]; i++) + if ((lpitem->item_text[i] == '\t') || + (lpitem->item_text[i] == '\b')) break; + } + + DrawText( hdc, lpitem->item_text, i, &rect, + DT_LEFT | DT_VCENTER | DT_SINGLELINE ); + + if (lpitem->item_text[i]) /* There's a tab or flush-right char */ + { + if (lpitem->item_text[i] == '\t') + { + rect.left = lpitem->xTab; + DrawText( hdc, lpitem->item_text + i + 1, -1, &rect, + DT_LEFT | DT_VCENTER | DT_SINGLELINE ); + } + else DrawText( hdc, lpitem->item_text + i + 1, -1, &rect, + DT_RIGHT | DT_VCENTER | DT_SINGLELINE ); } - else DrawText( hdc, lpitem->item_text, -1, &rect, - DT_LEFT | DT_VCENTER | DT_SINGLELINE ); } } @@ -535,18 +593,20 @@ static void MENU_DrawPopupMenu( HWND hwnd, HDC hdc, HMENU hmenu ) * * Paint a menu bar. Returns the height of the menu bar. */ -WORD MENU_DrawMenuBar(HDC hDC, LPRECT lprect, HMENU hmenu, BOOL suppress_draw) +WORD MENU_DrawMenuBar(HDC hDC, LPRECT lprect, HWND hwnd, BOOL suppress_draw) { LPPOPUPMENU lppop; LPMENUITEM lpitem; int i; - - lppop = (LPPOPUPMENU) USER_HEAP_ADDR( hmenu ); + WND *wndPtr = WIN_FindWndPtr( hwnd ); + + lppop = (LPPOPUPMENU) USER_HEAP_ADDR( wndPtr->wIDmenu ); if (lppop == NULL || lprect == NULL) return SYSMETRICS_CYMENU; #ifdef DEBUG_MENU printf("MENU_DrawMenuBar(%04X, %08X, %08X); !\n", hDC, lprect, lppop); #endif - if (lppop->Height == 0) MENU_MenuBarCalcSize(hDC, lprect, lppop); + if (lppop->Height == 0) MENU_MenuBarCalcSize(hDC, lprect, lppop, hwnd); + lprect->bottom = lprect->top + lppop->Height; if (suppress_draw) return lppop->Height; FillRect(hDC, lprect, sysColorObjects.hbrushMenu ); @@ -582,7 +642,7 @@ static BOOL MENU_ShowPopup(HWND hwndOwner, HMENU hmenu, WORD id, int x, int y) } SendMessage( hwndOwner, WM_INITMENUPOPUP, hmenu, MAKELONG( id, (menu->wFlags & MF_POPUP) ? 1 : 0 )); - MENU_PopupMenuCalcSize( menu ); + MENU_PopupMenuCalcSize( menu, hwndOwner ); if (!menu->hWnd) { WND *wndPtr = WIN_FindWndPtr( hwndOwner ); @@ -1302,8 +1362,10 @@ static BOOL MENU_TrackMenu( HMENU hmenu, WORD wFlags, int x, int y, void MENU_TrackMouseMenuBar( HWND hwnd, POINT pt ) { WND *wndPtr = WIN_FindWndPtr( hwnd ); + SendMessage( hwnd, WM_ENTERMENULOOP, 0, 0 ); MENU_TrackMenu( (HMENU)wndPtr->wIDmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, hwnd, NULL ); + SendMessage( hwnd, WM_EXITMENULOOP, 0, 0 ); } @@ -1315,11 +1377,13 @@ void MENU_TrackMouseMenuBar( HWND hwnd, POINT pt ) void MENU_TrackKbdMenuBar( HWND hwnd, WORD wParam ) { WND *wndPtr = WIN_FindWndPtr( hwnd ); + SendMessage( hwnd, WM_ENTERMENULOOP, 0, 0 ); /* Select first selectable item */ MENU_SelectItem( wndPtr->wIDmenu, NO_SELECTED_ITEM ); MENU_SelectNextItem( (HMENU)wndPtr->wIDmenu ); MENU_TrackMenu( (HMENU)wndPtr->wIDmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON, 0, 0, hwnd, NULL ); + SendMessage( hwnd, WM_EXITMENULOOP, 0, 0 ); } @@ -1343,9 +1407,6 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) { case WM_CREATE: { -#ifdef DEBUG_MENU - printf("PopupMenu WM_CREATE lParam=%08X !\n", lParam); -#endif CREATESTRUCT *createStruct = (CREATESTRUCT *)lParam; HMENU hmenu = (HMENU) ((int)createStruct->lpCreateParams & 0xffff); SetWindowWord( hwnd, 0, hmenu ); @@ -1388,76 +1449,12 @@ WORD MENU_GetMenuBarHeight( HWND hwnd, WORD menubarWidth, int orgX, int orgY ) if (!(lppop = (LPPOPUPMENU)USER_HEAP_ADDR( wndPtr->wIDmenu ))) return 0; hdc = GetDC( hwnd ); SetRect( &rectBar, orgX, orgY, orgX+menubarWidth, orgY+SYSMETRICS_CYMENU ); - MENU_MenuBarCalcSize( hdc, &rectBar, lppop ); + MENU_MenuBarCalcSize( hdc, &rectBar, lppop, hwnd ); ReleaseDC( hwnd, hdc ); return lppop->Height; } - - - -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_MENUSHORTCUT - printf("GetShortCutString // '%s' \n", str2); -#endif - return str2; - } - } -#ifdef DEBUG_MENUSHORTCUT - printf("GetShortCutString NULL \n"); -#endif - return NULL; -} - - - -int GetShortCutPos(LPSTR str) -{ - int i; - for (i = 0; i < strlen(str); i++) { - if (str[i] == '\t' && str[i + 1] != '\t') { -#ifdef DEBUG_MENUSHORTCUT - printf("GetShortCutPos = %d \n", i); -#endif - return i; - } - } -#ifdef DEBUG_MENUSHORTCUT - printf("GetShortCutString NULL \n"); -#endif - return -1; -} - - /********************************************************************** * ChangeMenu [USER.153] */ @@ -1688,12 +1685,22 @@ BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewIt if (IS_STRING_ITEM(wFlags)) { + /* Item beginning with a backspace is a help item */ + if (lpNewItem[0] == '\b') + { + lpitem->item_flags |= MF_HELP; + lpNewItem++; + } lpitem->hText = USER_HEAP_ALLOC( GMEM_MOVEABLE, strlen(lpNewItem)+1 ); lpitem->item_text = (char *)USER_HEAP_ADDR( lpitem->hText ); strcpy( lpitem->item_text, lpNewItem ); - lpitem->sel_key = GetSelectionKey( lpitem->item_text ); } + else if (wFlags & MF_BITMAP) lpitem->hText = LOWORD((DWORD)lpNewItem); else lpitem->item_text = lpNewItem; + + if (wFlags & MF_POPUP) /* Set the MF_POPUP flag on the popup-menu */ + ((POPUPMENU *)USER_HEAP_ADDR(wItemID))->wFlags |= MF_POPUP; + SetRectEmpty( &lpitem->rect ); lpitem->hCheckBit = hStdCheck; lpitem->hUnCheckBit = 0; @@ -1786,8 +1793,8 @@ BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewIt lpitem->hText = USER_HEAP_ALLOC( GMEM_MOVEABLE, strlen(lpNewItem)+1 ); lpitem->item_text = (char *)USER_HEAP_ADDR( lpitem->hText ); strcpy( lpitem->item_text, lpNewItem ); - lpitem->sel_key = GetSelectionKey( lpitem->item_text ); } + else if (wFlags & MF_BITMAP) lpitem->hText = LOWORD((DWORD)lpNewItem); else lpitem->item_text = lpNewItem; SetRectEmpty( &lpitem->rect ); return TRUE; diff --git a/controls/static.c b/controls/static.c index 409fd03253a..5d71bc9bb2e 100644 --- a/controls/static.c +++ b/controls/static.c @@ -12,7 +12,7 @@ static char Copyright[] = "Copyright David W. Metcalfe, 1993"; #include "win.h" #include "user.h" -LONG StaticWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam); +extern void DEFWND_SetText( HWND hwnd, LPSTR text ); /* windows/defwnd.c */ static LONG PaintTextfn(HWND hwnd); static LONG PaintRectfn(HWND hwnd); @@ -67,6 +67,27 @@ LONG StaticWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam) InvalidateRect(hWnd, NULL, FALSE); break; + case WM_NCCREATE: + if (style == SS_ICON) + { + /* Note: we use wndPtr->hText to store the icon handle */ + CREATESTRUCT * createStruct = (CREATESTRUCT *)lParam; + if (createStruct->lpszName) + wndPtr->hText = LoadIcon( createStruct->hInstance, + createStruct->lpszName ); + return 1; + } + else return DefWindowProc(hWnd, uMsg, wParam, lParam); + + case WM_NCDESTROY: + if (style == SS_ICON) + { + if (wndPtr->hText) DestroyIcon( wndPtr->hText ); + wndPtr->hText = 0; + return 0; + } + else return DefWindowProc(hWnd, uMsg, wParam, lParam); + case WM_CREATE: if (style < 0L || style >= (LONG)DIM(staticfn)) { lResult = -1L; @@ -100,27 +121,26 @@ LONG StaticWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam) break; case WM_SETTEXT: - if (wndPtr->hText) - USER_HEAP_FREE(wndPtr->hText); - - wndPtr->hText = USER_HEAP_ALLOC(GMEM_MOVEABLE, - strlen((LPSTR)lParam) + 1); - textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText); - strcpy(textPtr, (LPSTR)lParam); - InvalidateRect(hWnd, NULL, TRUE); + if (style == SS_ICON) break; + DEFWND_SetText( hWnd, (LPSTR)lParam ); + InvalidateRect( hWnd, NULL, FALSE ); + UpdateWindow( hWnd ); break; - case WM_KEYDOWN: - case WM_KEYUP: - case WM_CHAR: - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_MOUSEMOVE: - return(SendMessage(wndPtr->hwndParent, uMsg, wParam, lParam)); + case WM_NCHITTEST: + return HTTRANSPARENT; + + case STM_GETICON: + if (style != SS_ICON) return 0; + return (HICON)wndPtr->hText; + + case STM_SETICON: + if (style != SS_ICON) return 0; + if (wndPtr->hText) DestroyIcon( wndPtr->hText ); + wndPtr->hText = wParam; + InvalidateRect( hWnd, NULL, TRUE ); + UpdateWindow( hWnd ); + return 0; default: lResult = DefWindowProc(hWnd, uMsg, wParam, lParam); @@ -280,30 +300,11 @@ static LONG PaintIconfn(HWND hwnd) PAINTSTRUCT ps; RECT rc; HDC hdc; - LPSTR textPtr; - HICON hIcon; wndPtr = WIN_FindWndPtr(hwnd); hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rc); FillRect(hdc, &rc, GetStockObject(WHITE_BRUSH)); - textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText); - printf("SS_ICON : textPtr='%8x' / left=%d top=%d right=%d bottom=%d \n", - textPtr, rc.left, rc.top, rc.right, rc.bottom); -/* - SetWindowPos(hwnd, (HWND)NULL, 0, 0, 32, 32, - SWP_NOZORDER | SWP_NOMOVE); - GetClientRect(hwnd, &rc); - printf("SS_ICON : textPtr='%s' / left=%d top=%d right=%d bottom=%d \n", - textPtr, rc.left, rc.top, rc.right, rc.bottom); -*/ - hIcon = LoadIcon(wndPtr->hInstance, textPtr); - DrawIcon(hdc, rc.left, rc.top, hIcon); + if (wndPtr->hText) DrawIcon(hdc, rc.left, rc.top, wndPtr->hText ); EndPaint(hwnd, &ps); } - - - - - - diff --git a/controls/widgets.c b/controls/widgets.c index c6866c696f9..104b13507bf 100644 --- a/controls/widgets.c +++ b/controls/widgets.c @@ -40,7 +40,7 @@ static WNDCLASS WIDGETS_BuiltinClasses[] = 0, 0, 0, 0, NULL, POPUPMENU_CLASS_NAME }, { CS_GLOBALCLASS, (LONG(*)())DesktopWndProc, 0, sizeof(DESKTOPINFO), 0, 0, 0, 0, NULL, DESKTOP_CLASS_NAME }, - { CS_GLOBALCLASS, (LONG(*)())DefDlgProc, 0, DLGWINDOWEXTRA, + { CS_GLOBALCLASS | CS_SAVEBITS, (LONG(*)())DefDlgProc, 0, DLGWINDOWEXTRA, 0, 0, 0, 0, NULL, DIALOG_CLASS_NAME }, { CS_GLOBALCLASS, (LONG(*)())MDIClientWndProc, 0, sizeof(MDICLIENTINFO), 0, 0, 0, STOCK_LTGRAY_BRUSH, NULL, "MDICLIENT" } @@ -58,9 +58,12 @@ static WNDCLASS WIDGETS_BuiltinClasses[] = BOOL WIDGETS_Init(void) { int i; - for (i = 0; i < NB_BUILTIN_CLASSES; i++) + WNDCLASS *class = WIDGETS_BuiltinClasses; + + for (i = 0; i < NB_BUILTIN_CLASSES; i++, class++) { - if (!RegisterClass(&WIDGETS_BuiltinClasses[i])) return FALSE; + class->hCursor = LoadCursor( 0, IDC_ARROW ); + if (!RegisterClass( class )) return FALSE; } return TRUE; } diff --git a/if1632/Imakefile b/if1632/Imakefile index cc922a05a4a..4f25af04bfc 100644 --- a/if1632/Imakefile +++ b/if1632/Imakefile @@ -72,5 +72,5 @@ includes:: install:: clean:: - $(RM) dll* dtb* pop.h + $(RM) dll* dtb* pop.h call.s touch pop.h diff --git a/if1632/gdi.spec b/if1632/gdi.spec index b39fef7ad4a..a4665f8633a 100644 --- a/if1632/gdi.spec +++ b/if1632/gdi.spec @@ -54,7 +54,7 @@ length 490 39 pascal RestoreDC(word s_word) RestoreDC(1 2) 40 pascal FillRgn(word word word) FillRgn(1 2 3) #41 pascal FrameRgn -#42 pascal InvertRgn +42 pascal InvertRgn(word word) InvertRgn(1 2) 43 pascal PaintRgn(word word) PaintRgn(1 2) 44 pascal SelectClipRgn(word word) SelectClipRgn(1 2) 45 pascal SelectObject(word word) SelectObject(1 2) diff --git a/if1632/user.spec b/if1632/user.spec index 371b3d76f05..6798d123ef5 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -241,7 +241,7 @@ length 540 #231 GETSYSTEMDEBUGSTATE 232 pascal SetWindowPos(word word word word word word word) SetWindowPos(1 2 3 4 5 6 7) -#233 SETPARENT +233 pascal SetParent(word word) SetParent(1 2) 234 pascal UnhookWindowsHook(s_word ptr) UnhookWindowsHook(1 2) 235 pascal DefHookProc(s_word word long ptr) DefHookProc(1 2 3 4) 236 pascal GetCapture() GetCapture() diff --git a/include/bitmaps/check_boxes b/include/bitmaps/check_boxes new file mode 100644 index 00000000000..44c0363b7fe --- /dev/null +++ b/include/bitmaps/check_boxes @@ -0,0 +1,26 @@ +#define check_boxes_width 56 +#define check_boxes_height 39 +static char check_boxes_bits[] = { + 0xff, 0xdf, 0xff, 0xf7, 0xff, 0xfd, 0x7f, 0x01, 0xd0, 0x00, 0xf6, 0xff, + 0xfd, 0x7f, 0x01, 0x50, 0x01, 0x35, 0x80, 0x1d, 0x70, 0x01, 0x50, 0x82, + 0x34, 0x80, 0x2d, 0x68, 0x01, 0x50, 0x44, 0x34, 0x80, 0x4d, 0x64, 0x01, + 0x50, 0x28, 0x34, 0x80, 0x8d, 0x62, 0x01, 0x50, 0x10, 0x34, 0x80, 0x0d, + 0x61, 0x01, 0x50, 0x28, 0x34, 0x80, 0x8d, 0x62, 0x01, 0x50, 0x44, 0x34, + 0x80, 0x4d, 0x64, 0x01, 0x50, 0x82, 0x34, 0x80, 0x2d, 0x68, 0x01, 0x50, + 0x01, 0x35, 0x80, 0x1d, 0x70, 0x01, 0xd0, 0x00, 0xf6, 0xff, 0xfd, 0x7f, + 0xff, 0xdf, 0xff, 0xf7, 0xff, 0xfd, 0x7f, 0xe0, 0x00, 0x38, 0x00, 0x0e, + 0x80, 0x03, 0x18, 0x03, 0xc6, 0x80, 0x3f, 0xe0, 0x0f, 0x04, 0x04, 0x01, + 0xc1, 0x71, 0x70, 0x1c, 0x02, 0x88, 0x38, 0xe2, 0xe0, 0xb8, 0x3b, 0x02, + 0x88, 0x7c, 0x62, 0xc0, 0xd8, 0x37, 0x01, 0x50, 0xfe, 0x34, 0x80, 0xed, + 0x6f, 0x01, 0x50, 0xfe, 0x34, 0x80, 0xed, 0x6f, 0x01, 0x50, 0xfe, 0x34, + 0x80, 0xed, 0x6f, 0x02, 0x88, 0x7c, 0x62, 0xc0, 0xd8, 0x37, 0x02, 0x88, + 0x38, 0xe2, 0xe0, 0xb8, 0x3b, 0x04, 0x04, 0x01, 0xc1, 0x71, 0x70, 0x1c, + 0x18, 0x03, 0xc6, 0x80, 0x3f, 0xe0, 0x0f, 0xe0, 0x00, 0x38, 0x00, 0x0e, + 0x80, 0x03, 0x00, 0xc0, 0xff, 0x07, 0x00, 0xfc, 0x7f, 0x00, 0xc0, 0xaa, + 0x06, 0x00, 0xfc, 0x7f, 0x00, 0x40, 0x55, 0x05, 0x00, 0x5c, 0x75, 0x00, + 0xc0, 0xaa, 0x06, 0x00, 0xac, 0x6a, 0x00, 0x40, 0x55, 0x05, 0x00, 0x5c, + 0x75, 0x00, 0xc0, 0xaa, 0x06, 0x00, 0xac, 0x6a, 0x00, 0x40, 0x55, 0x05, + 0x00, 0x5c, 0x75, 0x00, 0xc0, 0xaa, 0x06, 0x00, 0xac, 0x6a, 0x00, 0x40, + 0x55, 0x05, 0x00, 0x5c, 0x75, 0x00, 0xc0, 0xaa, 0x06, 0x00, 0xac, 0x6a, + 0x00, 0x40, 0x55, 0x05, 0x00, 0x5c, 0x75, 0x00, 0xc0, 0xaa, 0x06, 0x00, + 0xfc, 0x7f, 0x00, 0xc0, 0xff, 0x07, 0x00, 0xfc, 0x7f}; diff --git a/include/gdi.h b/include/gdi.h index 1920d07a719..b86d50823a5 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -8,6 +8,7 @@ #define GDI_H #include +#include #include "windows.h" #include "segmem.h" @@ -32,6 +33,7 @@ typedef struct tagREGION WORD type; RECT box; Pixmap pixmap; + Region xrgn; } REGION; typedef struct tagGDIOBJHDR diff --git a/include/menu.h b/include/menu.h index 2e0f7ca1d8c..fad8bb1f6bf 100644 --- a/include/menu.h +++ b/include/menu.h @@ -11,14 +11,14 @@ typedef struct tagMENUITEM { - WORD item_flags; - WORD item_id; - RECT rect; - WORD sel_key; - HBITMAP hCheckBit; - HBITMAP hUnCheckBit; + WORD item_flags; /* Item flags */ + WORD item_id; /* Item or popup id */ + RECT rect; /* Item area (relative to menu window) */ + WORD xTab; /* X position of text after Tab */ + HBITMAP hCheckBit; /* Bitmap for checked item */ + HBITMAP hUnCheckBit; /* Bitmap for unchecked item */ + HANDLE hText; /* Handle to item string or bitmap */ char *item_text; - HANDLE hText; } MENUITEM, *LPMENUITEM; diff --git a/include/msdos.h b/include/msdos.h index e5443f10f22..e2b645028db 100644 --- a/include/msdos.h +++ b/include/msdos.h @@ -14,6 +14,18 @@ struct dosdirent { long filetime; }; +struct fcb { + BYTE drive; + char name[8]; + char extension[3]; + BYTE dummy1[4]; + int filesize; + WORD date_write; + WORD time_write; + struct dosdirent *directory; + BYTE dummy2[9]; +}; + #define DOSVERSION 0x0330; #define MAX_DOS_DRIVES 26 diff --git a/include/options.h b/include/options.h index 3caf1fd24ab..e8bed9f32c6 100644 --- a/include/options.h +++ b/include/options.h @@ -13,8 +13,8 @@ struct options char * desktopGeometry; /* NULL when no desktop */ char * programName; /* To use when loading resources */ int usePrivateMap; - int synchronous; - int nobackingstore; + int synchronous; /* X synchronous mode */ + int backingstore; /* Use backing store */ short cmdShow; int relay_debug; int debug; diff --git a/include/segmem.h b/include/segmem.h index afe7741cdb4..c5b03c63127 100644 --- a/include/segmem.h +++ b/include/segmem.h @@ -55,7 +55,7 @@ typedef struct segment_descriptor_s unsigned short owner; /* Handle of owner program */ unsigned char type; /* DATA or CODE */ #ifdef HAVE_IPC - key_t shm_key; /* Shared memory key or IPC_PRIVATE */ + key_t shm_key; /* Shared memory key or -1 */ #endif } SEGDESC; diff --git a/include/win.h b/include/win.h index 1c3fcc800a3..22290ddc1e0 100644 --- a/include/win.h +++ b/include/win.h @@ -42,19 +42,20 @@ typedef struct tagWND DWORD dwStyle; /* Window style (from CreateWindow) */ DWORD dwExStyle; /* Extended style (from CreateWindowEx) */ HANDLE hdce; /* Window DCE (if CS_OWNDC or CS_CLASSDC) */ - void *VScroll; /* Vertical ScrollBar Struct Pointer */ - void *HScroll; /* Horizontal ScrollBar Struct Pointer */ + void *VScroll; /* Vertical ScrollBar Struct Pointer */ + void *HScroll; /* Horizontal ScrollBar Struct Pointer */ WORD scroll_flags; /* scrolls flags (vert & horz visible) */ WORD wIDmenu; /* ID or hmenu (from CreateWindow) */ HANDLE hText; /* Handle of window text */ WORD flags; /* Misc. flags (see below) */ Window window; /* X window */ - Window icon; /* icon's X window */ HICON hIcon; /* icon's MS-windows handle */ - RECT rectClientSave; /* where client rect is saved when icon*/ - HMENU hSysMenu; /* window's copy of System Menu */ + WORD iconWidth; /* width of icon */ + WORD iconHeight; /* height of icon */ + RECT rectClientSave; /* where client rect is saved when icon*/ + HMENU hSysMenu; /* window's copy of System Menu */ HANDLE hProp; /* Handle of Properties List */ - HTASK hTask; /* Task Handle of the owner */ + HTASK hTask; /* Task Handle of the owner */ WORD wExtra[1]; /* Window extra bytes */ } WND; diff --git a/include/windows.h b/include/windows.h index 711210a5ee5..5443498ab37 100644 --- a/include/windows.h +++ b/include/windows.h @@ -1513,6 +1513,8 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE #define WM_MOUSELAST WM_MBUTTONDBLCLK #define WM_PARENTNOTIFY 0x0210 +#define WM_ENTERMENULOOP 0x0211 +#define WM_EXITMENULOOP 0x0212 #define WM_MDICREATE 0x0220 #define WM_MDIDESTROY 0x0221 @@ -1565,9 +1567,29 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE #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 }; +/* +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, + SW_INTERNAL_HIDE, SW_INTERNAL_RESTORE }; +*/ + + +#define SW_HIDE 0 +#define SW_SHOWNORMAL 1 +#define SW_NORMAL 1 +#define SW_SHOWMINIMIZED 2 +#define SW_SHOWMAXIMIZED 3 +#define SW_MAXIMIZE 3 +#define SW_SHOWNOACTIVATE 4 +#define SW_SHOW 5 +#define SW_MINIMIZE 6 +#define SW_SHOWMINNOACTIVE 7 +#define SW_SHOWNA 8 +#define SW_RESTORE 9 +#define SW_INTERNAL_HIDE 20 +#define SW_INTERNAL_RESTORE 21 + /* WM_SIZE message wParam values */ #define SIZE_RESTORED 0 diff --git a/loader/selector.c b/loader/selector.c index c2faab80227..03711aa446c 100644 --- a/loader/selector.c +++ b/loader/selector.c @@ -156,19 +156,23 @@ IPCCopySelector(int i_old, unsigned long new, int swap_type) * to get one. In this case, we'll also have to copy the data * to protect it. */ - if (s_old->shm_key == 0) + if (s_old->shm_key == -1) { - s_old->shm_key = shmget(IPC_PRIVATE, s_old->length, 0600); - if (s_old->shm_key == 0) + s_old->shm_key = shmget(IPC_PRIVATE, s_old->length, IPC_CREAT); + if (s_old->shm_key == -1) { - if (s_new) + if (s_new) { memset(s_new, 0, sizeof(*s_new)); + s_new->shm_key = -1; + } return -1; } - if (shmat(s_old->shm_key, base_addr, 0) == NULL) + if (shmat(s_old->shm_key, base_addr, 0) == (char *) -1) { - if (s_new) + if (s_new) { memset(s_new, 0, sizeof(*s_new)); + s_new->shm_key = -1; + } shmctl(s_old->shm_key, IPC_RMID, NULL); return -1; } @@ -183,10 +187,12 @@ IPCCopySelector(int i_old, unsigned long new, int swap_type) */ else { - if (shmat(s_old->shm_key, base_addr, 0) == NULL) + if (shmat(s_old->shm_key, base_addr, 0) == (char *) -1) { - if (s_new) + if (s_new) { memset(s_new, 0, sizeof(*s_new)); + s_new->shm_key = -1; + } return -1; } } @@ -257,6 +263,9 @@ WORD AllocSelector(WORD old_selector) else { memset(s_new, 0, sizeof(*s_new)); +#ifdef HAVE_IPC + s_new->shm_key = -1; +#endif SelectorMap[i_new] = i_new; } @@ -400,6 +409,19 @@ WORD AllocDStoCSAlias(WORD ds_selector) return PrestoChangoSelector(ds_selector, cs_selector); } +/********************************************************************** + * CleanupSelectors + */ + +void CleanupSelectors(void) +{ + int sel_idx; + + for (sel_idx = FIRST_SELECTOR; sel_idx < MAX_SELECTORS; sel_idx++) + if (SelectorMap[sel_idx]) + FreeSelector((sel_idx << 3) | 7); +} + /********************************************************************** * FreeSelector */ @@ -417,10 +439,11 @@ WORD FreeSelector(WORD sel) return 0; s = &Segments[sel_idx]; - if (s->shm_key == 0) + if (s->shm_key == -1) { munmap(s->base_addr, ((s->length + PAGE_SIZE) & ~(PAGE_SIZE - 1))); memset(s, 0, sizeof(*s)); + s->shm_key = -1; SelectorMap[sel_idx] = 0; } else @@ -436,6 +459,7 @@ WORD FreeSelector(WORD sel) shmctl(s->shm_key, IPC_RMID, NULL); memset(s, 0, sizeof(*s)); + s->shm_key = -1; SelectorMap[sel_idx] = 0; } @@ -521,12 +545,17 @@ CreateNewSegments(int code_flag, int read_only, int length, int n_segments) MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); #endif - +#ifdef HAVE_IPC + s->shm_key = -1; +#endif if (set_ldt_entry(i, (unsigned long) s->base_addr, (s->length - 1) & 0xffff, 0, contents, read_only, 0) < 0) { memset(s, 0, sizeof(*s)); +#ifdef HAVE_IPC + s->shm_key = -1; +#endif return NULL; } @@ -982,6 +1011,9 @@ CreateSelectors(struct w_files * wpnt) myerror("CreateSelectors: GlobalAlloc() failed"); s->base_addr = (void *) ((LONG) s->selector << 16); +#ifdef HAVE_IPC + s->shm_key = -1; +#endif if (!(s->flags & NE_SEGFLAGS_DATA)) PrestoChangoSelector(s->selector, s->selector); else diff --git a/misc/file.c b/misc/file.c index db2293dfe0d..0551a6a27d7 100644 --- a/misc/file.c +++ b/misc/file.c @@ -173,7 +173,7 @@ INT OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle) ofs->nErrCode = ExtendedError; return -1; } - handle = open (ofs->szPathName, (wStyle & 0x0003) | O_CREAT, 0x666); + handle = open (unixfilename, (wStyle & 0x0003) | O_CREAT, 0x666); if (handle == -1) { errno_to_doserr(); diff --git a/misc/main.c b/misc/main.c index 4479cdc0033..623c6eddd4e 100644 --- a/misc/main.c +++ b/misc/main.c @@ -52,7 +52,7 @@ struct options Options = NULL, /* programName */ FALSE, /* usePrivateMap */ FALSE, /* synchronous */ - FALSE, /* no backing store */ + FALSE, /* backing store */ SW_SHOWNORMAL, /* cmdShow */ FALSE }; @@ -60,6 +60,7 @@ struct options Options = static XrmOptionDescRec optionsTable[] = { + { "-backingstore", ".backingstore", XrmoptionNoArg, (caddr_t)"on" }, { "-desktop", ".desktop", XrmoptionSepArg, (caddr_t)NULL }, { "-depth", ".depth", XrmoptionSepArg, (caddr_t)NULL }, { "-display", ".display", XrmoptionSepArg, (caddr_t)NULL }, @@ -67,7 +68,6 @@ static XrmOptionDescRec optionsTable[] = { "-name", ".name", XrmoptionSepArg, (caddr_t)NULL }, { "-privatemap", ".privatemap", XrmoptionNoArg, (caddr_t)"on" }, { "-synchronous", ".synchronous", XrmoptionNoArg, (caddr_t)"on" }, - { "-nobackingstore",".nobackingstore", XrmoptionNoArg, (caddr_t)"on" }, { "-spy", ".spy", XrmoptionSepArg, (caddr_t)NULL }, { "-debug", ".debug", XrmoptionNoArg, (caddr_t)"on" }, { "-relaydbg", ".relaydbg", XrmoptionNoArg, (caddr_t)"on" } @@ -87,7 +87,7 @@ static XrmOptionDescRec optionsTable[] = " -name name Set the application name\n" \ " -privatemap Use a private color map\n" \ " -synchronous Turn on synchronous display mode\n" \ - " -nobackingstore Turn off backing store\n" \ + " -backingstore Turn on backing store\n" \ " -spy file Turn on message spying to the specified file\n" \ " -relaydbg Display call relay information\n" @@ -242,8 +242,8 @@ static void MAIN_ParseOptions( int *argc, char *argv[] ) Options.usePrivateMap = TRUE; if (MAIN_GetResource( db, ".synchronous", &value )) Options.synchronous = TRUE; - if (MAIN_GetResource( db, ".nobackingstore", &value )) - Options.nobackingstore = TRUE; + if (MAIN_GetResource( db, ".backingstore", &value )) + Options.backingstore = TRUE; if (MAIN_GetResource( db, ".relaydbg", &value )) Options.relay_debug = TRUE; if (MAIN_GetResource( db, ".debug", &value )) @@ -350,6 +350,7 @@ static void called_at_exit(void) sync_profiles(); MAIN_RestoreSetup(); WSACleanup(); + CleanupSelectors(); } /*********************************************************************** diff --git a/miscemu/int21.c b/miscemu/int21.c index 5ed34e0196b..7596aa49d23 100644 --- a/miscemu/int21.c +++ b/miscemu/int21.c @@ -841,31 +841,70 @@ static void DumpFCB(BYTE *fcb) static void FindFirstFCB(struct sigcontext_struct *context) { BYTE *fcb = pointer(DS, DX); + struct fcb *standard_fcb; + struct fcb *output_fcb; int drive; + char path[12]; DumpFCB( fcb ); - - if (*fcb) - drive = *fcb - 1; + + if ((*fcb) == 0xff) + { + standard_fcb = fcb + 7; + output_fcb = dta + 7; + *dta = 0xff; + } else - drive = DOS_GetDefaultDrive(); + { + standard_fcb = fcb; + output_fcb = dta; + } - if (*(fcb - 7) == 0xff) { - if (*(fcb - 1) == FA_DIREC) { - /* return volume label */ + if (standard_fcb->drive) + { + drive = standard_fcb->drive - 1; + if (!DOS_ValidDrive(drive)) + { + Error (InvalidDrive, EC_MediaError, EL_Disk); + AL = 0xff; + return; + } + } + else + drive = DOS_GetDefaultDrive(); - memset(dta, ' ', 11); - if (DOS_GetVolumeLabel(drive) != NULL) - strncpy(dta, DOS_GetVolumeLabel(drive), 8); - *(dta + 0x0b) = FA_DIREC; + output_fcb->drive = drive; - AL; - return; - } - } - IntBarf(0x21, context); + if (*(fcb) == 0xff) + { + if (*(fcb+6) & FA_LABEL) /* return volume label */ + { + *(dta+6) = FA_LABEL; + memset(&output_fcb->name, ' ', 11); + if (DOS_GetVolumeLabel(drive) != NULL) + { + strncpy(&output_fcb->name, DOS_GetVolumeLabel(drive), 11); + AL = 0x00; + return; + } + } + } + + strncpy(&(output_fcb->name),&(standard_fcb->name),11); + if (*fcb == 0xff) + *(dta+6) = ( *(fcb+6) & (!FA_DIREC)); + + sprintf(path,"%c:*.*",drive+'A'); + if ((output_fcb->directory = DOS_opendir(path))==NULL) + { + Error (PathNotFound, EC_MediaError, EL_Disk); + AL = 0xff; + return; + } + } + static void DeleteFileFCB(struct sigcontext_struct *context) { BYTE *fcb = pointer(DS, DX); diff --git a/objects/bitmap.c b/objects/bitmap.c index cd4f6232e31..93b0e4ac723 100644 --- a/objects/bitmap.c +++ b/objects/bitmap.c @@ -13,6 +13,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "bitmap.h" /* Include OEM bitmaps */ +#include "bitmaps/check_boxes" #include "bitmaps/check_mark" #include "bitmaps/menu_arrow" @@ -64,7 +65,7 @@ static XImage *BITMAP_BmpToImage( BITMAP * bmp, void * bmpData ) extern void _XInitImageFuncPtrs( XImage* ); XImage * image; - image = XCreateImage( XT_display, DefaultVisualOfScreen(screen), + image = XCreateImage( display, DefaultVisualOfScreen(screen), bmp->bmBitsPixel, ZPixmap, 0, bmpData, bmp->bmWidth, bmp->bmHeight, 16, bmp->bmWidthBytes ); if (!image) return 0; @@ -94,6 +95,12 @@ HBITMAP BITMAP_LoadOEMBitmap( WORD id ) data = menu_arrow_bits; break; + case OBM_CHECKBOXES: + width = check_boxes_width; + height = check_boxes_height; + data = check_boxes_bits; + break; + case OBM_CHECK: width = check_mark_width; height = check_mark_height; diff --git a/objects/clipping.c b/objects/clipping.c index a5240ff0bd6..9675b9c92bc 100644 --- a/objects/clipping.c +++ b/objects/clipping.c @@ -21,7 +21,12 @@ void CLIPPING_SetDeviceClipping( DC * dc ) if (dc->w.hGCClipRgn) { RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(dc->w.hGCClipRgn, REGION_MAGIC); - if (obj->region.pixmap) + if (obj->region.xrgn) + { + XSetRegion( display, dc->u.x.gc, obj->region.xrgn ); + XSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY ); + } + else if (obj->region.pixmap) { XSetClipMask( display, dc->u.x.gc, obj->region.pixmap ); XSetClipOrigin( display, dc->u.x.gc, diff --git a/objects/region.c b/objects/region.c index afe4dd449df..74ec57baea6 100644 --- a/objects/region.c +++ b/objects/region.c @@ -1,15 +1,14 @@ /* * GDI region objects * - * Copyright 1993 Alexandre Julliard + * Copyright 1993, 1994 Alexandre Julliard */ -static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +static char Copyright[] = "Copyright Alexandre Julliard, 1993, 1994"; #include #include -#include -#include + #include "gdi.h" /* GC used for region operations */ @@ -26,24 +25,46 @@ BOOL REGION_Init() tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 ); if (tmpPixmap) { - regionGC = XCreateGC( XT_display, tmpPixmap, 0, NULL ); - XFreePixmap( XT_display, tmpPixmap ); + regionGC = XCreateGC( display, tmpPixmap, 0, NULL ); + XFreePixmap( display, tmpPixmap ); if (!regionGC) return FALSE; - XSetForeground( XT_display, regionGC, 1 ); - XSetGraphicsExposures( XT_display, regionGC, False ); + XSetForeground( display, regionGC, 1 ); + XSetGraphicsExposures( display, regionGC, False ); return TRUE; } else return FALSE; } +/*********************************************************************** + * REGION_MakePixmap + * + * Make a pixmap of an X region. + */ +static BOOL REGION_MakePixmap( REGION *region ) +{ + int width = region->box.right - region->box.left; + int height = region->box.bottom - region->box.top; + + if (!region->xrgn) return TRUE; /* Null region */ + region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 ); + if (!region->pixmap) return FALSE; + XSetRegion( display, regionGC, region->xrgn ); + XSetClipOrigin( display, regionGC, region->box.left, region->box.top ); + XSetFunction( display, regionGC, GXcopy ); + XFillRectangle( display, region->pixmap, regionGC, 0, 0, width, height ); + XSetClipMask( display, regionGC, None ); /* Clear clip region */ + return TRUE; +} + + /*********************************************************************** * REGION_SetRect * - * Set the bounding box of the region and create the pixmap. + * Set the bounding box of the region and create the pixmap (or the X rgn). * The hrgn must be valid. */ -static BOOL REGION_SetRect( HRGN hrgn, LPRECT rect ) +static BOOL REGION_SetRect( HRGN hrgn, LPRECT rect, BOOL createXrgn ) { int width, height; @@ -60,21 +81,33 @@ static BOOL REGION_SetRect( HRGN hrgn, LPRECT rect ) region->box.top = 0; region->box.bottom = 0; region->pixmap = 0; + region->xrgn = 0; return TRUE; } - region->type = SIMPLEREGION; - region->box = *rect; - - /* Create pixmap */ + region->type = SIMPLEREGION; + region->box = *rect; + region->xrgn = 0; + region->pixmap = 0; - region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 ); - if (!region->pixmap) return FALSE; + if (createXrgn) /* Create and set the X region */ + { + Region tmprgn; + XRectangle xrect = { region->box.left, region->box.top, width, height}; - /* Fill pixmap */ - - XSetFunction( XT_display, regionGC, GXclear ); - XFillRectangle( XT_display, region->pixmap, regionGC, - 0, 0, width, height ); + if (!(tmprgn = XCreateRegion())) return FALSE; + if ((region->xrgn = XCreateRegion())) + XUnionRectWithRegion( &xrect, tmprgn, region->xrgn ); + XDestroyRegion( tmprgn ); + if (!region->xrgn) return FALSE; + } + else /* Create the pixmap */ + { + region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1); + if (!region->pixmap) return FALSE; + /* Fill the pixmap */ + XSetFunction( display, regionGC, GXclear ); + XFillRectangle(display, region->pixmap, regionGC, 0, 0, width, height); + } return TRUE; } @@ -84,7 +117,8 @@ static BOOL REGION_SetRect( HRGN hrgn, LPRECT rect ) */ BOOL REGION_DeleteObject( HRGN hrgn, RGNOBJ * obj ) { - if (obj->region.pixmap) XFreePixmap( XT_display, obj->region.pixmap ); + if (obj->region.pixmap) XFreePixmap( display, obj->region.pixmap ); + if (obj->region.xrgn) XDestroyRegion( obj->region.xrgn ); return GDI_FreeObject( hrgn ); } @@ -100,6 +134,7 @@ int OffsetRgn( HRGN hrgn, short x, short y ) printf( "OffsetRgn: %d %d,%d\n", hrgn, x, y ); #endif OffsetRect( &obj->region.box, x, y ); + if (obj->region.xrgn) XOffsetRegion( obj->region.xrgn, x, y ); return obj->region.type; } @@ -134,7 +169,6 @@ HRGN CreateRectRgn( short left, short top, short right, short bottom ) */ HRGN CreateRectRgnIndirect( LPRECT rect ) { - RGNOBJ * rgnObj; HRGN hrgn; #ifdef DEBUG_REGION @@ -145,24 +179,11 @@ HRGN CreateRectRgnIndirect( LPRECT rect ) /* Create region */ if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0; - if (!REGION_SetRect( hrgn, rect )) + if (!REGION_SetRect( hrgn, rect, TRUE )) { GDI_FreeObject( hrgn ); return 0; } - rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn ); - - /* Fill pixmap */ - - if (rgnObj->region.type != NULLREGION) - { - int width = rgnObj->region.box.right - rgnObj->region.box.left; - int height = rgnObj->region.box.bottom - rgnObj->region.box.top; - XSetFunction( XT_display, regionGC, GXcopy ); - XFillRectangle( XT_display, rgnObj->region.pixmap, regionGC, - 0, 0, width, height ); - } - return hrgn; } @@ -185,7 +206,7 @@ HRGN CreateRoundRectRgn( short left, short top, short right, short bottom, /* Create region */ if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0; - if (!REGION_SetRect( hrgn, &rect )) + if (!REGION_SetRect( hrgn, &rect, FALSE )) { GDI_FreeObject( hrgn ); return 0; @@ -198,23 +219,23 @@ HRGN CreateRoundRectRgn( short left, short top, short right, short bottom, { int width = rgnObj->region.box.right - rgnObj->region.box.left; int height = rgnObj->region.box.bottom - rgnObj->region.box.top; - XSetFunction( XT_display, regionGC, GXcopy ); - XFillRectangle( XT_display, rgnObj->region.pixmap, regionGC, + XSetFunction( display, regionGC, GXcopy ); + XFillRectangle( display, rgnObj->region.pixmap, regionGC, 0, ellipse_height / 2, width, height - ellipse_height ); - XFillRectangle( XT_display, rgnObj->region.pixmap, regionGC, + XFillRectangle( display, rgnObj->region.pixmap, regionGC, ellipse_width / 2, 0, width - ellipse_width, height ); - XFillArc( XT_display, rgnObj->region.pixmap, regionGC, + XFillArc( display, rgnObj->region.pixmap, regionGC, 0, 0, ellipse_width, ellipse_height, 0, 360*64 ); - XFillArc( XT_display, rgnObj->region.pixmap, regionGC, + XFillArc( display, rgnObj->region.pixmap, regionGC, width - ellipse_width, 0, ellipse_width, ellipse_height, 0, 360*64 ); - XFillArc( XT_display, rgnObj->region.pixmap, regionGC, + XFillArc( display, rgnObj->region.pixmap, regionGC, 0, height - ellipse_height, ellipse_width, ellipse_height, 0, 360*64 ); - XFillArc( XT_display, rgnObj->region.pixmap, regionGC, + XFillArc( display, rgnObj->region.pixmap, regionGC, width - ellipse_width, height - ellipse_height, ellipse_width, ellipse_height, 0, 360*64 ); } @@ -238,21 +259,9 @@ void SetRectRgn( HRGN hrgn, short left, short top, short right, short bottom ) /* Free previous pixmap */ if (!(rgnObj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return; - if (rgnObj->region.pixmap) - XFreePixmap( XT_display, rgnObj->region.pixmap ); - - if (!REGION_SetRect( hrgn, &rect )) return; - - /* Fill pixmap */ - - if (rgnObj->region.type != NULLREGION) - { - int width = rgnObj->region.box.right - rgnObj->region.box.left; - int height = rgnObj->region.box.bottom - rgnObj->region.box.top; - XSetFunction( XT_display, regionGC, GXcopy ); - XFillRectangle( XT_display, rgnObj->region.pixmap, regionGC, - 0, 0, width, height ); - } + if (rgnObj->region.pixmap) XFreePixmap( display, rgnObj->region.pixmap ); + if (rgnObj->region.xrgn) XDestroyRegion( rgnObj->region.xrgn ); + REGION_SetRect( hrgn, &rect, TRUE ); } @@ -282,7 +291,7 @@ HRGN CreateEllipticRgnIndirect( LPRECT rect ) /* Create region */ if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0; - if (!REGION_SetRect( hrgn, rect )) + if (!REGION_SetRect( hrgn, rect, FALSE )) { GDI_FreeObject( hrgn ); return 0; @@ -295,8 +304,8 @@ HRGN CreateEllipticRgnIndirect( LPRECT rect ) { int width = rgnObj->region.box.right - rgnObj->region.box.left; int height = rgnObj->region.box.bottom - rgnObj->region.box.top; - XSetFunction( XT_display, regionGC, GXcopy ); - XFillArc( XT_display, rgnObj->region.pixmap, regionGC, + XSetFunction( display, regionGC, GXcopy ); + XFillArc( display, rgnObj->region.pixmap, regionGC, 0, 0, width, height, 0, 360*64 ); } @@ -321,70 +330,67 @@ HRGN CreatePolyPolygonRgn( POINT * points, short * count, { RGNOBJ * rgnObj; HRGN hrgn; - RECT box; - int i, j, totalPoints; - POINT * pt; - XPoint * xpoints; - - if (!nbpolygons) return 0; + int i, j, maxPoints; + XPoint *xpoints, *pt; + XRectangle rect; + Region xrgn; + #ifdef DEBUG_REGION printf( "CreatePolyPolygonRgn: %d polygons\n", nbpolygons ); #endif - - /* Find bounding box */ - box.top = box.left = 32767; - box.right = box.bottom = 0; - for (i = totalPoints = 0, pt = points; i < nbpolygons; i++) + /* Allocate points array */ + + if (!nbpolygons) return 0; + for (i = maxPoints = 0; i < nbpolygons; i++) + if (maxPoints < count[i]) maxPoints = count[i]; + if (!maxPoints) return 0; + if (!(xpoints = (XPoint *) malloc( sizeof(XPoint) * maxPoints ))) + return 0; + + /* Allocate region */ + + if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) { - totalPoints += count[i]; - for (j = 0; j < count[i]; j++, pt++) - { - if (pt->x < box.left) box.left = pt->x; - if (pt->x > box.right) box.right = pt->x; - if (pt->y < box.top) box.top = pt->y; - if (pt->y > box.bottom) box.bottom = pt->y; - } - } - if (!totalPoints) return 0; - - /* Build points array */ - - xpoints = (XPoint *) malloc( sizeof(XPoint) * totalPoints ); - if (!xpoints) return 0; - for (i = 0, pt = points; i < totalPoints; i++, pt++) - { - xpoints[i].x = pt->x - box.left; - xpoints[i].y = pt->y - box.top; - } - - /* Create region */ - - if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC )) || - !REGION_SetRect( hrgn, &box )) - { - if (hrgn) GDI_FreeObject( hrgn ); free( xpoints ); return 0; } rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn ); + rgnObj->region.type = SIMPLEREGION; + rgnObj->region.pixmap = 0; - /* Fill pixmap */ + /* Create X region */ - if (rgnObj->region.type != NULLREGION) + for (i = 0; i < nbpolygons; i++, count++) { - XSetFunction( XT_display, regionGC, GXcopy ); - if (mode == WINDING) XSetFillRule( XT_display, regionGC, WindingRule ); - else XSetFillRule( XT_display, regionGC, EvenOddRule ); - for (i = j = 0; i < nbpolygons; i++) + for (j = *count, pt = xpoints; j > 0; j--, points++, pt++) { - XFillPolygon( XT_display, rgnObj->region.pixmap, regionGC, - &xpoints[j], count[i], Complex, CoordModeOrigin ); - j += count[i]; + pt->x = points->x; + pt->y = points->y; } + xrgn = XPolygonRegion( xpoints, *count, + (mode == WINDING) ? WindingRule : EvenOddRule ); + if (!xrgn) break; + if (i > 0) + { + Region tmprgn = XCreateRegion(); + if (mode == WINDING) XUnionRegion(xrgn,rgnObj->region.xrgn,tmprgn); + else XXorRegion( xrgn, rgnObj->region.xrgn, tmprgn ); + XDestroyRegion( rgnObj->region.xrgn ); + rgnObj->region.xrgn = tmprgn; + } + else rgnObj->region.xrgn = xrgn; } - + free( xpoints ); + if (!xrgn) + { + GDI_FreeObject( hrgn ); + return 0; + } + XClipBox( rgnObj->region.xrgn, &rect ); + SetRect( &rgnObj->region.box, rect.x, rect.y, + rect.x + rect.width, rect.y + rect.height); return hrgn; } @@ -394,19 +400,25 @@ HRGN CreatePolyPolygonRgn( POINT * points, short * count, */ BOOL PtInRegion( HRGN hrgn, short x, short y ) { - XImage * image; BOOL res; RGNOBJ * obj; POINT pt = { x, y }; if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return FALSE; if (!PtInRect( &obj->region.box, pt )) return FALSE; - image = XGetImage( XT_display, obj->region.pixmap, - x - obj->region.box.left, y - obj->region.box.top, - 1, 1, AllPlanes, ZPixmap ); - if (!image) return FALSE; - res = (XGetPixel( image, 0, 0 ) != 0); - XDestroyImage( image ); + if (obj->region.xrgn) + { + return XPointInRegion( obj->region.xrgn, x, y ); + } + else + { + XImage *image = XGetImage( display, obj->region.pixmap, + x - obj->region.box.left, y - obj->region.box.top, + 1, 1, AllPlanes, ZPixmap ); + if (!image) return FALSE; + res = (XGetPixel( image, 0, 0 ) != 0); + XDestroyImage( image ); + } return res; } @@ -422,24 +434,33 @@ BOOL RectInRegion( HRGN hrgn, LPRECT rect ) int x, y; if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return FALSE; - if (!IntersectRect( &intersect, &obj->region.box, rect )) return FALSE; + if (obj->region.xrgn) + { + return (XRectInRegion( obj->region.xrgn, rect->left, rect->top, + rect->right-rect->left, + rect->bottom-rect->top ) != RectangleOut); + } + else + { + if (!IntersectRect( &intersect, &obj->region.box, rect )) return FALSE; - image = XGetImage( XT_display, obj->region.pixmap, - intersect.left - obj->region.box.left, - intersect.top - obj->region.box.top, - intersect.right - intersect.left, - intersect.bottom - intersect.top, - AllPlanes, ZPixmap ); - if (!image) return FALSE; - for (y = 0; y < image->height; y++) - for (x = 0; x < image->width; x++) - if (XGetPixel( image, x, y ) != 0) - { - XDestroyImage( image ); - return TRUE; - } + image = XGetImage( display, obj->region.pixmap, + intersect.left - obj->region.box.left, + intersect.top - obj->region.box.top, + intersect.right - intersect.left, + intersect.bottom - intersect.top, + AllPlanes, ZPixmap ); + if (!image) return FALSE; + for (y = 0; y < image->height; y++) + for (x = 0; x < image->width; x++) + if (XGetPixel( image, x, y ) != 0) + { + XDestroyImage( image ); + return TRUE; + } - XDestroyImage( image ); + XDestroyImage( image ); + } return FALSE; } @@ -451,6 +472,7 @@ BOOL EqualRgn( HRGN rgn1, HRGN rgn2 ) { RGNOBJ *obj1, *obj2; XImage *image1, *image2; + Pixmap pixmap1, pixmap2; int width, height, x, y; /* Compare bounding boxes */ @@ -461,19 +483,27 @@ BOOL EqualRgn( HRGN rgn1, HRGN rgn2 ) return (obj2->region.type == NULLREGION); else if (obj2->region.type == NULLREGION) return FALSE; if (!EqualRect( &obj1->region.box, &obj2->region.box )) return FALSE; - + if (obj1->region.xrgn && obj2->region.xrgn) + { + return XEqualRegion( obj1->region.xrgn, obj2->region.xrgn ); + } + /* Get pixmap contents */ + if (!(pixmap1 = obj1->region.pixmap) && + !REGION_MakePixmap( &obj1->region )) return FALSE; + if (!(pixmap2 = obj2->region.pixmap) && + !REGION_MakePixmap( &obj2->region )) return FALSE; width = obj1->region.box.right - obj1->region.box.left; height = obj1->region.box.bottom - obj1->region.box.top; - image1 = XGetImage( XT_display, obj1->region.pixmap, + image1 = XGetImage( display, obj1->region.pixmap, + 0, 0, width, height, AllPlanes, ZPixmap ); + image2 = XGetImage( display, obj2->region.pixmap, 0, 0, width, height, AllPlanes, ZPixmap ); - if (!image1) return FALSE; - image2 = XGetImage( XT_display, obj2->region.pixmap, - 0, 0, width, height, AllPlanes, ZPixmap ); - if (!image2) + if (!image1 || !image2) { - XDestroyImage( image1 ); + if (image1) XDestroyImage( image1 ); + if (image2) XDestroyImage( image2 ); return FALSE; } @@ -503,7 +533,7 @@ void REGION_CopyIntersection( REGION * dest, REGION * src ) { RECT inter; if (!IntersectRect( &inter, &dest->box, &src->box )) return; - XCopyArea( XT_display, src->pixmap, dest->pixmap, regionGC, + XCopyArea( display, src->pixmap, dest->pixmap, regionGC, inter.left - src->box.left, inter.top - src->box.top, inter.right - inter.left, inter.bottom - inter.top, inter.left - dest->box.left, inter.top - dest->box.top ); @@ -533,6 +563,68 @@ int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode ) return ERROR; region = &destObj->region; + if (src1Obj->region.xrgn && ((mode == RGN_COPY) || src2Obj->region.xrgn)) + { + /* Perform the operation with X regions */ + + if (region->pixmap) XFreePixmap( display, region->pixmap ); + region->pixmap = 0; + if (!region->xrgn) region->xrgn = XCreateRegion(); + switch(mode) + { + case RGN_AND: + XIntersectRegion( src1Obj->region.xrgn, src2Obj->region.xrgn, + region->xrgn ); + break; + case RGN_OR: + XUnionRegion( src1Obj->region.xrgn, src2Obj->region.xrgn, + region->xrgn ); + break; + case RGN_XOR: + XXorRegion( src1Obj->region.xrgn, src2Obj->region.xrgn, + region->xrgn ); + break; + case RGN_DIFF: + XSubtractRegion( src1Obj->region.xrgn, src2Obj->region.xrgn, + region->xrgn ); + break; + case RGN_COPY: + { + Region tmprgn = XCreateRegion(); + XUnionRegion( tmprgn, src1Obj->region.xrgn, region->xrgn ); + XDestroyRegion( tmprgn ); + } + break; + default: + return ERROR; + } + if (XEmptyRegion(region->xrgn)) + { + region->type = NULLREGION; + region->xrgn = 0; + return NULLREGION; + } + else + { + XRectangle rect; + XClipBox( region->xrgn, &rect ); + region->type = COMPLEXREGION; + region->box.left = rect.x; + region->box.top = rect.y; + region->box.right = rect.x + rect.width; + region->box.bottom = rect.y + rect.height; + return COMPLEXREGION; + } + } + else /* Create pixmaps if needed */ + { + if (!src1Obj->region.pixmap) + if (!REGION_MakePixmap( &src1Obj->region )) return ERROR; + if ((mode != RGN_COPY) && !src2Obj->region.pixmap) + if (!REGION_MakePixmap( &src2Obj->region )) return ERROR; + } + + switch(mode) { case RGN_AND: @@ -564,11 +656,13 @@ int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode ) return ERROR; } - if (region->pixmap) XFreePixmap( XT_display, region->pixmap ); + if (region->pixmap) XFreePixmap( display, region->pixmap ); + if (region->xrgn) XDestroyRegion( region->xrgn ); if (!res) { region->type = NULLREGION; region->pixmap = 0; + region->xrgn = 0; return NULLREGION; } @@ -587,39 +681,40 @@ int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode ) exit(1); } region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 ); + region->xrgn = 0; switch(mode) { case RGN_AND: - XSetFunction( XT_display, regionGC, GXcopy ); + XSetFunction( display, regionGC, GXcopy ); REGION_CopyIntersection( region, &src1Obj->region ); - XSetFunction( XT_display, regionGC, GXand ); + XSetFunction( display, regionGC, GXand ); REGION_CopyIntersection( region, &src2Obj->region ); break; case RGN_OR: case RGN_XOR: - XSetFunction( XT_display, regionGC, GXclear ); - XFillRectangle( XT_display, region->pixmap, regionGC, + XSetFunction( display, regionGC, GXclear ); + XFillRectangle( display, region->pixmap, regionGC, 0, 0, width, height ); - XSetFunction( XT_display, regionGC, (mode == RGN_OR) ? GXor : GXxor); + XSetFunction( display, regionGC, (mode == RGN_OR) ? GXor : GXxor); REGION_CopyIntersection( region, &src1Obj->region ); REGION_CopyIntersection( region, &src2Obj->region ); break; case RGN_DIFF: - XSetFunction( XT_display, regionGC, GXclear ); - XFillRectangle( XT_display, region->pixmap, regionGC, + XSetFunction( display, regionGC, GXclear ); + XFillRectangle( display, region->pixmap, regionGC, 0, 0, width, height ); - XSetFunction( XT_display, regionGC, GXcopy ); + XSetFunction( display, regionGC, GXcopy ); REGION_CopyIntersection( region, &src1Obj->region ); - XSetFunction( XT_display, regionGC, GXandInverted ); + XSetFunction( display, regionGC, GXandInverted ); REGION_CopyIntersection( region, &src2Obj->region ); break; case RGN_COPY: - XSetFunction( XT_display, regionGC, GXcopy ); - XCopyArea( XT_display, src1Obj->region.pixmap, region->pixmap, + XSetFunction( display, regionGC, GXcopy ); + XCopyArea( display, src1Obj->region.pixmap, region->pixmap, regionGC, 0, 0, width, height, 0, 0 ); break; } diff --git a/windows/dce.c b/windows/dce.c index 58216b4b799..2148af1e9cd 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -183,25 +183,6 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) dc->w.DCSizeX = wndPtr->rectWindow.right - wndPtr->rectWindow.left; dc->w.DCSizeY = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top; } - else if (IsIconic(hwnd)) /* if we have an icon */ - { - /* more things are hardcoded here than should be, - * I assume the icon windows is 100 pixels 1/2 of which is 50 - * this just sets up the dc so it knows about the size of - * the icon area - */ - dc->u.x.drawable = wndPtr->icon; - if (wndPtr->hIcon != (HICON)NULL) { - lpico = (ICONALLOC *)GlobalLock(wndPtr->hIcon); - dc->w.DCSizeX = /* (int)lpico->descriptor.Width */ 100; - dc->w.DCSizeY = (int)lpico->descriptor.Height + 20; - } else { - dc->w.DCOrgX = /* 64 */ 100; /* assume max size */ - dc->w.DCOrgY = 64 + 20; - } - dc->w.DCOrgX = 0; - dc->w.DCOrgY = 0; - } else { dc->w.DCOrgX = wndPtr->rectClient.left - wndPtr->rectWindow.left; @@ -223,11 +204,12 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) if ((flags & DCX_INTERSECTRGN) || (flags & DCX_EXCLUDERGN)) { HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 ); - if (hrgn && !IsIconic(hwnd)) + if (hrgn) { if (CombineRgn( hrgn, InquireVisRgn(hdc), hrgnClip, - (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF )) + (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF )) { SelectVisRgn( hdc, hrgn ); + } DeleteObject( hrgn ); } } diff --git a/windows/defwnd.c b/windows/defwnd.c index 12443b104e7..071e681b2a4 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -44,6 +44,7 @@ void DEFWND_SetText( HWND hwnd, LPSTR text ) strcpy( textPtr, text ); } +#include /*********************************************************************** * DefWindowProc (USER.107) @@ -75,13 +76,10 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) case WM_NCCALCSIZE: return NC_HandleNCCalcSize( hwnd, (NCCALCSIZE_PARAMS *)lParam ); + case WM_PAINTICON: case WM_NCPAINT: return NC_HandleNCPaint( hwnd, (HRGN)wParam ); - case WM_PAINTICON: - printf("going to call NC_HandleNCPaintIcon\n"); - return NC_HandleNCPaintIcon( hwnd ); - case WM_NCHITTEST: return NC_HandleNCHitTest( hwnd, MAKEPOINT(lParam) ); @@ -89,6 +87,7 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) case WM_NCLBUTTONDOWN: return NC_HandleNCLButtonDown( hwnd, wParam, lParam ); + case WM_LBUTTONDBLCLK: case WM_NCLBUTTONDBLCLK: return NC_HandleNCLButtonDblClk( hwnd, wParam, lParam ); diff --git a/windows/dialog.c b/windows/dialog.c index 7b28b2dd13f..eeb5311b9f9 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -78,12 +78,14 @@ static DLGCONTROLHEADER * DIALOG_GetControl( DLGCONTROLHEADER * ptr, *class = p; p += strlen(p) + 1; } -/* FIXME: how can I determine if the resource id is an integer or a string ? */ - if (*p == 0xff) { -/* *(DWORD*)text = (*p << 8) | *p;*/ - *(DWORD*)text = 0xebeb; + if (*p == 0xff) + { + /* Integer id, not documented (?). Only works for SS_ICON controls */ + *text = (char *)MAKEINTRESOURCE( p[1] + 256*p[2] ); p += 4; - } else { + } + else + { *text = p; p += strlen(p) + 2; } @@ -263,8 +265,10 @@ HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate, /* Create dialog main window */ rect.left = rect.top = 0; - rect.right = template.header->cx * xUnit / 4; - rect.bottom = template.header->cy * yUnit / 8; + if (!(template.header->style & DS_ABSALIGN)) + ClientToScreen( owner, (POINT *)&rect ); + rect.right = rect.left + template.header->cx * xUnit / 4; + rect.bottom = rect.top + template.header->cy * yUnit / 8; if (template.header->style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME; AdjustWindowRectEx( &rect, template.header->style, hMenu, exStyle ); @@ -300,11 +304,8 @@ HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate, #ifdef DEBUG_DIALOG printf( " %s ", class); - if ((DWORD*)text < 0x10000) - printf("'%4X'", (DWORD*)text); - else - printf("'%s'", text); - + if ((int)text & 0xffff0000) printf("'%s'", text); + else printf("%4X", (int)text & 0xffff); printf(" %d, %d, %d, %d, %d, %08x\n", header->id, header->x, header->y, header->cx, header->cy, header->style ); #endif @@ -329,11 +330,6 @@ HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate, hwnd, header->id, HIWORD((LONG)dlgHeapBase), NULL ); } else { - if ((strcmp(class, "STATIC") == 0) & - ((header->style & SS_ICON) == SS_ICON)) { - header->cx = 32; - header->cy = 32; - } header->style |= WS_CHILD; CreateWindowEx( WS_EX_NOPARENTNOTIFY, class, text, header->style, diff --git a/windows/event.c b/windows/event.c index 4b6b3fd7029..a1dd581e3dc 100644 --- a/windows/event.c +++ b/windows/event.c @@ -252,13 +252,6 @@ static void EVENT_Expose( HWND hwnd, XExposeEvent *event ) WND * wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return; - if (IsIconic(hwnd) && wndPtr->hIcon) - { - SendMessage(hwnd, WM_PAINTICON, 0, 0); - return; - } - - /* Make position relative to client area instead of window */ rect.left = event->x - (wndPtr->rectClient.left - wndPtr->rectWindow.left); rect.top = event->y - (wndPtr->rectClient.top - wndPtr->rectWindow.top); diff --git a/windows/graphics.c b/windows/graphics.c index 089e3cc6520..b3c93072527 100644 --- a/windows/graphics.c +++ b/windows/graphics.c @@ -18,6 +18,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "gdi.h" #include "syscolor.h" +extern const int DC_XROPfunction[]; + extern int COLOR_ToPhysical( DC *dc, COLORREF color ); static inline swap_int(int *a, int *b) @@ -473,6 +475,10 @@ COLORREF GetPixel( HDC hdc, short x, short y ) DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); if (!dc) return 0; +#ifdef SOLITAIRE_SPEED_HACK + return 0; +#endif + x = dc->w.DCOrgX + XLPTODP( dc, x ); y = dc->w.DCOrgY + YLPTODP( dc, y ); if ((x < 0) || (y < 0)) return 0; @@ -551,6 +557,20 @@ BOOL FillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush ) } +/*********************************************************************** + * InvertRgn (GDI.42) + */ +BOOL InvertRgn( HDC hdc, HRGN hrgn ) +{ + HBRUSH prevBrush = SelectObject( hdc, GetStockObject(BLACK_BRUSH) ); + WORD prevROP = SetROP2( hdc, R2_NOT ); + BOOL retval = PaintRgn( hdc, hrgn ); + SelectObject( hdc, prevBrush ); + SetROP2( hdc, prevROP ); + return retval; +} + + /*********************************************************************** * DrawFocusRect (USER.466) */ @@ -582,6 +602,44 @@ void DrawFocusRect( HDC hdc, LPRECT rc ) } +/********************************************************************** + * GRAPH_DrawBitmap + * + * Short-cut function to blit a bitmap into a device. + * Faster than CreateCompatibleDC() + SelectBitmap() + BitBlt() + DeleteDC(). + */ +BOOL GRAPH_DrawBitmap( HDC hdc, HBITMAP hbitmap, int xdest, int ydest, + int xsrc, int ysrc, int width, int height, int rop ) +{ + XGCValues val; + BITMAPOBJ *bmp; + DC *dc; + + if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE; + if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) + return FALSE; + val.function = DC_XROPfunction[(rop >> 16) & 0x0f]; + val.foreground = dc->w.textPixel; + val.background = dc->w.backgroundPixel; + XChangeGC(display, dc->u.x.gc, GCFunction|GCForeground|GCBackground, &val); + if (bmp->bitmap.bmBitsPixel == 1) + { + XCopyPlane( display, bmp->pixmap, dc->u.x.drawable, dc->u.x.gc, + xsrc, ysrc, width, height, + dc->w.DCOrgX + xdest, dc->w.DCOrgY + ydest, 1 ); + return TRUE; + } + else if (bmp->bitmap.bmBitsPixel == dc->w.bitsPerPixel) + { + XCopyArea( display, bmp->pixmap, dc->u.x.drawable, dc->u.x.gc, + xsrc, ysrc, width, height, + dc->w.DCOrgX + xdest, dc->w.DCOrgY + ydest ); + return TRUE; + } + else return FALSE; +} + + /********************************************************************** * DrawReliefRect (Not a MSWin Call) */ diff --git a/windows/icon.c b/windows/icon.c index ba7d94da01c..8b137891791 100644 --- a/windows/icon.c +++ b/windows/icon.c @@ -1,187 +1 @@ -/* - * Iconification functions - * - * Copyright 1994 John Richardson - */ - -static char Copyright[] = "Copyright John Richardson, 1994"; - -#include "win.h" -#include "class.h" -#include "message.h" -#include "sysmetrics.h" -#include "user.h" -#include "scroll.h" -#include "menu.h" -#include "icon.h" - -RECT myrect; - - -ICON_Iconify(HWND hwnd) -{ - WND *wndPtr = WIN_FindWndPtr( hwnd ); - GC testgc; - WND *parwPtr; - -#ifdef DEBUG_ICON - printf("ICON_Iconify %d\n", hwnd); -#endif - - parwPtr = WIN_FindWndPtr(wndPtr->hwndParent); - if (parwPtr == NULL) { - printf("argh, the parent is NULL, what to do?\n"); - exit(1); - } - wndPtr->dwStyle |= WS_MINIMIZE; - XUnmapWindow(display, wndPtr->window); - if (wndPtr->icon == NULL) { - printf("argh, couldn't find icon\n"); - exit(1); - } -#ifdef DEBUG_ICON - printf("parent edge values are %d, %d\n", parwPtr->rectWindow.left, - parwPtr->rectWindow.bottom); -#endif - wndPtr->ptIconPos.x = parwPtr->rectWindow.left + 10; - wndPtr->ptIconPos.y = parwPtr->rectWindow.bottom - 80; - -#ifdef NOT - wndPtr->rectWindow.right = 100; - wndPtr->rectWindow.bottom = 32; - wndPtr->rectNormal.right = 1000; - wndPtr->rectNormal.bottom = 32; - wndPtr->rectClient.top= wndPtr->ptIconPos.y; - wndPtr->rectClient.left= wndPtr->ptIconPos.x; - - wndPtr->rectClient.right = 100; - wndPtr->rectClient.bottom = 64; -#endif - wndPtr->rectClientSave = wndPtr->rectNormal; - myrect = wndPtr->rectClient; - - MoveWindow(hwnd, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y, - 100, 64+20, FALSE); - - XMoveWindow(display, wndPtr->icon, - wndPtr->ptIconPos.x, wndPtr->ptIconPos.y); - - XMapWindow(display, wndPtr->icon); - - SendMessage(hwnd, WM_PAINTICON, 0, 0); -#ifdef DEBUG_ICON - printf("done with iconify\n"); -#endif -} - - -BOOL ICON_isAtPoint(HWND hwnd, POINT pt) -{ - WND *wndPtr = WIN_FindWndPtr( hwnd ); - int iconWidth, iconHeight; - -/**************** - if (wndPtr->hwndParent != GetDesktopWindow()) { - pt.x -= wndPtr->rectClient.left; - pt.y -= wndPtr->rectClient.top; - } -*****************/ - - - if (wndPtr->hIcon != (HICON)NULL) { - ICONALLOC *lpico; - lpico = (ICONALLOC *)GlobalLock(wndPtr->hIcon); - iconWidth = (int)lpico->descriptor.Width; - iconHeight = (int)lpico->descriptor.Height; - } else { - iconWidth = 64; - iconHeight = 64; - } - -#ifdef DEBUG_ICON - printf("icon x,y is %d,%d\n", - wndPtr->ptIconPos.x, wndPtr->ptIconPos.y); - - printf("icon end x,y is %d,%d\n", - wndPtr->ptIconPos.x + 100, - wndPtr->ptIconPos.y + iconHeight + 20); - - printf("mouse pt x,y is %d,%d\n", pt.x, pt.y); - - printf("%d\n", IsIconic(hwnd)); - printf("%d\n", (pt.x >= wndPtr->ptIconPos.x)); - printf("%d\n", (pt.x < wndPtr->ptIconPos.x + 100)); - printf("%d\n", (pt.y >= wndPtr->ptIconPos.y)); - printf("%d\n", (pt.y < wndPtr->ptIconPos.y + iconHeight + 20)); - printf("%d\n", !(wndPtr->dwStyle & WS_DISABLED)); - printf("%d\n", (wndPtr->dwStyle & WS_VISIBLE)); - printf("%d\n", !(wndPtr->dwExStyle & WS_EX_TRANSPARENT)); -#endif - - if ( IsIconic(hwnd) && - (pt.x >= wndPtr->ptIconPos.x) && - (pt.x < wndPtr->ptIconPos.x + 100) && - (pt.y >= wndPtr->ptIconPos.y) && - (pt.y < wndPtr->ptIconPos.y + iconHeight + 20) && - !(wndPtr->dwStyle & WS_DISABLED) && - (wndPtr->dwStyle & WS_VISIBLE) && - !(wndPtr->dwExStyle & WS_EX_TRANSPARENT)) - { -#ifdef DEBUG_ICON - printf("got a winner!\n"); -#endif - return 1; - } - - return 0; - -} - -HWND ICON_findIconFromPoint(POINT pt) -{ - HWND hwnd = GetTopWindow( GetDesktopWindow() ); - WND *wndPtr; - HWND hwndRet = 0; - - while (hwnd) { - - if ( !(wndPtr=WIN_FindWndPtr(hwnd))) return 0; - if (ICON_isAtPoint(hwnd, pt)) { -#ifdef DEBUG_ICON - printf("returning\n"); -#endif - return hwndRet = hwnd; - } else { -#ifdef DEBUG_ICON - printf("checking child\n"); -#endif - hwnd = wndPtr->hwndChild; - } - } - return hwndRet; -} - - -ICON_Deiconify(HWND hwnd) -{ - WND *wndPtr = WIN_FindWndPtr( hwnd ); - -#ifdef DEBUG_ICON - printf("deiconifying\n"); -#endif - XUnmapWindow(display, wndPtr->icon); - wndPtr->dwStyle &= ~WS_MINIMIZE; -/* wndPtr->rectNormal = myrect; -*/ - MoveWindow(hwnd, - wndPtr->rectClientSave.left, - wndPtr->rectClientSave.top, - wndPtr->rectClientSave.right - wndPtr->rectClientSave.left, - wndPtr->rectClientSave.bottom - wndPtr->rectClientSave.top, - FALSE); - - XMapWindow(display, wndPtr->window); -} - - diff --git a/windows/mdi.c b/windows/mdi.c index 80dd6d78c58..66a511ea563 100644 --- a/windows/mdi.c +++ b/windows/mdi.c @@ -16,7 +16,7 @@ #define DEBUG_MDI /* */ extern WORD MENU_DrawMenuBar( HDC hDC, LPRECT lprect, - HMENU hmenu, BOOL suppress_draw ); /* menu.c */ + HWND hwnd, BOOL suppress_draw ); /* menu.c */ /********************************************************************** * MDIRecreateMenuList @@ -310,6 +310,7 @@ LONG MDIRestoreChild(HWND parent, MDICLIENTINFO *ci) ci->flagChildMaximized = FALSE; + ShowWindow(child, SW_RESTORE); /* display the window */ SendMessage(GetParent(parent), WM_NCPAINT, 1, 0); MDIBringChildToTop(parent, child, FALSE, FALSE); @@ -571,7 +572,7 @@ LONG MDIPaintMaximized(HWND hwndFrame, HWND hwndClient, WORD message, rect.right -= SYSMETRICS_CXSIZE; rect.bottom = rect.top + SYSMETRICS_CYMENU; - MENU_DrawMenuBar(hdc, &rect, wndPtr->wIDmenu, FALSE); + MENU_DrawMenuBar(hdc, &rect, hwndFrame, FALSE); DeleteDC(hdcMem); ReleaseDC(hwndFrame, hdc); @@ -751,8 +752,6 @@ DefMDIChildProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) return SendMessage(GetParent(hwnd), WM_MDIMAXIMIZE, hwnd, 0); case SC_RESTORE: - if (IsIconic(hwnd)) - ICON_Deiconify(hwnd); return SendMessage(GetParent(hwnd), WM_MDIRESTORE, hwnd, 0); } break; diff --git a/windows/message.c b/windows/message.c index fdac1359809..6d7a21a437f 100644 --- a/windows/message.c +++ b/windows/message.c @@ -198,6 +198,7 @@ static void MSG_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos ) * Return value indicates whether the translated message must be passed * to the user. * Actions performed: + * - Find the window for this message. * - Translate button-down messages in double-clicks. * - Send the WM_NCHITTEST message to find where the cursor is. * - Activate the window if needed. @@ -208,6 +209,7 @@ static void MSG_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos ) static BOOL MSG_TranslateMouseMsg( MSG *msg, BOOL remove ) { BOOL eatMsg = FALSE; + LONG hittest_result; static DWORD lastClickTime = 0; static WORD lastClickMsg = 0; static POINT lastClickPos = { 0, 0 }; @@ -216,10 +218,29 @@ static BOOL MSG_TranslateMouseMsg( MSG *msg, BOOL remove ) (msg->message == WM_RBUTTONDOWN) || (msg->message == WM_MBUTTONDOWN)); + /* Find the window */ + + if (GetCapture()) + { + msg->hwnd = GetCapture(); + msg->lParam = MAKELONG( msg->pt.x, msg->pt.y ); + ScreenToClient( msg->hwnd, (LPPOINT)&msg->lParam ); + return TRUE; /* No need to further process the message */ + } + else msg->hwnd = WindowFromPoint( msg->pt ); + /* Send the WM_NCHITTEST message */ - LONG hittest_result = SendMessage( msg->hwnd, WM_NCHITTEST, 0, - MAKELONG( msg->pt.x, msg->pt.y ) ); + hittest_result = SendMessage( msg->hwnd, WM_NCHITTEST, 0, + MAKELONG( msg->pt.x, msg->pt.y ) ); + while ((hittest_result == HTTRANSPARENT) && (msg->hwnd)) + { + msg->hwnd = GetParent(msg->hwnd); + if (!msg->hwnd) + hittest_result = SendMessage( msg->hwnd, WM_NCHITTEST, 0, + MAKELONG( msg->pt.x, msg->pt.y ) ); + } + if (!msg->hwnd) msg->hwnd = GetDesktopWindow(); /* Send the WM_PARENTNOTIFY message */ @@ -305,6 +326,29 @@ static BOOL MSG_TranslateMouseMsg( MSG *msg, BOOL remove ) } +/*********************************************************************** + * MSG_TranslateKeyboardMsg + * + * Translate an keyboard hardware event into a real message. + * Return value indicates whether the translated message must be passed + * to the user. + */ +static BOOL MSG_TranslateKeyboardMsg( MSG *msg ) +{ + /* Should check Ctrl-Esc and PrintScreen here */ + + msg->hwnd = GetFocus(); + if (!msg->hwnd) + { + /* Send the message to the active window instead, */ + /* translating messages to their WM_SYS equivalent */ + msg->hwnd = GetActiveWindow(); + msg->message += WM_SYSKEYDOWN - WM_KEYDOWN; + } + return TRUE; +} + + /********************************************************************** * SetDoubleClickTime (USER.20) */ @@ -391,30 +435,6 @@ void hardware_event( WORD message, WORD wParam, LONG lParam, msg.pt.x = xPos & 0xffff; msg.pt.y = yPos & 0xffff; - /* Determine the hwnd for this message */ - /* Maybe this should be done in GetMessage() */ - - if (msg.hwnd = ICON_findIconFromPoint(msg.pt)) { - SendMessage( msg.hwnd, WM_SYSCOMMAND, SC_RESTORE, *(LONG*)&msg.pt ); - return; - } - - - if ((message >= WM_MOUSEFIRST) && (message <= WM_MOUSELAST)) - { - /* Mouse event */ - if (GetCapture()) msg.hwnd = GetCapture(); - else msg.hwnd = WindowFromPoint( msg.pt ); - } - else if ((message >= WM_KEYFIRST) && (message <= WM_KEYLAST)) - { - /* Keyboard event */ - msg.hwnd = GetFocus(); - if (!msg.hwnd && ((message==WM_KEYDOWN) || (message==WM_SYSKEYDOWN))) - MessageBeep(0); /* Beep on key press if no focus */ - } - if (!msg.hwnd) return; /* No window for this message */ - /* Merge with previous event if possible */ if (sysMsgQueue->msgCount && (message == WM_MOUSEMOVE)) @@ -438,6 +458,7 @@ void hardware_event( WORD message, WORD wParam, LONG lParam, * Like GetMessage(), but only return mouse and keyboard events. * Used internally for window moving and resizing. Mouse messages * are not translated. + * Warning: msg->hwnd is always 0. */ BOOL MSG_GetHardwareMessage( LPMSG msg ) { @@ -560,6 +581,9 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd, int pos, mask; LONG nextExp; /* Next timer expiration time */ XEvent event; + fd_set read_set; + struct timeval timeout; + int fd = ConnectionNumber(display); if (first || last) { @@ -572,25 +596,9 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd, } else mask = QS_MOUSE | QS_KEY | QS_POSTMESSAGE | QS_TIMER | QS_PAINT; - while (XPending( display )) - { - XNextEvent( display, &event ); - EVENT_ProcessEvent( &event ); - } - while(1) { - /* First handle a WM_QUIT message */ - if (msgQueue->wPostQMsg) - { - msg->hwnd = hwnd; - msg->message = WM_QUIT; - msg->wParam = msgQueue->wExitCode; - msg->lParam = 0; - break; - } - - /* Then handle a message put by SendMessage() */ + /* First handle a message put by SendMessage() */ if (msgQueue->status & QS_SENDMESSAGE) { if (!hwnd || (msgQueue->hWnd == hwnd)) @@ -623,7 +631,7 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd, } /* Now find a hardware event */ - pos = MSG_FindMsg( sysMsgQueue, hwnd, first, last ); + pos = MSG_FindMsg( sysMsgQueue, 0, first, last ); if (pos != -1) { QMSG *qmsg = &sysMsgQueue->messages[pos]; @@ -639,10 +647,27 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd, MSG_RemoveMsg( sysMsgQueue, pos ); continue; } + else if ((msg->message >= WM_KEYFIRST) && + (msg->message <= WM_KEYLAST)) + if (!MSG_TranslateKeyboardMsg( msg )) + { + MSG_RemoveMsg( sysMsgQueue, pos ); + continue; + } if (flags & PM_REMOVE) MSG_RemoveMsg( sysMsgQueue, pos ); break; } + /* Now handle a WM_QUIT message */ + if (msgQueue->wPostQMsg) + { + msg->hwnd = hwnd; + msg->message = WM_QUIT; + msg->wParam = msgQueue->wExitCode; + msg->lParam = 0; + break; + } + /* Now find a WM_PAINT message */ if ((msgQueue->status & QS_PAINT) && (mask & QS_PAINT)) { @@ -662,21 +687,27 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd, else nextExp = -1; /* No timeout needed */ /* Wait until something happens */ - if (peek) return FALSE; - if (!XPending( display ) && (nextExp != -1)) + FD_ZERO( &read_set ); + FD_SET( fd, &read_set ); + if (peek) + { + timeout.tv_sec = 0; + timeout.tv_usec = 0; + if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1) + return FALSE; /* No data waiting to be read */ + } + else if (!XPending( display ) && (nextExp != -1)) { - fd_set read_set; - struct timeval timeout; - int fd = ConnectionNumber(display); - FD_ZERO( &read_set ); - FD_SET( fd, &read_set ); timeout.tv_sec = nextExp / 1000; timeout.tv_usec = (nextExp % 1000) * 1000; if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1) continue; /* On timeout or error, restart from the start */ } - XNextEvent( display, &event ); - EVENT_ProcessEvent( &event ); + while (XPending( display )) + { + XNextEvent( display, &event ); + EVENT_ProcessEvent( &event ); + } } /* We got a message */ @@ -825,11 +856,10 @@ void WaitMessage( void ) (appMsgQueue->status & (QS_SENDMESSAGE | QS_PAINT)) || (appMsgQueue->msgCount) || (sysMsgQueue->msgCount) ) break; + nextExp = -1; if ((appMsgQueue->status & QS_TIMER) && TIMER_CheckTimer( &nextExp, &msg, 0, FALSE)) break; - else - nextExp=-1; if (!XPending( display ) && (nextExp != -1)) { diff --git a/windows/nonclient.c b/windows/nonclient.c index 2bb188e3667..5909530b312 100644 --- a/windows/nonclient.c +++ b/windows/nonclient.c @@ -30,12 +30,15 @@ extern BOOL AboutWine_Proc( HWND hDlg, WORD msg, WORD wParam, LONG lParam ); extern void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, POINT *minTrack, POINT *maxTrack ); /* winpos.c */ extern void CURSOR_SetWinCursor( HWND hwnd, HCURSOR hcursor ); /* cursor.c */ +extern BOOL GRAPH_DrawBitmap( HDC hdc, HBITMAP hbitmap, int xdest, int ydest, + int xsrc, int ysrc, int width, int height, + int rop ); /* graphics.c */ extern WORD MENU_GetMenuBarHeight( HWND hwnd, WORD menubarWidth, int orgX, int orgY ); /* menu.c */ extern void MENU_TrackMouseMenuBar( HWND hwnd, POINT pt ); /* menu.c */ extern void MENU_TrackKbdMenuBar( HWND hwnd, WORD wParam ); /* menu.c */ extern WORD MENU_DrawMenuBar( HDC hDC, LPRECT lprect, - HMENU hmenu, BOOL suppress_draw ); /* menu.c */ + HWND hwnd, BOOL suppress_draw ); /* menu.c */ /* Some useful macros */ @@ -126,6 +129,12 @@ LONG NC_HandleNCCalcSize( HWND hwnd, NCCALCSIZE_PARAMS *params ) if (!wndPtr) return 0; + /* + * we don't want to change the size if hwnd is an icon since + * there are no window manager handles on an icon + */ + if(IsIconic(hwnd)) return 0; + NC_AdjustRect( &tmpRect, wndPtr->dwStyle, FALSE, wndPtr->dwExStyle ); params->rgrc[0].left -= tmpRect.left; params->rgrc[0].top -= tmpRect.top; @@ -174,22 +183,34 @@ void NC_GetInsideRect( HWND hwnd, RECT *rect ) /*********************************************************************** - * NC_InternalNCHitTest + * NC_HandleNCHitTest * - * Perform the hit test calculation, but whithout testing the capture - * window. + * Handle a WM_NCHITTEST message. Called from DefWindowProc(). */ -static LONG NC_InternalNCHitTest( HWND hwnd, POINT pt ) +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 + GetWindowRect( hwnd, &rect ); if (!PtInRect( &rect, pt )) return HTNOWHERE; - /* Check borders */ + /* + * if this is a iconic window, we don't care were the hit + * occured, only that it did occur, just return HTCAPTION + * so the caller knows the icon did get hit + */ + if (IsIconic(hwnd)) + { + return HTCAPTION; /* change this to something meaningful? */ + } + /* Check borders */ if (HAS_THICKFRAME( wndPtr->dwStyle )) { InflateRect( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME ); @@ -301,21 +322,6 @@ static LONG NC_InternalNCHitTest( HWND hwnd, POINT pt ) } -/*********************************************************************** - * NC_HandleNCHitTest - * - * Handle a WM_NCHITTEST message. Called from DefWindowProc(). - */ -LONG NC_HandleNCHitTest( HWND hwnd, POINT pt ) -{ -#ifdef DEBUG_NONCLIENT - printf( "NC_HandleNCHitTest: hwnd=%x pt=%d,%d\n", hwnd, pt.x, pt.y ); -#endif - if (hwnd == GetCapture()) return HTCLIENT; - return NC_InternalNCHitTest( hwnd, pt ); -} - - /*********************************************************************** * NC_DrawSysButton */ @@ -323,18 +329,12 @@ void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down ) { RECT rect; WND *wndPtr = WIN_FindWndPtr( hwnd ); - HDC hdcMem = CreateCompatibleDC( hdc ); - if (hdcMem) - { - NC_GetInsideRect( hwnd, &rect ); - if (wndPtr->dwStyle & WS_CHILD) - SelectObject( hdcMem, hbitmapMDIClose ); - else - SelectObject( hdcMem, hbitmapClose ); - BitBlt( hdc, rect.left, rect.top, SYSMETRICS_CXSIZE, - SYSMETRICS_CYSIZE, hdcMem, 1, 1, down ? NOTSRCCOPY : SRCCOPY ); - DeleteDC( hdcMem ); - } + NC_GetInsideRect( hwnd, &rect ); + GRAPH_DrawBitmap( hdc, (wndPtr->dwStyle & WS_CHILD) ? + hbitmapMDIClose : hbitmapClose, + rect.left, rect.top, + 1, 1, SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE, + down ? NOTSRCCOPY : SRCCOPY ); } @@ -344,17 +344,12 @@ void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down ) static void NC_DrawMaxButton( HWND hwnd, HDC hdc, BOOL down ) { RECT rect; - HDC hdcMem = CreateCompatibleDC( hdc ); - if (hdcMem) - { - NC_GetInsideRect( hwnd, &rect ); - if (IsZoomed(hwnd)) - SelectObject( hdcMem, down ? hbitmapRestoreD : hbitmapRestore ); - else SelectObject( hdcMem, down ? hbitmapMaximizeD : hbitmapMaximize ); - BitBlt( hdc, rect.right - SYSMETRICS_CXSIZE - 1, rect.top - 1, - SYSMETRICS_CXSIZE+2, SYSMETRICS_CYSIZE+2, hdcMem, 0, 0, SRCCOPY); - DeleteDC( hdcMem ); - } + NC_GetInsideRect( hwnd, &rect ); + GRAPH_DrawBitmap( hdc, (IsZoomed(hwnd) ? + (down ? hbitmapRestoreD : hbitmapRestore) : + (down ? hbitmapMaximizeD : hbitmapMaximize)), + rect.right - SYSMETRICS_CXSIZE - 1, rect.top - 1, + 0, 0, SYSMETRICS_CXSIZE+2, SYSMETRICS_CYSIZE+2, SRCCOPY ); } @@ -365,18 +360,11 @@ static void NC_DrawMinButton( HWND hwnd, HDC hdc, BOOL down ) { RECT rect; WND *wndPtr = WIN_FindWndPtr( hwnd ); - HDC hdcMem = CreateCompatibleDC( hdc ); - if (hdcMem) - { - NC_GetInsideRect( hwnd, &rect ); - if (wndPtr->dwStyle & WS_MAXIMIZEBOX) - rect.right -= SYSMETRICS_CXSIZE + 1; - if (down) SelectObject( hdcMem, hbitmapMinimizeD ); - else SelectObject( hdcMem, hbitmapMinimize ); - BitBlt( hdc, rect.right - SYSMETRICS_CXSIZE - 1, rect.top - 1, - SYSMETRICS_CXSIZE+2, SYSMETRICS_CYSIZE+2, hdcMem, 0, 0, SRCCOPY); - DeleteDC( hdcMem ); - } + NC_GetInsideRect( hwnd, &rect ); + if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= SYSMETRICS_CXSIZE + 1; + GRAPH_DrawBitmap( hdc, (down ? hbitmapMinimizeD : hbitmapMinimize), + rect.right - SYSMETRICS_CXSIZE - 1, rect.top - 1, + 0, 0, SYSMETRICS_CXSIZE+2, SYSMETRICS_CYSIZE+2, SRCCOPY ); } @@ -583,6 +571,27 @@ void NC_DoNCPaint( HWND hwnd, HRGN hrgn, BOOL active, BOOL suppress_menupaint ) OffsetRgn( hrgn, xoffset, yoffset ); /* Restore region */ } if (!hdc) return; + + + /* + * If this is an icon, we don't want to do any more nonclient painting + * of the window manager. + * If there is a class icon to draw, draw it + */ + if (IsIconic(hwnd)) + { + if (wndPtr->hIcon) + { + SendMessage(hwnd, WM_ICONERASEBKGND, hdc, 0); + Rectangle(hdc, wndPtr->rectWindow.left, wndPtr->rectWindow.top, + wndPtr->rectWindow.right, wndPtr->rectWindow.bottom); + DrawIcon(hdc, 0, 0, wndPtr->hIcon); + } + ReleaseDC(hwnd, hdc); + + return; + } + if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left, wndPtr->rectClient.top-wndPtr->rectWindow.top, wndPtr->rectClient.right-wndPtr->rectWindow.left, @@ -628,8 +637,7 @@ void NC_DoNCPaint( HWND hwnd, HRGN hrgn, BOOL active, BOOL suppress_menupaint ) { RECT r = rect; r.bottom = rect.top + SYSMETRICS_CYMENU; /* default height */ - rect.top += MENU_DrawMenuBar( hdc, &r, (HMENU)wndPtr->wIDmenu, - suppress_menupaint ); + rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ); } if (wndPtr->dwStyle & (WS_VSCROLL | WS_HSCROLL)) { @@ -665,46 +673,6 @@ void NC_DoNCPaint( HWND hwnd, HRGN hrgn, BOOL active, BOOL suppress_menupaint ) } -NC_DoNCPaintIcon(HWND hwnd) -{ - WND *wndPtr = WIN_FindWndPtr(hwnd); - PAINTSTRUCT ps; - HDC hdc; - int ret; - DC *dc; - GC testgc; - int s; - char buffer[256]; - - printf("painting icon\n"); - if (wndPtr == NULL) { - printf("argh, can't find an icon to draw\n"); - return; - } - hdc = BeginPaint(hwnd, &ps); - - ret = DrawIcon(hdc, 100/2 - 16, 0, wndPtr->hIcon); - printf("ret is %d\n", ret); - - if (s=GetWindowText(hwnd, buffer, 256)) - { - /*SetBkColor(hdc, TRANSPARENT); */ - TextOut(hdc, 0, 32, buffer, s); - } - EndPaint(hwnd, &ps); - - printf("done painting icon\n"); - -} - - -LONG NC_HandleNCPaintIcon( HWND hwnd ) -{ - NC_DoNCPaintIcon(hwnd); - return 0; -} - - /*********************************************************************** * NC_HandleNCPaint @@ -761,8 +729,8 @@ LONG NC_HandleSetCursor( HWND hwnd, WORD wParam, LONG lParam ) CURSOR_SetWinCursor( hwnd, classPtr->wc.hCursor ); return TRUE; } + else return FALSE; } - break; case HTLEFT: case HTRIGHT: @@ -830,7 +798,7 @@ static LONG NC_StartSizeMove( HWND hwnd, WORD wParam, POINT *capturePoint ) switch(msg.message) { case WM_MOUSEMOVE: - hittest = NC_InternalNCHitTest( hwnd, msg.pt ); + hittest = NC_HandleNCHitTest( hwnd, msg.pt ); pt = msg.pt; if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT)) hittest = 0; @@ -890,7 +858,7 @@ static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT pt ) POINT minTrack, maxTrack, capturePoint = pt; WND * wndPtr = WIN_FindWndPtr( hwnd ); - if (IsZoomed(hwnd) || IsIconic(hwnd) || !IsWindowVisible(hwnd)) return; + if (IsZoomed(hwnd) || !IsWindowVisible(hwnd)) return; hittest = wParam & 0x0f; thickframe = HAS_THICKFRAME( wndPtr->dwStyle ); @@ -1053,7 +1021,7 @@ static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam ) BOOL oldstate = pressed; MSG_GetHardwareMessage( &msg ); - pressed = (NC_InternalNCHitTest( hwnd, msg.pt ) == wParam); + pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam); if (pressed != oldstate) { if (wParam == HTMINBUTTON) NC_DrawMinButton( hwnd, hdc, pressed ); @@ -1103,7 +1071,7 @@ static void NC_TrackScrollBar( HWND hwnd, WORD wParam, POINT pt ) do { MSG_GetHardwareMessage( &msg ); - ScreenToClient( msg.hwnd, &msg.pt ); + ScreenToClient( hwnd, &msg.pt ); switch(msg.message) { case WM_LBUTTONUP: @@ -1210,6 +1178,16 @@ LONG NC_HandleNCLButtonDown( HWND hwnd, WORD wParam, LONG lParam ) */ LONG NC_HandleNCLButtonDblClk( HWND hwnd, WORD wParam, LONG lParam ) { + /* + * if this is an icon, send a restore since we are handling + * a double click + */ + if (IsIconic(hwnd)) + { + SendMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, lParam); + return 0; + } + switch(wParam) /* Hit test */ { case HTCAPTION: @@ -1247,8 +1225,7 @@ LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt ) break; case SC_MINIMIZE: - ICON_Iconify( hwnd ); - /*ShowWindow( hwnd, SW_MINIMIZE );*/ + ShowWindow( hwnd, SW_MINIMIZE ); break; case SC_MAXIMIZE: @@ -1256,7 +1233,6 @@ LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt ) break; case SC_RESTORE: - ICON_Deiconify(hwnd); ShowWindow( hwnd, SW_RESTORE ); break; diff --git a/windows/painting.c b/windows/painting.c index abac9b5458b..8c5658c49c7 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -98,6 +98,14 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags ) if (!hwnd) hwnd = GetDesktopWindow(); if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE; + /* + * I can't help but feel that this belongs somewhere upstream... + * + * Don't redraw the window if it is iconified and we have an + * icon to draw for it + */ + if (IsIconic(hwnd) && wndPtr->hIcon) return FALSE; + GetClientRect( hwnd, &rectClient ); rectWindow = wndPtr->rectWindow; OffsetRect(&rectWindow, -wndPtr->rectClient.left, -wndPtr->rectClient.top); diff --git a/windows/timer.c b/windows/timer.c index 641bbe05bf8..6aad7aca111 100644 --- a/windows/timer.c +++ b/windows/timer.c @@ -134,7 +134,25 @@ static WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, if (!timeout) return 0; if (!hwnd && !proc) return 0; - + + /* Check if there's already a timer with the same hwnd and id */ + + if (hwnd) + { + for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++) + if ((pTimer->hwnd == hwnd) && (pTimer->id == id) && + (pTimer->timeout != 0)) + { + /* Got one: set new values and return */ + pTimer->timeout = timeout; + pTimer->expires = GetTickCount() + timeout; + pTimer->proc = proc; + TIMER_RemoveTimer( pTimer ); + TIMER_InsertTimer( pTimer ); + return id; + } + } + /* Find a free timer */ for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++) diff --git a/windows/win.c b/windows/win.c index 39249089092..2c27a7665b1 100644 --- a/windows/win.c +++ b/windows/win.c @@ -251,8 +251,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, CREATESTRUCT *createStruct; HANDLE hcreateStruct; int wmcreate; - XSetWindowAttributes win_attr, icon_attr; - int iconWidth, iconHeight; + XSetWindowAttributes win_attr; #ifdef DEBUG_WIN printf( "CreateWindowEx: %04X '%s' '%s' %04X %d,%d %dx%d %04X %04X %04X %08X\n", @@ -373,11 +372,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, /* Only select focus events on top-level override-redirect windows */ if (win_attr.override_redirect) win_attr.event_mask |= FocusChangeMask; } - if (Options.nobackingstore) - win_attr.backing_store = NotUseful; - else - win_attr.backing_store = Always; - + win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful; win_attr.save_under = ((classPtr->wc.style & CS_SAVEBITS) != 0); WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack ); @@ -392,7 +387,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, height = maxSize.y; wndPtr->rectWindow.bottom = y + height; } - + wndPtr->window = XCreateWindow( display, parentPtr->window, x + parentPtr->rectClient.left - parentPtr->rectWindow.left, y + parentPtr->rectClient.top - parentPtr->rectWindow.top, @@ -403,42 +398,22 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, XStoreName( display, wndPtr->window, windowName ); - /* create icon window */ - - icon_attr.override_redirect = rootWindow==DefaultRootWindow(display); - icon_attr.background_pixel = WhitePixelOfScreen(screen); - icon_attr.event_mask = ExposureMask | KeyPressMask | - ButtonPressMask | ButtonReleaseMask; - + /* + * store icon handle, icon handle is kept in class. If we + * have an icon, make the icon size the size of the icon, + * if we don't have an icon, just give it 64x64 + */ wndPtr->hIcon = classPtr->wc.hIcon; if (wndPtr->hIcon != (HICON)NULL) { ICONALLOC *lpico; lpico = (ICONALLOC *)GlobalLock(wndPtr->hIcon); - printf("icon is %d x %d\n", - (int)lpico->descriptor.Width, - (int)lpico->descriptor.Height); - iconWidth = (int)lpico->descriptor.Width; - iconHeight = (int)lpico->descriptor.Height; + wndPtr->iconWidth = (int)lpico->descriptor.Width; + wndPtr->iconHeight = (int)lpico->descriptor.Height; } else { - printf("icon was NULL\n"); - iconWidth = 64; - iconHeight = 64; + wndPtr->iconWidth = 64; + wndPtr->iconHeight = 64; } - wndPtr->icon = XCreateWindow(display, parentPtr->window, - 10, 10, 100, iconHeight+20, - 0, CopyFromParent, - InputOutput, CopyFromParent, - CWBorderPixel | CWEventMask | CWOverrideRedirect, - &icon_attr); - - if (style & WS_MINIMIZE) - { - style &= ~WS_MINIMIZE; - } - - - #ifdef DEBUG_MENU printf("CreateWindowEx // menu=%04X instance=%04X classmenu=%08X !\n", menu, instance, classPtr->wc.lpszMenuName); @@ -505,11 +480,12 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, else CURSOR_SetWinCursor( hwnd, LoadCursor( 0, IDC_ARROW )); EVENT_RegisterWindow( wndPtr->window, hwnd ); - EVENT_RegisterWindow( wndPtr->icon, hwnd ); WIN_SendParentNotify( hwnd, WM_CREATE, MAKELONG( hwnd, wndPtr->wIDmenu ) ); if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW ); +/* if (style & WS_MINIMIZE) ShowWindow( hwnd, SW_MINIMIZE ); */ + #ifdef DEBUG_WIN printf( "CreateWindowEx: return %04X \n", hwnd); #endif @@ -805,6 +781,27 @@ HWND GetParent(HWND hwnd) return wndPtr->hwndParent; } +/***************************************************************** + * SetParent (USER.233) + */ +HWND SetParent(HWND hwndChild, HWND hwndNewParent) +{ + HWND temp; + + WND *wndPtr = WIN_FindWndPtr(hwndChild); + if (!wndPtr || !(wndPtr->dwStyle & WS_CHILD)) return 0; + + temp = wndPtr->hwndParent; + + if (hwndNewParent) + wndPtr->hwndParent = hwndNewParent; + else + wndPtr->hwndParent = GetDesktopWindow(); + + return temp; +} + + /******************************************************************* * IsChild (USER.48) diff --git a/windows/winpos.c b/windows/winpos.c index 8e013e73829..a9415cdfde6 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -10,9 +10,12 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "user.h" #include "win.h" #include "message.h" +#include static HWND hwndActive = 0; /* Currently active window */ +/* #define DEBUG_WIN /**/ + /*********************************************************************** * GetWindowRect (USER.32) @@ -220,6 +223,45 @@ BOOL MoveWindow( HWND hwnd, short x, short y, short cx, short cy, BOOL repaint) } +/* + * hwnd is the handle to the first child window to hide + */ +static void WINPOS_hideChildren(HWND hwnd) +{ + WND *wndPtr; + + while (hwnd) { + ShowWindow(hwnd, SW_HIDE); + wndPtr = WIN_FindWndPtr(hwnd); + assert(wndPtr); + WINPOS_hideChildren(wndPtr->hwndChild); + hwnd = wndPtr->hwndNext; + } +} + + +static void WINPOS_ChildrenComeOutToPlay(HWND hwnd) +{ + WND *wndPtr; + + while (hwnd) { + /* + * we shouldn't really be calling SW_SHOWNOACTIVATE + * here because we wake up all windows, even the ones + * the user has decided to iconify or hide + * + * have to use SHOWNOACTIVATE instead of SHOWNORMAL + * since we are traversing the window tree and don't + * want windows linked/unlined under us + */ + ShowWindow(hwnd, SW_SHOWNOACTIVATE); + wndPtr = WIN_FindWndPtr(hwnd); + assert(wndPtr); + WINPOS_ChildrenComeOutToPlay(wndPtr->hwndChild); + hwnd = wndPtr->hwndNext; + } +} + /*********************************************************************** * ShowWindow (USER.42) */ @@ -227,41 +269,72 @@ BOOL ShowWindow( HWND hwnd, int cmd ) { WND * wndPtr = WIN_FindWndPtr( hwnd ); BOOL wasVisible; + BOOL wasIconic; int swpflags = 0; + if (!wndPtr) return FALSE; + #ifdef DEBUG_WIN printf("ShowWindow: hwnd=%04X, cmd=%d\n", hwnd, cmd); #endif - - if (!wndPtr) return FALSE; + + /* + * wasVisible is true if user has not made window invisible + * wasIconic is true if the window is not iconified + */ wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0; + switch(cmd) { case SW_HIDE: - if (!wasVisible) return FALSE; /* Nothing to do */ + /* + * if the window wasn't visible to begin with -- just return + */ + if (!wasVisible) + return FALSE; /* Nothing to do */ swpflags |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER; break; + case SW_SHOWMINNOACTIVE: case SW_SHOWMINIMIZED: - case SW_SHOWMAXIMIZED: - case SW_MINIMIZE: + case SW_MINIMIZE: wndPtr->dwStyle |= WS_MINIMIZE; swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER; + + /* + * tell children that they are getting hidden + */ + WINPOS_hideChildren(wndPtr->hwndChild); + + /* store the size and position of the window, so we can + * deiconify it to the same size and position + */ + wndPtr->rectNormal = wndPtr->rectWindow; + wndPtr->ptIconPos.x = wndPtr->rectWindow.left; + wndPtr->ptIconPos.y = wndPtr->rectWindow.top; + /* move the window to icon size and position and + * tell it that it is going to have to be painted + */ + MoveWindow(hwnd, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y, + wndPtr->iconWidth, wndPtr->iconHeight, FALSE); + SendMessage(hwnd, WM_PAINTICON, 0, 0); break; + case SW_SHOWNA: - case SW_MAXIMIZE: + case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE: */ case SW_SHOW: swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE; break; - case SW_NORMAL: - case SW_SHOWNORMAL: + + case SW_SHOWNORMAL: /* same as SW_NORMAL: */ case SW_SHOWNOACTIVATE: case SW_RESTORE: + wasIconic = IsIconic(hwnd); wndPtr->dwStyle &= ~WS_MINIMIZE; wndPtr->dwStyle &= ~WS_MAXIMIZE; swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE; @@ -270,8 +343,17 @@ BOOL ShowWindow( HWND hwnd, int cmd ) swpflags |= SWP_NOZORDER; if (GetActiveWindow()) swpflags |= SWP_NOACTIVATE; } + if (wasIconic) { + MoveWindow(hwnd, wndPtr->rectNormal.left, + wndPtr->rectNormal.top, + wndPtr->rectNormal.right - wndPtr->rectNormal.left, + wndPtr->rectNormal.bottom - wndPtr->rectNormal.top, + FALSE); + } + WINPOS_ChildrenComeOutToPlay(wndPtr->hwndChild); break; } + SendMessage( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 ); SetWindowPos( hwnd, 0, 0, 0, 0, 0, swpflags ); @@ -288,6 +370,7 @@ BOOL ShowWindow( HWND hwnd, int cmd ) SendMessage( hwnd, WM_MOVE, 0, MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) ); } + return wasVisible; }