2013-06-27 59 views
0

我想要使用Windows C API制作自定义的Windows 8样式按钮。但是,当我尝试绘制按钮上的文本后,我重画按钮没有可见发生! 我甚至试图创建一个静态窗口作为按钮的子节点,并发送WS_ERASEBKGND消息给它,当我重绘按钮,但只要我重新绘制第一次它消失的按钮! 这里是我的自定义按钮的窗口过程:在windows api中的自定义按钮上绘制文本

LRESULT CALLBACK ButtonWindowProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) 
{ 
    //static HWND static_text_handle; 
    HDC hdc; 
    PAINTSTRUCT ps; 
    DWORD color; 
    HFONT font,holdFont; 
    static RECT rect; 
    wchar_t test[] = L"test"; 
    TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT),TME_LEAVE,hwnd,HOVER_DEFAULT}; 
    /*static*/ HBRUSH brush = CreateSolidBrush(RGB(20,30,40)); 
    /*static*/ HBRUSH clicked_brush = CreateSolidBrush(RGB(40,50,60)); 
    /*static*/ HBRUSH hover_brush = CreateSolidBrush(RGB(70,80,90)); 
    //TrackMouseEvent(&tme); 
    switch(msg) 
    { 
    case WM_CREATE: 
     //static_text_handle = CreateWindowW(L"Static",L"test",WS_CHILD | WS_VISIBLE,0,0,20,20,hwnd,NULL,NULL,NULL); 
     //brush = ((struct custom_button_colors*)(lParam))->default_color; 
     //clicked_brush = ((struct custom_button_colors*)(lParam))->push_color; 
     //hover_brush = ((struct custom_button_colors*)(lParam))->hover_color; 
     break; 
    case WM_LBUTTONDOWN: 
      SendMessage(hwnd,WM_ERASEBKGND,(WPARAM)GetDC(hwnd),(LPARAM)LPARAM_L_DOWN); 
      break; 
    case WM_LBUTTONUP: 
     SendMessage(hwnd,WM_ERASEBKGND,(WPARAM)GetDC(hwnd),(LPARAM)LPARAM_L_UP); 
     break; 
    case WM_MOUSEMOVE: 
     //Beep(1000,1000); 
     TrackMouseEvent(&tme); 
     if (GetAsyncKeyState(VK_LBUTTON)) 
     { 
      SendMessage(hwnd,WM_ERASEBKGND,(WPARAM)GetDC(hwnd),(LPARAM)LPARAM_L_DOWN); 
     } 
     else 
     { 
      SendMessage(hwnd,WM_ERASEBKGND,(WPARAM)GetDC(hwnd),(LPARAM)LPARAM_MOUSEHOVER); 
     } 
     break; 
    case WM_MOUSELEAVE: 
     SendMessage(hwnd,WM_ERASEBKGND,(WPARAM)GetDC(hwnd),(LPARAM)-1); 
     break; 
    case WM_ERASEBKGND: 
     GetClientRect(hwnd,&rect); 
     if (lParam == LPARAM_L_DOWN) 
     { 
      FillRect((HDC)wParam,&rect,clicked_brush); 
     } 
     else if (lParam == LPARAM_MOUSEHOVER) 
     { 
      FillRect((HDC)wParam,&rect,hover_brush); 
      break; 
     } 
     else 
     { 
      POINT mousepos; 
      GetCursorPos(&mousepos); 
      if (WindowFromPoint(mousepos) == hwnd) 
      { 
       FillRect((HDC)wParam,&rect,hover_brush); 
      } 
      else 
      { 
       FillRect((HDC)wParam,&rect,brush); 
      } 
     } 
     hdc = BeginPaint(hwnd,&ps); 
     color = GetSysColor(COLOR_BTNFACE); 
     SetBkColor(hdc,color); 
     font = CreateFontW(25, 0, 0, 0, FW_MEDIUM, 0, 0, 0, 0,0, 0, ANTIALIASED_QUALITY, 0, L"Tahoma"); 
     holdFont = SelectObject(hdc, font); 
     TextOutW(hdc,200,200,test,lstrlenW(test)); 
     SelectObject(hdc,holdFont); 
     DeleteObject(font); 
     EndPaint(hwnd,&ps); 
     break; 
    default: 
     return DefWindowProc(hwnd,msg,wParam,lParam); 
    } 
    return 0; 
} 

我在窗户绝对初学者编程很抱歉,如果我的问题是微不足道的。

回答

1

1)不要在WM_ERASEBKGND中使用BeginPaint/EndPaint。在WM_PAINT处理程序中移动该代码。

2)使用SetWindowLong和GWL_USERDATA索引来存储按钮状态(UP或DOWN)并使用GetWindowLong检索当前状态。

3)使用SetCapture捕获鼠标,从WM_LBUTTONDOWN开始。根据鼠标位置更新按钮的状态(向上或向下)

4)当您需要绘画发生时使用RedrawWindow