1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00
wine/controls/button.c
Alexandre Julliard dba420a731 Release 940201
Tue Feb  1 21:14:47 1994  Bob Amstadt  (bob@pooh)

	* [loader/selector.c]
	Added function CreateNewSegments().  Modified IPCCopySelector
	to allow aliasing to any arbitrary memory space.

	* [memory/global.c]
	Fixed potential bug in GlobalGetFreeSegments().

	* [memory/linear.c]
	Created functions GlobalLinearLock() and GlobalLinearUnlock().

Tue Feb  1 05:51:43 1994  julliard@di.epfl.ch (Alexandre Julliard)

	* [controls/widgets.c]
	Removed CAPTION window class.

	* [loader/cursor.c]
	Bug fix in LoadCursor(): don't allocate memory every time for
	built-in cursors.

	* [windows/clipping.c]
	Invalidate child windows in InvalidateRgn().

	* [windows/defwnd.c]
	Added repaint of the caption when changing window text.

	* [windows/event.c]
	Modified SetCapture() to allow keyboard events while capturing.

	* [windows/message.c]
	New function MSG_GetHardwareMessage(), to do mouse tracking
	without returning control to the Windows program.

	* [windows/nonclient.c]
	A couple of changes in frame drawing for DLGMODALFRAME windows.
	Rewritten window moving code, to use MSG_GetHardwareMessage()
	instead of non-client mouse events (this is the way Windows
	does it), and to send WM_ENTERSIZEMOVE messages.
	Removed WM_NCBUTTONUP and WM_NCMOUSEMOVE handlers.

	* [windows/win.c]
	Allocate temporary structures on the USER heap instead of
	using GlobalAlloc().

	* [windows/winpos.c]
	Added function WINPOS_GetMinMaxInfo() to get sizing informations.

Jan 31, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [windows/nonclient.c]
	Call to StdDrawScrollBar() during NC's drawing.
	Call to NC_ScrollBarButtonDown() on NC mouse events WM_LBUTTONDOWN.
	Call to NC_ScrollBarButtonUp() on NC mouse events WM_LBUTTONUP.
	Call to NC_ScrollBarMouseMove() on NC mouse events WM_MOUSEMOVE.

	* [controls/menu.c]
	New GetSubMenu() function.
	Move GetMenu() & SetMenu() functions from 'windows/win.c'.

	* [controls/listbox.c]
	Start changes to satisfy recent changes in scrollbars/windows.

	* [loader/resource.c]
	Put some code in LoadAccelerators() stub.
	New TranslateAccelerator() function.

	* [windows/win.c]
	Remove GetMenu() & SetMenu() functions.
	Call to NC_CreateScrollBars() if required by CreateWindow().

Mon Jan 24 10:40:10 EST 1994 John Richardson (jrichard@cs.uml.edu)

        * [window/win.c]
        Added functions EnumWindows, EnumChildWindows, and helper
        WIN_EnumChildWin.  EnumWindows won't list all wine windows
        because GetDesktopWindow isn't complete.  However, the code
        is in place for it to work correctly and only needs 
        GetDesktopWindow to do so.  

Tue Jan 25 05:51:47 1994  julliard@di.epfl.ch (Alexandre Julliard)

	* [windows/defwnd.c]
	Added handling of activation messages (WM_ACTIVATE,
	WM_NCACTIVATE, WM_MOUSEACTIVATE)

	* [windows/event.c]
	De-activate the window when losing input focus.

	* [windows/focus.c]
	Bug fix in SetFocus().

	* [windows/message.c]
	Added activation of the window on mouse-clicks.

	* [windows/nonclient.c]
	Changed non-client area painting to use the correct colors
	depending upon the activation state.
	Added WM_NCACTIVATE message handling.
	Fixed a couple of bugs in window moving and resizing.

	* [windows/winpos.c]
	Implemented Get/SetActiveWindow().
	Implemented SWP_NOACTIVATE flag in SetWindowPos().

