2013-07-16 3 views
1

나는 이미 사용자 지정 그리기, 소유자 그리기 및 서브 클래 싱에 대해 알고 있습니다. 지금까지 내 선택은 맞춤 그림입니다. 서브 클래 싱이 나의 두 번째 선택이지만 버튼의 양은 엄청납니다. 누구든지 다른 의견이 있으면 의견을 말하십시오. 어쨌든 나는 사용자 정의 도면을위한 코드를 게시 할 것입니다. Win32에서는 어디서나 직접적인 대답이 없기 때문입니다.버튼의 기능을 win32에서 유지하면서 버튼의 색상을 변경하는 방법은 무엇입니까?

+0

이 상황에서 정상적으로해야 할 일은 질문을하고 나 자신의 질문에 답하는 것입니다. 자유롭게 여기에있는 것을 편집하고 해답으로 해답을 추가하십시오. – Collin

+0

감사합니다. 나는 미래에 그것을 명심 할 것이다. – FrogTheFrog

+0

질문을 편집하여 다른 사람이 답을 쓸 수있는 충분한 질문이되도록하십시오 (뭔가 배울 수도 있음). 지금 귀하의 질문은 대부분 의견에 속하는 메타 토론으로 가득 차 있으며 "진정한 질문이 아님"으로 마감 될 것입니다. –

답변

5

Nothing is selected First button is selected and was pushedSecond button was pushed and the mouse is over it (notice the increse of brightness - cutom hilight)

제 버튼이 선택되고, 가압하고, 두번째 버튼을 가압 할 때 마지막 쇼와 마우스가 넘으면 것도, 두 번째 프로그램을 선택하지 않은 경우

첫번째 픽처 도시 합니다 (알 밝기 증가 - cutom hilight). 이렇게하려면 NM_CUSTOMDRAW 메시지를 잡고 직접 페인트해야합니다. 그리고 이것이 당신이하는 방법입니다. 또한 그라디언트 브러시 기능과 몇 가지 설명이 추가되었습니다.

#pragma comment(linker,"\"/manifestdependency:type='win32' \ 
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ 
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") 

#include <Windows.h> 
#include <Commctrl.h> 

#define IDC_EXIT_BUTTON 101 
#define IDC_PUSHLIKE_BUTTON 102 

HBRUSH CreateGradientBrush(COLORREF top, COLORREF bottom, LPNMCUSTOMDRAW item) 
    { 
     HBRUSH Brush = NULL; 
     HDC hdcmem = CreateCompatibleDC(item->hdc); 
     HBITMAP hbitmap = CreateCompatibleBitmap(item->hdc, item->rc.right-item->rc.left, item->rc.bottom-item->rc.top); 
     SelectObject(hdcmem, hbitmap); 

     int r1 = GetRValue(top), r2 = GetRValue(bottom), g1 = GetGValue(top), g2 = GetGValue(bottom), b1 = GetBValue(top), b2 = GetBValue(bottom); 
     for(int i = 0; i < item->rc.bottom-item->rc.top; i++) 
     { 
      RECT temp; 
      int r,g,b; 
      r = int(r1 + double(i * (r2-r1)/item->rc.bottom-item->rc.top)); 
      g = int(g1 + double(i * (g2-g1)/item->rc.bottom-item->rc.top)); 
      b = int(b1 + double(i * (b2-b1)/item->rc.bottom-item->rc.top)); 
      Brush = CreateSolidBrush(RGB(r, g, b)); 
      temp.left = 0; 
      temp.top = i; 
      temp.right = item->rc.right-item->rc.left; 
      temp.bottom = i + 1; 
      FillRect(hdcmem, &temp, Brush); 
      DeleteObject(Brush); 
     } 
     HBRUSH pattern = CreatePatternBrush(hbitmap); 

     DeleteDC(hdcmem); 
     DeleteObject(Brush); 
     DeleteObject(hbitmap); 

     return pattern; 
    } 

