本文详叙了自制一个bitmapbutton类的一种制作方法。这个子定义的bitmapbutton类有类似于MFC种CBitmapButton类的功能。
这个bitmapbutton有关联四个位图,分别一般状态,按下状态,焦点状态,和无效状态的位图。该bitmapbutton类的对象能接受消息,能向主窗口传递消息。模仿了CBitmapButton类的大部分功能。
下面是该类的申明和实现。
// FileName:BitmapButton.h: interface for the BitmapButton class.
// Envionment:Visual C++ 6.0,Windows 9x/2k
//
// Author:kaitty
// Email:kaitty@x263.net or nsi10102@nsi
// Date: 2002.2.10
//***********************************************************************************
// 说明:这是一个自定义的BitmapButton类,功能是使一个Button上关联四个
// 位图。
// 接口:HWND CreateBitmapButtonWindow(LPCSTR lpClassName,LPCSTR lpWindowName,DWORD dwStyle,
// int x,int y,int nWidth,int nHeight,
// HWND hwndParent,HMENU hmenu,HINSTANCE hInstance,
// UINT upBitmap,UINT downBitmap,UINT focusBitmap,UINT disableBitmap);
// 创建一个BitmapButton;
// int SetBitmap(HWND hwnd,UINT upBitmap,UINT downBitmap,UINT focusBitmap,UINT disableBitmap);
// 改变关联Button的位图。
// BOOL EnableBitmapButton(HWND hwnd,BOOL bEnable);
// 使Button有效或无效。
// int GetWindowState(HWND hwnd);
// 获取Button状态;返回值为0,1,2,3中的一个。
***********************************************************************************
#define WM_BITMAP WM_USER+999 自己定义消息,用于把button变为无效状态
struct PrivateInfo{
HBITMAP hbitmap0;
HBITMAP hbitmap1;
HBITMAP hbitmap2;
HBITMAP hbitmap3;
int state;
};
class BitmapButton
{
private:
HWND m_hwnd; // 对象的窗口句柄
public:
virtual ~BitmapButton();
BitmapButton(LPCTSTR lpClassName,LPCSTR lpWindowName,DWORD dwStyle,
int x,int y,int nWidth,int nHeight,
HWND hwndParent,HMENU hmenu,HINSTANCE hInstance,
UINT upBitmap,UINT downBitmap,UINT focusBitmap,UINT disableBitmap);//构造函数
BOOL EnableBitmapButton(HWND hwnd,BOOL bEnable); // 使button无效或有效
int GetWindowState(HWND hwnd); // 获取 button得窗口句柄
int SetBitmap(HWND hwnd,UINT upBitmap,UINT downBitmap,UINT focusBitmap,UINT disableBitmap); // 重新设置关联位图
};
LRESULT CALLBACK ButtonProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); //窗口函数
***********************************************************************************
// FileName:BitmapButton.cpp : implementation file
// Envionment:Visual C++ 6.0,Windows 9x/2k
//
// Author:kaitty
// Email:kaitty@x263.net or nsi10102@nsi
// Date: 2002.2.10
***********************************************************************************
#include "stdafx.h"
#include "BitmapButton.h"
#include "resource.h"
///////////////////////////////////////////////////////////////////////
BitmapButton::~BitmapButton()
{
}
/////////////////////////////////////////////////////////////////
BitmapButton::BitmapButton(LPCTSTR lpClassName,LPCSTR lpWindowName,DWORD dwStyle,
int x,int y,int nWidth,int nHeight,
HWND hwndParent,HMENU hmenu,HINSTANCE hInstance,
UINT upBitmap,UINT downBitmap,UINT focusBitmap,UINT disableBitmap)
{
WNDCLASS wnd;
wnd.cbClsExtra = 0;
wnd.cbWndExtra = 0;
wnd.hbrBackground = NULL;
wnd.hCursor = LoadCursor(NULL,IDC_ARROW);
wnd.hIcon = NULL;
wnd.hInstance = (HINSTANCE)GetWindowLong(hwndParent,GWL_HINSTANCE);
wnd.lpfnWndProc = (WNDPROC)ButtonProc;
wnd.lpszClassName = lpClassName;
wnd.lpszMenuName = NULL;
wnd.style = CS_HREDRAW | CS_VREDRAW;
if(!RegisterClass(&wnd)) return ;
HWND hwnd;
hwnd=CreateWindow(lpClassName,lpWindowName,dwStyle,
x,y,nWidth,nHeight,hwndParent,hmenu,hInstance,NULL);
PrivateInfo *pPrivateInfo=new PrivateInfo;
pPrivateInfo->state=0;
pPrivateInfo->hbitmap0=LoadBitmap(hInstance,MAKEINTRESOURCE(upBitmap));
pPrivateInfo->hbitmap1=LoadBitmap(hInstance,MAKEINTRESOURCE(downBitmap));
pPrivateInfo->hbitmap2=LoadBitmap(hInstance,MAKEINTRESOURCE(focusBitmap));
pPrivateInfo->hbitmap3=LoadBitmap(hInstance,MAKEINTRESOURCE(disableBitmap));
SetWindowLong(hwnd,GWL_USERDATA,(long)pPrivateInfo);
ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);
m_hwnd = hwnd;
}
////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK ButtonProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int xPos,yPos;
PrivateInfo *pPrivate;
HRGN hrgn;
HDC hdc,hdcmem;
PAINTSTRUCT ps;
RECT rect;
GetWindowRect(hWnd,&rect);
hrgn=CreateRectRgn(0,0,rect.right-rect.left,rect.bottom-rect.top);
pPrivate=(PrivateInfo*)GetWindowLong(hWnd,GWL_USERDATA);
xPos = LOWORD(lParam);
yPos = HIWORD(lParam);
switch (message)
{
case WM_CREATE:
break;
case WM_COMMAND:
break;
case WM_PAINT:
RECT rt;
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
GetClientRect(hWnd, &rt);
BITMAP bm;
hdcmem=CreateCompatibleDC(hdc);
switch(pPrivate->state)
{
case 0:SelectObject(hdcmem,pPrivate->hbitmap0);
GetObject(pPrivate->hbitmap0,sizeof(BITMAP),&bm);break;
case 1:SelectObject(hdcmem,pPrivate->hbitmap1);
GetObject(pPrivate->hbitmap1,sizeof(BITMAP),&bm);break;
case 2:SelectObject(hdcmem,pPrivate->hbitmap2);
GetObject(pPrivate->hbitmap2,sizeof(BITMAP),&bm);break;
case 3:SelectObject(hdcmem,pPrivate->hbitmap3);
GetObject(pPrivate->hbitmap3,sizeof(BITMAP),&bm);break;
}
StretchBlt(hdc,0,0,rect.right-rect.left,rect.bottom-rect.top,hdcmem,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
DeleteDC(hdcmem);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
DeleteObject(pPrivate->hbitmap0);
DeleteObject(pPrivate->hbitmap1);
DeleteObject(pPrivate->hbitmap2);
DeleteObject(pPrivate->hbitmap3);
DestroyWindow(hWnd);
break;
case WM_LBUTTONDOWN:
if(pPrivate->state!=3)
{
pPrivate->state=2;
if(!(GetCapture()==hWnd)) SetCapture(hWnd);
InvalidateRect(hWnd,NULL,0);
};
break;
case WM_LBUTTONUP:
if(pPrivate->state!=3)
{
ReleaseCapture();
pPrivate->state=0;
if(PtInRegion(hrgn,xPos,yPos))
SendMessage(GetParent(hWnd),WM_COMMAND,GetWindowLong(hWnd,GWL_ID),0);
};
break;
case WM_MOUSEMOVE:
HCURSOR hcur;
if(pPrivate->state!=3)
{
if(!(GetCapture()==hWnd)) SetCapture(hWnd);
hcur=LoadCursor((HINSTANCE)GetWindowLong(GetParent(hWnd),GWL_HINSTANCE),MAKEINTRESOURCE(IDC_HAND));
SetCursor(hcur);
if((GetCapture()==hWnd)&&(!PtInRegion(hrgn,xPos,yPos)))
{ pPrivate->state=0; ReleaseCapture();}
else pPrivate->state=1;
InvalidateRect(hWnd,NULL,0);
};
break;
case WM_BITMAP:
if(wParam==1) pPrivate->state=0;
else pPrivate->state=3;
InvalidateRect(hWnd,NULL,0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////
BOOL BitmapButton::EnableBitmapButton(HWND hwnd,BOOL bEnable)
{
SendMessage(hwnd,WM_BITMAP,bEnable,0);
return true;
}
///////////////////////////////////////////////////////////////////////
int BitmapButton::GetWindowState(HWND hwnd)
{
PrivateInfo *pPrivate;
pPrivate=(PrivateInfo*)GetWindowLong(hwnd,GWL_USERDATA);
return pPrivate->state;
}
//////////////////////////////////////////////////////////////////////////
int BitmapButton::SetBitmap(HWND hwnd,UINT upBitmap,UINT downBitmap,UINT focusBitmap,UINT disableBitmap)
{
PrivateInfo *pPrivateInfo=new PrivateInfo;
pPrivateInfo=(PrivateInfo*)GetWindowLong(hwnd,GWL_USERDATA);
DeleteObject(pPrivateInfo->hbitmap0);
DeleteObject(pPrivateInfo->hbitmap1);
DeleteObject(pPrivateInfo->hbitmap2);
DeleteObject(pPrivateInfo->hbitmap3);
pPrivateInfo->hbitmap0=LoadBitmap((HINSTANCE)GetWindowLong(GetParent(hwnd),GWL_HINSTANCE),MAKEINTRESOURCE(upBitmap));
pPrivateInfo->hbitmap1=LoadBitmap((HINSTANCE)GetWindowLong(GetParent(hwnd),GWL_HINSTANCE),MAKEINTRESOURCE(downBitmap));
pPrivateInfo->hbitmap2=LoadBitmap((HINSTANCE)GetWindowLong(GetParent(hwnd),GWL_HINSTANCE),MAKEINTRESOURCE(focusBitmap));
pPrivateInfo->hbitmap3=LoadBitmap((HINSTANCE)GetWindowLong(GetParent(hwnd),GWL_HINSTANCE),MAKEINTRESOURCE(disableBitmap));
return true;
}