Jan 17, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [misc/message.c]
	MessageBox has a CaptionBar for his title except for
		MB_SYSTEMMODAL with MB_ICONHAND.

	* [windows/nonclient.c]
	Call to NC_TrackSysMenu on SysMenu button mouse click.

	* [windows/defwnd.c]
	Call to NC_TrackSysMenu on Alt key (VK_MENU).

	* [controls/menu.c]
	New GetSystemMenu() function.
	New CopySystemMenu() internal function.
	New NC_TrackSysMenu() internal function.

	* [include/windows.h]
	New WM_INITMENU, WM_INITMENUPOPUP, WM_MENUSELECT & WM_MENUCHAR defines.
1994-02-02 06:48:31 +00:00

1064 lines
26 KiB
C

/* File: button.c -- Button type widgets
*
* Copyright (C) 1993 Johannes Ruscheinski
* Copyright (C) 1993 David Metcalfe
*/
static char Copyright1[] = "Copyright Johannes Ruscheinski, 1993";
static char Copyright2[] = "Copyright David Metcalfe, 1993";
#include <windows.h>
#include "win.h"
#include "user.h"
LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam);
static COLORREF color_windowtext, color_windowframe, color_btnface,
color_btnshadow, color_btntext, color_btnhighlight;
static BOOL pressed;
#define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \
SendMessage(GetParent(hWndCntrl), WM_COMMAND, \
GetDlgCtrlID(hWndCntrl), MAKELPARAM(hWndCntrl, wNotifyCode));
#define DIM(array) ((sizeof array)/(sizeof array[0]))
static LONG PB_Paint(HWND hWnd);
static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
static LONG PB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam);
static LONG PB_KillFocus(HWND hwnd);
static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc);
static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc);
static LONG CB_Paint(HWND hWnd);
static LONG CB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
static LONG CB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
static LONG CB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam);
static LONG CB_KillFocus(HWND hWnd);
static LONG CB_SetCheck(HWND hWnd, WORD wParam);
static LONG CB_GetCheck(HWND hWnd);
static LONG RB_Paint(HWND hWnd);
static LONG RB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
static LONG RB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
static LONG RB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam);
static LONG RB_KillFocus(HWND hWnd);
static LONG RB_SetCheck(HWND hWnd, WORD wParam);
static LONG RB_GetCheck(HWND hWnd);
static LONG GB_Paint(HWND hWnd);
static LONG UB_Paint(HWND hWnd);
static LONG UB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
static LONG UB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
static LONG UB_KillFocus(HWND hWnd);
static LONG OB_Paint(HWND hWnd);
static LONG OB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
static LONG OB_KillFocus(HWND hWnd);
typedef struct
{
LONG (*paintfn)();
LONG (*lButtonDownfn)();
LONG (*lButtonUpfn)();
LONG (*lButtonDblClkfn)();
LONG (*killFocusfn)();
LONG (*setCheckfn)();
LONG (*getCheckfn)();
} BTNFN;
#define MAX_BTN_TYPE 12
static BTNFN btnfn[MAX_BTN_TYPE] =
{
{
(LONG(*)())PB_Paint, /* BS_PUSHBUTTON */
(LONG(*)())PB_LButtonDown,
(LONG(*)())PB_LButtonUp,
(LONG(*)())PB_LButtonDblClk,
(LONG(*)())PB_KillFocus,
(LONG(*)())NULL,
(LONG(*)())NULL
},
{
(LONG(*)())PB_Paint, /* BS_DEFPUSHBUTTON */
(LONG(*)())PB_LButtonDown,
(LONG(*)())PB_LButtonUp,
(LONG(*)())PB_LButtonDblClk,
(LONG(*)())PB_KillFocus,
(LONG(*)())NULL,
(LONG(*)())NULL
},
{
(LONG(*)())CB_Paint, /* BS_CHECKBOX */
(LONG(*)())CB_LButtonDown,
(LONG(*)())CB_LButtonUp,
(LONG(*)())CB_LButtonDblClk,
(LONG(*)())CB_KillFocus,
(LONG(*)())CB_SetCheck,
(LONG(*)())CB_GetCheck
},
{
(LONG(*)())CB_Paint, /* BS_AUTOCHECKBOX */
(LONG(*)())CB_LButtonDown,
(LONG(*)())CB_LButtonUp,
(LONG(*)())CB_LButtonDblClk,
(LONG(*)())CB_KillFocus,
(LONG(*)())CB_SetCheck,
(LONG(*)())CB_GetCheck
},
{
(LONG(*)())RB_Paint, /* BS_RADIOBUTTON */
(LONG(*)())RB_LButtonDown,
(LONG(*)())RB_LButtonUp,
(LONG(*)())RB_LButtonDblClk,
(LONG(*)())RB_KillFocus,
(LONG(*)())RB_SetCheck,
(LONG(*)())RB_GetCheck
},
{
(LONG(*)())CB_Paint, /* BS_3STATE */
(LONG(*)())CB_LButtonDown,
(LONG(*)())CB_LButtonUp,
(LONG(*)())CB_LButtonDblClk,
(LONG(*)())CB_KillFocus,
(LONG(*)())CB_SetCheck,
(LONG(*)())CB_GetCheck
},
{
(LONG(*)())CB_Paint, /* BS_AUTO3STATE */
(LONG(*)())CB_LButtonDown,
(LONG(*)())CB_LButtonUp,
(LONG(*)())CB_LButtonDblClk,
(LONG(*)())CB_KillFocus,
(LONG(*)())CB_SetCheck,
(LONG(*)())CB_GetCheck
},
{
(LONG(*)())GB_Paint, /* BS_GROUPBOX */
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL
},
{
(LONG(*)())UB_Paint, /* BS_USERBUTTON */
(LONG(*)())UB_LButtonDown,
(LONG(*)())UB_LButtonUp,
(LONG(*)())NULL,
(LONG(*)())UB_KillFocus,
(LONG(*)())NULL,
(LONG(*)())NULL
},
{
(LONG(*)())RB_Paint, /* BS_AUTORADIOBUTTON */
(LONG(*)())RB_LButtonDown,
(LONG(*)())RB_LButtonUp,
(LONG(*)())RB_LButtonDblClk,
(LONG(*)())RB_KillFocus,
(LONG(*)())RB_SetCheck,
(LONG(*)())RB_GetCheck
},
{
(LONG(*)())NULL, /* Not defined */
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL
},
{
(LONG(*)())OB_Paint, /* BS_OWNERDRAW */
(LONG(*)())OB_LButtonDown,
(LONG(*)())OB_LButtonUp,
(LONG(*)())NULL,
(LONG(*)())OB_KillFocus,
(LONG(*)())NULL,
(LONG(*)())NULL
},
};
LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam)
{
LONG lResult = 0;
HDC hDC;
RECT rc;
WND *wndPtr = WIN_FindWndPtr(hWnd);
LONG style = wndPtr->dwStyle & 0x0000000F;
switch (uMsg) {
/* case WM_GETDLGCODE:
lResult = DLGC_BUTTON;
break;
*/
case WM_ENABLE:
InvalidateRect(hWnd, NULL, FALSE);
break;
case WM_CREATE:
if (style < 0L || style >= (LONG)DIM(btnfn))
lResult = -1L;
else
{
/* initialise colours used for button rendering: */
color_windowtext = GetSysColor(COLOR_WINDOWTEXT);
color_windowframe = GetSysColor(COLOR_WINDOWFRAME);
color_btnface = GetSysColor(COLOR_BTNFACE);
color_btnshadow = GetSysColor(COLOR_BTNSHADOW);
color_btntext = GetSysColor(COLOR_BTNTEXT);
color_btnhighlight = GetSysColor(COLOR_BTNHIGHLIGHT);
(WORD)(*(wndPtr->wExtra)) = 0;
pressed = FALSE;
lResult = 0L;
}
break;
case WM_PAINT:
if (btnfn[style].paintfn)
(btnfn[style].paintfn)(hWnd);
break;
case WM_LBUTTONDOWN:
if (btnfn[style].lButtonDownfn)
(btnfn[style].lButtonDownfn)(hWnd, wParam, lParam);
break;
case WM_LBUTTONUP:
if (btnfn[style].lButtonUpfn)
(btnfn[style].lButtonUpfn)(hWnd, wParam, lParam);
break;
case WM_LBUTTONDBLCLK:
if (btnfn[style].lButtonDblClkfn)
(btnfn[style].lButtonDblClkfn)(hWnd, wParam, lParam);
break;
case WM_SETFOCUS:
break;
case WM_KILLFOCUS:
if (btnfn[style].killFocusfn)
(btnfn[style].killFocusfn)(hWnd);
break;
case WM_SYSCOLORCHANGE:
color_windowtext = GetSysColor(COLOR_WINDOWTEXT);
color_windowframe = GetSysColor(COLOR_WINDOWFRAME);
color_btnface = GetSysColor(COLOR_BTNFACE);
color_btnshadow = GetSysColor(COLOR_BTNSHADOW);
color_btntext = GetSysColor(COLOR_BTNTEXT);
color_btnhighlight = GetSysColor(COLOR_BTNHIGHLIGHT);
InvalidateRect(hWnd, NULL, TRUE);
break;
case BM_SETCHECK:
if (btnfn[style].setCheckfn)
(btnfn[style].setCheckfn)(hWnd, wParam);
break;
case BM_GETCHECK:
if (btnfn[style].getCheckfn)
return (btnfn[style].getCheckfn)(hWnd);
break;
default:
lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
break;
}
GlobalUnlock(hWnd);
return lResult;
}
/**********************************************************************
* Push Button Functions
*/
static LONG PB_Paint(HWND hWnd)
{
PAINTSTRUCT ps;
RECT rc;
HDC hDC;
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc);
if (pressed)
DrawPressedPushButton(hDC, hWnd, rc);
else
DrawRaisedPushButton(hDC, hWnd, rc);
EndPaint(hWnd, &ps);
}
static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
{
/* SetFocus(hWnd); */
SetCapture(hWnd);
pressed = TRUE;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
pressed = FALSE;
ReleaseCapture();
GetClientRect(hWnd, &rc);
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_CLICKED);
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
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);
}
static LONG PB_KillFocus(HWND hWnd)
{
pressed = FALSE;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc)
{
HPEN hOldPen, hFramePen;
HBRUSH hOldBrush, hShadowBrush, hHighlightBrush, hBackgrndBrush;
HRGN rgn1, rgn2, rgn;
int len;
static char text[50+1];
POINT points[6];
DWORD dwTextSize;
int delta;
TEXTMETRIC tm;
int i;
hFramePen = CreatePen(PS_SOLID, 1, color_windowframe);
hBackgrndBrush = CreateSolidBrush(color_btnface);
hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hFramePen);
hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBackgrndBrush);
SetBkMode(hDC, TRANSPARENT);
rgn = CreateRectRgn(0, 0, 0, 0);
rgn1 = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
SendMessage(GetParent(hButton), WM_CTLCOLOR, (WORD)hDC,
MAKELPARAM(hButton, CTLCOLOR_BTN));
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
/* draw button label, if any: */
len = GetWindowText(hButton, text, sizeof text);
if (len >= 1) {
rc.left--; rc.bottom--;
DrawText(hDC, text, len, &rc,
DT_SINGLELINE | DT_CENTER| DT_VCENTER);
}
/* draw button highlight */
points[0].x = rc.left+2;
points[0].y = rc.bottom;
points[1].x = rc.left+4;
points[1].y = rc.bottom-2;
points[2].x = rc.left+4;
points[2].y = rc.top+3;
points[3].x = rc.right-3;
points[3].y = rc.top+3;
points[4].x = rc.right-1;
points[4].y = rc.top+1;
points[5].x = rc.left+2;
points[5].y = rc.top+1;
hHighlightBrush = CreateSolidBrush(color_btnhighlight);
rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE);
CombineRgn(rgn, rgn1, rgn2, RGN_AND);
FillRgn(hDC, rgn2, hHighlightBrush);
/* draw button shadow: */
points[0].x = rc.left+2;
points[0].y = rc.bottom;
points[1].x = rc.left+4;
points[1].y = rc.bottom-2;
points[2].x = rc.right-3;
points[2].y = rc.bottom-2;
points[3].x = rc.right-3;
points[3].y = rc.top+3;
points[4].x = rc.right-1;
points[4].y = rc.top;
points[5].x = rc.right-1;
points[5].y = rc.bottom;
hShadowBrush = CreateSolidBrush(color_btnshadow);
rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE);
CombineRgn(rgn, rgn1, rgn2, RGN_AND);
FillRgn(hDC, rgn2, hShadowBrush);
/* do we have the focus? */
if (len >= 1 && GetFocus() == hButton) {
dwTextSize = GetTextExtent(hDC, text, len);
delta = ((rc.right - rc.left) - LOWORD(dwTextSize) - 1) >> 1;
rc.left += delta; rc.right -= delta;
GetTextMetrics(hDC, &tm);
delta = ((rc.bottom - rc.top) - tm.tmHeight - 1) >> 1;
rc.top += delta; rc.bottom -= delta;
DrawFocusRect(hDC, &rc);
}
SelectObject(hDC, (HANDLE)hOldPen);
SelectObject(hDC, (HANDLE)hOldBrush);
DeleteObject((HANDLE)hFramePen);
DeleteObject((HANDLE)hShadowBrush);
DeleteObject((HANDLE)hBackgrndBrush);
DeleteObject((HANDLE)rgn1);
DeleteObject((HANDLE)rgn2);
DeleteObject((HANDLE)rgn);
}
static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc)
{
HPEN hOldPen, hShadowPen, hFramePen;
HBRUSH hOldBrush, hBackgrndBrush;
HRGN rgn1, rgn2, rgn;
int len;
static char text[50+1];
DWORD dwTextSize;
int delta;
TEXTMETRIC tm;
hFramePen = CreatePen(PS_SOLID, 1, color_windowframe);
hBackgrndBrush = CreateSolidBrush(color_btnface);
hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBackgrndBrush);
hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hFramePen);
SetBkMode(hDC, TRANSPARENT);
/* 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);
/* draw button shadow: */
hShadowPen = CreatePen(PS_SOLID, 1, color_btnshadow);
SelectObject(hDC, (HANDLE)hShadowPen);
MoveTo(hDC, rc.left+1, rc.bottom-1);
LineTo(hDC, rc.left+1, rc.top+1);
LineTo(hDC, rc.right-1, rc.top+1);
/* draw button label, if any: */
len = GetWindowText(hButton, text, sizeof text);
if (len >= 1) {
rc.top++; rc.left++;
DrawText(hDC, text, len, &rc,
DT_SINGLELINE | DT_CENTER| DT_VCENTER);
}
/* do we have the focus? */
if (len >= 1 && GetFocus() == hButton) {
dwTextSize = GetTextExtent(hDC, text, len);
delta = ((rc.right - rc.left) - LOWORD(dwTextSize) - 1) >> 1;
rc.left += delta; rc.right -= delta;
GetTextMetrics(hDC, &tm);
delta = ((rc.bottom - rc.top) - tm.tmHeight - 1) >> 1;
rc.top += delta; rc.bottom -= delta;
DrawFocusRect(hDC, &rc);
}
SelectObject(hDC, (HANDLE)hOldPen);
SelectObject(hDC, (HANDLE)hOldBrush);
DeleteObject((HANDLE)hBackgrndBrush);
DeleteObject(SelectObject(hDC, (HANDLE)hFramePen));
DeleteObject(SelectObject(hDC, (HANDLE)hShadowPen));
}
/**********************************************************************
* Check Box Functions
*/
static LONG CB_Paint(HWND hWnd)
{
PAINTSTRUCT ps;
RECT rc, rc3;
HDC hDC;
HPEN hPen, hOldPen;
HBRUSH hBrush, hGrayBrush;
int textlen, delta;
char *text;
HANDLE hText;
TEXTMETRIC tm;
SIZE size;
WND *wndPtr = WIN_FindWndPtr(hWnd);
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc);
hPen = CreatePen(PS_SOLID, 1, color_windowtext);
hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hPen);
hGrayBrush = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
MAKELPARAM(hWnd, CTLCOLOR_BTN));
FillRect(hDC, &rc, hBrush);
textlen = GetWindowTextLength(hWnd);
hText = USER_HEAP_ALLOC(0, textlen+1);
text = USER_HEAP_ADDR(hText);
GetWindowText(hWnd, text, textlen+1);
GetTextMetrics(hDC, &tm);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
Rectangle(hDC, 0, rc.top + delta, tm.tmHeight, tm.tmHeight + delta);
if (pressed)
Rectangle(hDC, 1, rc.top + delta + 1, tm.tmHeight - 1,
tm.tmHeight + delta - 1);
switch ((WORD)(*(wndPtr->wExtra)))
{
case 1:
MoveTo(hDC, 0, rc.top + delta);
LineTo(hDC, tm.tmHeight - 1, tm.tmHeight + delta - 1);
MoveTo(hDC, 0, tm.tmHeight + delta - 1);
LineTo(hDC, tm.tmHeight - 1, rc.top + delta);
break;
case 2:
rc3.left = 1;
rc3.top = rc.top + delta + 1;
rc3.right = tm.tmHeight - 1;
rc3.bottom = tm.tmHeight + delta - 1;
FillRect(hDC, &rc3, hGrayBrush);
break;
}
rc.left = tm.tmHeight + tm.tmAveCharWidth / 2;
DrawText(hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER);
/* do we have the focus? */
if (GetFocus() == hWnd)
{
GetTextExtentPoint(hDC, text, textlen, &size);
rc.top += delta - 1;
rc.bottom -= delta + 1;
rc.left--;
rc.right = rc.left + size.cx + 2;
DrawFocusRect(hDC, &rc);
}
USER_HEAP_FREE(hText);
GlobalUnlock(hWnd);
EndPaint(hWnd, &ps);
}
static LONG CB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
HDC hDC;
TEXTMETRIC tm;
int delta;
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
ReleaseDC(hWnd, hDC);
GetClientRect(hWnd, &rc);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
rc.top += delta;
rc.bottom = tm.tmHeight + delta;
rc.right = tm.tmHeight;
if (PtInRect(&rc, MAKEPOINT(lParam)))
{
/* SetFocus(hWnd); */
SetCapture(hWnd);
pressed = TRUE;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
}
static LONG CB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
HDC hDC;
TEXTMETRIC tm;
int delta;
WND *wndPtr = WIN_FindWndPtr(hWnd);
LONG style;
pressed = FALSE;
ReleaseCapture();
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
ReleaseDC(hWnd, hDC);
GetClientRect(hWnd, &rc);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
rc.top += delta;
rc.bottom = tm.tmHeight + delta;
rc.right = tm.tmHeight;
if (PtInRect(&rc, MAKEPOINT(lParam)))
{
style = wndPtr->dwStyle & 0x0000000F;
if (style == BS_AUTOCHECKBOX)
{
switch ((WORD)(*(wndPtr->wExtra)))
{
case 0:
(WORD)(*(wndPtr->wExtra)) = 1;
break;
case 1:
(WORD)(*(wndPtr->wExtra)) = 0;
break;
}
}
else if (style == BS_AUTO3STATE)
{
switch ((WORD)(*(wndPtr->wExtra)))
{
case 0:
(WORD)(*(wndPtr->wExtra)) = 1;
break;
case 1:
(WORD)(*(wndPtr->wExtra)) = 2;
break;
case 2:
(WORD)(*(wndPtr->wExtra)) = 0;
break;
}
}
NOTIFY_PARENT(hWnd, BN_CLICKED);
}
GlobalUnlock(hWnd);
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
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;
rc.right = tm.tmHeight;
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED);
}
static LONG CB_KillFocus(HWND hWnd)
{
pressed = FALSE;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
static LONG CB_SetCheck(HWND hWnd, WORD wParam)
{
WND *wndPtr = WIN_FindWndPtr(hWnd);
if ((WORD)(*(wndPtr->wExtra)) != wParam)
{
(WORD)(*(wndPtr->wExtra)) = wParam;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
GlobalUnlock(hWnd);
}
static LONG CB_GetCheck(HWND hWnd)
{
WORD wResult;
WND *wndPtr = WIN_FindWndPtr(hWnd);
wResult = (WORD)(*(wndPtr->wExtra));
GlobalUnlock(hWnd);
return (LONG)wResult;
}
/**********************************************************************
* Radio Button Functions
*/
static LONG RB_Paint(HWND hWnd)
{
PAINTSTRUCT ps;
RECT rc;
HDC hDC;
HPEN hPen, hOldPen;
HBRUSH hBrush, hOldBrush;
int textlen, delta;
char *text;
HANDLE hText;
TEXTMETRIC tm;
SIZE size;
WND *wndPtr = WIN_FindWndPtr(hWnd);
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc);
hPen = CreatePen(PS_SOLID, 1, color_windowtext);
hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hPen);
hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
MAKELPARAM(hWnd, CTLCOLOR_BTN));
FillRect(hDC, &rc, hBrush);
textlen = GetWindowTextLength(hWnd);
hText = USER_HEAP_ALLOC(0, textlen+1);
text = USER_HEAP_ADDR(hText);
GetWindowText(hWnd, text, textlen+1);
GetTextMetrics(hDC, &tm);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
Ellipse(hDC, 0, rc.top + delta, tm.tmHeight, tm.tmHeight + delta);
if (pressed)
Ellipse(hDC, 1, rc.top + delta + 1, tm.tmHeight - 1,
tm.tmHeight + delta - 1);
if ((WORD)(*(wndPtr->wExtra)) == 1)
{
hBrush = CreateSolidBrush(color_windowtext);
hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBrush);
Ellipse(hDC, 3, rc.top + delta + 3, tm.tmHeight - 3,
tm.tmHeight + delta -3);
SelectObject(hDC, (HANDLE)hOldBrush);
DeleteObject((HANDLE)hBrush);
}
rc.left = tm.tmHeight + tm.tmAveCharWidth / 2;
DrawText(hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER);
/* do we have the focus? */
if (GetFocus() == hWnd)
{
GetTextExtentPoint(hDC, text, textlen, &size);
rc.top += delta - 1;
rc.bottom -= delta + 1;
rc.left--;
rc.right = rc.left + size.cx + 2;
DrawFocusRect(hDC, &rc);
}
USER_HEAP_FREE(hText);
GlobalUnlock(hWnd);
EndPaint(hWnd, &ps);
}
static LONG RB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
HDC hDC;
TEXTMETRIC tm;
int delta;
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
ReleaseDC(hWnd, hDC);
GetClientRect(hWnd, &rc);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
rc.top += delta;
rc.bottom = tm.tmHeight + delta;
rc.right = tm.tmHeight;
if (PtInRect(&rc, MAKEPOINT(lParam)))
{
/* SetFocus(hWnd); */
SetCapture(hWnd);
pressed = TRUE;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
}
static LONG RB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
HDC hDC;
TEXTMETRIC tm;
int delta;
WND *wndPtr = WIN_FindWndPtr(hWnd);
LONG style;
pressed = FALSE;
ReleaseCapture();
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
ReleaseDC(hWnd, hDC);
GetClientRect(hWnd, &rc);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
rc.top += delta;
rc.bottom = tm.tmHeight + delta;
rc.right = tm.tmHeight;
if (PtInRect(&rc, MAKEPOINT(lParam)))
{
style = wndPtr->dwStyle & 0x0000000F;
if (style == BS_AUTORADIOBUTTON)
(WORD)(*(wndPtr->wExtra)) = 1;
NOTIFY_PARENT(hWnd, BN_CLICKED);
}
GlobalUnlock(hWnd);
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
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;
rc.right = tm.tmHeight;
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED);
}
static LONG RB_KillFocus(HWND hWnd)
{
pressed = FALSE;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
static LONG RB_SetCheck(HWND hWnd, WORD wParam)
{
WND *wndPtr = WIN_FindWndPtr(hWnd);
if ((WORD)(*(wndPtr->wExtra)) != wParam)
{
(WORD)(*(wndPtr->wExtra)) = wParam;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
GlobalUnlock(hWnd);
}
static LONG RB_GetCheck(HWND hWnd)
{
WORD wResult;
WND *wndPtr = WIN_FindWndPtr(hWnd);
wResult = (WORD)(*(wndPtr->wExtra));
GlobalUnlock(hWnd);
return (LONG)wResult;
}
/**********************************************************************
* Group Box Functions
*/
static LONG GB_Paint(HWND hWnd)
{
PAINTSTRUCT ps;
RECT rc;
HDC hDC;
HPEN hPen, hOldPen;
HBRUSH hBrush;
int textlen;
char *text;
HANDLE hText;
SIZE size;
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc);
hPen = CreatePen(PS_SOLID, 1, color_windowtext);
hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hPen);
hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
MAKELPARAM(hWnd, CTLCOLOR_BTN));
FillRect(hDC, &rc, hBrush);
textlen = GetWindowTextLength(hWnd);
hText = USER_HEAP_ALLOC(0, textlen+1);
text = USER_HEAP_ADDR(hText);
GetWindowText(hWnd, text, textlen+1);
GetTextExtentPoint(hDC, text, textlen, &size);
rc.top = 5;
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
rc.left = 10;
rc.top = 0;
rc.right = rc.left + size.cx + 1;
rc.bottom = size.cy;
DrawText(hDC, text, textlen, &rc, DT_SINGLELINE);
USER_HEAP_FREE(hText);
EndPaint(hWnd, &ps);
}
/**********************************************************************
* User Button Functions
*/
static LONG UB_Paint(HWND hWnd)
{
PAINTSTRUCT ps;
HDC hDC;
RECT rc;
HBRUSH hBrush;
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc);
hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
MAKELPARAM(hWnd, CTLCOLOR_BTN));
FillRect(hDC, &rc, hBrush);
NOTIFY_PARENT(hWnd, BN_PAINT);
/* do we have the focus? */
if (GetFocus() == hWnd)
DrawFocusRect(hDC, &rc);
EndPaint(hWnd, &ps);
}
static LONG UB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
/* SetFocus(hWnd); */
SetCapture(hWnd);
GetClientRect(hWnd, &rc);
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_HILITE);
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
static LONG UB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
ReleaseCapture();
GetClientRect(hWnd, &rc);
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_UNHILITE);
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
static LONG UB_KillFocus(HWND hWnd)
{
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
/**********************************************************************
* Ownerdrawn Button Functions
*/
static LONG OB_Paint(HWND hWnd)
{
PAINTSTRUCT ps;
HDC hDC;
RECT rc;
HANDLE hDis;
LPDRAWITEMSTRUCT lpdis;
WND *wndPtr = WIN_FindWndPtr(hWnd);
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc);
hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
lpdis->hDC = hDC;
lpdis->itemID = 0;
CopyRect(&lpdis->rcItem, &rc);
lpdis->CtlID = wndPtr->wIDmenu;
lpdis->CtlType = ODT_BUTTON;
lpdis->itemAction = ODA_DRAWENTIRE;
/* printf("ownerdrawn button WM_DRAWITEM CtrlID=%X\n", lpdis->CtlID);*/
SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis);
USER_HEAP_FREE(hDis);
EndPaint(hWnd, &ps);
}
static LONG OB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
{
HDC hDC;
RECT rc;
HANDLE hDis;
LPDRAWITEMSTRUCT lpdis;
WND *wndPtr = WIN_FindWndPtr(hWnd);
/* SetFocus(hWnd); */
SetCapture(hWnd);
hDC = GetDC(hWnd);
GetClientRect(hWnd, &rc);
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_CLICKED);
GetClientRect(hWnd, &rc);
hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
lpdis->hDC = hDC;
lpdis->itemID = 0;
CopyRect(&lpdis->rcItem, &rc);
lpdis->CtlID = wndPtr->wIDmenu;
lpdis->CtlType = ODT_BUTTON;
lpdis->itemAction = ODA_SELECT;
SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis);
USER_HEAP_FREE(hDis);
ReleaseDC(hWnd, hDC);
}
static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
{
HDC hDC;
RECT rc;
HANDLE hDis;
LPDRAWITEMSTRUCT lpdis;
WND *wndPtr = WIN_FindWndPtr(hWnd);
ReleaseCapture();
hDC = GetDC(hWnd);
GetClientRect(hWnd, &rc);
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_CLICKED);
GetClientRect(hWnd, &rc);
hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
lpdis->hDC = hDC;
lpdis->itemID = 0;
CopyRect(&lpdis->rcItem, &rc);
lpdis->CtlID = wndPtr->wIDmenu;
lpdis->CtlType = ODT_BUTTON;
lpdis->itemAction = ODA_SELECT;
SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis);
USER_HEAP_FREE(hDis);
ReleaseDC(hWnd, hDC);
}
static LONG OB_KillFocus(HWND hWnd)
{
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}