近日对我写的按钮控件做了些许修改,让它更加完善了,下面给出完整代码:
bb.h:
#if !defined(AFX_BB_H__E2D72529_DDA6_4CB2_B212_AB7319736D8E__INCLUDED_)
#define AFX_BB_H__E2D72529_DDA6_4CB2_B212_AB7319736D8E__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// bb.h : header file
//
/
// bb window
class bb : public CButton
{
// Construction
public:
bb();
// Attributes
public:
void settextcolor(COLORREF);
void settextbkcolor(COLORREF);
void setbkcolor(COLORREF);
void setimage(char *i);
void setbkmode(int m);
void setfont(int f1,char *f2);
void settransparent();
void setnottransparent();
HBITMAP loadjpg(CString strFileName);
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(bb)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~bb();
// Generated message map functions
protected:
//{{AFX_MSG(bb)
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
//}}AFX_MSG
COLORREF textcolor;
COLORREF textbkcolor;
COLORREF bkcolor;
char *image;
int bkmode;
CFont *f;
HBITMAP m_hBitmap;
int transparent;
DECLARE_MESSAGE_MAP()
};
/
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_BB_H__E2D72529_DDA6_4CB2_B212_AB7319736D8E__INCLUDED_)
bb.cpp:
// bb.cpp : implementation file
//
#include "stdafx.h"
#include "1.h"
#include "bb.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// bb
bb::bb()
{
textbkcolor=::GetSysColor(COLOR_3DFACE);
textcolor=RGB(220,0,0);
bkcolor=::GetSysColor(COLOR_3DFACE);
bkmode=1;
image=0;
f=new CFont;
transparent=0;
}
bb::~bb()
{
delete []image;
f->DeleteObject();
}
BEGIN_MESSAGE_MAP(bb, CButton)
//{{AFX_MSG_MAP(bb)
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// bb message handlers
void bb::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC dc;
CRect rect;
dc.Attach(lpDrawItemStruct ->hDC); // Get the Button DC to CDC
rect=lpDrawItemStruct->rcItem;
rect = lpDrawItemStruct->rcItem; //Store the Button rect to our local rect.
rect = lpDrawItemStruct -> rcItem;
if(!this->transparent){
CBitmap m_Bitmap;
CDC dcMem;
BITMAP s_Bmp;
if(image){
CBitmap *old;
m_Bitmap.Attach(m_hBitmap);
dcMem.CreateCompatibleDC(&dc); // 创建于内存设备环境相兼容的设备环境
old= dcMem.SelectObject(&m_Bitmap);
// 将位图对象选入到内存设备环境中
m_Bitmap.GetBitmap(&s_Bmp); // 获取位图信息
dc.StretchBlt(rect.left,rect.top,rect.Width(),rect.Height(),
&dcMem,0,0,s_Bmp.bmWidth,s_Bmp.bmHeight,SRCCOPY);
dcMem.SelectObject(old);
m_Bitmap.Detach();
//::AfxMessageBox(image);
}else{
//dc.Draw3dRect(&rect,RGB(2,25,25),RGB(10,0,10));
dc.FillSolidRect(&rect,bkcolor);//Here you can define the required color to appear on the Button.
}
}
UINT state=lpDrawItemStruct->itemState; //This defines the state of the Push button either pressed or not.
if((state & ODS_SELECTED))
{
dc.DrawEdge(&rect,EDGE_SUNKEN,BF_RECT);
}
else
{
dc.DrawEdge(&rect,EDGE_RAISED,BF_RECT);
}
dc.SetBkMode(TRANSPARENT);
dc.SetBkColor(textbkcolor); //Setting the Text Background color
dc.SetTextColor(textcolor); //Setting the Text Color
TCHAR buffer[MAX_PATH]; //To store the Caption of the button.
ZeroMemory(buffer,MAX_PATH ); //Intializing the buffer to zero
::GetWindowText(lpDrawItemStruct->hwndItem,buffer,MAX_PATH); //Get the Caption of Button Window
dc.DrawText(buffer,&rect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);//Redraw the Caption of Button Window
dc.Detach(); // Detach the Button DC
}
void bb::settextcolor(COLORREF a){
this->textcolor=a;
this->Invalidate();
}
void bb::settextbkcolor(COLORREF a){
this->textbkcolor=a;
this->Invalidate();
}
void bb::setbkcolor(COLORREF a){
this->bkcolor=a;
delete[] image;
image=0;
this->Invalidate();
}
void bb::setbkmode(int a){
this->bkmode=a;
this->Invalidate();
}
void bb::setimage(char *i){
delete[] image;
image=new char[strlen(i)+1];
::strcpy(image,i);
m_hBitmap=loadjpg(image);
this->Invalidate();
}
void bb::setfont(int f2,char *f1){
if(f){
delete f;
}
f=new CFont;
f->CreatePointFont(f2,f1);
this->SetFont(f);
this->Invalidate();
}
void bb::settransparent(){
this->transparent=1;
CRect Rect;
GetWindowRect(&Rect);
GetParent()->ScreenToClient(&Rect);
GetParent()->InvalidateRect(&Rect);
//GetParent()->UpdateWindow();
}
void bb::setnottransparent(){
this->transparent=0;
CRect Rect;
GetWindowRect(&Rect);
GetParent()->ScreenToClient(&Rect);
GetParent()->InvalidateRect(&Rect);
// GetParent()->UpdateWindow();
}
BOOL bb::OnEraseBkgnd(CDC* pDC)
{
if(transparent){
// ::AfxMessageBox("1");
return true;
}else{
return CButton::OnEraseBkgnd(pDC);
}
}
HBITMAP bb::loadjpg(CString strFileName)
{
IPicture* p=NULL;
IStream* s=NULL;
HGLOBAL hG;
void* pp;
FILE* fp;
// Read file in memory
fp = fopen(strFileName,"rb");
if (!fp)
return NULL;
fseek(fp,0,SEEK_END);
int fs = ftell(fp);
fseek(fp,0,SEEK_SET);
hG = GlobalAlloc(GPTR,fs);
if (!hG)
{
fclose(fp);
return NULL;
}
pp = (void*)hG;
fread(pp,1,fs,fp);
fclose(fp);
CreateStreamOnHGlobal(hG,false,&s);
if (!s)
{
GlobalFree(hG);
return NULL;
}
OleLoadPicture(s,0,false,IID_IPicture,(void**)&p);
if (!p)
{
s->Release();
GlobalFree(hG);
return NULL;
}
s->Release();
GlobalFree(hG);
HBITMAP hB = 0;
p->get_Handle((unsigned int*)&hB);
// Copy the image. Necessary, because upon p's release,
// the handle is destroyed.
HBITMAP hBB = (HBITMAP)CopyImage( hB,IMAGE_BITMAP,0,0,LR_COPYRETURNORG );
p->Release();
return hBB;
}
BOOL bb::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message==WM_LBUTTONDBLCLK)
pMsg->message=WM_LBUTTONDOWN;
return CButton::PreTranslateMessage(pMsg);
}
做了些许修改,重绘时整个窗口不再闪烁,并且支持jpg和gif文件作为背景,实现透明按钮,其他的都是原样了,不再说明。
本控件还有不足之处,还望大家多多指正。