blob: 1a13b9d8223f81f872716b7db96b770a096e7ead [file] [log] [blame]
/* 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"
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);
typedef struct
{
LONG (*paintfn)();
LONG (*lButtonDownfn)();
LONG (*lButtonUpfn)();
LONG (*lButtonDblClkfn)();
LONG (*killFocusfn)();
LONG (*setCheckfn)();
LONG (*getCheckfn)();
} BTNFN;
#define MAX_BTN_TYPE 10
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 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)
(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 = LocalAlloc(LMEM_MOVEABLE, textlen+1);
text = LocalLock(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);
}
LocalUnlock(hText);
LocalFree(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 = LocalAlloc(LMEM_MOVEABLE, textlen+1);
text = LocalLock(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);
}
LocalUnlock(hText);
LocalFree(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 = LocalAlloc(LMEM_MOVEABLE, textlen+1);
text = LocalLock(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);
LocalUnlock(hText);
LocalFree(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);
}