1. 程式人生 > >MFC按鈕自繪

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。