LRESULT CALLBACK MainWindow(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
    static HBRUSH defaultbrush = NULL; 
    static HBRUSH hotbrush = NULL; 
    static HBRUSH selectbrush = NULL; 
    static HBRUSH push_uncheckedbrush = NULL; 
    static HBRUSH push_checkedbrush = NULL; 
    static HBRUSH push_hotbrush1 = NULL; 
    static HBRUSH push_hotbrush2 = NULL; 
    switch (msg) 
    { 
     case WM_CREATE: 
      { 
       HWND Exit_Button = CreateWindowEx(NULL, L"BUTTON", L"EXIT", 
                 WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 
                 50, 50, 100, 100, hwnd, (HMENU)IDC_EXIT_BUTTON, NULL, NULL); 
       if(Exit_Button == NULL) 
        { 
         MessageBox(NULL, L"Button Creation Failed!", L"Error!", MB_ICONEXCLAMATION); 
         exit(EXIT_FAILURE); 
        } 

       HWND Pushlike_Button = CreateWindowEx(NULL, L"BUTTON", L"PUSH ME!", 
                 WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX | BS_PUSHLIKE, 
                 200, 50, 100, 100, hwnd, (HMENU)IDC_PUSHLIKE_BUTTON, NULL, NULL); 
       if(Pushlike_Button == NULL) 
        { 
         MessageBox(NULL, L"Button Creation Failed!", L"Error!", MB_ICONEXCLAMATION); 
         exit(EXIT_FAILURE); 
        } 
      } 
     break; 
     case WM_COMMAND: 
      { 
       switch(LOWORD(wParam)) 
        { 
         case IDC_EXIT_BUTTON: 
          { 
           SendMessage(hwnd, WM_CLOSE, 0, 0); 
          } 
         break; 
        } 
      } 
     break; 
     case WM_NOTIFY: 
     { 
      LPNMHDR some_item = (LPNMHDR)lParam; 

      if (some_item->idFrom == IDC_EXIT_BUTTON && some_item->code == NM_CUSTOMDRAW) 
      { 
       LPNMCUSTOMDRAW item = (LPNMCUSTOMDRAW)some_item; 

       if (item->uItemState & CDIS_SELECTED) 
       { 
        //Select our color when the button is selected 
        if (selectbrush == NULL) 
         selectbrush = CreateGradientBrush(RGB(180, 0, 0), RGB(255, 180, 0), item); 

        //Create pen for button border 
        HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0)); 

        //Select our brush into hDC 
        HGDIOBJ old_pen = SelectObject(item->hdc, pen); 
        HGDIOBJ old_brush = SelectObject(item->hdc, selectbrush); 

        //If you want rounded button, then use this, otherwise use FillRect(). 
        RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 5, 5); 

        //Clean up 
        SelectObject(item->hdc, old_pen); 
        SelectObject(item->hdc, old_brush); 
        DeleteObject(pen); 

        //Now, I don't want to do anything else myself (draw text) so I use this value for return: 
        return CDRF_DODEFAULT; 
        //Let's say I wanted to draw text and stuff, then I would have to do it before return with 
        //DrawText() or other function and return CDRF_SKIPDEFAULT 
       } 
       else 
       { 
        if (item->uItemState & CDIS_HOT) //Our mouse is over the button 
        { 
         //Select our color when the mouse hovers our button 
         if (hotbrush == NULL) 
          hotbrush = CreateGradientBrush(RGB(255, 230, 0), RGB(245, 0, 0), item); 

         HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0)); 

         HGDIOBJ old_pen = SelectObject(item->hdc, pen); 
         HGDIOBJ old_brush = SelectObject(item->hdc, hotbrush); 

         RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 5, 5); 

         SelectObject(item->hdc, old_pen); 
         SelectObject(item->hdc, old_brush); 
         DeleteObject(pen); 

         return CDRF_DODEFAULT; 
        } 

        //Select our color when our button is doing nothing 
        if (defaultbrush == NULL) 
         defaultbrush = CreateGradientBrush(RGB(255, 180, 0), RGB(180, 0, 0), item); 

        HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0)); 

        HGDIOBJ old_pen = SelectObject(item->hdc, pen); 
        HGDIOBJ old_brush = SelectObject(item->hdc, defaultbrush); 

        RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 5, 5); 

        SelectObject(item->hdc, old_pen); 
        SelectObject(item->hdc, old_brush); 
        DeleteObject(pen); 

        return CDRF_DODEFAULT; 
       } 
      } 
      else if (some_item->idFrom == IDC_PUSHLIKE_BUTTON && some_item->code == NM_CUSTOMDRAW) 
      { 
       LPNMCUSTOMDRAW item = (LPNMCUSTOMDRAW)some_item; 

       if (IsDlgButtonChecked(hwnd, some_item->idFrom)) 
       { 
        if (item->uItemState & CDIS_HOT) 
        { 

         if (push_hotbrush1 == NULL) 
          push_hotbrush1 = CreateGradientBrush(RGB(0, 0, 245), RGB(0, 230, 255), item); 

         HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0)); 

         HGDIOBJ old_pen = SelectObject(item->hdc, pen); 
         HGDIOBJ old_brush = SelectObject(item->hdc, push_hotbrush1); 

         RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 10, 10); 

         SelectObject(item->hdc, old_pen); 
         SelectObject(item->hdc, old_brush); 
         DeleteObject(pen); 

         return CDRF_DODEFAULT; 
        } 


        if (push_checkedbrush == NULL) 
         push_checkedbrush = CreateGradientBrush(RGB(0, 0, 180), RGB(0, 222, 200), item); 


        HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0)); 


        HGDIOBJ old_pen = SelectObject(item->hdc, pen); 
        HGDIOBJ old_brush = SelectObject(item->hdc, push_checkedbrush); 


        RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 10, 10); 


        SelectObject(item->hdc, old_pen); 
        SelectObject(item->hdc, old_brush); 
        DeleteObject(pen); 


        return CDRF_DODEFAULT; 
       } 
       else 
       { 
        if (item->uItemState & CDIS_HOT) 
        { 
         if (push_hotbrush2 == NULL) 
          push_hotbrush2 = CreateGradientBrush(RGB(255, 230, 0), RGB(245, 0, 0), item); 

         HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0)); 

         HGDIOBJ old_pen = SelectObject(item->hdc, pen); 
         HGDIOBJ old_brush = SelectObject(item->hdc, push_hotbrush2); 

         RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 10, 10); 

         SelectObject(item->hdc, old_pen); 
         SelectObject(item->hdc, old_brush); 
         DeleteObject(pen); 

         return CDRF_DODEFAULT; 
        } 

        if (push_uncheckedbrush == NULL) 
         push_uncheckedbrush = CreateGradientBrush(RGB(255, 180, 0), RGB(180, 0, 0), item); 

        HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0)); 

        HGDIOBJ old_pen = SelectObject(item->hdc, pen); 
        HGDIOBJ old_brush = SelectObject(item->hdc, defaultbrush); 

        RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 10, 10); 

        SelectObject(item->hdc, old_pen); 
        SelectObject(item->hdc, old_brush); 
        DeleteObject(pen); 

        return CDRF_DODEFAULT; 
       } 
      } 
      return CDRF_DODEFAULT; 
     } 
     break; 
     case WM_CTLCOLORBTN: //In order to make those edges invisble when we use RoundRect(), 
      {    //we make the color of our button's background match window's background 
       return (LRESULT)GetSysColorBrush(COLOR_WINDOW+1); 
      } 
     break; 
     case WM_CLOSE: 
      { 
       DestroyWindow(hwnd); 
       return 0; 
      } 
     break; 
     case WM_DESTROY: 
      { 
       DeleteObject(defaultbrush); 
       DeleteObject(selectbrush); 
       DeleteObject(hotbrush); 
       DeleteObject(push_checkedbrush); 
       DeleteObject(push_hotbrush1); 
       DeleteObject(push_hotbrush2); 
       DeleteObject(push_uncheckedbrush); 
       PostQuitMessage(0); 
       return 0; 
      } 
     break; 
     default: 
      return DefWindowProc(hwnd, msg, wParam, lParam); 
    } 
    return 0; 
} 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
{ 
    WNDCLASSEX wc; 
    HWND hwnd; 
    MSG msg; 
    const wchar_t ClassName[] = L"Main_Window"; 

    wc.cbSize  = sizeof(WNDCLASSEX); 
    wc.style   = 0; 
    wc.lpfnWndProc = MainWindow; 
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hInstance  = hInstance; 
    wc.hIcon   = LoadIcon(NULL, IDI_APPLICATION); 
    wc.hCursor  = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW+1); 
    wc.lpszMenuName = NULL; 
    wc.lpszClassName = ClassName; 
    wc.hIconSm  = LoadIcon(NULL, IDI_APPLICATION); 

    if(!RegisterClassEx(&wc)) 
    { 
     MessageBox(NULL, L"Window Registration Failed!", L"Error", MB_ICONEXCLAMATION | MB_OK); 
     exit(EXIT_FAILURE); 
    } 

    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, ClassName, L"Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 368, 248, NULL, NULL, hInstance, NULL); 

    if(hwnd == NULL) 
    { 
     MessageBox(NULL, L"Window Creation Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK); 
     exit(EXIT_FAILURE); 
    } 

    ShowWindow(hwnd, nCmdShow); 
    UpdateWindow(hwnd); 

    while(GetMessage(&msg, NULL, 0, 0) > 0) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 

    return msg.message; 
} 
+0

+1 가능한 일에 대한 훌륭한 시연. 어떤 앱이라도 너무 깔끔하게 보일지 확신 할 수는 없지만, 이는 모든 종류의 맞춤형 버튼을위한 유용한 프레임 워크입니다. –

관련 문제