Ownerdraw-Technik und Hintergrund/Text-farbe von Statics/Editboxen...
-
// Dieses Beispielprogramm erzeugt: // - 1 Fenster // - 2 Owner-Draw Buttons // - 1 Editbox // - 1 Label (alias Static) // // Bei den relevanten Teilen sind hoffentlich genug Kommentare ;-) #include "stdafx.h" #include "resource.h" // Foward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); bool DrawButton(DRAWITEMSTRUCT *dis); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // TODO: Place code here. MSG msg; // Initialize global strings MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW|CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = 0; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW); wcex.lpszMenuName = 0; wcex.lpszClassName = "window_class"; wcex.hIconSm = 0; return RegisterClassEx(&wcex); } BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hWnd=CreateWindow("window_class", "titel", WS_VISIBLE|WS_BORDER|WS_SYSMENU|WS_MINIMIZEBOX, 20, 20, 300, 150, NULL, NULL, hInstance, NULL); // 2 Buttons erzeugen: CreateWindow("BUTTON","Ein Button",BS_OWNERDRAW|WS_CHILD|WS_VISIBLE,5,5,100,20,hWnd,NULL,hInstance,NULL); CreateWindow("BUTTON","Noch ein Button",BS_OWNERDRAW|WS_CHILD|WS_VISIBLE,110,5,100,20,hWnd,NULL,hInstance,NULL); // Editbox und Static erzeugen: CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","Eine Editbox",WS_CHILD|WS_VISIBLE,5,30,100,20,hWnd,NULL,hInstance,NULL); CreateWindow("STATIC","Ein Label",WS_CHILD|WS_VISIBLE,110,30,100,20,hWnd,NULL,hInstance,NULL); return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { // Das Übliche: case WM_DESTROY: PostQuitMessage(0); break; // Diese Nachricht wird für das Label gesendet, für die Editbox // nur, wenn die Editbox disabled ist. case WM_CTLCOLORSTATIC: // Texthintergrund auf transparent setzen: SetBkMode((HDC)wParam,TRANSPARENT); // Textfarbe auf rot setzen SetTextColor((HDC)wParam,RGB(255,0,0)); // Hintergrundfarbe auf blau setzen: // Achtung: Den Handle, den CreateSolidBrush() zurückliefert // kann nicht mehr gelöscht werden, wenn man es so aufruft: return (long)CreateSolidBrush(RGB(0,0,255)); break; // Diese Nachricht wird für die EditBox gesendet: case WM_CTLCOLOREDIT: SetBkMode((HDC)wParam,TRANSPARENT); // Texthintergrund auf transparent setzen SetTextColor((HDC)wParam,RGB(255,255,255)); // Textfarbe auf Weiss setzen return (long)CreateSolidBrush(RGB(0,0,0)); // Hintergrundfarbe auf schwarz setzen break; // Diese Nachricht wird für beide Buttons gesendet: case WM_DRAWITEM: // Hier rufe ich zwecks Übersichtlichkeit eine eigene // Funktion zum Button zeichnen auf: return DrawButton((LPDRAWITEMSTRUCT)lParam); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
bool DrawButton(DRAWITEMSTRUCT *dis) { HGDIOBJ OldObj; char text[500]; HBRUSH aBrush; RECT rt; // Damit man später nicht immer "dis->rcItem" schreiben muss: rt.left=dis->rcItem.left; rt.top=dis->rcItem.top; rt.right=dis->rcItem.right; rt.bottom=dis->rcItem.bottom; // Bei itemAction ist das Style ODA_DRAWENTIRE enthalten, also // muss alles gezeichnet werden: if (dis->itemAction & ODA_DRAWENTIRE) { // Hintergrund zeichnen: aBrush=GetSysColorBrush(COLOR_BTNFACE); OldObj=SelectObject(dis->hDC,aBrush); PatBlt(dis->hDC,1,1,(rt.right-2),(rt.bottom-2),PATCOPY); DeleteObject(SelectObject(dis->hDC,OldObj)); // Text holen: GetWindowText(dis->hwndItem,text,500); // Text zeichnen: // Standard-Schriftart holen: OldObj=SelectObject(dis->hDC,GetStockObject(DEFAULT_GUI_FONT)); // Hintergrund des Textes auf Transparent schalten: SetBkMode(dis->hDC,TRANSPARENT); // Textfarbe setzen: SetTextColor(dis->hDC,RGB(0,0,0)); // Und nun endlich zeichnen: rt.top=rt.top+2; // Nur, damits besser passt: DrawText(dis->hDC,text,strlen(text),&rt,DT_CENTER); // Caption zeichnen rt.top=rt.top-2; // Damits wieder stimmt! // Schriftart wieder freigeben und altes Objekt wieder selektieren: DeleteObject(SelectObject(dis->hDC,OldObj)); } // Bei itemAction ist ODA_SELECT oder ODA_DRAWENTIRE enthalten, // es muss der Rand (Border) also gezeichnet werden: if (dis->itemAction & (ODA_SELECT|ODA_DRAWENTIRE)) { if (dis->itemState & ODS_SELECTED) { // Der Button ist gedrückt, also zeichnen wir // am rechten Rand und am unteren Rand des Buttons // eine weisse Linie: aBrush=GetSysColorBrush(COLOR_BTNHILIGHT); OldObj=SelectObject(dis->hDC,aBrush); PatBlt(dis->hDC,(rt.right-1),0,(rt.right-1),(rt.bottom-1),PATCOPY); PatBlt(dis->hDC,0,(rt.bottom-1),rt.right,1,PATCOPY); DeleteObject(SelectObject(dis->hDC,OldObj)); // und als oberen und linken Rand einen grauen Rand: aBrush=GetSysColorBrush(COLOR_BTNSHADOW); OldObj=SelectObject(dis->hDC,aBrush); PatBlt(dis->hDC,0,0,(rt.right-1),1,PATCOPY); PatBlt(dis->hDC,0,0,1,rt.bottom,PATCOPY); DeleteObject(SelectObject(dis->hDC,OldObj)); } else { // Der Button ist nicht gedrückt, also zeichnen wir // alles mit umgekehrten Farben, der untere und rechte // Rand wird jetzt statt weiss grau: aBrush=GetSysColorBrush(COLOR_BTNSHADOW); OldObj=SelectObject(dis->hDC,aBrush); PatBlt(dis->hDC,(rt.right-1),0,(rt.right-1),(rt.bottom-1),PATCOPY); PatBlt(dis->hDC,0,(rt.bottom-1),rt.right,1,PATCOPY); DeleteObject(SelectObject(dis->hDC,OldObj)); // ...und der obere und linke Rand wird weiss: aBrush=GetSysColorBrush(COLOR_BTNHILIGHT); OldObj=SelectObject(dis->hDC,aBrush); PatBlt(dis->hDC,0,0,(rt.right-1),1,PATCOPY); PatBlt(dis->hDC,0,0,1,rt.bottom,PATCOPY); DeleteObject(SelectObject(dis->hDC,OldObj)); } } // itemAction enthält das Style ODA_FOCUS, es soll also eine // gestrichelte Fokus-Linie gezeichnet werden, wozu ich jetzt // keine Lust mehr hatte: if (dis->itemAction & ODA_FOCUS) { // Hier könnte man noch den einen gestrichelten Rahmen // zeichnen, da der Button den Keyboard-Fokus hat } else { // Der Button hat keinen Keyboard-Fokus (mehr) } return true; }
1 von 1