天天看點

MFC 自繪按鈕的實作

==================

添加兩幅位圖 IDB_GETFOCUS IDB_LOSTFOCUS

==========================

在對話框視窗屬性中添加WM_DRAWITEM消息響應函數

=========================

函數代碼如下

void CMyButtonDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)

{

 // TODO: 在此添加消息處理程式代碼和/或調用預設值

 CDC ButtonDC;

 CBitmap bitmapTrans;

 BITMAP bmp;

 CDC mem;

 CRect rc;

 //得到用于繪圖按鈕的DC

 ButtonDC.Attach(lpDrawItemStruct->hDC);

 //準備用于向按鈕區域傳送位圖

 mem.CreateCompatibleDC(&ButtonDC);

 //擷取按鈕所占矩形大小

 rc=lpDrawItemStruct->rcItem;

 //擷取按鈕目前所處的狀态,根據不同狀态繪制不同按鈕

 UINT state=lpDrawItemStruct->itemState;

 //如果按鈕已獲得焦點,繪制選中狀态下的按鈕

 if(state & ODS_FOCUS)

 {

  bitmapTrans.LoadBitmapW(IDB_GETFOCUS);

  bitmapTrans.GetBitmap(&bmp);

  CBitmap *old=mem.SelectObject(&bitmapTrans);

  //向按鈕所在位置傳輸位圖

  //隻用StetchBlt的目的是為了讓位圖随按鈕的大小而改變

  ButtonDC.StretchBlt(rc.left,rc.top,rc.right,rc.bottom,&mem,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);

  mem.SelectObject(old);

  bitmapTrans.DeleteObject();

  //設定文字背景為透明

  ButtonDC.SetBkMode(TRANSPARENT);

  //繪制按鈕标題

  ButtonDC.DrawText(_T("已選中"),&rc,DT_CENTER|DT_VCENTER|DT_SINGLELINE);

 }

 else

 {

  //繪制未選中狀态下的按鈕

  bitmapTrans.LoadBitmapW(IDB_LOSTFOCUS);

  CBitmap *old2=mem.SelectObject(&bitmapTrans);

  bitmapTrans.GetBitmap(&bmp);

  CBitmap *old=mem.SelectObject(&bitmapTrans);

  ButtonDC.StretchBlt(rc.left,rc.top,rc.right,rc.bottom,&mem,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);

  ButtonDC.DrawText(_T("未選中"),&rc,DT_CENTER|DT_VCENTER|DT_SINGLELINE);

  mem.SelectObject(old2);

  bitmapTrans.DeleteObject();

 }

 //

 CDialogEx::OnDrawItem(nIDCtl, lpDrawItemStruct);

}

=============================

這裡隻對ODS_FOCUS狀态進行了定制,其他狀态原理同此

随時通路MEASUREITEMSTRUCT資料結構的資料成員是進行自繪的關鍵