/* 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 #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 = 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); } /********************************************************************** * 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); }