窗口子类化实现自绘按钮如此简单

来源:互联网 发布:linux怎么安装eclipse 编辑:程序博客网 时间:2024/06/11 03:45

有没有发现利用createwindow创建按钮感觉太单调,msdn上说的owndraw 按钮太复杂,其实子类化按钮,可以很方便的实现自绘按钮,只需要会点贴图知识就行了。

下面采用gdi+贴图:(关于gdi+环境的搭建我在前面的章节里已经介绍了)

 

第一步:

WNDPROC Button1Proc;
 LRESULT CALLBACK ButtonProc1(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);

第二步:

case WM_CREATE:
  {
   //创建按钮
     HWND hBtn1=CreateWindow(L"button",
    L"哈哈",
    WS_CHILD|WS_VISIBLE,
    15,5,
    100,80,
    hwnd,
    (HMENU)101,
    ((LPCREATESTRUCT)lParam)->hInstance,
    NULL);

Button1Proc= (WNDPROC)SetWindowLong(hBtn1, GWL_WNDPROC,(LONG)ButtonProc1);

break;

}

第三步:

LRESULT CALLBACK ButtonProc1(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 static Image *gImag1=NULL;
 static Image *gImag2=NULL;
 static Image *g_Image=NULL;
 TRACKMOUSEEVENT trmouse;
 static int x=0,y=0;
 switch(message)
 {
 case WM_CREATE:
  {
   //HINSTANCE hInst=(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE);
   ////// 设置分层属性
   SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
   //// 设置透明色
   COLORREF clTransparent = RGB(0,0,0);
   SetLayeredWindowAttributes(hwnd, clTransparent,0, LWA_COLORKEY);
   break;
  }
 case WM_SETCURSOR:
  {
   SetCursor(LoadCursor(NULL, IDC_HAND));
   break;
  }
 case WM_ERASEBKGND:
  {
   return 0;
  }
 case WM_PAINT:
  {
   hdc=BeginPaint(hwnd,&ps);
   RECT rect;
   GetWindowRect(hwnd,&rect);
   HDC hMemDC=CreateCompatibleDC(hdc);
   HBITMAP hMemBM=CreateCompatibleBitmap(hdc,rect.right-rect.left,rect.bottom-rect.top);
   SelectObject(hMemDC,hMemBM);
   if (gImag1==NULL)
   {
    gImag1=Image::FromFile(_T("btn1_1.jpg"));
    g_Image=gImag1;
   }
   if (gImag2==NULL)
   {
    gImag2=Image::FromFile(_T("btn1_2.jpg"));
   }
   
   Graphics g(hMemDC);
   
   {
    g.DrawImage(g_Image,x,y,rect.right-rect.left,rect.bottom-rect.top);
   }
   BitBlt(hdc,0,0,rect.right-rect.left,rect.bottom-rect.top,hMemDC,0,0,SRCCOPY);
   DeleteDC(hMemDC);
   DeleteObject(hMemBM);
   EndPaint(hwnd,&ps);
   return 0;
  }
 case WM_MOUSEMOVE:    //窗口默认情况下不响应MOUSELEAVE和MOUSEHOVER,需要用此消息来激活
  {
   SetCursor(LoadCursor(NULL, IDC_HAND));
   trmouse.cbSize=sizeof(trmouse);
   trmouse.dwFlags=TME_LEAVE|TME_HOVER;
   trmouse.hwndTrack=hwnd;
   trmouse.dwHoverTime=10;
   if(!_TrackMouseEvent(&trmouse))
    return FALSE;
   return 0;
  }break;
 case WM_MOUSEHOVER:
  {
   g_Image=gImag2;
   InvalidateRect(hwnd,NULL,TRUE);
   return 0;
  }break;
 case WM_MOUSELEAVE:
  {
    PlaySound(TEXT("mousemove.wav"),NULL,SND_ALIAS| SND_ASYNC);
   g_Image=gImag1;
   InvalidateRect(hwnd,NULL,TRUE);
   return 0;
  }break;
 case WM_LBUTTONDOWN:
  {
   x=2;
   y=2;
   InvalidateRect(hwnd,NULL,TRUE);
   
   break;
  }break;
 case WM_LBUTTONUP:
  {
   x=0;
   y=0;
   InvalidateRect(hwnd,NULL,TRUE);
   MessageBox(hwnd,L"哈哈",NULL,MB_OK|MB_ICONINFORMATION);
   break;
  }break;
 default:
  return CallWindowProc(Button1Proc, hwnd, message, wParam, lParam);
 }
 return 0;
 
}