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.


Anmelden zum Antworten