MFC/VC++中怎样设置位图按钮并且位图不会覆盖文字——–位图按钮
1:第一次嘗試
設(shè)置??? IDC_BUTTON3按鈕風(fēng)格的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:第二次嘗試:https://wenku.baidu.com/view/95f2be7a1711cc7931b716e2.html
2.1建立基于對話框的MFC,并且將 IDC_BUTTON3按鈕風(fēng)格的ower-draw打鉤:
2.2 聲明CBitamapButton m_btnBMP;
2.3 在對話框類CtestDlg的構(gòu)造函數(shù)中m_btnBMP.loadbitmaps(IDB_BITMAP1,IDB_BITMAP2,IDB_BITMAP3,IDB_BITMAP4);
2.4 然后在OnInitialDilog中:m_btnBMP.SubClassDlgItem(IDC_BUTTON3,this);m_btnBMP.SizeToContent();
缺點(diǎn):覆蓋掉了文字,并且也有閃屏
?
?
位圖按鈕
由于MFC提供的按鈕外觀不是很漂亮(其實是很丑),所以使用按鈕的時候往往要自己重新繪制,最多的就是添加自己的漂亮圖片。
1.CButton中提供了SetBitmap函數(shù),可以給按鈕設(shè)置位圖,使用方法如下:
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);
優(yōu)點(diǎn):使用方法簡單
缺點(diǎn):位圖單一,不能顯示區(qū)分按鈕各種狀態(tài),有閃屏情況
2.使用MS做好的CBitmapButton類:
CBitmapButton是MS封裝好的位圖按鈕類,從CButton類繼承而來,提供兩種使用方法,但使用前要創(chuàng)建一個CButton對象與其關(guān)聯(lián),另外,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方法:
創(chuàng)建一個按鈕資源ID為IDC_MYBUTTON并且具有BS_OWNERDRAW屬性,設(shè)定Caption為:MYBUTTON,插入四張資源位圖ID為"MYBUTTONU","MYBUTTOND","MYBUTTONF","MYBUTTONX",分別表示按鈕的”彈起“,”按下“,”焦點(diǎn)“,”禁用“狀態(tài)。最后調(diào)用AutoLoad函數(shù)就可以自動加載了:
CBitmapButton bmpButton;
bmpButton.AutoLoad(IDC_MYBUTTON, this);
以上兩種用法
優(yōu)點(diǎn):使用簡單,很好的用位圖表示了按鈕的各種狀態(tài),豐富了按鈕的外觀
缺點(diǎn):有閃屏情況
MS真讓人受傷啊,提供了位圖按鈕的使用,但就是不能用,都有閃屏。所以只有自己重新繪制了:
3.添加自定義類,從CButton繼承,在類向?qū)е刑砑犹摵瘮?shù)DrawItem,然后重畫:
??? //從lpDrawItemStruct獲取控件的相關(guān)信息
??? CRect rect = lpDrawItemStruct->rcItem;
??? CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
??? int nSaveDC=pDC->SaveDC();
??? UINT state = lpDrawItemStruct->itemState;
??? if(state & ODS_SELECTED)
??? {
??? ?? // 畫按鈕按下狀態(tài)的時候需要顯示的位圖
??? ??? DrawBmpState(pDC, m_bmpResDown);
??? }
??? else
??? {
??? ?? // 畫按鈕其他狀態(tài)的時候需要顯示的位圖
??? ??? DrawBmpState(pDC, m_bmpResUp);
??? }
????
??? // 恢復(fù)DC
??? pDC->RestoreDC(nSaveDC);
注:DrawBmpState用來畫按鈕的各種狀態(tài),采用雙緩沖技術(shù),在PC上測試運(yùn)行正常,但是在手持設(shè)備運(yùn)行有閃屏情況。閃屏發(fā)生在按其他按鈕的時候,由于這個按鈕要丟失焦點(diǎn),狀態(tài)轉(zhuǎn)換太快,處理器速度跟不上的原因。(這只是我的個人猜測,高人知道的請賜教)。或者是其他的原因。總之閃屏就像一個甩不掉的魔鬼一樣如影隨形,最后只能自己重畫了。
4.在OnPaint中徹底重畫,定制自己的位圖按鈕:
添加CBmpButton類繼承自CButton:
添加BOOL m_bDown;初始化為FALSE,用來標(biāo)識按鈕的按下狀態(tài),當(dāng)按鈕按下是置為TRUE,否則為FALSE,主要是為了避免當(dāng)鼠標(biāo)在其他地方按下后,然后在按鈕上釋放造成的按鈕重繪。
添加WM_PAINT消息重繪:
??? CPaintDC dc(this); // device context for painting
??? if(m_bDown)
??? {
??? ??? DrawBmpState(&dc, m_bmpResDown);
??? }
??? else
??? {
??? ??? DrawBmpState(&dc, m_bmpResUp);
??? }
DrawBmpState函數(shù)用來畫按鈕各個狀態(tài)的位圖,采用雙緩沖技術(shù)避免了按鈕重繪時的閃屏,這里只列出了兩種:彈起和按下:
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);
??? }
這樣就避免了重繪按鈕的閃屏,希望閃屏以后不要再來!
總結(jié)
以上是生活随笔為你收集整理的MFC/VC++中怎样设置位图按钮并且位图不会覆盖文字——–位图按钮的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网站程序员的程序员成长之路大概分几个阶段
- 下一篇: VC的MFC中重绘函数的使用总结(整理)