本文详叙了自制一个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:[email protected] 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:[email protected] 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; }

|