ColorButton
-
Hi Leudde,
für die, die es interessiert: ich habe soeben meine erste Version der Fensterklasse COLORBUTTON fertiggestellt. Hier der Code für die Header-Datei://--------------------------------------------------------------------------- #ifndef ColorButtonH #define ColorButtonH //--------------------------------------------------------------------------- #include <windows.h> //--------------------------------------------------------------------------- typedef struct _COLORBUTTONINFO { HGLOBAL hGlobal; HWND hwnd; LONG Style; DWORD ExStyle; WORD ID; HFONT Font; COLORREF Color; COLORREF FontColor; HBRUSH Brush; BOOL MouseIn; BOOL MouseDown; TCHAR Text[1024]; } COLORBUTTONINFO, *LPCOLORBUTTONINFO; //--------------------------------------------------------------------------- // Internally used functions LRESULT CALLBACK ColorButtonWindowProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam); LPCOLORBUTTONINFO GetColorButtonInfo(HWND hwnd); int GetText(HWND hwnd, LPTSTR lpszText, int nMaxCount); VOID SetText(HWND hwnd, LPCTSTR lpszText); VOID PaintButton(HDC hdc, LPCOLORBUTTONINFO lpInfo, LPRECT lprc); //--------------------------------------------------------------------------- // functions for the user VOID RegisterColorButtonClass(HINSTANCE hInstance); COLORREF GetColor(HWND hwnd); VOID SetColor(HWND hwnd, COLORREF color); COLORREF GetFontColor(HWND hwnd); VOID SetFontColor(HWND hwnd, COLORREF color); //--------------------------------------------------------------------------- #endif
Und noch der für die C(PP)-Datei:
//--------------------------------------------------------------------------- #include "ColorButton.h" //--------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// //// //// //// ColorButton v1.0 //// //// //// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// //// //// //// This is a button which is very similar to the standard Windows //// //// button. In Version 1.0 it only can show text. With SetColor() //// //// and SetFontColor() you can define the look of your button. But //// //// first of all you have to call RegisterColorButtonClass() in //// //// order to be able to use the COLORBUTTON-class. //// //// //// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// VOID RegisterColorButtonClass(HINSTANCE hInstance) { WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = ColorButtonWindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetSysColorBrush(COLOR_BTNFACE); wc.lpszMenuName = NULL; wc.lpszClassName = TEXT("COLORBUTTON"); RegisterClass(&wc); } //--------------------------------------------------------------------------- LRESULT CALLBACK ColorButtonWindowProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) { static LPVOID lpUserData; static LPCOLORBUTTONINFO lpColorButtonInfo; static PAINTSTRUCT ps; static HDC hdc; static HGLOBAL hGlobal; static RECT rc; static TRACKMOUSEEVENT tme; switch( uiMsg ) { case WM_CREATE: { LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam; // Allocate memory for every ColorButton hGlobal = GlobalAlloc(GMEM_FIXED, sizeof(COLORBUTTONINFO)); lpUserData = GlobalLock(hGlobal); SetWindowLong(hwnd, GWL_USERDATA, (LONG)lpUserData); // Fill it with initial values lpColorButtonInfo = (LPCOLORBUTTONINFO)lpUserData; lpColorButtonInfo->hGlobal = hGlobal; lpColorButtonInfo->hwnd = hwnd; lpColorButtonInfo->Color = GetSysColor(COLOR_BTNFACE); lpColorButtonInfo->Brush = GetSysColorBrush(COLOR_BTNFACE); lpColorButtonInfo->MouseDown = FALSE; lpColorButtonInfo->Style = lpcs->style; lpColorButtonInfo->ExStyle = lpcs->dwExStyle; lpColorButtonInfo->ID = (WORD)lpcs->hMenu; SetText(hwnd, lpcs->lpszName); tme.cbSize = sizeof(TRACKMOUSEEVENT); return 0; } case WM_SETTEXT: SetText(hwnd, (LPCTSTR)lParam); return TRUE; case WM_GETTEXT: return GetText(hwnd, (LPTSTR)lParam, (UINT)wParam); case WM_SETFONT: lpColorButtonInfo = GetColorButtonInfo(hwnd); lpColorButtonInfo->Font = (HFONT)wParam; if( LOWORD(lParam) ) InvalidateRect(hwnd, NULL, TRUE); break; case WM_GETFONT: lpColorButtonInfo = GetColorButtonInfo(hwnd); return (LRESULT)lpColorButtonInfo->Font; case WM_LBUTTONDOWN: lpColorButtonInfo = GetColorButtonInfo(hwnd); lpColorButtonInfo->MouseDown = TRUE; lpColorButtonInfo->MouseIn = TRUE; tme.dwFlags = TME_LEAVE; tme.hwndTrack = hwnd; TrackMouseEvent(&tme); SetFocus(hwnd); InvalidateRect(hwnd, NULL, TRUE); return 0; case WM_LBUTTONUP: lpColorButtonInfo = GetColorButtonInfo(hwnd); lpColorButtonInfo->MouseDown = FALSE; ReleaseCapture(); tme.dwFlags = TME_CANCEL | TME_LEAVE; tme.hwndTrack = hwnd; TrackMouseEvent(&tme); InvalidateRect(hwnd, NULL, TRUE); if(lpColorButtonInfo->MouseIn) { WPARAM wparam = MAKEWPARAM(lpColorButtonInfo->ID, BN_CLICKED); SendMessage(GetParent(hwnd), WM_COMMAND, wparam, (LPARAM)hwnd); } return 0; case WM_MOUSELEAVE: { lpColorButtonInfo = GetColorButtonInfo(hwnd); lpColorButtonInfo->MouseIn = FALSE; if(lpColorButtonInfo->MouseDown) SetCapture(hwnd); InvalidateRect(hwnd, NULL, TRUE); return 0; } case WM_MOUSEMOVE: { lpColorButtonInfo = GetColorButtonInfo(hwnd); if(lpColorButtonInfo->MouseDown && !lpColorButtonInfo->MouseIn) { POINT pt; GetCursorPos(&pt); if( WindowFromPoint(pt) == hwnd ) { TRACKMOUSEEVENT tme; lpColorButtonInfo->MouseIn = TRUE; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_LEAVE; tme.hwndTrack = hwnd; TrackMouseEvent(&tme); ReleaseCapture(); InvalidateRect(hwnd, NULL, TRUE); } } return 0; } case WM_KILLFOCUS: InvalidateRect(hwnd, NULL, TRUE); return 0; case WM_SETFOCUS: InvalidateRect(hwnd, NULL, TRUE); return 0; case WM_PAINT: lpColorButtonInfo = GetColorButtonInfo(hwnd); hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rc); FillRect(hdc, &ps.rcPaint, lpColorButtonInfo->Brush); PaintButton(hdc, lpColorButtonInfo, &rc); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: GlobalFree( GetColorButtonInfo(hwnd)->hGlobal ); return 0; } return DefWindowProc(hwnd, uiMsg, wParam, lParam); } //--------------------------------------------------------------------------- LPCOLORBUTTONINFO GetColorButtonInfo(HWND hwnd) { LPVOID lpUserData = (LPVOID)GetWindowLong(hwnd, GWL_USERDATA); return (LPCOLORBUTTONINFO)lpUserData; } //--------------------------------------------------------------------------- COLORREF GetColor(HWND hwnd) { LPCOLORBUTTONINFO lpInfo = GetColorButtonInfo(hwnd); return lpInfo->Color; } //--------------------------------------------------------------------------- VOID SetColor(HWND hwnd, COLORREF color) { LPCOLORBUTTONINFO lpInfo = GetColorButtonInfo(hwnd); HBRUSH hBrush = CreateSolidBrush(color); lpInfo->Color = color; DeleteObject(lpInfo->Brush); lpInfo->Brush = hBrush; InvalidateRect(hwnd, NULL, TRUE); } //--------------------------------------------------------------------------- COLORREF GetFontColor(HWND hwnd) { LPCOLORBUTTONINFO lpInfo = GetColorButtonInfo(hwnd); return lpInfo->FontColor; } //--------------------------------------------------------------------------- VOID SetFontColor(HWND hwnd, COLORREF color) { LPCOLORBUTTONINFO lpInfo = GetColorButtonInfo(hwnd); lpInfo->FontColor = color; InvalidateRect(hwnd, NULL, TRUE); } //--------------------------------------------------------------------------- VOID SetText(HWND hwnd, LPCTSTR lpszText) { LPCOLORBUTTONINFO lpInfo = GetColorButtonInfo(hwnd); lstrcpyn(lpInfo->Text, lpszText, 1023); } //--------------------------------------------------------------------------- int GetText(HWND hwnd, LPTSTR lpszText, int nMaxCount) { LPCOLORBUTTONINFO lpInfo = GetColorButtonInfo(hwnd); lstrcpyn(lpszText, lpInfo->Text, nMaxCount); return lstrlen(lpszText); } //--------------------------------------------------------------------------- VOID PaintButton(HDC hdc, LPCOLORBUTTONINFO lpInfo, LPRECT lprc) { static int width; static int height; static HPEN hPen1, hPen2; static SIZE size; static RECT rc; static int dXY; width = lprc->right; height = lprc->bottom; dXY = (lpInfo->MouseIn && lpInfo->MouseDown) ? 0 : 1; if( GetFocus() != lpInfo->hwnd ) // button doesn't have focus { // Thin button frame hPen1 = CreatePen(PS_SOLID, 0, RGB(255,255,255)); DeleteObject( SelectObject(hdc, hPen1) ); MoveToEx(hdc, 0, height-2, NULL); LineTo(hdc, 0, 0); LineTo(hdc, width-1, 0); hPen2 = CreatePen(PS_SOLID, 0, RGB(0,0,0)); DeleteObject( SelectObject(hdc, hPen2) ); LineTo(hdc, width-1, height-1); LineTo(hdc, -1, height-1); hPen1 = CreatePen(PS_SOLID, 0, RGB(128,128,128)); DeleteObject( SelectObject(hdc, hPen1) ); MoveToEx(hdc, 1, height-2, NULL); LineTo(hdc, width-2, height-2); LineTo(hdc, width-2, 0); } else // button has focus { if(lpInfo->MouseIn && lpInfo->MouseDown) // button is pressed { // Simple thick frame SetRect(&rc, 0, 0, width, height); FrameRect(hdc, &rc, CreateSolidBrush( RGB(0,0,0) )); SetRect(&rc, 1, 1, width - 1, height - 1); FrameRect(hdc, &rc, CreateSolidBrush( RGB(128,128,128) )); } else // button is not pressed { // A bit more complicated thick frame SetRect(&rc, 0, 0, width, height); FrameRect(hdc, &rc, CreateSolidBrush( RGB(0,0,0) )); SetRect(&rc, 1, 1, width - 1, height - 1); FrameRect(hdc, &rc, CreateSolidBrush( RGB(0,0,0) )); hPen1 = CreatePen(PS_SOLID, 0, RGB(255,255,255)); DeleteObject( SelectObject(hdc, hPen1) ); MoveToEx(hdc, 1, height-3, NULL); LineTo(hdc, 1, 1); LineTo(hdc, width-2, 1); hPen2 = CreatePen(PS_SOLID, 0, RGB(128,128,128)); DeleteObject( SelectObject(hdc, hPen2) ); MoveToEx(hdc, width-3, 2, NULL); LineTo(hdc, width-3, height-3); LineTo(hdc, 2, height-3); } } DeleteObject( SelectObject(hdc, lpInfo->Font) ); GetTextExtentPoint32(hdc, lpInfo->Text, lstrlen(lpInfo->Text), &size); SetRect(&rc, 4, 4, width - 5, height - 5); SetBkColor(hdc, lpInfo->Color); SetTextColor(hdc, lpInfo->FontColor); ExtTextOut(hdc, (width - size.cx) / 2 - dXY, (height - size.cy) / 2 - dXY, ETO_CLIPPED | ETO_OPAQUE, &rc, lpInfo->Text, lstrlen(lpInfo->Text), NULL); } //---------------------------------------------------------------------------
Einfach die Header-Datei inkludieren und los. Die Klasse registriert man per RegisterColorButtonClass(). Ein kleines Beispiel:
RegisterColorButtonClass(); hColorButton = CreateWindow(TEXT("COLORBUTTON"), TEXT("OK"), WS_VISIBLE | WS_CHILD | WS_TABSTOP, 400, 30, 75, 23, hWndMain, (HMENU)IDOK, hInstance, NULL); SendMessage( hColorButton, WM_SETFONT, (WPARAM)(HFONT)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(TRUE, 0) ); SetColor(hColorButton, RGB(255,255,255)); SetFontColor(hColorButton, RGB(0,0,255));
So bekommt man einen weißen Button mit blauer Schrift.
Ich werde dann in nächster Zeit noch die verschiedenen Button-Styles implementieren (BS_BITMAP usw.). Aber als rohe Fassung kann man diesen Button schon benutzen.