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).
This commit is contained in:
Alexandre Julliard 1994-09-16 09:24:37 +00:00
parent 3f2abfaa0a
commit 940d58c201
37 changed files with 1348 additions and 1171 deletions

136
ChangeLog
View File

@ -1,3 +1,139 @@
----------------------------------------------------------------------
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> Tue Aug 9 23:58:29 MET DST 1994 <erik@hacktic.nl>

View File

@ -12,15 +12,19 @@ static char Copyright2[] = "Copyright David Metcalfe, 1993";
#include "user.h" #include "user.h"
#include "syscolor.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) \ #define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \
SendMessage(GetParent(hWndCntrl), WM_COMMAND, \ SendMessage(GetParent(hWndCntrl), WM_COMMAND, \
GetDlgCtrlID(hWndCntrl), MAKELPARAM(hWndCntrl, wNotifyCode)); GetDlgCtrlID(hWndCntrl), MAKELPARAM(hWndCntrl, wNotifyCode));
#define DIM(array) ((sizeof array)/(sizeof array[0])) #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_Paint(HWND hWnd);
static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam); static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam); static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
@ -54,136 +58,60 @@ static LONG OB_KillFocus(HWND hWnd);
typedef struct typedef struct
{ {
LONG (*paintfn)(); LONG (*paintfn)( HWND );
LONG (*lButtonDownfn)(); LONG (*lButtonDownfn)( HWND, WORD, LONG );
LONG (*lButtonUpfn)(); LONG (*lButtonUpfn)( HWND, WORD, LONG );
LONG (*lButtonDblClkfn)(); LONG (*lButtonDblClkfn)( HWND, WORD, LONG );
LONG (*killFocusfn)(); LONG (*killFocusfn)( HWND );
LONG (*setCheckfn)(); LONG (*setCheckfn)( HWND, WORD );
LONG (*getCheckfn)(); LONG (*getCheckfn)( HWND );
} BTNFN; } BTNFN;
#define MAX_BTN_TYPE 12 #define MAX_BTN_TYPE 12
static BTNFN btnfn[MAX_BTN_TYPE] = static BTNFN btnfn[MAX_BTN_TYPE] =
{ {
{ /* BS_PUSHBUTTON */
(LONG(*)())PB_Paint, /* BS_PUSHBUTTON */ { PB_Paint, PB_LButtonDown, PB_LButtonUp, PB_LButtonDblClk,
(LONG(*)())PB_LButtonDown, PB_KillFocus, NULL, NULL },
(LONG(*)())PB_LButtonUp, /* BS_DEFPUSHBUTTON */
(LONG(*)())PB_LButtonDblClk, { PB_Paint, PB_LButtonDown, PB_LButtonUp, PB_LButtonDblClk,
(LONG(*)())PB_KillFocus, PB_KillFocus, NULL, NULL },
(LONG(*)())NULL, /* BS_CHECKBOX */
(LONG(*)())NULL { CB_Paint, CB_LButtonDown, CB_LButtonUp, CB_LButtonDblClk,
}, CB_KillFocus, CB_SetCheck, CB_GetCheck },
{ /* BS_AUTOCHECKBOX */
(LONG(*)())PB_Paint, /* BS_DEFPUSHBUTTON */ { CB_Paint, CB_LButtonDown, CB_LButtonUp, CB_LButtonDblClk,
(LONG(*)())PB_LButtonDown, CB_KillFocus, CB_SetCheck, CB_GetCheck },
(LONG(*)())PB_LButtonUp, /* BS_RADIOBUTTON */
(LONG(*)())PB_LButtonDblClk, { RB_Paint, RB_LButtonDown, RB_LButtonUp, RB_LButtonDblClk,
(LONG(*)())PB_KillFocus, RB_KillFocus, RB_SetCheck, RB_GetCheck },
(LONG(*)())NULL, /* BS_3STATE */
(LONG(*)())NULL { CB_Paint, CB_LButtonDown, CB_LButtonUp, CB_LButtonDblClk,
}, CB_KillFocus, CB_SetCheck, CB_GetCheck },
{ /* BS_AUTO3STATE */
(LONG(*)())CB_Paint, /* BS_CHECKBOX */ { CB_Paint, CB_LButtonDown, CB_LButtonUp, CB_LButtonDblClk,
(LONG(*)())CB_LButtonDown, CB_KillFocus, CB_SetCheck, CB_GetCheck },
(LONG(*)())CB_LButtonUp, /* BS_GROUPBOX */
(LONG(*)())CB_LButtonDblClk, { GB_Paint, NULL, NULL, NULL, NULL, NULL, NULL },
(LONG(*)())CB_KillFocus, /* BS_USERBUTTON */
(LONG(*)())CB_SetCheck, { UB_Paint, UB_LButtonDown, UB_LButtonUp, NULL, UB_KillFocus, NULL, NULL },
(LONG(*)())CB_GetCheck /* BS_AUTORADIOBUTTON */
}, { RB_Paint, RB_LButtonDown, RB_LButtonUp, RB_LButtonDblClk,
{ RB_KillFocus, RB_SetCheck, RB_GetCheck },
(LONG(*)())CB_Paint, /* BS_AUTOCHECKBOX */ /* Not defined */
(LONG(*)())CB_LButtonDown, { NULL, NULL, NULL, NULL, NULL, NULL, NULL },
(LONG(*)())CB_LButtonUp, /* BS_OWNERDRAW */
(LONG(*)())CB_LButtonDblClk, { OB_Paint, OB_LButtonDown, OB_LButtonUp, NULL, OB_KillFocus, NULL, NULL }
(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
},
}; };
static HBITMAP hbitmapCheckBoxes = 0;
static WORD checkBoxWidth = 0, checkBoxHeight = 0;
LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam) LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam)
{ {
LONG lResult = 0; LONG lResult = 0;
HDC hDC;
RECT rc;
WND *wndPtr = WIN_FindWndPtr(hWnd); WND *wndPtr = WIN_FindWndPtr(hWnd);
LONG style = wndPtr->dwStyle & 0x0000000F; LONG style = wndPtr->dwStyle & 0x0000000F;
@ -197,12 +125,20 @@ LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam)
break; break;
case WM_CREATE: 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)) if (style < 0L || style >= (LONG)DIM(btnfn))
lResult = -1L; lResult = -1L;
else else
{ {
(WORD)(*(wndPtr->wExtra)) = 0; (WORD)(*(wndPtr->wExtra)) = 0;
pressed = FALSE;
lResult = 0L; lResult = 0L;
} }
break; break;
@ -227,6 +163,12 @@ LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam)
(btnfn[style].lButtonDblClkfn)(hWnd, wParam, lParam); (btnfn[style].lButtonDblClkfn)(hWnd, wParam, lParam);
break; break;
case WM_SETTEXT:
DEFWND_SetText( hWnd, (LPSTR)lParam );
InvalidateRect( hWnd, NULL, FALSE );
UpdateWindow( hWnd );
return 0;
case WM_SETFOCUS: case WM_SETFOCUS:
break; break;
@ -270,76 +212,71 @@ static LONG PB_Paint(HWND hWnd)
hDC = BeginPaint(hWnd, &ps); hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc); GetClientRect(hWnd, &rc);
if (pressed) if (GetCapture() == hWnd)
DrawPressedPushButton(hDC, hWnd, rc); DrawPressedPushButton(hDC, hWnd, rc);
else else
DrawRaisedPushButton(hDC, hWnd, rc); DrawRaisedPushButton(hDC, hWnd, rc);
EndPaint(hWnd, &ps); EndPaint(hWnd, &ps);
return 0;
} }
static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam) static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
{ {
SetFocus(hWnd); SetFocus(hWnd);
SetCapture(hWnd); SetCapture(hWnd);
pressed = TRUE;
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
return 0;
} }
static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
{ {
RECT rc; RECT rc;
pressed = FALSE;
ReleaseCapture(); ReleaseCapture();
GetClientRect(hWnd, &rc); GetClientRect(hWnd, &rc);
if (PtInRect(&rc, MAKEPOINT(lParam))) if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_CLICKED); NOTIFY_PARENT(hWnd, BN_CLICKED);
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
return 0;
} }
static LONG PB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam) 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) static LONG PB_KillFocus(HWND hWnd)
{ {
pressed = FALSE;
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
return 0;
} }
static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc) static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc)
{ {
HPEN hOldPen; HPEN hOldPen;
HBRUSH hOldBrush; HBRUSH hOldBrush;
HRGN rgn1, rgn2, rgn; HRGN rgn;
int len; int len;
static char text[50+1]; char *text;
POINT points[6]; POINT points[6];
DWORD dwTextSize; DWORD dwTextSize;
int delta; int delta;
TEXTMETRIC tm; TEXTMETRIC tm;
WND *wndPtr = WIN_FindWndPtr( hButton );
hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowFrame); hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowFrame);
hOldBrush = (HBRUSH)SelectObject(hDC, sysColorObjects.hbrushBtnFace); hOldBrush = (HBRUSH)SelectObject(hDC, sysColorObjects.hbrushBtnFace);
SetBkMode(hDC, TRANSPARENT); SetBkMode(hDC, TRANSPARENT);
SetTextColor( hDC, GetSysColor(COLOR_BTNTEXT) );
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));
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom); Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
/* draw button label, if any: */ /* draw button label, if any: */
len = GetWindowText(hButton, text, sizeof text); text = USER_HEAP_ADDR( wndPtr->hText );
len = strlen(text);
if (len >= 1) { if (len >= 1) {
rc.left--; rc.bottom--; rc.left--; rc.bottom--;
DrawText(hDC, text, len, &rc, DrawText(hDC, text, len, &rc,
@ -359,9 +296,8 @@ static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc)
points[4].y = rc.top+1; points[4].y = rc.top+1;
points[5].x = rc.left+2; points[5].x = rc.left+2;
points[5].y = rc.top+1; points[5].y = rc.top+1;
rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE); rgn = CreatePolygonRgn(points, DIM(points), ALTERNATE);
CombineRgn(rgn, rgn1, rgn2, RGN_AND); FillRgn(hDC, rgn, sysColorObjects.hbrushBtnHighlight);
FillRgn(hDC, rgn2, sysColorObjects.hbrushBtnHighlight);
/* draw button shadow: */ /* draw button shadow: */
points[0].x = rc.left+2; points[0].x = rc.left+2;
@ -376,9 +312,8 @@ static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc)
points[4].y = rc.top; points[4].y = rc.top;
points[5].x = rc.right-1; points[5].x = rc.right-1;
points[5].y = rc.bottom; points[5].y = rc.bottom;
rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE); rgn = CreatePolygonRgn(points, DIM(points), ALTERNATE);
CombineRgn(rgn, rgn1, rgn2, RGN_AND); FillRgn(hDC, rgn, sysColorObjects.hbrushBtnShadow);
FillRgn(hDC, rgn2, sysColorObjects.hbrushBtnShadow);
/* do we have the focus? */ /* do we have the focus? */
if (len >= 1 && GetFocus() == hButton) { if (len >= 1 && GetFocus() == hButton) {
@ -393,8 +328,6 @@ static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc)
SelectObject(hDC, (HANDLE)hOldPen); SelectObject(hDC, (HANDLE)hOldPen);
SelectObject(hDC, (HANDLE)hOldBrush); SelectObject(hDC, (HANDLE)hOldBrush);
DeleteObject((HANDLE)rgn1);
DeleteObject((HANDLE)rgn2);
DeleteObject((HANDLE)rgn); DeleteObject((HANDLE)rgn);
} }
@ -404,18 +337,16 @@ static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc)
HPEN hOldPen; HPEN hOldPen;
HBRUSH hOldBrush; HBRUSH hOldBrush;
int len; int len;
static char text[50+1]; char *text;
DWORD dwTextSize; DWORD dwTextSize;
int delta; int delta;
TEXTMETRIC tm; TEXTMETRIC tm;
WND *wndPtr = WIN_FindWndPtr( hButton );
hOldBrush = (HBRUSH)SelectObject(hDC, sysColorObjects.hbrushBtnFace); hOldBrush = (HBRUSH)SelectObject(hDC, sysColorObjects.hbrushBtnFace);
hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowFrame); hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowFrame);
SetBkMode(hDC, TRANSPARENT); SetBkMode(hDC, TRANSPARENT);
SetTextColor( hDC, GetSysColor(COLOR_BTNTEXT) );
/* give parent a chance to alter parameters: */
SendMessage(GetParent(hButton), WM_CTLCOLOR, (WORD)hDC,
MAKELPARAM(hButton, CTLCOLOR_BTN));
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom); Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
/* draw button shadow: */ /* draw button shadow: */
@ -424,7 +355,8 @@ static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc)
PatBlt(hDC, rc.left+1, rc.top+1, rc.right-rc.left-2, 1, PATCOPY ); PatBlt(hDC, rc.left+1, rc.top+1, rc.right-rc.left-2, 1, PATCOPY );
/* draw button label, if any: */ /* draw button label, if any: */
len = GetWindowText(hButton, text, sizeof text); text = USER_HEAP_ADDR( wndPtr->hText );
len = strlen(text);
if (len >= 1) { if (len >= 1) {
rc.top++; rc.left++; rc.top++; rc.left++;
DrawText(hDC, text, len, &rc, DrawText(hDC, text, len, &rc,
@ -454,13 +386,11 @@ static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc)
static LONG CB_Paint(HWND hWnd) static LONG CB_Paint(HWND hWnd)
{ {
PAINTSTRUCT ps; PAINTSTRUCT ps;
RECT rc, rc3; RECT rc;
HDC hDC; HDC hDC;
HPEN hOldPen; HBRUSH hBrush;
HBRUSH hBrush, hGrayBrush;
int textlen, delta; int textlen, delta;
char *text; char *text;
HANDLE hText;
TEXTMETRIC tm; TEXTMETRIC tm;
SIZE size; SIZE size;
WND *wndPtr = WIN_FindWndPtr(hWnd); WND *wndPtr = WIN_FindWndPtr(hWnd);
@ -468,44 +398,23 @@ static LONG CB_Paint(HWND hWnd)
hDC = BeginPaint(hWnd, &ps); hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc); GetClientRect(hWnd, &rc);
hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowText);
hGrayBrush = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC, hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
MAKELPARAM(hWnd, CTLCOLOR_BTN)); MAKELPARAM(hWnd, CTLCOLOR_BTN));
FillRect(hDC, &rc, hBrush); FillRect(hDC, &rc, hBrush);
textlen = GetWindowTextLength(hWnd); text = USER_HEAP_ADDR( wndPtr->hText );
hText = USER_HEAP_ALLOC(0, textlen+1); textlen = strlen( text );
text = USER_HEAP_ADDR(hText);
GetWindowText(hWnd, text, textlen+1);
GetTextMetrics(hDC, &tm); GetTextMetrics(hDC, &tm);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1; 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))) GRAPH_DrawBitmap( hDC, hbitmapCheckBoxes,
{ rc.left, rc.top + delta,
case 1: ((GetCapture() == hWnd) ? 2*checkBoxWidth : 0) +
MoveTo(hDC, 0, rc.top + delta); (wndPtr->wExtra[0] ? checkBoxWidth : 0),
LineTo(hDC, tm.tmHeight - 1, tm.tmHeight + delta - 1); ((wndPtr->wExtra[0] == 2) ? 2*checkBoxHeight : 0),
MoveTo(hDC, 0, tm.tmHeight + delta - 1); checkBoxWidth, checkBoxHeight, SRCCOPY );
LineTo(hDC, tm.tmHeight - 1, rc.top + delta);
break;
case 2: rc.left = checkBoxWidth + tm.tmAveCharWidth / 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;
DrawText(hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER); DrawText(hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER);
/* do we have the focus? */ /* do we have the focus? */
@ -519,53 +428,30 @@ static LONG CB_Paint(HWND hWnd)
DrawFocusRect(hDC, &rc); DrawFocusRect(hDC, &rc);
} }
SelectObject(hDC, hOldPen);
USER_HEAP_FREE(hText);
EndPaint(hWnd, &ps); EndPaint(hWnd, &ps);
return 0;
} }
static LONG CB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam) static LONG CB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
{ {
RECT rc; RECT rc;
HDC hDC;
TEXTMETRIC tm;
int delta;
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
ReleaseDC(hWnd, hDC);
GetClientRect(hWnd, &rc); 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); SetFocus(hWnd);
SetCapture(hWnd); SetCapture(hWnd);
pressed = TRUE;
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
} return 0;
} }
static LONG CB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) static LONG CB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
{ {
RECT rc; RECT rc;
HDC hDC;
TEXTMETRIC tm;
int delta;
WND *wndPtr = WIN_FindWndPtr(hWnd); WND *wndPtr = WIN_FindWndPtr(hWnd);
LONG style; LONG style;
pressed = FALSE;
ReleaseCapture(); ReleaseCapture();
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
ReleaseDC(hWnd, hDC);
GetClientRect(hWnd, &rc); GetClientRect(hWnd, &rc);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
rc.top += delta;
rc.bottom = tm.tmHeight + delta;
if (PtInRect(&rc, MAKEPOINT(lParam))) if (PtInRect(&rc, MAKEPOINT(lParam)))
{ {
@ -604,31 +490,20 @@ static LONG CB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
} }
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
return 0;
} }
static LONG CB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam) 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) static LONG CB_KillFocus(HWND hWnd)
{ {
pressed = FALSE;
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
return 0;
} }
static LONG CB_SetCheck(HWND hWnd, WORD wParam) static LONG CB_SetCheck(HWND hWnd, WORD wParam)
@ -637,10 +512,14 @@ static LONG CB_SetCheck(HWND hWnd, WORD wParam)
if ((WORD)(*(wndPtr->wExtra)) != wParam) if ((WORD)(*(wndPtr->wExtra)) != wParam)
{ {
RECT rect;
GetClientRect( hWnd, &rect );
rect.right = rect.left + checkBoxWidth; /* Only invalidate check-box */
(WORD)(*(wndPtr->wExtra)) = wParam; (WORD)(*(wndPtr->wExtra)) = wParam;
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, &rect, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
} }
return 0;
} }
static LONG CB_GetCheck(HWND hWnd) static LONG CB_GetCheck(HWND hWnd)
@ -662,11 +541,9 @@ static LONG RB_Paint(HWND hWnd)
PAINTSTRUCT ps; PAINTSTRUCT ps;
RECT rc; RECT rc;
HDC hDC; HDC hDC;
HPEN hOldPen; HBRUSH hBrush;
HBRUSH hBrush, hOldBrush;
int textlen, delta; int textlen, delta;
char *text; char *text;
HANDLE hText;
TEXTMETRIC tm; TEXTMETRIC tm;
SIZE size; SIZE size;
WND *wndPtr = WIN_FindWndPtr(hWnd); WND *wndPtr = WIN_FindWndPtr(hWnd);
@ -674,35 +551,21 @@ static LONG RB_Paint(HWND hWnd)
hDC = BeginPaint(hWnd, &ps); hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc); GetClientRect(hWnd, &rc);
hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowText);
hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC, hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
MAKELPARAM(hWnd, CTLCOLOR_BTN)); MAKELPARAM(hWnd, CTLCOLOR_BTN));
FillRect(hDC, &rc, hBrush); 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); GetTextMetrics(hDC, &tm);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1; delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
Ellipse(hDC, 0, rc.top + delta, tm.tmHeight, tm.tmHeight + delta); GRAPH_DrawBitmap( hDC, hbitmapCheckBoxes,
if (pressed) rc.left, rc.top + delta,
Ellipse(hDC, 1, rc.top + delta + 1, tm.tmHeight - 1, ((GetCapture() == hWnd) ? 2*checkBoxWidth : 0) +
tm.tmHeight + delta - 1); (wndPtr->wExtra[0] ? checkBoxWidth : 0), checkBoxHeight,
checkBoxWidth, checkBoxHeight, SRCCOPY );
if ((WORD)(*(wndPtr->wExtra)) == 1) text = USER_HEAP_ADDR( wndPtr->hText );
{ textlen = strlen( text );
hBrush = CreateSolidBrush( GetNearestColor(hDC, GetSysColor(COLOR_WINDOWTEXT))); rc.left = checkBoxWidth + tm.tmAveCharWidth / 2;
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;
DrawText(hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER); DrawText(hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER);
/* do we have the focus? */ /* do we have the focus? */
@ -716,53 +579,31 @@ static LONG RB_Paint(HWND hWnd)
DrawFocusRect(hDC, &rc); DrawFocusRect(hDC, &rc);
} }
SelectObject(hDC, hOldPen );
USER_HEAP_FREE(hText);
EndPaint(hWnd, &ps); EndPaint(hWnd, &ps);
return 0;
} }
static LONG RB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam) static LONG RB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
{ {
RECT rc; RECT rc;
HDC hDC;
TEXTMETRIC tm;
int delta;
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
ReleaseDC(hWnd, hDC);
GetClientRect(hWnd, &rc); GetClientRect(hWnd, &rc);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1; if (GetFocus() != hWnd) SetFocus(hWnd);
rc.top += delta; else rc.right = rc.left + checkBoxWidth;
rc.bottom = tm.tmHeight + delta;
if (PtInRect(&rc, MAKEPOINT(lParam)))
{
SetFocus(hWnd);
SetCapture(hWnd); SetCapture(hWnd);
pressed = TRUE; InvalidateRect(hWnd, &rc, FALSE);
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
} return 0;
} }
static LONG RB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) static LONG RB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
{ {
RECT rc; RECT rc;
HDC hDC;
TEXTMETRIC tm;
int delta;
WND *wndPtr = WIN_FindWndPtr(hWnd); WND *wndPtr = WIN_FindWndPtr(hWnd);
LONG style; LONG style;
pressed = FALSE;
ReleaseCapture(); ReleaseCapture();
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
ReleaseDC(hWnd, hDC);
GetClientRect(hWnd, &rc); GetClientRect(hWnd, &rc);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
rc.top += delta;
rc.bottom = tm.tmHeight + delta;
if (PtInRect(&rc, MAKEPOINT(lParam))) if (PtInRect(&rc, MAKEPOINT(lParam)))
{ {
@ -771,33 +612,24 @@ static LONG RB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
(WORD)(*(wndPtr->wExtra)) = 1; (WORD)(*(wndPtr->wExtra)) = 1;
NOTIFY_PARENT(hWnd, BN_CLICKED); NOTIFY_PARENT(hWnd, BN_CLICKED);
} }
InvalidateRect(hWnd, NULL, FALSE); rc.right = rc.left + checkBoxWidth;
InvalidateRect(hWnd, &rc, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
return 0;
} }
static LONG RB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam) 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) static LONG RB_KillFocus(HWND hWnd)
{ {
pressed = FALSE;
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
return 0;
} }
static LONG RB_SetCheck(HWND hWnd, WORD wParam) static LONG RB_SetCheck(HWND hWnd, WORD wParam)
@ -806,10 +638,14 @@ static LONG RB_SetCheck(HWND hWnd, WORD wParam)
if ((WORD)(*(wndPtr->wExtra)) != wParam) if ((WORD)(*(wndPtr->wExtra)) != wParam)
{ {
RECT rc;
GetClientRect( hWnd, &rc );
rc.right = rc.left + checkBoxWidth;
(WORD)(*(wndPtr->wExtra)) = wParam; (WORD)(*(wndPtr->wExtra)) = wParam;
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, &rc, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
} }
return 0;
} }
static LONG RB_GetCheck(HWND hWnd) static LONG RB_GetCheck(HWND hWnd)
@ -831,39 +667,38 @@ static LONG GB_Paint(HWND hWnd)
PAINTSTRUCT ps; PAINTSTRUCT ps;
RECT rc; RECT rc;
HDC hDC; HDC hDC;
HPEN hOldPen;
HBRUSH hBrush; HBRUSH hBrush;
int textlen;
char *text; char *text;
HANDLE hText;
SIZE size; SIZE size;
WND *wndPtr = WIN_FindWndPtr( hWnd );
hDC = BeginPaint(hWnd, &ps); hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc); GetClientRect(hWnd, &rc);
hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowText); SelectObject( hDC, sysColorObjects.hpenWindowFrame );
hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC, hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
MAKELPARAM(hWnd, CTLCOLOR_BTN)); MAKELPARAM(hWnd, CTLCOLOR_BTN));
FillRect(hDC, &rc, hBrush); FillRect(hDC, &rc, hBrush);
textlen = GetWindowTextLength(hWnd); text = USER_HEAP_ADDR( wndPtr->hText );
hText = USER_HEAP_ALLOC(0, textlen+1); GetTextExtentPoint(hDC, text, strlen(text), &size);
text = USER_HEAP_ADDR(hText);
GetWindowText(hWnd, text, textlen+1); MoveTo( hDC, 8, 5 );
GetTextExtentPoint(hDC, text, textlen, &size); LineTo( hDC, rc.left, 5 );
LineTo( hDC, rc.left, rc.bottom-1 );
LineTo( hDC, rc.right-1, rc.bottom-1 );
LineTo( hDC, rc.right-1, 5 );
LineTo( hDC, rc.left + size.cx + 12, 5 );
rc.top = 5;
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
rc.left = 10; rc.left = 10;
rc.top = 0; rc.top = 0;
rc.right = rc.left + size.cx + 1; rc.right = rc.left + size.cx + 1;
rc.bottom = size.cy; 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); EndPaint(hWnd, &ps);
return 0;
} }
@ -892,19 +727,16 @@ static LONG UB_Paint(HWND hWnd)
DrawFocusRect(hDC, &rc); DrawFocusRect(hDC, &rc);
EndPaint(hWnd, &ps); EndPaint(hWnd, &ps);
return 0;
} }
static LONG UB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam) static LONG UB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
{ {
RECT rc;
SetFocus(hWnd); SetFocus(hWnd);
SetCapture(hWnd); SetCapture(hWnd);
GetClientRect(hWnd, &rc);
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_HILITE);
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
return 0;
} }
static LONG UB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) static LONG UB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
@ -920,12 +752,14 @@ static LONG UB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
} }
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
return 0;
} }
static LONG UB_KillFocus(HWND hWnd) static LONG UB_KillFocus(HWND hWnd)
{ {
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
return 0;
} }
@ -955,33 +789,31 @@ static LONG OB_Paint(HWND hWnd)
SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis); SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis);
USER_HEAP_FREE(hDis); USER_HEAP_FREE(hDis);
EndPaint(hWnd, &ps); EndPaint(hWnd, &ps);
return 0;
} }
static LONG OB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam) static LONG OB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
{ {
HDC hDC; HDC hDC;
RECT rc;
HANDLE hDis; HANDLE hDis;
LPDRAWITEMSTRUCT lpdis; LPDRAWITEMSTRUCT lpdis;
WND *wndPtr = WIN_FindWndPtr(hWnd); WND *wndPtr = WIN_FindWndPtr(hWnd);
SetFocus(hWnd); SetFocus(hWnd);
SetCapture(hWnd); SetCapture(hWnd);
hDC = GetDC(hWnd); hDC = GetDC(hWnd);
GetClientRect(hWnd, &rc);
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_CLICKED); NOTIFY_PARENT(hWnd, BN_CLICKED);
GetClientRect(hWnd, &rc);
hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT)); hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis); lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
lpdis->hDC = hDC; lpdis->hDC = hDC;
lpdis->itemID = 0; lpdis->itemID = 0;
CopyRect(&lpdis->rcItem, &rc); GetClientRect( hWnd, &lpdis->rcItem );
lpdis->CtlID = wndPtr->wIDmenu; lpdis->CtlID = wndPtr->wIDmenu;
lpdis->CtlType = ODT_BUTTON; lpdis->CtlType = ODT_BUTTON;
lpdis->itemAction = ODA_SELECT; lpdis->itemAction = ODA_SELECT;
SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis); SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis);
USER_HEAP_FREE(hDis); USER_HEAP_FREE(hDis);
ReleaseDC(hWnd, hDC); ReleaseDC(hWnd, hDC);
return 0;
} }
static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
@ -996,7 +828,6 @@ static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
GetClientRect(hWnd, &rc); GetClientRect(hWnd, &rc);
if (PtInRect(&rc, MAKEPOINT(lParam))) if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_CLICKED); NOTIFY_PARENT(hWnd, BN_CLICKED);
GetClientRect(hWnd, &rc);
hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT)); hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis); lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
lpdis->hDC = hDC; lpdis->hDC = hDC;
@ -1008,11 +839,13 @@ static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis); SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis);
USER_HEAP_FREE(hDis); USER_HEAP_FREE(hDis);
ReleaseDC(hWnd, hDC); ReleaseDC(hWnd, hDC);
return 0;
} }
static LONG OB_KillFocus(HWND hWnd) static LONG OB_KillFocus(HWND hWnd)
{ {
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
return 0;
} }

