天天看點

MFC按鈕自繪

 之前經常看到同僚和各位網友說控件自繪,沒有相關需求,是以一直沒有了解過,現在終于忍不住,學習下這方面知識。 

控件自繪的方式有兩種:1.将控件的自繪封裝成一個類,控件類中自己繪制2.直接在父視窗進行自繪。

首先學習下第一種方式,在vs2008下示例:

1、建立基于對話框的MFC程式OwnerDrawing,添加按鈕ID為IDC_BUTTON1。

2、項目名上右擊->添加->類,添加MFC類(選MFC類非C++類),派生于CButton 的名為CMyBtn的類。

3、給IDC_BUTTON1添加CMyBtn類型的變量m_btn。

4、将IDC_BUTTON1的Owner Draw屬性設定為true。

5、随便添加兩個.bmp位圖,ID為IDB_BITMAP1、IDB_BITMAP2。

6、CMyBtn類中重載CButton類的DrawItem()函數。

//聲明:
afx_msg void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

//定義
void CMyBtn::DrawItem(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.LoadBitmap(IDB_BITMAP2);      
        bitmapTrans.GetBitmap(&bmp);      
        CBitmap *old=mem.SelectObject(&bitmapTrans);        //向按鈕所在位置傳輸位圖        
        //使用StretcnBlt的目的是為了讓位圖随按鈕的大小而改變     
        ButtonDC.StretchBlt(rc.left,rc.top,rc.right,rc.bottom,&mem,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);    
        mem.SelectObject(old);       
        bitmapTrans.DeleteObject();    
    }    
    else   
    {      
        bitmapTrans.LoadBitmap(IDB_BITMAP1);       
        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);    
        mem.SelectObject(old2);      
        bitmapTrans.DeleteObject();   
    }
}

           

這樣,就實作了當IDC_BUTTON1沒有焦點時按鈕bmp為IDB_BITMAP1,有焦點時按鈕bmp為IDB_BITMAP2。

繼續閱讀