Release 940912
Thu Aug 25 15:24:36 EDT 1994 <jrichard@cs.uml.edu>
* [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 <t.d.g.sandford@bradford.ac.uk>
* [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).
diff --git a/ChangeLog b/ChangeLog
index e7dfebd..1e09a06 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,140 @@
----------------------------------------------------------------------
+Thu Aug 25 15:24:36 EDT 1994 <jrichard@cs.uml.edu>
+
+ * [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 <t.d.g.sandford@bradford.ac.uk>
+
+ * [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 <erik@hacktic.nl>
* [misc/file.c]
diff --git a/controls/button.c b/controls/button.c
index a5d3946..7e2d99e 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -12,15 +12,19 @@
#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 @@
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 @@
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 @@
(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 @@
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 @@
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 @@
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 @@
SelectObject(hDC, (HANDLE)hOldPen);
SelectObject(hDC, (HANDLE)hOldBrush);
- DeleteObject((HANDLE)rgn1);
- DeleteObject((HANDLE)rgn2);
DeleteObject((HANDLE)rgn);
}
@@ -404,18 +337,16 @@
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 @@
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 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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
(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 @@
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 @@
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);
- rc.top = 5;
- Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
+ 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.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 @@
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 @@
}
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 @@
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 @@
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 @@
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 e1f5d7f..4045177 100644
--- a/controls/desktop.c
+++ b/controls/desktop.c
@@ -8,11 +8,15 @@
#include <fcntl.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#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 @@
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 @@
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 0f791c7..16e515d 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -38,6 +38,9 @@
/* 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 @@
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 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 @@
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 @@
*
* 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 @@
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 @@
/* 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 @@
*
* 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 @@
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 @@
*
* 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 @@
lppop->Height = 0;
maxY = lprect->top;
start = 0;
+ helpPos = -1;
while (start < lppop->nItems)
{
lpitem = &items[start];
@@ -352,9 +392,10 @@
/* 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 @@
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 @@
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 @@
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 @@
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;
}
- else DrawText( hdc, lpitem->item_text, -1, &rect,
- DT_LEFT | DT_VCENTER | DT_SINGLELINE );
+
+ 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 );
+ }
}
}
@@ -535,18 +593,20 @@
*
* 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 @@
}
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 @@
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_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 @@
{
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 @@
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 @@
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 @@
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 409fd03..5d71bc9 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -12,7 +12,7 @@
#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 @@
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 @@
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 @@
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 c6866c6..104b135 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -40,7 +40,7 @@
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 @@
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 cc922a0..4f25af0 100644
--- a/if1632/Imakefile
+++ b/if1632/Imakefile
@@ -72,5 +72,5 @@
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 b39fef7..a4665f8 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -54,7 +54,7 @@
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 371b3d7..6798d12 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -241,7 +241,7 @@
#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 0000000..44c0363
--- /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 1920d07..b86d508 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -8,6 +8,7 @@
#define GDI_H
#include <X11/Xlib.h>
+#include <X11/Xutil.h>
#include "windows.h"
#include "segmem.h"
@@ -32,6 +33,7 @@
WORD type;
RECT box;
Pixmap pixmap;
+ Region xrgn;
} REGION;
typedef struct tagGDIOBJHDR
diff --git a/include/menu.h b/include/menu.h
index 2e0f7ca..fad8bb1 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 e5443f1..e2b6450 100644
--- a/include/msdos.h
+++ b/include/msdos.h
@@ -14,6 +14,18 @@
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 3caf1fd..e8bed9f 100644
--- a/include/options.h
+++ b/include/options.h
@@ -13,8 +13,8 @@
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 afe7741..c5b03c6 100644
--- a/include/segmem.h
+++ b/include/segmem.h
@@ -55,7 +55,7 @@
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 1c3fcc8..22290dd 100644
--- a/include/win.h
+++ b/include/win.h
@@ -42,19 +42,20 @@
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 711210a..5443498 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1513,6 +1513,8 @@
#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 @@
#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 c2faab8..03711aa 100644
--- a/loader/selector.c
+++ b/loader/selector.c
@@ -156,19 +156,23 @@
* 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 @@
*/
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 @@
else
{
memset(s_new, 0, sizeof(*s_new));
+#ifdef HAVE_IPC
+ s_new->shm_key = -1;
+#endif
SelectorMap[i_new] = i_new;
}
@@ -401,6 +410,19 @@
}
/**********************************************************************
+ * 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
*/
WORD FreeSelector(WORD sel)
@@ -417,10 +439,11 @@
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 @@
shmctl(s->shm_key, IPC_RMID, NULL);
memset(s, 0, sizeof(*s));
+ s->shm_key = -1;
SelectorMap[sel_idx] = 0;
}
@@ -521,12 +545,17 @@
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 @@
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 db2293d..0551a6a 100644
--- a/misc/file.c
+++ b/misc/file.c
@@ -173,7 +173,7 @@
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 4479cdc..623c6ed 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -52,7 +52,7 @@
NULL, /* programName */
FALSE, /* usePrivateMap */
FALSE, /* synchronous */
- FALSE, /* no backing store */
+ FALSE, /* backing store */
SW_SHOWNORMAL, /* cmdShow */
FALSE
};
@@ -60,6 +60,7 @@
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 @@
{ "-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 @@
" -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 @@
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 @@
sync_profiles();
MAIN_RestoreSetup();
WSACleanup();
+ CleanupSelectors();
}
/***********************************************************************
diff --git a/miscemu/int21.c b/miscemu/int21.c
index 5ed34e0..7596aa4 100644
--- a/miscemu/int21.c
+++ b/miscemu/int21.c
@@ -841,31 +841,70 @@
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 cd4f623..93b0e4a 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -13,6 +13,7 @@
#include "bitmap.h"
/* Include OEM bitmaps */
+#include "bitmaps/check_boxes"
#include "bitmaps/check_mark"
#include "bitmaps/menu_arrow"
@@ -64,7 +65,7 @@
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 @@
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 a5240ff..9675b9c 100644
--- a/objects/clipping.c
+++ b/objects/clipping.c
@@ -21,7 +21,12 @@
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 afe4dd4..74ec57b 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 <stdlib.h>
#include <stdio.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
+
#include "gdi.h"
/* GC used for region operations */
@@ -26,11 +25,11 @@
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;
@@ -38,12 +37,34 @@
/***********************************************************************
+ * 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 @@
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 @@
*/
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 @@
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 CreateRectRgnIndirect( LPRECT rect )
{
- RGNOBJ * rgnObj;
HRGN hrgn;
#ifdef DEBUG_REGION
@@ -145,24 +179,11 @@
/* 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 @@
/* 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 @@
{
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 @@
/* 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 @@
/* 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 @@
{
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 @@
{
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 @@
*/
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 @@
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 @@
{
RGNOBJ *obj1, *obj2;
XImage *image1, *image2;
+ Pixmap pixmap1, pixmap2;
int width, height, x, y;
/* Compare bounding boxes */
@@ -461,19 +483,27 @@
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 @@
{
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 @@
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 @@
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 @@
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 58216b4..2148af1 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -183,25 +183,6 @@
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 @@
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 12443b1..071e681 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -44,6 +44,7 @@
strcpy( textPtr, text );
}
+#include <assert.h>
/***********************************************************************
* DefWindowProc (USER.107)
@@ -75,13 +76,10 @@
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 @@
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 7b28b2d..eeb5311 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -78,12 +78,14 @@
*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 @@
/* 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 @@
#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, 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 4b6b3fd..a1dd581 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -252,13 +252,6 @@
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 089e3cc..b3c9307 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -18,6 +18,8 @@
#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 @@
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;
@@ -552,6 +558,20 @@
/***********************************************************************
+ * 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)
*/
void DrawFocusRect( HDC hdc, LPRECT rc )
@@ -583,6 +603,44 @@
/**********************************************************************
+ * 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)
*/
void DrawReliefRect( HDC hdc, RECT rect, int thickness, BOOL pressed )
diff --git a/windows/icon.c b/windows/icon.c
index ba7d94d..8b13789 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 80dd6d7..66a511e 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 @@
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 @@
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 @@
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 fdac135..6d7a21a 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -198,6 +198,7 @@
* 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 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 @@
(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 @@
}
+/***********************************************************************
+ * 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 @@
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 @@
* 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 @@
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 @@
}
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 @@
}
/* 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 @@
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 @@
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)
{
- fd_set read_set;
- struct timeval timeout;
- int fd = ConnectionNumber(display);
- FD_ZERO( &read_set );
- FD_SET( fd, &read_set );
+ 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))
+ {
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 @@
(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 2bb188e..5909530 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -30,12 +30,15 @@
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 @@
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 @@
/***********************************************************************
- * 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 );
@@ -302,39 +323,18 @@
/***********************************************************************
- * 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
*/
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 @@
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 @@
{
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 @@
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 @@
{
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 @@
}
-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 @@
CURSOR_SetWinCursor( hwnd, classPtr->wc.hCursor );
return TRUE;
}
+ else return FALSE;
}
- break;
case HTLEFT:
case HTRIGHT:
@@ -830,7 +798,7 @@
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 @@
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 @@
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 @@
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_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 @@
break;
case SC_MINIMIZE:
- ICON_Iconify( hwnd );
- /*ShowWindow( hwnd, SW_MINIMIZE );*/
+ ShowWindow( hwnd, SW_MINIMIZE );
break;
case SC_MAXIMIZE:
@@ -1256,7 +1233,6 @@
break;
case SC_RESTORE:
- ICON_Deiconify(hwnd);
ShowWindow( hwnd, SW_RESTORE );
break;
diff --git a/windows/painting.c b/windows/painting.c
index abac9b5..8c5658c 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -98,6 +98,14 @@
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 641bbe0..6aad7ac 100644
--- a/windows/timer.c
+++ b/windows/timer.c
@@ -134,7 +134,25 @@
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 3924908..2c27a76 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -251,8 +251,7 @@
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 @@
/* 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 @@
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 @@
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 @@
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 @@
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 8e013e7..a9415cd 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -10,9 +10,12 @@
#include "user.h"
#include "win.h"
#include "message.h"
+#include <assert.h>
static HWND hwndActive = 0; /* Currently active window */
+/* #define DEBUG_WIN /**/
+
/***********************************************************************
* GetWindowRect (USER.32)
@@ -220,6 +223,45 @@
}
+/*
+ * 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 @@
{
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 @@
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 @@
SendMessage( hwnd, WM_MOVE, 0,
MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
}
+
return wasVisible;
}