View File

@ -8,11 +8,15 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1994";
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "win.h" #include "win.h"
#include "desktop.h" #include "desktop.h"
#include "prototypes.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 * DESKTOP_LoadBitmap
@ -85,17 +89,15 @@ static LONG DESKTOP_DoEraseBkgnd( HWND hwnd, HDC hdc, DESKTOPINFO *infoPtr )
if (infoPtr->hbitmapWallPaper) if (infoPtr->hbitmapWallPaper)
{ {
int x, y; int x, y;
HDC hdcmem;
hdcmem = CreateCompatibleDC( hdc );
SelectObject( hdcmem, infoPtr->hbitmapWallPaper );
if (infoPtr->fTileWallPaper) if (infoPtr->fTileWallPaper)
{ {
for (y = 0; y < rect.bottom; y += infoPtr->bitmapSize.cy) for (y = 0; y < rect.bottom; y += infoPtr->bitmapSize.cy)
for (x = 0; x < rect.right; x += infoPtr->bitmapSize.cx) for (x = 0; x < rect.right; x += infoPtr->bitmapSize.cx)
BitBlt( hdc, x, y, GRAPH_DrawBitmap( hdc, infoPtr->hbitmapWallPaper,
infoPtr->bitmapSize.cx, infoPtr->bitmapSize.cy, x, y, 0, 0,
hdcmem, 0, 0, SRCCOPY ); infoPtr->bitmapSize.cx,
infoPtr->bitmapSize.cy, SRCCOPY );
} }
else else
{ {
@ -103,10 +105,10 @@ static LONG DESKTOP_DoEraseBkgnd( HWND hwnd, HDC hdc, DESKTOPINFO *infoPtr )
y = (rect.top + rect.bottom - infoPtr->bitmapSize.cy) / 2; y = (rect.top + rect.bottom - infoPtr->bitmapSize.cy) / 2;
if (x < 0) x = 0; if (x < 0) x = 0;
if (y < 0) y = 0; if (y < 0) y = 0;
BitBlt( hdc, x, y, infoPtr->bitmapSize.cx, infoPtr->bitmapSize.cy, GRAPH_DrawBitmap( hdc, infoPtr->hbitmapWallPaper, x, y, 0, 0,
hdcmem, 0, 0, SRCCOPY ); infoPtr->bitmapSize.cx, infoPtr->bitmapSize.cy,
SRCCOPY );
} }
DeleteDC( hdcmem );
} }
return 1; return 1;

View File

