W
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.