1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > MFC/VC++中怎样设置位图按钮并且位图不会覆盖文字——–位图按钮

MFC/VC++中怎样设置位图按钮并且位图不会覆盖文字——–位图按钮

时间:2021-05-21 02:04:18

相关推荐

MFC/VC++中怎样设置位图按钮并且位图不会覆盖文字——–位图按钮

1:第一次尝试

设置 IDC_BUTTON3按钮风格的bitmap为true

在OnInitialDilog中:

CButton* cbpTest = NULL;

HINSTANCE hInstance=AfxGetResourceHandle();

HBITMAP m_hBmp4=(HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_BITMAP1), IMAGE_BITMAP, 0, 0, 0);

cbpTest = (CButton*)GetDlgItem(IDC_BUTTON3);

::PostMessage(cbpTest->GetSafeHwnd(), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)m_hBmp4);

覆盖掉了文字,并且也有闪屏

2:第二次尝试:/view/95f2be7a1711cc7931b716e2.html

2.1建立基于对话框的MFC,并且将 IDC_BUTTON3按钮风格的ower-draw打钩:

2.2 声明CBitamapButton m_btnBMP;

2.3 在对话框类CtestDlg的构造函数中m_btnBMP.loadbitmaps(IDB_BITMAP1,IDB_BITMAP2,IDB_BITMAP3,IDB_BITMAP4);

2.4 然后在OnInitialDilog中:m_btnBMP.SubClassDlgItem(IDC_BUTTON3,this);m_btnBMP.SizeToContent();

缺点:覆盖掉了文字,并且也有闪屏

位图按钮

由于MFC提供的按钮外观不是很漂亮(其实是很丑),所以使用按钮的时候往往要自己重新绘制,最多的就是添加自己的漂亮图片。

1.CButton中提供了SetBitmap函数,可以给按钮设置位图,使用方法如下:

CButton button;

button.Create(_T("My button"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, CRect(10,10,100,30),this, 1);

CBitmap bmp;

bmp.LoadBitmap(IDB_BMP);

button.SetBitmap(bmp);

优点:使用方法简单

缺点:位图单一,不能显示区分按钮各种状态,有闪屏情况

2.使用MS做好的CBitmapButton类:

CBitmapButton是MS封装好的位图按钮类,从CButton类继承而来,提供两种使用方法,但使用前要创建一个CButton对象与其关联,另外,CBitmapButton类必须具有BS_OWNERDRAW属性:

<1> 使用LoadBitmaps方法:

CBitmapButton bmpButton;

bmpButton.Create(NULL, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, CRect(10, 10, 100, 100), this, BTN_ID);

bmpButton.LoadBitmaps(IDB_UP, IDB_DOWN, IDB_FOCUS, IDB_DISABLE);

<2>使用AutoLoad方法:

创建一个按钮资源ID为IDC_MYBUTTON并且具有BS_OWNERDRAW属性,设定Caption为:MYBUTTON,插入四张资源位图ID为"MYBUTTONU","MYBUTTOND","MYBUTTONF","MYBUTTONX",分别表示按钮的”弹起“,”按下“,”焦点“,”禁用“状态。最后调用AutoLoad函数就可以自动加载了:

CBitmapButton bmpButton;

bmpButton.AutoLoad(IDC_MYBUTTON, this);

以上两种用法

优点:使用简单,很好的用位图表示了按钮的各种状态,丰富了按钮的外观

缺点:有闪屏情况

MS真让人受伤啊,提供了位图按钮的使用,但就是不能用,都有闪屏。所以只有自己重新绘制了:

3.添加自定义类,从CButton继承,在类向导中添加虚函数DrawItem,然后重画:

//从lpDrawItemStruct获取控件的相关信息

CRect rect = lpDrawItemStruct->rcItem;

CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC);

int nSaveDC=pDC->SaveDC();

UINT state = lpDrawItemStruct->itemState;

if(state & ODS_SELECTED)

{

// 画按钮按下状态的时候需要显示的位图

DrawBmpState(pDC, m_bmpResDown);

}

else

{

// 画按钮其他状态的时候需要显示的位图

DrawBmpState(pDC, m_bmpResUp);

}

// 恢复DC

pDC->RestoreDC(nSaveDC);

注:DrawBmpState用来画按钮的各种状态,采用双缓冲技术,在PC上测试运行正常,但是在手持设备运行有闪屏情况。闪屏发生在按其他按钮的时候,由于这个按钮要丢失焦点,状态转换太快,处理器速度跟不上的原因。(这只是我的个人猜测,高人知道的请赐教)。或者是其他的原因。总之闪屏就像一个甩不掉的魔鬼一样如影随形,最后只能自己重画了。

4.在OnPaint中彻底重画,定制自己的位图按钮:

添加CBmpButton类继承自CButton:

添加BOOL m_bDown;初始化为FALSE,用来标识按钮的按下状态,当按钮按下是置为TRUE,否则为FALSE,主要是为了避免当鼠标在其他地方按下后,然后在按钮上释放造成的按钮重绘。

添加WM_PAINT消息重绘:

CPaintDC dc(this); // device context for painting

if(m_bDown)

{

DrawBmpState(&dc, m_bmpResDown);

}

else

{

DrawBmpState(&dc, m_bmpResUp);

}

DrawBmpState函数用来画按钮各个状态的位图,采用双缓冲技术避免了按钮重绘时的闪屏,这里只列出了两种:弹起和按下:

VOID CBmpButton::DrawBmpState(CDC *pDC, HBITMAP hBitmap)

{

CRect rect;

//GetWindowRect(&rect);

GetClientRect(&rect);

CDC MemDC,mdc;

mdc.CreateCompatibleDC(NULL);

MemDC.CreateCompatibleDC(NULL);

CBitmap MemBitmap;

MemBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());

MemDC.SelectObject(&MemBitmap);

MemDC.FillSolidRect(0,0,rect.Width(),rect.Height(),RGB(0,0,0));

//b1.LoadBitmap(bmpID);

//pb1 = CBitmap::FromHandle(hBitmap);

mdc.SelectObject(hBitmap);

MemDC.BitBlt(0,0,rect.Width(),rect.Height(),&mdc,0,0,SRCCOPY);

pDC->BitBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY);

//绘图完成后的清理

MemBitmap.DeleteObject();

MemDC.DeleteDC();

}

添加WM_LBUTTONDOWN事件:

m_bDown = TRUE;

InvalidateRect(NULL);

添加WM_LBUTTONUP事件:

if(m_bDown)

{

m_bDown = FALSE;

InvalidateRect(NULL);

}

这样就避免了重绘按钮的闪屏,希望闪屏以后不要再来!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。