@ -38,6 +38,9 @@ static BOOL fEndMenuCalled = FALSE;
/* Space between 2 menu bar items */ /* Space between 2 menu bar items */
#define MENU_BAR_ITEMS_SPACE 16 #define MENU_BAR_ITEMS_SPACE 16
/* Minimum width of a tab character */
#define MENU_TAB_SPACE 8
/* Height of a separator item */ /* Height of a separator item */
#define SEPARATOR_HEIGHT 5 #define SEPARATOR_HEIGHT 5
@ -52,6 +55,9 @@ static BOOL fEndMenuCalled = FALSE;
extern void NC_DrawSysButton(HWND hwnd, HDC hdc, BOOL down); /* nonclient.c */ extern void NC_DrawSysButton(HWND hwnd, HDC hdc, BOOL down); /* nonclient.c */
extern void CURSOR_SetWinCursor( HWND hwnd, HCURSOR hcursor ); /* cursor.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; extern HINSTANCE hSysRes;
@ -59,9 +65,6 @@ static HMENU hSysMenu = 0;
static HBITMAP hStdCheck = 0; static HBITMAP hStdCheck = 0;
static HBITMAP hStdMnArrow = 0; static HBITMAP hStdMnArrow = 0;
WORD GetSelectionKey(LPSTR str);
LPSTR GetShortCutString(LPSTR str);
int GetShortCutPos(LPSTR str);
HMENU CopySysMenu(); HMENU CopySysMenu();
WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu); WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu);
@ -225,9 +228,14 @@ static WORD MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu, WORD key )
menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu ); menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
lpitem = (MENUITEM *) USER_HEAP_ADDR( menu->hItems ); lpitem = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
key = toupper(key);
for (i = 0; i < menu->nItems; i++, lpitem++) 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, menuchar = SendMessage( hwndOwner, WM_MENUCHAR, key,
MAKELONG( menu->wFlags, hmenu ) ); MAKELONG( menu->wFlags, hmenu ) );
@ -242,11 +250,14 @@ static WORD MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu, WORD key )
* *
* Calculate the size of the menu item and store it in lpitem->rect. * 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 ) int orgX, int orgY, BOOL menuBar )
{ {
DWORD dwSize; DWORD dwSize;
char *p;
SetRect( &lpitem->rect, orgX, orgY, orgX, orgY ); SetRect( &lpitem->rect, orgX, orgY, orgX, orgY );
lpitem->xTab = 0;
if (lpitem->item_flags & MF_SEPARATOR) if (lpitem->item_flags & MF_SEPARATOR)
{ {
@ -264,8 +275,7 @@ static void MENU_CalcItemSize( HDC hdc, LPMENUITEM lpitem,
if (lpitem->item_flags & MF_BITMAP) if (lpitem->item_flags & MF_BITMAP)
{ {
BITMAP bm; BITMAP bm;
HBITMAP hbitmap = (HBITMAP)LOWORD((LONG)lpitem->item_text); GetObject( (HBITMAP)lpitem->hText, sizeof(BITMAP), (LPSTR)&bm );
GetObject(hbitmap, sizeof(BITMAP), (LPSTR)&bm);
lpitem->rect.right += bm.bmWidth; lpitem->rect.right += bm.bmWidth;
lpitem->rect.bottom += bm.bmHeight; lpitem->rect.bottom += bm.bmHeight;
return; return;
@ -273,10 +283,26 @@ static void MENU_CalcItemSize( HDC hdc, LPMENUITEM lpitem,
/* If we get here, then it is a text item */ /* 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)); dwSize = GetTextExtent( hdc, lpitem->item_text, strlen(lpitem->item_text));
lpitem->rect.right += LOWORD(dwSize); lpitem->rect.right += LOWORD(dwSize);
lpitem->rect.bottom += max( HIWORD(dwSize), SYSMETRICS_CYMENU ); lpitem->rect.bottom += max( HIWORD(dwSize), SYSMETRICS_CYMENU );
if (menuBar) lpitem->rect.right += MENU_BAR_ITEMS_SPACE;
else if ((p = strchr( lpitem->item_text, '\t' )) != NULL)
{
/* Item contains a tab (only meaningful in popup menus) */
lpitem->xTab = check_bitmap_width + MENU_TAB_SPACE +
LOWORD( GetTextExtent( hdc, lpitem->item_text,
(int)(p - lpitem->item_text) ));
lpitem->rect.right += MENU_TAB_SPACE;
}
else
{
if (strchr( lpitem->item_text, '\b' ))
lpitem->rect.right += MENU_TAB_SPACE;
lpitem->xTab = lpitem->rect.right - check_bitmap_width
- arrow_bitmap_width;
}
} }
@ -285,11 +311,12 @@ static void MENU_CalcItemSize( HDC hdc, LPMENUITEM lpitem,
* *
* Calculate the size of a popup menu. * Calculate the size of a popup menu.
*/ */
static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop ) static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop, HWND hwndOwner )
{ {
LPMENUITEM items, lpitem; LPMENUITEM items, lpitem;
HDC hdc; HDC hdc;
int start, i, orgX, orgY, maxX; int start, i;
int orgX, orgY, maxX, maxTab, maxTabWidth;
lppop->Width = lppop->Height = 0; lppop->Width = lppop->Height = 0;
if (lppop->nItems == 0) return; if (lppop->nItems == 0) return;
@ -301,19 +328,30 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop )
lpitem = &items[start]; lpitem = &items[start];
orgX = maxX; orgX = maxX;
orgY = 0; orgY = 0;
maxTab = maxTabWidth = 0;
/* Parse items until column break or end of menu */ /* Parse items until column break or end of menu */
for (i = start; i < lppop->nItems; i++, lpitem++) for (i = start; i < lppop->nItems; i++, lpitem++)
{ {
if ((i != start) && if ((i != start) &&
(lpitem->item_flags & (MF_MENUBREAK | MF_MENUBARBREAK))) break; (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 ); maxX = max( maxX, lpitem->rect.right );
orgY = lpitem->rect.bottom; 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) */ /* 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 ); lppop->Height = max( lppop->Height, orgY );
} }
@ -327,10 +365,11 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop )
* *
* Calculate the size of the menu bar. * 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; LPMENUITEM lpitem, items;
int start, i, orgX, orgY, maxY; int start, i, orgX, orgY, maxY, helpPos;
if ((lprect == NULL) || (lppop == NULL)) return; if ((lprect == NULL) || (lppop == NULL)) return;
if (lppop->nItems == 0) return; if (lppop->nItems == 0) return;
@ -343,6 +382,7 @@ static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, LPPOPUPMENU lppop )
lppop->Height = 0; lppop->Height = 0;
maxY = lprect->top; maxY = lprect->top;
start = 0; start = 0;
helpPos = -1;
while (start < lppop->nItems) while (start < lppop->nItems)
{ {
lpitem = &items[start]; lpitem = &items[start];
@ -352,9 +392,10 @@ static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, LPPOPUPMENU lppop )
/* Parse items until line break or end of menu */ /* Parse items until line break or end of menu */
for (i = start; i < lppop->nItems; i++, lpitem++) for (i = start; i < lppop->nItems; i++, lpitem++)
{ {
if ((helpPos == -1) && (lpitem->item_flags & MF_HELP)) helpPos = i;
if ((i != start) && if ((i != start) &&
(lpitem->item_flags & (MF_MENUBREAK | MF_MENUBARBREAK))) break; (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 (lpitem->rect.right > lprect->right)
{ {
if (i != start) break; if (i != start) break;
@ -370,6 +411,23 @@ static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, LPPOPUPMENU lppop )
lprect->bottom = maxY; lprect->bottom = maxY;
lppop->Height = lprect->bottom - lprect->top; lppop->Height = lprect->bottom - lprect->top;
/* Flush right all items between the MF_HELP and the last item */
/* (if several lines, only move the last line) */
if (helpPos != -1)
{
lpitem = &items[lppop->nItems-1];
orgY = lpitem->rect.top;
orgX = lprect->right;
for (i = lppop->nItems - 1; i >= helpPos; i--, lpitem--)
{
if (lpitem->rect.top != orgY) break; /* Other line */
if (lpitem->rect.right >= orgX) break; /* Too far right already */
lpitem->rect.left += orgX - lpitem->rect.right;
lpitem->rect.right = orgX;
orgX = lpitem->rect.left;
}
}
} }
@ -406,6 +464,7 @@ static void MENU_DrawMenuItem( HDC hdc, LPMENUITEM lpitem,
SelectObject( hdc, sysColorObjects.hpenWindowFrame ); SelectObject( hdc, sysColorObjects.hpenWindowFrame );
MoveTo( hdc, rect.left, rect.top + SEPARATOR_HEIGHT/2 ); MoveTo( hdc, rect.left, rect.top + SEPARATOR_HEIGHT/2 );
LineTo( hdc, rect.right, rect.top + SEPARATOR_HEIGHT/2 ); LineTo( hdc, rect.right, rect.top + SEPARATOR_HEIGHT/2 );
return;
} }
/* Setup colors */ /* Setup colors */
@ -433,40 +492,29 @@ static void MENU_DrawMenuItem( HDC hdc, LPMENUITEM lpitem,
if (lpitem->item_flags & MF_CHECKED) if (lpitem->item_flags & MF_CHECKED)
{ {
HDC hMemDC = CreateCompatibleDC( hdc ); GRAPH_DrawBitmap(hdc, lpitem->hCheckBit ? lpitem->hCheckBit :
if (lpitem->hCheckBit == 0) SelectObject(hMemDC, hStdCheck); hStdCheck, rect.left,
else SelectObject(hMemDC, lpitem->hCheckBit); (rect.top+rect.bottom-check_bitmap_height) / 2,
BitBlt( hdc, rect.left, 0, 0, check_bitmap_width, check_bitmap_height,
(rect.top + rect.bottom - check_bitmap_height) / 2, SRCCOPY);
check_bitmap_width, check_bitmap_height,
hMemDC, 0, 0, SRCCOPY );
DeleteDC( hMemDC );
} }
else /* Not checked */ else if (lpitem->hUnCheckBit != 0) /* Not checked */
{ {
if (lpitem->hUnCheckBit != 0) GRAPH_DrawBitmap(hdc, lpitem->hUnCheckBit, rect.left,
{ (rect.top+rect.bottom-check_bitmap_height) / 2,
HDC hMemDC = CreateCompatibleDC( hdc ); 0, 0, check_bitmap_width, check_bitmap_height,
SelectObject(hMemDC, lpitem->hUnCheckBit); SRCCOPY);
BitBlt( hdc, rect.left,
(rect.top + rect.bottom - check_bitmap_height) / 2,
check_bitmap_width, check_bitmap_height,
hMemDC, 0, 0, SRCCOPY );
DeleteDC( hMemDC );
}
} }
/* Draw the popup-menu arrow */ /* Draw the popup-menu arrow */
if (lpitem->item_flags & MF_POPUP) if (lpitem->item_flags & MF_POPUP)
{ {
HDC hMemDC = CreateCompatibleDC( hdc ); GRAPH_DrawBitmap( hdc, hStdMnArrow,
SelectObject(hMemDC, hStdMnArrow); rect.right-arrow_bitmap_width-1,
BitBlt( hdc, rect.right-arrow_bitmap_width-1, (rect.top+rect.bottom-arrow_bitmap_height) / 2,
(rect.top + rect.bottom - arrow_bitmap_height) / 2, 0, 0, arrow_bitmap_width, arrow_bitmap_height,
arrow_bitmap_width, arrow_bitmap_height, SRCCOPY );
hMemDC, 0, 0, SRCCOPY );
DeleteDC(hMemDC);
} }
rect.left += check_bitmap_width; rect.left += check_bitmap_width;
@ -477,33 +525,43 @@ static void MENU_DrawMenuItem( HDC hdc, LPMENUITEM lpitem,
if (lpitem->item_flags & MF_BITMAP) if (lpitem->item_flags & MF_BITMAP)
{ {
HBITMAP hbitmap = (HBITMAP)LOWORD((LONG)lpitem->item_text); GRAPH_DrawBitmap( hdc, (HBITMAP)lpitem->hText, rect.left, rect.top,
HDC hMemDC = CreateCompatibleDC( hdc ); 0, 0, rect.right-rect.left, rect.bottom-rect.top,
SelectObject( hMemDC, hbitmap ); SRCCOPY );
BitBlt( hdc, rect.left, rect.top,
rect.right-rect.left, rect.bottom-rect.top,
hMemDC, 0, 0, SRCCOPY );
DeleteDC( hMemDC );
return; return;
} }
/* No bitmap - process text if present */ /* No bitmap - process text if present */
else if ((lpitem->item_text) != ((char *) NULL)) else if ((lpitem->item_text) != ((char *) NULL))
{ {
int x = GetShortCutPos(lpitem->item_text); register int i;
if (menuBar) if (menuBar)
{ {
rect.left += MENU_BAR_ITEMS_SPACE / 2; rect.left += MENU_BAR_ITEMS_SPACE / 2;
rect.right -= 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, for (i = 0; lpitem->item_text[i]; i++)
if ((lpitem->item_text[i] == '\t') ||
(lpitem->item_text[i] == '\b')) break;
}
DrawText( hdc, lpitem->item_text, i, &rect,
DT_LEFT | DT_VCENTER | DT_SINGLELINE ); DT_LEFT | DT_VCENTER | DT_SINGLELINE );
DrawText( hdc, lpitem->item_text + x, -1, &rect,
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 ); DT_RIGHT | DT_VCENTER | DT_SINGLELINE );
} }
else DrawText( hdc, lpitem->item_text, -1, &rect,
DT_LEFT | DT_VCENTER | DT_SINGLELINE );
} }
} }
@ -535,18 +593,20 @@ static void MENU_DrawPopupMenu( HWND hwnd, HDC hdc, HMENU hmenu )
* *
* Paint a menu bar. Returns the height of the menu bar. * 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; LPPOPUPMENU lppop;
LPMENUITEM lpitem; LPMENUITEM lpitem;
int i; int i;
WND *wndPtr = WIN_FindWndPtr( hwnd );
lppop = (LPPOPUPMENU) USER_HEAP_ADDR( hmenu ); lppop = (LPPOPUPMENU) USER_HEAP_ADDR( wndPtr->wIDmenu );
if (lppop == NULL || lprect == NULL) return SYSMETRICS_CYMENU; if (lppop == NULL || lprect == NULL) return SYSMETRICS_CYMENU;
#ifdef DEBUG_MENU #ifdef DEBUG_MENU
printf("MENU_DrawMenuBar(%04X, %08X, %08X); !\n", hDC, lprect, lppop); printf("MENU_DrawMenuBar(%04X, %08X, %08X); !\n", hDC, lprect, lppop);
#endif #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; if (suppress_draw) return lppop->Height;
FillRect(hDC, lprect, sysColorObjects.hbrushMenu ); FillRect(hDC, lprect, sysColorObjects.hbrushMenu );
@ -582,7 +642,7 @@ static BOOL MENU_ShowPopup(HWND hwndOwner, HMENU hmenu, WORD id, int x, int y)
} }
SendMessage( hwndOwner, WM_INITMENUPOPUP, hmenu, SendMessage( hwndOwner, WM_INITMENUPOPUP, hmenu,
MAKELONG( id, (menu->wFlags & MF_POPUP) ? 1 : 0 )); MAKELONG( id, (menu->wFlags & MF_POPUP) ? 1 : 0 ));
MENU_PopupMenuCalcSize( menu ); MENU_PopupMenuCalcSize( menu, hwndOwner );
if (!menu->hWnd) if (!menu->hWnd)
{ {
WND *wndPtr = WIN_FindWndPtr( hwndOwner ); WND *wndPtr = WIN_FindWndPtr( hwndOwner );
@ -1302,8 +1362,10 @@ static BOOL MENU_TrackMenu( HMENU hmenu, WORD wFlags, int x, int y,
void MENU_TrackMouseMenuBar( HWND hwnd, POINT pt ) void MENU_TrackMouseMenuBar( HWND hwnd, POINT pt )
{ {
WND *wndPtr = WIN_FindWndPtr( hwnd ); WND *wndPtr = WIN_FindWndPtr( hwnd );
SendMessage( hwnd, WM_ENTERMENULOOP, 0, 0 );
MENU_TrackMenu( (HMENU)wndPtr->wIDmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON, MENU_TrackMenu( (HMENU)wndPtr->wIDmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
pt.x, pt.y, hwnd, NULL ); pt.x, pt.y, hwnd, NULL );
SendMessage( hwnd, WM_EXITMENULOOP, 0, 0 );
} }
@ -1315,11 +1377,13 @@ void MENU_TrackMouseMenuBar( HWND hwnd, POINT pt )
void MENU_TrackKbdMenuBar( HWND hwnd, WORD wParam ) void MENU_TrackKbdMenuBar( HWND hwnd, WORD wParam )
{ {
WND *wndPtr = WIN_FindWndPtr( hwnd ); WND *wndPtr = WIN_FindWndPtr( hwnd );
SendMessage( hwnd, WM_ENTERMENULOOP, 0, 0 );
/* Select first selectable item */ /* Select first selectable item */
MENU_SelectItem( wndPtr->wIDmenu, NO_SELECTED_ITEM ); MENU_SelectItem( wndPtr->wIDmenu, NO_SELECTED_ITEM );
MENU_SelectNextItem( (HMENU)wndPtr->wIDmenu ); MENU_SelectNextItem( (HMENU)wndPtr->wIDmenu );
MENU_TrackMenu( (HMENU)wndPtr->wIDmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON, MENU_TrackMenu( (HMENU)wndPtr->wIDmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
0, 0, hwnd, NULL ); 0, 0, hwnd, NULL );
SendMessage( hwnd, WM_EXITMENULOOP, 0, 0 );
} }
@ -1343,9 +1407,6 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
{ {
case WM_CREATE: case WM_CREATE:
{ {
#ifdef DEBUG_MENU
printf("PopupMenu WM_CREATE lParam=%08X !\n", lParam);
#endif
CREATESTRUCT *createStruct = (CREATESTRUCT *)lParam; CREATESTRUCT *createStruct = (CREATESTRUCT *)lParam;
HMENU hmenu = (HMENU) ((int)createStruct->lpCreateParams & 0xffff); HMENU hmenu = (HMENU) ((int)createStruct->lpCreateParams & 0xffff);
SetWindowWord( hwnd, 0, hmenu ); SetWindowWord( hwnd, 0, hmenu );
@ -1388,76 +1449,12 @@ WORD MENU_GetMenuBarHeight( HWND hwnd, WORD menubarWidth, int orgX, int orgY )
if (!(lppop = (LPPOPUPMENU)USER_HEAP_ADDR( wndPtr->wIDmenu ))) return 0; if (!(lppop = (LPPOPUPMENU)USER_HEAP_ADDR( wndPtr->wIDmenu ))) return 0;
hdc = GetDC( hwnd ); hdc = GetDC( hwnd );
SetRect( &rectBar, orgX, orgY, orgX+menubarWidth, orgY+SYSMETRICS_CYMENU ); SetRect( &rectBar, orgX, orgY, orgX+menubarWidth, orgY+SYSMETRICS_CYMENU );
MENU_MenuBarCalcSize( hdc, &rectBar, lppop ); MENU_MenuBarCalcSize( hdc, &rectBar, lppop, hwnd );
ReleaseDC( hwnd, hdc ); ReleaseDC( hwnd, hdc );
return lppop->Height; 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] * ChangeMenu [USER.153]
*/ */
@ -1688,12 +1685,22 @@ BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewIt
if (IS_STRING_ITEM(wFlags)) 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->hText = USER_HEAP_ALLOC( GMEM_MOVEABLE, strlen(lpNewItem)+1 );
lpitem->item_text = (char *)USER_HEAP_ADDR( lpitem->hText ); lpitem->item_text = (char *)USER_HEAP_ADDR( lpitem->hText );
strcpy( lpitem->item_text, lpNewItem ); 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; 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 ); SetRectEmpty( &lpitem->rect );
lpitem->hCheckBit = hStdCheck; lpitem->hCheckBit = hStdCheck;
lpitem->hUnCheckBit = 0; lpitem->hUnCheckBit = 0;
@ -1786,8 +1793,8 @@ BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewIt
lpitem->hText = USER_HEAP_ALLOC( GMEM_MOVEABLE, strlen(lpNewItem)+1 ); lpitem->hText = USER_HEAP_ALLOC( GMEM_MOVEABLE, strlen(lpNewItem)+1 );
lpitem->item_text = (char *)USER_HEAP_ADDR( lpitem->hText ); lpitem->item_text = (char *)USER_HEAP_ADDR( lpitem->hText );
strcpy( lpitem->item_text, lpNewItem ); 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; else lpitem->item_text = lpNewItem;
SetRectEmpty( &lpitem->rect ); SetRectEmpty( &lpitem->rect );
return TRUE; return TRUE;

View File

@ -12,7 +12,7 @@ static char Copyright[] = "Copyright David W. Metcalfe, 1993";
#include "win.h" #include "win.h"
#include "user.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 PaintTextfn(HWND hwnd);
static LONG PaintRectfn(HWND hwnd); static LONG PaintRectfn(HWND hwnd);
@ -67,6 +67,27 @@ LONG StaticWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam)
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, NULL, FALSE);
break; 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: case WM_CREATE:
if (style < 0L || style >= (LONG)DIM(staticfn)) { if (style < 0L || style >= (LONG)DIM(staticfn)) {
lResult = -1L; lResult = -1L;
@ -100,27 +121,26 @@ LONG StaticWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam)
break; break;
case WM_SETTEXT: case WM_SETTEXT:
if (wndPtr->hText) if (style == SS_ICON) break;
USER_HEAP_FREE(wndPtr->hText); DEFWND_SetText( hWnd, (LPSTR)lParam );
InvalidateRect( hWnd, NULL, FALSE );
wndPtr->hText = USER_HEAP_ALLOC(GMEM_MOVEABLE, UpdateWindow( hWnd );
strlen((LPSTR)lParam) + 1);
textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText);
strcpy(textPtr, (LPSTR)lParam);
InvalidateRect(hWnd, NULL, TRUE);
break; break;
case WM_KEYDOWN: case WM_NCHITTEST:
case WM_KEYUP: return HTTRANSPARENT;
case WM_CHAR:
case WM_LBUTTONDOWN: case STM_GETICON:
case WM_LBUTTONUP: if (style != SS_ICON) return 0;
case WM_MBUTTONDOWN: return (HICON)wndPtr->hText;
case WM_MBUTTONUP:
case WM_RBUTTONDOWN: case STM_SETICON:
case WM_RBUTTONUP: if (style != SS_ICON) return 0;
case WM_MOUSEMOVE: if (wndPtr->hText) DestroyIcon( wndPtr->hText );
return(SendMessage(wndPtr->hwndParent, uMsg, wParam, lParam)); wndPtr->hText = wParam;
InvalidateRect( hWnd, NULL, TRUE );
UpdateWindow( hWnd );
return 0;
default: default:
lResult = DefWindowProc(hWnd, uMsg, wParam, lParam); lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
@ -280,30 +300,11 @@ static LONG PaintIconfn(HWND hwnd)
PAINTSTRUCT ps; PAINTSTRUCT ps;
RECT rc; RECT rc;
HDC hdc; HDC hdc;
LPSTR textPtr;
HICON hIcon;
wndPtr = WIN_FindWndPtr(hwnd); wndPtr = WIN_FindWndPtr(hwnd);
hdc = BeginPaint(hwnd, &ps); hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rc); GetClientRect(hwnd, &rc);
FillRect(hdc, &rc, GetStockObject(WHITE_BRUSH)); FillRect(hdc, &rc, GetStockObject(WHITE_BRUSH));
textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText); if (wndPtr->hText) DrawIcon(hdc, rc.left, rc.top, 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);
EndPaint(hwnd, &ps); EndPaint(hwnd, &ps);
} }

