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

有没有发现利用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;
 
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值