View File

@ -40,7 +40,7 @@ static WNDCLASS WIDGETS_BuiltinClasses[] =
0, 0, 0, 0, NULL, POPUPMENU_CLASS_NAME }, 0, 0, 0, 0, NULL, POPUPMENU_CLASS_NAME },
{ CS_GLOBALCLASS, (LONG(*)())DesktopWndProc, 0, sizeof(DESKTOPINFO), { CS_GLOBALCLASS, (LONG(*)())DesktopWndProc, 0, sizeof(DESKTOPINFO),
0, 0, 0, 0, NULL, DESKTOP_CLASS_NAME }, 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 }, 0, 0, 0, 0, NULL, DIALOG_CLASS_NAME },
{ CS_GLOBALCLASS, (LONG(*)())MDIClientWndProc, 0, sizeof(MDICLIENTINFO), { CS_GLOBALCLASS, (LONG(*)())MDIClientWndProc, 0, sizeof(MDICLIENTINFO),
0, 0, 0, STOCK_LTGRAY_BRUSH, NULL, "MDICLIENT" } 0, 0, 0, STOCK_LTGRAY_BRUSH, NULL, "MDICLIENT" }
@ -58,9 +58,12 @@ static WNDCLASS WIDGETS_BuiltinClasses[] =
BOOL WIDGETS_Init(void) BOOL WIDGETS_Init(void)
{ {
int i; 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; return TRUE;
} }

View File

@ -72,5 +72,5 @@ includes::
install:: install::
clean:: clean::
$(RM) dll* dtb* pop.h $(RM) dll* dtb* pop.h call.s
touch pop.h touch pop.h

View File

@ -54,7 +54,7 @@ length 490
39 pascal RestoreDC(word s_word) RestoreDC(1 2) 39 pascal RestoreDC(word s_word) RestoreDC(1 2)
40 pascal FillRgn(word word word) FillRgn(1 2 3) 40 pascal FillRgn(word word word) FillRgn(1 2 3)
#41 pascal FrameRgn #41 pascal FrameRgn
#42 pascal InvertRgn 42 pascal InvertRgn(word word) InvertRgn(1 2)
43 pascal PaintRgn(word word) PaintRgn(1 2) 43 pascal PaintRgn(word word) PaintRgn(1 2)
44 pascal SelectClipRgn(word word) SelectClipRgn(1 2) 44 pascal SelectClipRgn(word word) SelectClipRgn(1 2)
45 pascal SelectObject(word word) SelectObject(1 2) 45 pascal SelectObject(word word) SelectObject(1 2)

View File

@ -241,7 +241,7 @@ length 540
#231 GETSYSTEMDEBUGSTATE #231 GETSYSTEMDEBUGSTATE
232 pascal SetWindowPos(word word word word word word word) 232 pascal SetWindowPos(word word word word word word word)
SetWindowPos(1 2 3 4 5 6 7) 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) 234 pascal UnhookWindowsHook(s_word ptr) UnhookWindowsHook(1 2)
235 pascal DefHookProc(s_word word long ptr) DefHookProc(1 2 3 4) 235 pascal DefHookProc(s_word word long ptr) DefHookProc(1 2 3 4)
236 pascal GetCapture() GetCapture() 236 pascal GetCapture() GetCapture()

View File

@ -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};

View File

@ -8,6 +8,7 @@
#define GDI_H #define GDI_H
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "windows.h" #include "windows.h"
#include "segmem.h" #include "segmem.h"
@ -32,6 +33,7 @@ typedef struct tagREGION
WORD type; WORD type;
RECT box; RECT box;
Pixmap pixmap; Pixmap pixmap;
Region xrgn;
} REGION; } REGION;
typedef struct tagGDIOBJHDR typedef struct tagGDIOBJHDR

View File

@ -11,14 +11,14 @@
typedef struct tagMENUITEM typedef struct tagMENUITEM
{ {
WORD item_flags; WORD item_flags; /* Item flags */
WORD item_id; WORD item_id; /* Item or popup id */
RECT rect; RECT rect; /* Item area (relative to menu window) */
WORD sel_key; WORD xTab; /* X position of text after Tab */
HBITMAP hCheckBit; HBITMAP hCheckBit; /* Bitmap for checked item */
HBITMAP hUnCheckBit; HBITMAP hUnCheckBit; /* Bitmap for unchecked item */
HANDLE hText; /* Handle to item string or bitmap */
char *item_text; char *item_text;
HANDLE hText;
} MENUITEM, *LPMENUITEM; } MENUITEM, *LPMENUITEM;

View File

@ -14,6 +14,18 @@ struct dosdirent {
long filetime; 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 DOSVERSION 0x0330;
#define MAX_DOS_DRIVES 26 #define MAX_DOS_DRIVES 26

View File

@ -13,8 +13,8 @@ struct options
char * desktopGeometry; /* NULL when no desktop */ char * desktopGeometry; /* NULL when no desktop */
char * programName; /* To use when loading resources */ char * programName; /* To use when loading resources */
int usePrivateMap; int usePrivateMap;
int synchronous; int synchronous; /* X synchronous mode */
int nobackingstore; int backingstore; /* Use backing store */
short cmdShow; short cmdShow;
int relay_debug; int relay_debug;
int debug; int debug;

View File

@ -55,7 +55,7 @@ typedef struct segment_descriptor_s
unsigned short owner; /* Handle of owner program */ unsigned short owner; /* Handle of owner program */
unsigned char type; /* DATA or CODE */ unsigned char type; /* DATA or CODE */
#ifdef HAVE_IPC #ifdef HAVE_IPC
key_t shm_key; /* Shared memory key or IPC_PRIVATE */ key_t shm_key; /* Shared memory key or -1 */
#endif #endif
} SEGDESC; } SEGDESC;

View File

@ -49,8 +49,9 @@ typedef struct tagWND
HANDLE hText; /* Handle of window text */ HANDLE hText; /* Handle of window text */
WORD flags; /* Misc. flags (see below) */ WORD flags; /* Misc. flags (see below) */
Window window; /* X window */ Window window; /* X window */
Window icon; /* icon's X window */
HICON hIcon; /* icon's MS-windows handle */ HICON hIcon; /* icon's MS-windows handle */
WORD iconWidth; /* width of icon */
WORD iconHeight; /* height of icon */
RECT rectClientSave; /* where client rect is saved when icon*/ RECT rectClientSave; /* where client rect is saved when icon*/
HMENU hSysMenu; /* window's copy of System Menu */ HMENU hSysMenu; /* window's copy of System Menu */
HANDLE hProp; /* Handle of Properties List */ HANDLE hProp; /* Handle of Properties List */

View File

@ -1513,6 +1513,8 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE
#define WM_MOUSELAST WM_MBUTTONDBLCLK #define WM_MOUSELAST WM_MBUTTONDBLCLK
#define WM_PARENTNOTIFY 0x0210 #define WM_PARENTNOTIFY 0x0210
#define WM_ENTERMENULOOP 0x0211
#define WM_EXITMENULOOP 0x0212
#define WM_MDICREATE 0x0220 #define WM_MDICREATE 0x0220
#define WM_MDIDESTROY 0x0221 #define WM_MDIDESTROY 0x0221
@ -1565,9 +1567,29 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE
#define SW_PARENTOPENING 3 #define SW_PARENTOPENING 3
#define SW_OTHERRESTORED 4 #define SW_OTHERRESTORED 4
enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED, /*
SW_MAXIMIZE, SW_SHOWNOACTIVATE, SW_SHOW, SW_MINIMIZE, enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED,
SW_SHOWMINNOACTIVE, SW_SHOWNA, SW_RESTORE }; 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 */ /* WM_SIZE message wParam values */
#define SIZE_RESTORED 0 #define SIZE_RESTORED 0

View File

@ -156,19 +156,23 @@ IPCCopySelector(int i_old, unsigned long new, int swap_type)
* to get one. In this case, we'll also have to copy the data * to get one. In this case, we'll also have to copy the data
* to protect it. * 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); s_old->shm_key = shmget(IPC_PRIVATE, s_old->length, IPC_CREAT);
if (s_old->shm_key == 0) if (s_old->shm_key == -1)
{ {
if (s_new) if (s_new) {
memset(s_new, 0, sizeof(*s_new)); memset(s_new, 0, sizeof(*s_new));
s_new->shm_key = -1;
}
return -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)); memset(s_new, 0, sizeof(*s_new));
s_new->shm_key = -1;
}
shmctl(s_old->shm_key, IPC_RMID, NULL); shmctl(s_old->shm_key, IPC_RMID, NULL);
return -1; return -1;
} }
@ -183,10 +187,12 @@ IPCCopySelector(int i_old, unsigned long new, int swap_type)
*/ */
else 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)); memset(s_new, 0, sizeof(*s_new));
s_new->shm_key = -1;
}
return -1; return -1;
} }
} }
@ -257,6 +263,9 @@ WORD AllocSelector(WORD old_selector)
else else
{ {
memset(s_new, 0, sizeof(*s_new)); memset(s_new, 0, sizeof(*s_new));
#ifdef HAVE_IPC
s_new->shm_key = -1;
#endif
SelectorMap[i_new] = i_new; SelectorMap[i_new] = i_new;
} }
@ -400,6 +409,19 @@ WORD AllocDStoCSAlias(WORD ds_selector)
return PrestoChangoSelector(ds_selector, cs_selector); return PrestoChangoSelector(ds_selector, cs_selector);
} }
/**********************************************************************
* CleanupSelectors
*/
void CleanupSelectors(void)
{
int sel_idx;
for (sel_idx = FIRST_SELECTOR; sel_idx < MAX_SELECTORS; sel_idx++)
if (SelectorMap[sel_idx])
FreeSelector((sel_idx << 3) | 7);
}
/********************************************************************** /**********************************************************************
* FreeSelector * FreeSelector
*/ */
@ -417,10 +439,11 @@ WORD FreeSelector(WORD sel)
return 0; return 0;
s = &Segments[sel_idx]; 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))); munmap(s->base_addr, ((s->length + PAGE_SIZE) & ~(PAGE_SIZE - 1)));
memset(s, 0, sizeof(*s)); memset(s, 0, sizeof(*s));
s->shm_key = -1;
SelectorMap[sel_idx] = 0; SelectorMap[sel_idx] = 0;
} }
else else
@ -436,6 +459,7 @@ WORD FreeSelector(WORD sel)
shmctl(s->shm_key, IPC_RMID, NULL); shmctl(s->shm_key, IPC_RMID, NULL);
memset(s, 0, sizeof(*s)); memset(s, 0, sizeof(*s));
s->shm_key = -1;
SelectorMap[sel_idx] = 0; SelectorMap[sel_idx] = 0;
} }
@ -521,12 +545,17 @@ CreateNewSegments(int code_flag, int read_only, int length, int n_segments)
MAP_FIXED | MAP_PRIVATE | MAP_ANON, MAP_FIXED | MAP_PRIVATE | MAP_ANON,
-1, 0); -1, 0);
#endif #endif
#ifdef HAVE_IPC
s->shm_key = -1;
#endif
if (set_ldt_entry(i, (unsigned long) s->base_addr, if (set_ldt_entry(i, (unsigned long) s->base_addr,
(s->length - 1) & 0xffff, 0, (s->length - 1) & 0xffff, 0,
contents, read_only, 0) < 0) contents, read_only, 0) < 0)
{ {
memset(s, 0, sizeof(*s)); memset(s, 0, sizeof(*s));
#ifdef HAVE_IPC
s->shm_key = -1;
#endif
return NULL; return NULL;
} }
@ -982,6 +1011,9 @@ CreateSelectors(struct w_files * wpnt)
myerror("CreateSelectors: GlobalAlloc() failed"); myerror("CreateSelectors: GlobalAlloc() failed");
s->base_addr = (void *) ((LONG) s->selector << 16); s->base_addr = (void *) ((LONG) s->selector << 16);
#ifdef HAVE_IPC
s->shm_key = -1;
#endif
if (!(s->flags & NE_SEGFLAGS_DATA)) if (!(s->flags & NE_SEGFLAGS_DATA))
PrestoChangoSelector(s->selector, s->selector); PrestoChangoSelector(s->selector, s->selector);
else else

View File

@ -173,7 +173,7 @@ INT OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle)
ofs->nErrCode = ExtendedError; ofs->nErrCode = ExtendedError;
return -1; return -1;
} }
handle = open (ofs->szPathName, (wStyle & 0x0003) | O_CREAT, 0x666); handle = open (unixfilename, (wStyle & 0x0003) | O_CREAT, 0x666);
if (handle == -1) if (handle == -1)
{ {
errno_to_doserr(); errno_to_doserr();

View File

@ -52,7 +52,7 @@ struct options Options =
NULL, /* programName */ NULL, /* programName */
FALSE, /* usePrivateMap */ FALSE, /* usePrivateMap */
FALSE, /* synchronous */ FALSE, /* synchronous */
FALSE, /* no backing store */ FALSE, /* backing store */
SW_SHOWNORMAL, /* cmdShow */ SW_SHOWNORMAL, /* cmdShow */
FALSE FALSE
}; };
@ -60,6 +60,7 @@ struct options Options =
static XrmOptionDescRec optionsTable[] = static XrmOptionDescRec optionsTable[] =
{ {
{ "-backingstore", ".backingstore", XrmoptionNoArg, (caddr_t)"on" },
{ "-desktop", ".desktop", XrmoptionSepArg, (caddr_t)NULL }, { "-desktop", ".desktop", XrmoptionSepArg, (caddr_t)NULL },
{ "-depth", ".depth", XrmoptionSepArg, (caddr_t)NULL }, { "-depth", ".depth", XrmoptionSepArg, (caddr_t)NULL },
{ "-display", ".display", XrmoptionSepArg, (caddr_t)NULL }, { "-display", ".display", XrmoptionSepArg, (caddr_t)NULL },
@ -67,7 +68,6 @@ static XrmOptionDescRec optionsTable[] =
{ "-name", ".name", XrmoptionSepArg, (caddr_t)NULL }, { "-name", ".name", XrmoptionSepArg, (caddr_t)NULL },
{ "-privatemap", ".privatemap", XrmoptionNoArg, (caddr_t)"on" }, { "-privatemap", ".privatemap", XrmoptionNoArg, (caddr_t)"on" },
{ "-synchronous", ".synchronous", XrmoptionNoArg, (caddr_t)"on" }, { "-synchronous", ".synchronous", XrmoptionNoArg, (caddr_t)"on" },
{ "-nobackingstore",".nobackingstore", XrmoptionNoArg, (caddr_t)"on" },
{ "-spy", ".spy", XrmoptionSepArg, (caddr_t)NULL }, { "-spy", ".spy", XrmoptionSepArg, (caddr_t)NULL },
{ "-debug", ".debug", XrmoptionNoArg, (caddr_t)"on" }, { "-debug", ".debug", XrmoptionNoArg, (caddr_t)"on" },
{ "-relaydbg", ".relaydbg", XrmoptionNoArg, (caddr_t)"on" } { "-relaydbg", ".relaydbg", XrmoptionNoArg, (caddr_t)"on" }
@ -87,7 +87,7 @@ static XrmOptionDescRec optionsTable[] =
" -name name Set the application name\n" \ " -name name Set the application name\n" \
" -privatemap Use a private color map\n" \ " -privatemap Use a private color map\n" \
" -synchronous Turn on synchronous display mode\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" \ " -spy file Turn on message spying to the specified file\n" \
" -relaydbg Display call relay information\n" " -relaydbg Display call relay information\n"
@ -242,8 +242,8 @@ static void MAIN_ParseOptions( int *argc, char *argv[] )
Options.usePrivateMap = TRUE; Options.usePrivateMap = TRUE;
if (MAIN_GetResource( db, ".synchronous", &value )) if (MAIN_GetResource( db, ".synchronous", &value ))
Options.synchronous = TRUE; Options.synchronous = TRUE;
if (MAIN_GetResource( db, ".nobackingstore", &value )) if (MAIN_GetResource( db, ".backingstore", &value ))
Options.nobackingstore = TRUE; Options.backingstore = TRUE;
if (MAIN_GetResource( db, ".relaydbg", &value )) if (MAIN_GetResource( db, ".relaydbg", &value ))
Options.relay_debug = TRUE; Options.relay_debug = TRUE;
if (MAIN_GetResource( db, ".debug", &value )) if (MAIN_GetResource( db, ".debug", &value ))
@ -350,6 +350,7 @@ static void called_at_exit(void)
sync_profiles(); sync_profiles();
MAIN_RestoreSetup(); MAIN_RestoreSetup();
WSACleanup(); WSACleanup();
CleanupSelectors();
} }
/*********************************************************************** /***********************************************************************

View File

@ -841,31 +841,70 @@ static void DumpFCB(BYTE *fcb)
static void FindFirstFCB(struct sigcontext_struct *context) static void FindFirstFCB(struct sigcontext_struct *context)
{ {
BYTE *fcb = pointer(DS, DX); BYTE *fcb = pointer(DS, DX);
struct fcb *standard_fcb;
struct fcb *output_fcb;
int drive; int drive;
char path[12];
DumpFCB( fcb ); DumpFCB( fcb );
if (*fcb) if ((*fcb) == 0xff)
drive = *fcb - 1; {
standard_fcb = fcb + 7;
output_fcb = dta + 7;
*dta = 0xff;
}
else else
drive = DOS_GetDefaultDrive(); {
standard_fcb = fcb;
output_fcb = dta;
}
if (*(fcb - 7) == 0xff) { if (standard_fcb->drive)
if (*(fcb - 1) == FA_DIREC) { {
/* return volume label */ drive = standard_fcb->drive - 1;
if (!DOS_ValidDrive(drive))
memset(dta, ' ', 11); {
if (DOS_GetVolumeLabel(drive) != NULL) Error (InvalidDrive, EC_MediaError, EL_Disk);
strncpy(dta, DOS_GetVolumeLabel(drive), 8); AL = 0xff;
*(dta + 0x0b) = FA_DIREC;
AL;
return; return;
} }
} }
IntBarf(0x21, context); else
drive = DOS_GetDefaultDrive();
output_fcb->drive = drive;
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) static void DeleteFileFCB(struct sigcontext_struct *context)
{ {
BYTE *fcb = pointer(DS, DX); BYTE *fcb = pointer(DS, DX);

View File

@ -13,6 +13,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993";
#include "bitmap.h" #include "bitmap.h"
/* Include OEM bitmaps */ /* Include OEM bitmaps */
#include "bitmaps/check_boxes"
#include "bitmaps/check_mark" #include "bitmaps/check_mark"
#include "bitmaps/menu_arrow" #include "bitmaps/menu_arrow"
@ -64,7 +65,7 @@ static XImage *BITMAP_BmpToImage( BITMAP * bmp, void * bmpData )
extern void _XInitImageFuncPtrs( XImage* ); extern void _XInitImageFuncPtrs( XImage* );
XImage * image; XImage * image;
image = XCreateImage( XT_display, DefaultVisualOfScreen(screen), image = XCreateImage( display, DefaultVisualOfScreen(screen),
bmp->bmBitsPixel, ZPixmap, 0, bmpData, bmp->bmBitsPixel, ZPixmap, 0, bmpData,
bmp->bmWidth, bmp->bmHeight, 16, bmp->bmWidthBytes ); bmp->bmWidth, bmp->bmHeight, 16, bmp->bmWidthBytes );
if (!image) return 0; if (!image) return 0;
@ -94,6 +95,12 @@ HBITMAP BITMAP_LoadOEMBitmap( WORD id )
data = menu_arrow_bits; data = menu_arrow_bits;
break; break;
case OBM_CHECKBOXES:
width = check_boxes_width;
height = check_boxes_height;
data = check_boxes_bits;
break;
case OBM_CHECK: case OBM_CHECK:
width = check_mark_width; width = check_mark_width;
height = check_mark_height; height = check_mark_height;

View File

@ -21,7 +21,12 @@ void CLIPPING_SetDeviceClipping( DC * dc )
if (dc->w.hGCClipRgn) if (dc->w.hGCClipRgn)
{ {
RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(dc->w.hGCClipRgn, REGION_MAGIC); 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 ); XSetClipMask( display, dc->u.x.gc, obj->region.pixmap );
XSetClipOrigin( display, dc->u.x.gc, XSetClipOrigin( display, dc->u.x.gc,

View File

@ -1,15 +1,14 @@
/* /*
* GDI region objects * 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 <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "gdi.h" #include "gdi.h"
/* GC used for region operations */ /* GC used for region operations */
@ -26,24 +25,46 @@ BOOL REGION_Init()
tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 ); tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 );
if (tmpPixmap) if (tmpPixmap)
{ {
regionGC = XCreateGC( XT_display, tmpPixmap, 0, NULL ); regionGC = XCreateGC( display, tmpPixmap, 0, NULL );
XFreePixmap( XT_display, tmpPixmap ); XFreePixmap( display, tmpPixmap );
if (!regionGC) return FALSE; if (!regionGC) return FALSE;
XSetForeground( XT_display, regionGC, 1 ); XSetForeground( display, regionGC, 1 );
XSetGraphicsExposures( XT_display, regionGC, False ); XSetGraphicsExposures( display, regionGC, False );
return TRUE; return TRUE;
} }
else return FALSE; else return FALSE;
} }
/***********************************************************************
* REGION_MakePixmap
*
* Make a pixmap of an X region.
*/
static BOOL REGION_MakePixmap( REGION *region )
{
int width = region->box.right - region->box.left;
int height = region->box.bottom - region->box.top;
if (!region->xrgn) return TRUE; /* Null region */
region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 );
if (!region->pixmap) return FALSE;
XSetRegion( display, regionGC, region->xrgn );
XSetClipOrigin( display, regionGC, region->box.left, region->box.top );
XSetFunction( display, regionGC, GXcopy );
XFillRectangle( display, region->pixmap, regionGC, 0, 0, width, height );
XSetClipMask( display, regionGC, None ); /* Clear clip region */
return TRUE;
}
/*********************************************************************** /***********************************************************************
* REGION_SetRect * 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. * 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; int width, height;
@ -60,21 +81,33 @@ static BOOL REGION_SetRect( HRGN hrgn, LPRECT rect )
region->box.top = 0; region->box.top = 0;
region->box.bottom = 0; region->box.bottom = 0;
region->pixmap = 0; region->pixmap = 0;
region->xrgn = 0;
return TRUE; return TRUE;
} }
region->type = SIMPLEREGION; region->type = SIMPLEREGION;
region->box = *rect; region->box = *rect;
region->xrgn = 0;
region->pixmap = 0;
/* Create pixmap */ if (createXrgn) /* Create and set the X region */
{
Region tmprgn;
XRectangle xrect = { region->box.left, region->box.top, width, height};
region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 ); 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; if (!region->pixmap) return FALSE;
/* Fill the pixmap */
/* Fill pixmap */ XSetFunction( display, regionGC, GXclear );
XFillRectangle(display, region->pixmap, regionGC, 0, 0, width, height);
XSetFunction( XT_display, regionGC, GXclear ); }
XFillRectangle( XT_display, region->pixmap, regionGC,
0, 0, width, height );
return TRUE; return TRUE;
} }
@ -84,7 +117,8 @@ static BOOL REGION_SetRect( HRGN hrgn, LPRECT rect )
*/ */
BOOL REGION_DeleteObject( HRGN hrgn, RGNOBJ * obj ) 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 ); return GDI_FreeObject( hrgn );
} }
@ -100,6 +134,7 @@ int OffsetRgn( HRGN hrgn, short x, short y )
printf( "OffsetRgn: %d %d,%d\n", hrgn, x, y ); printf( "OffsetRgn: %d %d,%d\n", hrgn, x, y );
#endif #endif
OffsetRect( &obj->region.box, x, y ); OffsetRect( &obj->region.box, x, y );
if (obj->region.xrgn) XOffsetRegion( obj->region.xrgn, x, y );
return obj->region.type; return obj->region.type;
} }
@ -134,7 +169,6 @@ HRGN CreateRectRgn( short left, short top, short right, short bottom )
*/ */
HRGN CreateRectRgnIndirect( LPRECT rect ) HRGN CreateRectRgnIndirect( LPRECT rect )
{ {
RGNOBJ * rgnObj;
HRGN hrgn; HRGN hrgn;
#ifdef DEBUG_REGION #ifdef DEBUG_REGION
@ -145,24 +179,11 @@ HRGN CreateRectRgnIndirect( LPRECT rect )
/* Create region */ /* Create region */
if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0; if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
if (!REGION_SetRect( hrgn, rect )) if (!REGION_SetRect( hrgn, rect, TRUE ))
{ {
GDI_FreeObject( hrgn ); GDI_FreeObject( hrgn );
return 0; 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; return hrgn;
} }
@ -185,7 +206,7 @@ HRGN CreateRoundRectRgn( short left, short top, short right, short bottom,
/* Create region */ /* Create region */
if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0; if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
if (!REGION_SetRect( hrgn, &rect )) if (!REGION_SetRect( hrgn, &rect, FALSE ))
{ {
GDI_FreeObject( hrgn ); GDI_FreeObject( hrgn );
return 0; return 0;
@ -198,23 +219,23 @@ HRGN CreateRoundRectRgn( short left, short top, short right, short bottom,
{ {
int width = rgnObj->region.box.right - rgnObj->region.box.left; int width = rgnObj->region.box.right - rgnObj->region.box.left;
int height = rgnObj->region.box.bottom - rgnObj->region.box.top; int height = rgnObj->region.box.bottom - rgnObj->region.box.top;
XSetFunction( XT_display, regionGC, GXcopy ); XSetFunction( display, regionGC, GXcopy );
XFillRectangle( XT_display, rgnObj->region.pixmap, regionGC, XFillRectangle( display, rgnObj->region.pixmap, regionGC,
0, ellipse_height / 2, 0, ellipse_height / 2,
width, height - ellipse_height ); width, height - ellipse_height );
XFillRectangle( XT_display, rgnObj->region.pixmap, regionGC, XFillRectangle( display, rgnObj->region.pixmap, regionGC,
ellipse_width / 2, 0, ellipse_width / 2, 0,
width - ellipse_width, height ); width - ellipse_width, height );
XFillArc( XT_display, rgnObj->region.pixmap, regionGC, XFillArc( display, rgnObj->region.pixmap, regionGC,
0, 0, 0, 0,
ellipse_width, ellipse_height, 0, 360*64 ); ellipse_width, ellipse_height, 0, 360*64 );
XFillArc( XT_display, rgnObj->region.pixmap, regionGC, XFillArc( display, rgnObj->region.pixmap, regionGC,
width - ellipse_width, 0, width - ellipse_width, 0,
ellipse_width, ellipse_height, 0, 360*64 ); ellipse_width, ellipse_height, 0, 360*64 );
XFillArc( XT_display, rgnObj->region.pixmap, regionGC, XFillArc( display, rgnObj->region.pixmap, regionGC,
0, height - ellipse_height, 0, height - ellipse_height,
ellipse_width, ellipse_height, 0, 360*64 ); 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, width - ellipse_width, height - ellipse_height,
ellipse_width, ellipse_height, 0, 360*64 ); ellipse_width, ellipse_height, 0, 360*64 );
} }
@ -238,21 +259,9 @@ void SetRectRgn( HRGN hrgn, short left, short top, short right, short bottom )
/* Free previous pixmap */ /* Free previous pixmap */
if (!(rgnObj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return; if (!(rgnObj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return;
if (rgnObj->region.pixmap) if (rgnObj->region.pixmap) XFreePixmap( display, rgnObj->region.pixmap );
XFreePixmap( XT_display, rgnObj->region.pixmap ); if (rgnObj->region.xrgn) XDestroyRegion( rgnObj->region.xrgn );
REGION_SetRect( hrgn, &rect, TRUE );
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 );
}
} }
@ -282,7 +291,7 @@ HRGN CreateEllipticRgnIndirect( LPRECT rect )
/* Create region */ /* Create region */
if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0; if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
if (!REGION_SetRect( hrgn, rect )) if (!REGION_SetRect( hrgn, rect, FALSE ))
{ {
GDI_FreeObject( hrgn ); GDI_FreeObject( hrgn );
return 0; return 0;
@ -295,8 +304,8 @@ HRGN CreateEllipticRgnIndirect( LPRECT rect )
{ {
int width = rgnObj->region.box.right - rgnObj->region.box.left; int width = rgnObj->region.box.right - rgnObj->region.box.left;
int height = rgnObj->region.box.bottom - rgnObj->region.box.top; int height = rgnObj->region.box.bottom - rgnObj->region.box.top;
XSetFunction( XT_display, regionGC, GXcopy ); XSetFunction( display, regionGC, GXcopy );
XFillArc( XT_display, rgnObj->region.pixmap, regionGC, XFillArc( display, rgnObj->region.pixmap, regionGC,
0, 0, width, height, 0, 360*64 ); 0, 0, width, height, 0, 360*64 );
} }
@ -321,70 +330,67 @@ HRGN CreatePolyPolygonRgn( POINT * points, short * count,
{ {
RGNOBJ * rgnObj; RGNOBJ * rgnObj;
HRGN hrgn; HRGN hrgn;
RECT box; int i, j, maxPoints;
int i, j, totalPoints; XPoint *xpoints, *pt;
POINT * pt; XRectangle rect;
XPoint * xpoints; Region xrgn;
if (!nbpolygons) return 0;
#ifdef DEBUG_REGION #ifdef DEBUG_REGION
printf( "CreatePolyPolygonRgn: %d polygons\n", nbpolygons ); printf( "CreatePolyPolygonRgn: %d polygons\n", nbpolygons );
#endif #endif
/* Find bounding box */ /* Allocate points array */
box.top = box.left = 32767; if (!nbpolygons) return 0;
box.right = box.bottom = 0; for (i = maxPoints = 0; i < nbpolygons; i++)
for (i = totalPoints = 0, pt = points; 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 ); free( xpoints );
return 0; return 0;
} }
rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn ); 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 ); for (j = *count, pt = xpoints; j > 0; j--, points++, pt++)
if (mode == WINDING) XSetFillRule( XT_display, regionGC, WindingRule );
else XSetFillRule( XT_display, regionGC, EvenOddRule );
for (i = j = 0; i < nbpolygons; i++)
{ {
XFillPolygon( XT_display, rgnObj->region.pixmap, regionGC, pt->x = points->x;
&xpoints[j], count[i], Complex, CoordModeOrigin ); pt->y = points->y;
j += count[i];
} }
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 ); 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; return hrgn;
} }
@ -394,19 +400,25 @@ HRGN CreatePolyPolygonRgn( POINT * points, short * count,
*/ */
BOOL PtInRegion( HRGN hrgn, short x, short y ) BOOL PtInRegion( HRGN hrgn, short x, short y )
{ {
XImage * image;
BOOL res; BOOL res;
RGNOBJ * obj; RGNOBJ * obj;
POINT pt = { x, y }; POINT pt = { x, y };
if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return FALSE; if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return FALSE;
if (!PtInRect( &obj->region.box, pt )) return FALSE; if (!PtInRect( &obj->region.box, pt )) return FALSE;
image = XGetImage( XT_display, obj->region.pixmap, 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, x - obj->region.box.left, y - obj->region.box.top,
1, 1, AllPlanes, ZPixmap ); 1, 1, AllPlanes, ZPixmap );
if (!image) return FALSE; if (!image) return FALSE;
res = (XGetPixel( image, 0, 0 ) != 0); res = (XGetPixel( image, 0, 0 ) != 0);
XDestroyImage( image ); XDestroyImage( image );
}
return res; return res;
} }
@ -422,9 +434,17 @@ BOOL RectInRegion( HRGN hrgn, LPRECT rect )
int x, y; int x, y;
if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return FALSE; if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) 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; if (!IntersectRect( &intersect, &obj->region.box, rect )) return FALSE;
image = XGetImage( XT_display, obj->region.pixmap, image = XGetImage( display, obj->region.pixmap,
intersect.left - obj->region.box.left, intersect.left - obj->region.box.left,
intersect.top - obj->region.box.top, intersect.top - obj->region.box.top,
intersect.right - intersect.left, intersect.right - intersect.left,
@ -440,6 +460,7 @@ BOOL RectInRegion( HRGN hrgn, LPRECT rect )
} }
XDestroyImage( image ); XDestroyImage( image );
}
return FALSE; return FALSE;
} }
@ -451,6 +472,7 @@ BOOL EqualRgn( HRGN rgn1, HRGN rgn2 )
{ {
RGNOBJ *obj1, *obj2; RGNOBJ *obj1, *obj2;
XImage *image1, *image2; XImage *image1, *image2;
Pixmap pixmap1, pixmap2;
int width, height, x, y; int width, height, x, y;
/* Compare bounding boxes */ /* Compare bounding boxes */
@ -461,19 +483,27 @@ BOOL EqualRgn( HRGN rgn1, HRGN rgn2 )
return (obj2->region.type == NULLREGION); return (obj2->region.type == NULLREGION);
else if (obj2->region.type == NULLREGION) return FALSE; else if (obj2->region.type == NULLREGION) return FALSE;
if (!EqualRect( &obj1->region.box, &obj2->region.box )) 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 */ /* 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; width = obj1->region.box.right - obj1->region.box.left;
height = obj1->region.box.bottom - obj1->region.box.top; 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 ); 0, 0, width, height, AllPlanes, ZPixmap );
if (!image1) return FALSE; image2 = XGetImage( display, obj2->region.pixmap,
image2 = XGetImage( XT_display, obj2->region.pixmap,
0, 0, width, height, AllPlanes, ZPixmap ); 0, 0, width, height, AllPlanes, ZPixmap );
if (!image2) if (!image1 || !image2)
{ {
XDestroyImage( image1 ); if (image1) XDestroyImage( image1 );
if (image2) XDestroyImage( image2 );
return FALSE; return FALSE;
} }
@ -503,7 +533,7 @@ void REGION_CopyIntersection( REGION * dest, REGION * src )
{ {
RECT inter; RECT inter;
if (!IntersectRect( &inter, &dest->box, &src->box )) return; 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.left - src->box.left, inter.top - src->box.top,
inter.right - inter.left, inter.bottom - inter.top, inter.right - inter.left, inter.bottom - inter.top,
inter.left - dest->box.left, inter.top - dest->box.top ); inter.left - dest->box.left, inter.top - dest->box.top );
@ -533,6 +563,68 @@ int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode )
return ERROR; return ERROR;
region = &destObj->region; 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) switch(mode)
{ {
case RGN_AND: case RGN_AND:
@ -564,11 +656,13 @@ int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode )
return ERROR; 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) if (!res)
{ {
region->type = NULLREGION; region->type = NULLREGION;
region->pixmap = 0; region->pixmap = 0;
region->xrgn = 0;
return NULLREGION; return NULLREGION;
} }
@ -587,39 +681,40 @@ int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode )
exit(1); exit(1);
} }
region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 ); region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 );
region->xrgn = 0;
switch(mode) switch(mode)
{ {
case RGN_AND: case RGN_AND:
XSetFunction( XT_display, regionGC, GXcopy ); XSetFunction( display, regionGC, GXcopy );
REGION_CopyIntersection( region, &src1Obj->region ); REGION_CopyIntersection( region, &src1Obj->region );
XSetFunction( XT_display, regionGC, GXand ); XSetFunction( display, regionGC, GXand );
REGION_CopyIntersection( region, &src2Obj->region ); REGION_CopyIntersection( region, &src2Obj->region );
break; break;
case RGN_OR: case RGN_OR:
case RGN_XOR: case RGN_XOR:
XSetFunction( XT_display, regionGC, GXclear ); XSetFunction( display, regionGC, GXclear );
XFillRectangle( XT_display, region->pixmap, regionGC, XFillRectangle( display, region->pixmap, regionGC,
0, 0, width, height ); 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, &src1Obj->region );
REGION_CopyIntersection( region, &src2Obj->region ); REGION_CopyIntersection( region, &src2Obj->region );
break; break;
case RGN_DIFF: case RGN_DIFF:
XSetFunction( XT_display, regionGC, GXclear ); XSetFunction( display, regionGC, GXclear );
XFillRectangle( XT_display, region->pixmap, regionGC, XFillRectangle( display, region->pixmap, regionGC,
0, 0, width, height ); 0, 0, width, height );
XSetFunction( XT_display, regionGC, GXcopy ); XSetFunction( display, regionGC, GXcopy );
REGION_CopyIntersection( region, &src1Obj->region ); REGION_CopyIntersection( region, &src1Obj->region );
XSetFunction( XT_display, regionGC, GXandInverted ); XSetFunction( display, regionGC, GXandInverted );
REGION_CopyIntersection( region, &src2Obj->region ); REGION_CopyIntersection( region, &src2Obj->region );
break; break;
case RGN_COPY: case RGN_COPY:
XSetFunction( XT_display, regionGC, GXcopy ); XSetFunction( display, regionGC, GXcopy );
XCopyArea( XT_display, src1Obj->region.pixmap, region->pixmap, XCopyArea( display, src1Obj->region.pixmap, region->pixmap,
regionGC, 0, 0, width, height, 0, 0 ); regionGC, 0, 0, width, height, 0, 0 );
break; break;
} }

View File

@ -183,25 +183,6 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
dc->w.DCSizeX = wndPtr->rectWindow.right - wndPtr->rectWindow.left; dc->w.DCSizeX = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
dc->w.DCSizeY = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top; 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 else
{ {
dc->w.DCOrgX = wndPtr->rectClient.left - wndPtr->rectWindow.left; dc->w.DCOrgX = wndPtr->rectClient.left - wndPtr->rectWindow.left;
@ -223,11 +204,12 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
if ((flags & DCX_INTERSECTRGN) || (flags & DCX_EXCLUDERGN)) if ((flags & DCX_INTERSECTRGN) || (flags & DCX_EXCLUDERGN))
{ {
HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 ); HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
if (hrgn && !IsIconic(hwnd)) if (hrgn)
{ {
if (CombineRgn( hrgn, InquireVisRgn(hdc), hrgnClip, if (CombineRgn( hrgn, InquireVisRgn(hdc), hrgnClip,
(flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF )) (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF )) {
SelectVisRgn( hdc, hrgn ); SelectVisRgn( hdc, hrgn );
}
DeleteObject( hrgn ); DeleteObject( hrgn );
} }
} }

View File

@ -44,6 +44,7 @@ void DEFWND_SetText( HWND hwnd, LPSTR text )
strcpy( textPtr, text ); strcpy( textPtr, text );
} }
#include <assert.h>
/*********************************************************************** /***********************************************************************
* DefWindowProc (USER.107) * DefWindowProc (USER.107)
@ -75,13 +76,10 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
case WM_NCCALCSIZE: case WM_NCCALCSIZE:
return NC_HandleNCCalcSize( hwnd, (NCCALCSIZE_PARAMS *)lParam ); return NC_HandleNCCalcSize( hwnd, (NCCALCSIZE_PARAMS *)lParam );
case WM_PAINTICON:
case WM_NCPAINT: case WM_NCPAINT:
return NC_HandleNCPaint( hwnd, (HRGN)wParam ); return NC_HandleNCPaint( hwnd, (HRGN)wParam );
case WM_PAINTICON:
printf("going to call NC_HandleNCPaintIcon\n");
return NC_HandleNCPaintIcon( hwnd );
case WM_NCHITTEST: case WM_NCHITTEST:
return NC_HandleNCHitTest( hwnd, MAKEPOINT(lParam) ); return NC_HandleNCHitTest( hwnd, MAKEPOINT(lParam) );
@ -89,6 +87,7 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
case WM_NCLBUTTONDOWN: case WM_NCLBUTTONDOWN:
return NC_HandleNCLButtonDown( hwnd, wParam, lParam ); return NC_HandleNCLButtonDown( hwnd, wParam, lParam );
case WM_LBUTTONDBLCLK:
case WM_NCLBUTTONDBLCLK: case WM_NCLBUTTONDBLCLK:
return NC_HandleNCLButtonDblClk( hwnd, wParam, lParam ); return NC_HandleNCLButtonDblClk( hwnd, wParam, lParam );

View File

@ -78,12 +78,14 @@ static DLGCONTROLHEADER * DIALOG_GetControl( DLGCONTROLHEADER * ptr,
*class = p; *class = p;
p += strlen(p) + 1; p += strlen(p) + 1;
} }
/* FIXME: how can I determine if the resource id is an integer or a string ? */ if (*p == 0xff)
if (*p == 0xff) { {
/* *(DWORD*)text = (*p << 8) | *p;*/ /* Integer id, not documented (?). Only works for SS_ICON controls */
*(DWORD*)text = 0xebeb; *text = (char *)MAKEINTRESOURCE( p[1] + 256*p[2] );
p += 4; p += 4;
} else { }
else
{
*text = p; *text = p;
p += strlen(p) + 2; p += strlen(p) + 2;
} }
@ -263,8 +265,10 @@ HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate,
/* Create dialog main window */ /* Create dialog main window */
rect.left = rect.top = 0; rect.left = rect.top = 0;
rect.right = template.header->cx * xUnit / 4; if (!(template.header->style & DS_ABSALIGN))
rect.bottom = template.header->cy * yUnit / 8; 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; if (template.header->style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME;
AdjustWindowRectEx( &rect, template.header->style, hMenu, exStyle ); AdjustWindowRectEx( &rect, template.header->style, hMenu, exStyle );
@ -300,11 +304,8 @@ HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate,
#ifdef DEBUG_DIALOG #ifdef DEBUG_DIALOG
printf( " %s ", class); printf( " %s ", class);
if ((DWORD*)text < 0x10000) if ((int)text & 0xffff0000) printf("'%s'", text);
printf("'%4X'", (DWORD*)text); else printf("%4X", (int)text & 0xffff);
else
printf("'%s'", text);
printf(" %d, %d, %d, %d, %d, %08x\n", header->id, header->x, header->y, printf(" %d, %d, %d, %d, %d, %08x\n", header->id, header->x, header->y,
header->cx, header->cy, header->style ); header->cx, header->cy, header->style );
#endif #endif
@ -329,11 +330,6 @@ HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate,
hwnd, header->id, HIWORD((LONG)dlgHeapBase), NULL ); hwnd, header->id, HIWORD((LONG)dlgHeapBase), NULL );
} }
else { else {
if ((strcmp(class, "STATIC") == 0) &
((header->style & SS_ICON) == SS_ICON)) {
header->cx = 32;
header->cy = 32;
}
header->style |= WS_CHILD; header->style |= WS_CHILD;
CreateWindowEx( WS_EX_NOPARENTNOTIFY, CreateWindowEx( WS_EX_NOPARENTNOTIFY,
class, text, header->style, class, text, header->style,

View File

@ -252,13 +252,6 @@ static void EVENT_Expose( HWND hwnd, XExposeEvent *event )
WND * wndPtr = WIN_FindWndPtr( hwnd ); WND * wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return; if (!wndPtr) return;
if (IsIconic(hwnd) && wndPtr->hIcon)
{
SendMessage(hwnd, WM_PAINTICON, 0, 0);
return;
}
/* Make position relative to client area instead of window */ /* Make position relative to client area instead of window */
rect.left = event->x - (wndPtr->rectClient.left - wndPtr->rectWindow.left); rect.left = event->x - (wndPtr->rectClient.left - wndPtr->rectWindow.left);
rect.top = event->y - (wndPtr->rectClient.top - wndPtr->rectWindow.top); rect.top = event->y - (wndPtr->rectClient.top - wndPtr->rectWindow.top);

View File

@ -18,6 +18,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993";
#include "gdi.h" #include "gdi.h"
#include "syscolor.h" #include "syscolor.h"
extern const int DC_XROPfunction[];
extern int COLOR_ToPhysical( DC *dc, COLORREF color ); extern int COLOR_ToPhysical( DC *dc, COLORREF color );
static inline swap_int(int *a, int *b) static inline swap_int(int *a, int *b)
@ -473,6 +475,10 @@ COLORREF GetPixel( HDC hdc, short x, short y )
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return 0; if (!dc) return 0;
#ifdef SOLITAIRE_SPEED_HACK
return 0;
#endif
x = dc->w.DCOrgX + XLPTODP( dc, x ); x = dc->w.DCOrgX + XLPTODP( dc, x );
y = dc->w.DCOrgY + YLPTODP( dc, y ); y = dc->w.DCOrgY + YLPTODP( dc, y );
if ((x < 0) || (y < 0)) return 0; if ((x < 0) || (y < 0)) return 0;
@ -551,6 +557,20 @@ BOOL FillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush )
} }
/***********************************************************************
* InvertRgn (GDI.42)
*/
BOOL InvertRgn( HDC hdc, HRGN hrgn )
{
HBRUSH prevBrush = SelectObject( hdc, GetStockObject(BLACK_BRUSH) );
WORD prevROP = SetROP2( hdc, R2_NOT );
BOOL retval = PaintRgn( hdc, hrgn );
SelectObject( hdc, prevBrush );
SetROP2( hdc, prevROP );
return retval;
}
/*********************************************************************** /***********************************************************************
* DrawFocusRect (USER.466) * DrawFocusRect (USER.466)
*/ */
@ -582,6 +602,44 @@ void DrawFocusRect( HDC hdc, LPRECT rc )
} }
/**********************************************************************
* GRAPH_DrawBitmap
*
* Short-cut function to blit a bitmap into a device.
* Faster than CreateCompatibleDC() + SelectBitmap() + BitBlt() + DeleteDC().
*/
BOOL GRAPH_DrawBitmap( HDC hdc, HBITMAP hbitmap, int xdest, int ydest,
int xsrc, int ysrc, int width, int height, int rop )
{
XGCValues val;
BITMAPOBJ *bmp;
DC *dc;
if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE;
if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
return FALSE;
val.function = DC_XROPfunction[(rop >> 16) & 0x0f];
val.foreground = dc->w.textPixel;
val.background = dc->w.backgroundPixel;
XChangeGC(display, dc->u.x.gc, GCFunction|GCForeground|GCBackground, &val);
if (bmp->bitmap.bmBitsPixel == 1)
{
XCopyPlane( display, bmp->pixmap, dc->u.x.drawable, dc->u.x.gc,
xsrc, ysrc, width, height,
dc->w.DCOrgX + xdest, dc->w.DCOrgY + ydest, 1 );
return TRUE;
}
else if (bmp->bitmap.bmBitsPixel == dc->w.bitsPerPixel)
{
XCopyArea( display, bmp->pixmap, dc->u.x.drawable, dc->u.x.gc,
xsrc, ysrc, width, height,
dc->w.DCOrgX + xdest, dc->w.DCOrgY + ydest );
return TRUE;
}
else return FALSE;
}
/********************************************************************** /**********************************************************************
* DrawReliefRect (Not a MSWin Call) * DrawReliefRect (Not a MSWin Call)
*/ */

View File

@ -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);
}

View File

@ -16,7 +16,7 @@
#define DEBUG_MDI /* */ #define DEBUG_MDI /* */
extern WORD MENU_DrawMenuBar( HDC hDC, LPRECT lprect, extern WORD MENU_DrawMenuBar( HDC hDC, LPRECT lprect,
HMENU hmenu, BOOL suppress_draw ); /* menu.c */ HWND hwnd, BOOL suppress_draw ); /* menu.c */
/********************************************************************** /**********************************************************************
* MDIRecreateMenuList * MDIRecreateMenuList
@ -310,6 +310,7 @@ LONG MDIRestoreChild(HWND parent, MDICLIENTINFO *ci)
ci->flagChildMaximized = FALSE; ci->flagChildMaximized = FALSE;
ShowWindow(child, SW_RESTORE); /* display the window */
SendMessage(GetParent(parent), WM_NCPAINT, 1, 0); SendMessage(GetParent(parent), WM_NCPAINT, 1, 0);
MDIBringChildToTop(parent, child, FALSE, FALSE); MDIBringChildToTop(parent, child, FALSE, FALSE);
@ -571,7 +572,7 @@ LONG MDIPaintMaximized(HWND hwndFrame, HWND hwndClient, WORD message,
rect.right -= SYSMETRICS_CXSIZE; rect.right -= SYSMETRICS_CXSIZE;
rect.bottom = rect.top + SYSMETRICS_CYMENU; rect.bottom = rect.top + SYSMETRICS_CYMENU;
MENU_DrawMenuBar(hdc, &rect, wndPtr->wIDmenu, FALSE); MENU_DrawMenuBar(hdc, &rect, hwndFrame, FALSE);
DeleteDC(hdcMem); DeleteDC(hdcMem);
ReleaseDC(hwndFrame, hdc); ReleaseDC(hwndFrame, hdc);
@ -751,8 +752,6 @@ DefMDIChildProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
return SendMessage(GetParent(hwnd), WM_MDIMAXIMIZE, hwnd, 0); return SendMessage(GetParent(hwnd), WM_MDIMAXIMIZE, hwnd, 0);
case SC_RESTORE: case SC_RESTORE:
if (IsIconic(hwnd))
ICON_Deiconify(hwnd);
return SendMessage(GetParent(hwnd), WM_MDIRESTORE, hwnd, 0); return SendMessage(GetParent(hwnd), WM_MDIRESTORE, hwnd, 0);
} }
break; break;

View File

@ -198,6 +198,7 @@ static void MSG_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos )
* Return value indicates whether the translated message must be passed * Return value indicates whether the translated message must be passed
* to the user. * to the user.
* Actions performed: * Actions performed:
* - Find the window for this message.
* - Translate button-down messages in double-clicks. * - Translate button-down messages in double-clicks.
* - Send the WM_NCHITTEST message to find where the cursor is. * - Send the WM_NCHITTEST message to find where the cursor is.
* - Activate the window if needed. * - Activate the window if needed.
@ -208,6 +209,7 @@ static void MSG_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos )
static BOOL MSG_TranslateMouseMsg( MSG *msg, BOOL remove ) static BOOL MSG_TranslateMouseMsg( MSG *msg, BOOL remove )
{ {
BOOL eatMsg = FALSE; BOOL eatMsg = FALSE;
LONG hittest_result;
static DWORD lastClickTime = 0; static DWORD lastClickTime = 0;
static WORD lastClickMsg = 0; static WORD lastClickMsg = 0;
static POINT lastClickPos = { 0, 0 }; static POINT lastClickPos = { 0, 0 };
@ -216,10 +218,29 @@ static BOOL MSG_TranslateMouseMsg( MSG *msg, BOOL remove )
(msg->message == WM_RBUTTONDOWN) || (msg->message == WM_RBUTTONDOWN) ||
(msg->message == WM_MBUTTONDOWN)); (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 */ /* Send the WM_NCHITTEST message */
LONG hittest_result = SendMessage( msg->hwnd, WM_NCHITTEST, 0, hittest_result = SendMessage( msg->hwnd, WM_NCHITTEST, 0,
MAKELONG( msg->pt.x, msg->pt.y ) ); 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 */ /* Send the WM_PARENTNOTIFY message */
@ -305,6 +326,29 @@ static BOOL MSG_TranslateMouseMsg( MSG *msg, BOOL remove )
} }
/***********************************************************************
* MSG_TranslateKeyboardMsg
*
* Translate an keyboard hardware event into a real message.
* Return value indicates whether the translated message must be passed
* to the user.
*/
static BOOL MSG_TranslateKeyboardMsg( MSG *msg )
{
/* Should check Ctrl-Esc and PrintScreen here */
msg->hwnd = GetFocus();
if (!msg->hwnd)
{
/* Send the message to the active window instead, */
/* translating messages to their WM_SYS equivalent */
msg->hwnd = GetActiveWindow();
msg->message += WM_SYSKEYDOWN - WM_KEYDOWN;
}
return TRUE;
}
/********************************************************************** /**********************************************************************
* SetDoubleClickTime (USER.20) * SetDoubleClickTime (USER.20)
*/ */
@ -391,30 +435,6 @@ void hardware_event( WORD message, WORD wParam, LONG lParam,
msg.pt.x = xPos & 0xffff; msg.pt.x = xPos & 0xffff;
msg.pt.y = yPos & 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 */ /* Merge with previous event if possible */
if (sysMsgQueue->msgCount && (message == WM_MOUSEMOVE)) if (sysMsgQueue->msgCount && (message == WM_MOUSEMOVE))
@ -438,6 +458,7 @@ void hardware_event( WORD message, WORD wParam, LONG lParam,
* Like GetMessage(), but only return mouse and keyboard events. * Like GetMessage(), but only return mouse and keyboard events.
* Used internally for window moving and resizing. Mouse messages * Used internally for window moving and resizing. Mouse messages
* are not translated. * are not translated.
* Warning: msg->hwnd is always 0.
*/ */
BOOL MSG_GetHardwareMessage( LPMSG msg ) BOOL MSG_GetHardwareMessage( LPMSG msg )
{ {
@ -560,6 +581,9 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd,
int pos, mask; int pos, mask;
LONG nextExp; /* Next timer expiration time */ LONG nextExp; /* Next timer expiration time */
XEvent event; XEvent event;
fd_set read_set;
struct timeval timeout;
int fd = ConnectionNumber(display);
if (first || last) if (first || last)
{ {
@ -572,25 +596,9 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd,
} }
else mask = QS_MOUSE | QS_KEY | QS_POSTMESSAGE | QS_TIMER | QS_PAINT; else mask = QS_MOUSE | QS_KEY | QS_POSTMESSAGE | QS_TIMER | QS_PAINT;
while (XPending( display ))
{
XNextEvent( display, &event );
EVENT_ProcessEvent( &event );
}
while(1) while(1)
{ {
/* First handle a WM_QUIT message */ /* First handle a message put by SendMessage() */
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() */
if (msgQueue->status & QS_SENDMESSAGE) if (msgQueue->status & QS_SENDMESSAGE)
{ {
if (!hwnd || (msgQueue->hWnd == hwnd)) if (!hwnd || (msgQueue->hWnd == hwnd))
@ -623,7 +631,7 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd,
} }
/* Now find a hardware event */ /* Now find a hardware event */
pos = MSG_FindMsg( sysMsgQueue, hwnd, first, last ); pos = MSG_FindMsg( sysMsgQueue, 0, first, last );
if (pos != -1) if (pos != -1)
{ {
QMSG *qmsg = &sysMsgQueue->messages[pos]; QMSG *qmsg = &sysMsgQueue->messages[pos];
@ -639,10 +647,27 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd,
MSG_RemoveMsg( sysMsgQueue, pos ); MSG_RemoveMsg( sysMsgQueue, pos );
continue; 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 ); if (flags & PM_REMOVE) MSG_RemoveMsg( sysMsgQueue, pos );
break; 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 */ /* Now find a WM_PAINT message */
if ((msgQueue->status & QS_PAINT) && (mask & QS_PAINT)) if ((msgQueue->status & QS_PAINT) && (mask & QS_PAINT))
{ {
@ -662,22 +687,28 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd,
else nextExp = -1; /* No timeout needed */ else nextExp = -1; /* No timeout needed */
/* Wait until something happens */ /* Wait until something happens */
if (peek) return FALSE;
if (!XPending( display ) && (nextExp != -1))
{
fd_set read_set;
struct timeval timeout;
int fd = ConnectionNumber(display);
FD_ZERO( &read_set ); FD_ZERO( &read_set );
FD_SET( fd, &read_set ); FD_SET( fd, &read_set );
if (peek)
{
timeout.tv_sec = 0;
timeout.tv_usec = 0;
if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1)
return FALSE; /* No data waiting to be read */
}
else if (!XPending( display ) && (nextExp != -1))
{
timeout.tv_sec = nextExp / 1000; timeout.tv_sec = nextExp / 1000;
timeout.tv_usec = (nextExp % 1000) * 1000; timeout.tv_usec = (nextExp % 1000) * 1000;
if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1) if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1)
continue; /* On timeout or error, restart from the start */ continue; /* On timeout or error, restart from the start */
} }
while (XPending( display ))
{
XNextEvent( display, &event ); XNextEvent( display, &event );
EVENT_ProcessEvent( &event ); EVENT_ProcessEvent( &event );
} }
}
/* We got a message */ /* We got a message */
if (peek) return TRUE; if (peek) return TRUE;
@ -825,11 +856,10 @@ void WaitMessage( void )
(appMsgQueue->status & (QS_SENDMESSAGE | QS_PAINT)) || (appMsgQueue->status & (QS_SENDMESSAGE | QS_PAINT)) ||
(appMsgQueue->msgCount) || (sysMsgQueue->msgCount) ) (appMsgQueue->msgCount) || (sysMsgQueue->msgCount) )
break; break;
nextExp = -1;
if ((appMsgQueue->status & QS_TIMER) && if ((appMsgQueue->status & QS_TIMER) &&
TIMER_CheckTimer( &nextExp, &msg, 0, FALSE)) TIMER_CheckTimer( &nextExp, &msg, 0, FALSE))
break; break;
else
nextExp=-1;
if (!XPending( display ) && (nextExp != -1)) if (!XPending( display ) && (nextExp != -1))
{ {

View File

@ -30,12 +30,15 @@ extern BOOL AboutWine_Proc( HWND hDlg, WORD msg, WORD wParam, LONG lParam );
extern void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, extern void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
POINT *minTrack, POINT *maxTrack ); /* winpos.c */ POINT *minTrack, POINT *maxTrack ); /* winpos.c */
extern void CURSOR_SetWinCursor( HWND hwnd, HCURSOR hcursor ); /* cursor.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, extern WORD MENU_GetMenuBarHeight( HWND hwnd, WORD menubarWidth,
int orgX, int orgY ); /* menu.c */ int orgX, int orgY ); /* menu.c */
extern void MENU_TrackMouseMenuBar( HWND hwnd, POINT pt ); /* menu.c */ extern void MENU_TrackMouseMenuBar( HWND hwnd, POINT pt ); /* menu.c */
extern void MENU_TrackKbdMenuBar( HWND hwnd, WORD wParam ); /* menu.c */ extern void MENU_TrackKbdMenuBar( HWND hwnd, WORD wParam ); /* menu.c */
extern WORD MENU_DrawMenuBar( HDC hDC, LPRECT lprect, 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 */ /* Some useful macros */
@ -126,6 +129,12 @@ LONG NC_HandleNCCalcSize( HWND hwnd, NCCALCSIZE_PARAMS *params )
if (!wndPtr) return 0; 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 ); NC_AdjustRect( &tmpRect, wndPtr->dwStyle, FALSE, wndPtr->dwExStyle );
params->rgrc[0].left -= tmpRect.left; params->rgrc[0].left -= tmpRect.left;
params->rgrc[0].top -= tmpRect.top; params->rgrc[0].top -= tmpRect.top;
@ -174,22 +183,34 @@ void NC_GetInsideRect( HWND hwnd, RECT *rect )
/*********************************************************************** /***********************************************************************
* NC_InternalNCHitTest * NC_HandleNCHitTest
* *
* Perform the hit test calculation, but whithout testing the capture * Handle a WM_NCHITTEST message. Called from DefWindowProc().
* window.
*/ */
static LONG NC_InternalNCHitTest( HWND hwnd, POINT pt ) LONG NC_HandleNCHitTest( HWND hwnd, POINT pt )
{ {
RECT rect; RECT rect;
WND *wndPtr = WIN_FindWndPtr( hwnd ); WND *wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return HTERROR; 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 ); GetWindowRect( hwnd, &rect );
if (!PtInRect( &rect, pt )) return HTNOWHERE; 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 )) if (HAS_THICKFRAME( wndPtr->dwStyle ))
{ {
InflateRect( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME ); InflateRect( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
@ -301,21 +322,6 @@ static LONG NC_InternalNCHitTest( HWND hwnd, POINT pt )
} }
/***********************************************************************
* NC_HandleNCHitTest
*
* Handle a WM_NCHITTEST message. Called from DefWindowProc().
*/
LONG NC_HandleNCHitTest( HWND hwnd, POINT pt )
{
#ifdef DEBUG_NONCLIENT
printf( "NC_HandleNCHitTest: hwnd=%x pt=%d,%d\n", hwnd, pt.x, pt.y );
#endif
if (hwnd == GetCapture()) return HTCLIENT;
return NC_InternalNCHitTest( hwnd, pt );
}
/*********************************************************************** /***********************************************************************
* NC_DrawSysButton * NC_DrawSysButton
*/ */
@ -323,18 +329,12 @@ void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
{ {
RECT rect; RECT rect;
WND *wndPtr = WIN_FindWndPtr( hwnd ); WND *wndPtr = WIN_FindWndPtr( hwnd );
HDC hdcMem = CreateCompatibleDC( hdc );
if (hdcMem)
{
NC_GetInsideRect( hwnd, &rect ); NC_GetInsideRect( hwnd, &rect );
if (wndPtr->dwStyle & WS_CHILD) GRAPH_DrawBitmap( hdc, (wndPtr->dwStyle & WS_CHILD) ?
SelectObject( hdcMem, hbitmapMDIClose ); hbitmapMDIClose : hbitmapClose,
else rect.left, rect.top,
SelectObject( hdcMem, hbitmapClose ); 1, 1, SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
BitBlt( hdc, rect.left, rect.top, SYSMETRICS_CXSIZE, down ? NOTSRCCOPY : SRCCOPY );
SYSMETRICS_CYSIZE, hdcMem, 1, 1, down ? NOTSRCCOPY : SRCCOPY );
DeleteDC( hdcMem );
}
} }
@ -344,17 +344,12 @@ void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
static void NC_DrawMaxButton( HWND hwnd, HDC hdc, BOOL down ) static void NC_DrawMaxButton( HWND hwnd, HDC hdc, BOOL down )
{ {
RECT rect; RECT rect;
HDC hdcMem = CreateCompatibleDC( hdc );
if (hdcMem)
{
NC_GetInsideRect( hwnd, &rect ); NC_GetInsideRect( hwnd, &rect );
if (IsZoomed(hwnd)) GRAPH_DrawBitmap( hdc, (IsZoomed(hwnd) ?
SelectObject( hdcMem, down ? hbitmapRestoreD : hbitmapRestore ); (down ? hbitmapRestoreD : hbitmapRestore) :
else SelectObject( hdcMem, down ? hbitmapMaximizeD : hbitmapMaximize ); (down ? hbitmapMaximizeD : hbitmapMaximize)),
BitBlt( hdc, rect.right - SYSMETRICS_CXSIZE - 1, rect.top - 1, rect.right - SYSMETRICS_CXSIZE - 1, rect.top - 1,
SYSMETRICS_CXSIZE+2, SYSMETRICS_CYSIZE+2, hdcMem, 0, 0, SRCCOPY); 0, 0, SYSMETRICS_CXSIZE+2, SYSMETRICS_CYSIZE+2, SRCCOPY );
DeleteDC( hdcMem );
}
} }
@ -365,18 +360,11 @@ static void NC_DrawMinButton( HWND hwnd, HDC hdc, BOOL down )
{ {
RECT rect; RECT rect;
WND *wndPtr = WIN_FindWndPtr( hwnd ); WND *wndPtr = WIN_FindWndPtr( hwnd );
HDC hdcMem = CreateCompatibleDC( hdc );
if (hdcMem)
{
NC_GetInsideRect( hwnd, &rect ); NC_GetInsideRect( hwnd, &rect );
if (wndPtr->dwStyle & WS_MAXIMIZEBOX) if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= SYSMETRICS_CXSIZE + 1;
rect.right -= SYSMETRICS_CXSIZE + 1; GRAPH_DrawBitmap( hdc, (down ? hbitmapMinimizeD : hbitmapMinimize),
if (down) SelectObject( hdcMem, hbitmapMinimizeD ); rect.right - SYSMETRICS_CXSIZE - 1, rect.top - 1,
else SelectObject( hdcMem, hbitmapMinimize ); 0, 0, SYSMETRICS_CXSIZE+2, SYSMETRICS_CYSIZE+2, SRCCOPY );
BitBlt( hdc, rect.right - SYSMETRICS_CXSIZE - 1, rect.top - 1,
SYSMETRICS_CXSIZE+2, SYSMETRICS_CYSIZE+2, hdcMem, 0, 0, SRCCOPY);
DeleteDC( hdcMem );
}
} }
@ -583,6 +571,27 @@ void NC_DoNCPaint( HWND hwnd, HRGN hrgn, BOOL active, BOOL suppress_menupaint )
OffsetRgn( hrgn, xoffset, yoffset ); /* Restore region */ OffsetRgn( hrgn, xoffset, yoffset ); /* Restore region */
} }
if (!hdc) return; 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, if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
wndPtr->rectClient.top-wndPtr->rectWindow.top, wndPtr->rectClient.top-wndPtr->rectWindow.top,
wndPtr->rectClient.right-wndPtr->rectWindow.left, wndPtr->rectClient.right-wndPtr->rectWindow.left,
@ -628,8 +637,7 @@ void NC_DoNCPaint( HWND hwnd, HRGN hrgn, BOOL active, BOOL suppress_menupaint )
{ {
RECT r = rect; RECT r = rect;
r.bottom = rect.top + SYSMETRICS_CYMENU; /* default height */ r.bottom = rect.top + SYSMETRICS_CYMENU; /* default height */
rect.top += MENU_DrawMenuBar( hdc, &r, (HMENU)wndPtr->wIDmenu, rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
suppress_menupaint );
} }
if (wndPtr->dwStyle & (WS_VSCROLL | WS_HSCROLL)) { if (wndPtr->dwStyle & (WS_VSCROLL | WS_HSCROLL)) {
@ -665,46 +673,6 @@ void NC_DoNCPaint( HWND hwnd, HRGN hrgn, BOOL active, BOOL suppress_menupaint )
} }
NC_DoNCPaintIcon(HWND hwnd)
{
WND *wndPtr = WIN_FindWndPtr(hwnd);
PAINTSTRUCT ps;
HDC hdc;
int ret;
DC *dc;
GC testgc;
int s;
char buffer[256];
printf("painting icon\n");
if (wndPtr == NULL) {
printf("argh, can't find an icon to draw\n");
return;
}
hdc = BeginPaint(hwnd, &ps);
ret = DrawIcon(hdc, 100/2 - 16, 0, wndPtr->hIcon);
printf("ret is %d\n", ret);
if (s=GetWindowText(hwnd, buffer, 256))
{
/*SetBkColor(hdc, TRANSPARENT); */
TextOut(hdc, 0, 32, buffer, s);
}
EndPaint(hwnd, &ps);
printf("done painting icon\n");
}
LONG NC_HandleNCPaintIcon( HWND hwnd )
{
NC_DoNCPaintIcon(hwnd);
return 0;
}
/*********************************************************************** /***********************************************************************
* NC_HandleNCPaint * NC_HandleNCPaint
@ -761,8 +729,8 @@ LONG NC_HandleSetCursor( HWND hwnd, WORD wParam, LONG lParam )
CURSOR_SetWinCursor( hwnd, classPtr->wc.hCursor ); CURSOR_SetWinCursor( hwnd, classPtr->wc.hCursor );
return TRUE; return TRUE;
} }
else return FALSE;
} }
break;
case HTLEFT: case HTLEFT:
case HTRIGHT: case HTRIGHT:
@ -830,7 +798,7 @@ static LONG NC_StartSizeMove( HWND hwnd, WORD wParam, POINT *capturePoint )
switch(msg.message) switch(msg.message)
{ {
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
hittest = NC_InternalNCHitTest( hwnd, msg.pt ); hittest = NC_HandleNCHitTest( hwnd, msg.pt );
pt = msg.pt; pt = msg.pt;
if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT)) if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
hittest = 0; hittest = 0;
@ -890,7 +858,7 @@ static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT pt )
POINT minTrack, maxTrack, capturePoint = pt; POINT minTrack, maxTrack, capturePoint = pt;
WND * wndPtr = WIN_FindWndPtr( hwnd ); WND * wndPtr = WIN_FindWndPtr( hwnd );
if (IsZoomed(hwnd) || IsIconic(hwnd) || !IsWindowVisible(hwnd)) return; if (IsZoomed(hwnd) || !IsWindowVisible(hwnd)) return;
hittest = wParam & 0x0f; hittest = wParam & 0x0f;
thickframe = HAS_THICKFRAME( wndPtr->dwStyle ); thickframe = HAS_THICKFRAME( wndPtr->dwStyle );
@ -1053,7 +1021,7 @@ static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
BOOL oldstate = pressed; BOOL oldstate = pressed;
MSG_GetHardwareMessage( &msg ); MSG_GetHardwareMessage( &msg );
pressed = (NC_InternalNCHitTest( hwnd, msg.pt ) == wParam); pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
if (pressed != oldstate) if (pressed != oldstate)
{ {
if (wParam == HTMINBUTTON) NC_DrawMinButton( hwnd, hdc, pressed ); if (wParam == HTMINBUTTON) NC_DrawMinButton( hwnd, hdc, pressed );
@ -1103,7 +1071,7 @@ static void NC_TrackScrollBar( HWND hwnd, WORD wParam, POINT pt )
do do
{ {
MSG_GetHardwareMessage( &msg ); MSG_GetHardwareMessage( &msg );
ScreenToClient( msg.hwnd, &msg.pt ); ScreenToClient( hwnd, &msg.pt );
switch(msg.message) switch(msg.message)
{ {
case WM_LBUTTONUP: case WM_LBUTTONUP:
@ -1210,6 +1178,16 @@ LONG NC_HandleNCLButtonDown( HWND hwnd, WORD wParam, LONG lParam )
*/ */
LONG NC_HandleNCLButtonDblClk( HWND hwnd, WORD wParam, LONG lParam ) 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 */ switch(wParam) /* Hit test */
{ {
case HTCAPTION: case HTCAPTION:
@ -1247,8 +1225,7 @@ LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt )
break; break;
case SC_MINIMIZE: case SC_MINIMIZE:
ICON_Iconify( hwnd ); ShowWindow( hwnd, SW_MINIMIZE );
/*ShowWindow( hwnd, SW_MINIMIZE );*/
break; break;
case SC_MAXIMIZE: case SC_MAXIMIZE:
@ -1256,7 +1233,6 @@ LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt )
break; break;
case SC_RESTORE: case SC_RESTORE:
ICON_Deiconify(hwnd);
ShowWindow( hwnd, SW_RESTORE ); ShowWindow( hwnd, SW_RESTORE );
break; break;

View File

@ -98,6 +98,14 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
if (!hwnd) hwnd = GetDesktopWindow(); if (!hwnd) hwnd = GetDesktopWindow();
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE; 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 ); GetClientRect( hwnd, &rectClient );
rectWindow = wndPtr->rectWindow; rectWindow = wndPtr->rectWindow;
OffsetRect(&rectWindow, -wndPtr->rectClient.left, -wndPtr->rectClient.top); OffsetRect(&rectWindow, -wndPtr->rectClient.left, -wndPtr->rectClient.top);

View File

@ -135,6 +135,24 @@ static WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout,
if (!timeout) return 0; if (!timeout) return 0;
if (!hwnd && !proc) 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 */ /* Find a free timer */
for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++) for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)

View File

@ -251,8 +251,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
CREATESTRUCT *createStruct; CREATESTRUCT *createStruct;
HANDLE hcreateStruct; HANDLE hcreateStruct;
int wmcreate; int wmcreate;
XSetWindowAttributes win_attr, icon_attr; XSetWindowAttributes win_attr;
int iconWidth, iconHeight;
#ifdef DEBUG_WIN #ifdef DEBUG_WIN
printf( "CreateWindowEx: %04X '%s' '%s' %04X %d,%d %dx%d %04X %04X %04X %08X\n", printf( "CreateWindowEx: %04X '%s' '%s' %04X %d,%d %dx%d %04X %04X %04X %08X\n",
@ -373,11 +372,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
/* Only select focus events on top-level override-redirect windows */ /* Only select focus events on top-level override-redirect windows */
if (win_attr.override_redirect) win_attr.event_mask |= FocusChangeMask; if (win_attr.override_redirect) win_attr.event_mask |= FocusChangeMask;
} }
if (Options.nobackingstore) win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
win_attr.backing_store = NotUseful;
else
win_attr.backing_store = Always;
win_attr.save_under = ((classPtr->wc.style & CS_SAVEBITS) != 0); win_attr.save_under = ((classPtr->wc.style & CS_SAVEBITS) != 0);
WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack ); WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
@ -403,42 +398,22 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
XStoreName( display, wndPtr->window, windowName ); XStoreName( display, wndPtr->window, windowName );
/* create icon window */ /*
* store icon handle, icon handle is kept in class. If we
icon_attr.override_redirect = rootWindow==DefaultRootWindow(display); * have an icon, make the icon size the size of the icon,
icon_attr.background_pixel = WhitePixelOfScreen(screen); * if we don't have an icon, just give it 64x64
icon_attr.event_mask = ExposureMask | KeyPressMask | */
ButtonPressMask | ButtonReleaseMask;
wndPtr->hIcon = classPtr->wc.hIcon; wndPtr->hIcon = classPtr->wc.hIcon;
if (wndPtr->hIcon != (HICON)NULL) { if (wndPtr->hIcon != (HICON)NULL) {
ICONALLOC *lpico; ICONALLOC *lpico;
lpico = (ICONALLOC *)GlobalLock(wndPtr->hIcon); lpico = (ICONALLOC *)GlobalLock(wndPtr->hIcon);
printf("icon is %d x %d\n", wndPtr->iconWidth = (int)lpico->descriptor.Width;
(int)lpico->descriptor.Width, wndPtr->iconHeight = (int)lpico->descriptor.Height;
(int)lpico->descriptor.Height);
iconWidth = (int)lpico->descriptor.Width;
iconHeight = (int)lpico->descriptor.Height;
} else { } else {
printf("icon was NULL\n"); wndPtr->iconWidth = 64;
iconWidth = 64; wndPtr->iconHeight = 64;
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 #ifdef DEBUG_MENU
printf("CreateWindowEx // menu=%04X instance=%04X classmenu=%08X !\n", printf("CreateWindowEx // menu=%04X instance=%04X classmenu=%08X !\n",
menu, instance, classPtr->wc.lpszMenuName); menu, instance, classPtr->wc.lpszMenuName);
@ -505,11 +480,12 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
else CURSOR_SetWinCursor( hwnd, LoadCursor( 0, IDC_ARROW )); else CURSOR_SetWinCursor( hwnd, LoadCursor( 0, IDC_ARROW ));
EVENT_RegisterWindow( wndPtr->window, hwnd ); EVENT_RegisterWindow( wndPtr->window, hwnd );
EVENT_RegisterWindow( wndPtr->icon, hwnd );
WIN_SendParentNotify( hwnd, WM_CREATE, MAKELONG( hwnd, wndPtr->wIDmenu ) ); WIN_SendParentNotify( hwnd, WM_CREATE, MAKELONG( hwnd, wndPtr->wIDmenu ) );
if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW ); if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
/* if (style & WS_MINIMIZE) ShowWindow( hwnd, SW_MINIMIZE ); */
#ifdef DEBUG_WIN #ifdef DEBUG_WIN
printf( "CreateWindowEx: return %04X \n", hwnd); printf( "CreateWindowEx: return %04X \n", hwnd);
#endif #endif
@ -805,6 +781,27 @@ HWND GetParent(HWND hwnd)
return wndPtr->hwndParent; 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) * IsChild (USER.48)

View File

@ -10,9 +10,12 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993";
#include "user.h" #include "user.h"
#include "win.h" #include "win.h"
#include "message.h" #include "message.h"
#include <assert.h>
static HWND hwndActive = 0; /* Currently active window */ static HWND hwndActive = 0; /* Currently active window */
/* #define DEBUG_WIN /**/
/*********************************************************************** /***********************************************************************
* GetWindowRect (USER.32) * GetWindowRect (USER.32)
@ -220,6 +223,45 @@ BOOL MoveWindow( HWND hwnd, short x, short y, short cx, short cy, BOOL repaint)
} }
/*
* hwnd is the handle to the first child window to hide
*/
static void WINPOS_hideChildren(HWND hwnd)
{
WND *wndPtr;
while (hwnd) {
ShowWindow(hwnd, SW_HIDE);
wndPtr = WIN_FindWndPtr(hwnd);
assert(wndPtr);
WINPOS_hideChildren(wndPtr->hwndChild);
hwnd = wndPtr->hwndNext;
}
}
static void WINPOS_ChildrenComeOutToPlay(HWND hwnd)
{
WND *wndPtr;
while (hwnd) {
/*
* we shouldn't really be calling SW_SHOWNOACTIVATE
* here because we wake up all windows, even the ones
* the user has decided to iconify or hide
*
* have to use SHOWNOACTIVATE instead of SHOWNORMAL
* since we are traversing the window tree and don't
* want windows linked/unlined under us
*/
ShowWindow(hwnd, SW_SHOWNOACTIVATE);
wndPtr = WIN_FindWndPtr(hwnd);
assert(wndPtr);
WINPOS_ChildrenComeOutToPlay(wndPtr->hwndChild);
hwnd = wndPtr->hwndNext;
}
}
/*********************************************************************** /***********************************************************************
* ShowWindow (USER.42) * ShowWindow (USER.42)
*/ */
@ -227,41 +269,72 @@ BOOL ShowWindow( HWND hwnd, int cmd )
{ {
WND * wndPtr = WIN_FindWndPtr( hwnd ); WND * wndPtr = WIN_FindWndPtr( hwnd );
BOOL wasVisible; BOOL wasVisible;
BOOL wasIconic;
int swpflags = 0; int swpflags = 0;
if (!wndPtr) return FALSE;
#ifdef DEBUG_WIN #ifdef DEBUG_WIN
printf("ShowWindow: hwnd=%04X, cmd=%d\n", hwnd, cmd); printf("ShowWindow: hwnd=%04X, cmd=%d\n", hwnd, cmd);
#endif #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; wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
switch(cmd) switch(cmd)
{ {
case SW_HIDE: 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 | swpflags |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER; SWP_NOACTIVATE | SWP_NOZORDER;
break; break;
case SW_SHOWMINNOACTIVE: case SW_SHOWMINNOACTIVE:
case SW_SHOWMINIMIZED: case SW_SHOWMINIMIZED:
case SW_SHOWMAXIMIZED:
case SW_MINIMIZE: case SW_MINIMIZE:
wndPtr->dwStyle |= WS_MINIMIZE; wndPtr->dwStyle |= WS_MINIMIZE;
swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER; 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; break;
case SW_SHOWNA: case SW_SHOWNA:
case SW_MAXIMIZE: case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE: */
case SW_SHOW: case SW_SHOW:
swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE; swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
break; break;
case SW_NORMAL:
case SW_SHOWNORMAL: case SW_SHOWNORMAL: /* same as SW_NORMAL: */
case SW_SHOWNOACTIVATE: case SW_SHOWNOACTIVATE:
case SW_RESTORE: case SW_RESTORE:
wasIconic = IsIconic(hwnd);
wndPtr->dwStyle &= ~WS_MINIMIZE; wndPtr->dwStyle &= ~WS_MINIMIZE;
wndPtr->dwStyle &= ~WS_MAXIMIZE; wndPtr->dwStyle &= ~WS_MAXIMIZE;
swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE; swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
@ -270,8 +343,17 @@ BOOL ShowWindow( HWND hwnd, int cmd )
swpflags |= SWP_NOZORDER; swpflags |= SWP_NOZORDER;
if (GetActiveWindow()) swpflags |= SWP_NOACTIVATE; 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; break;
} }
SendMessage( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 ); SendMessage( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 );
SetWindowPos( hwnd, 0, 0, 0, 0, 0, swpflags ); SetWindowPos( hwnd, 0, 0, 0, 0, 0, swpflags );
@ -288,6 +370,7 @@ BOOL ShowWindow( HWND hwnd, int cmd )
SendMessage( hwnd, WM_MOVE, 0, SendMessage( hwnd, WM_MOVE, 0,
MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) ); MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
} }
return wasVisible; return wasVisible;
} }