天天看點

VC 制作帶彈出式菜單的按鈕

帶有彈出式菜單的按鈕可以使一個按鈕具有多項選擇功能,擴充了按鈕的功能,相當于把多個按鈕內建于一體,可以減少按鈕數目。

這種按鈕的按鈕體分為兩個區域,單擊主體區域時,執行主體按鈕的功能,單擊選擇區域時,彈出一個菜單,可從中選擇要執行的功能。

下面,我們看一下它的制作過程:

一、建立一個以CButton類為基類的新類

單擊“Insert”→“New Class”,建立一個新類。基類設定為CButton,新類起名為CMenuButton。

二、利用自繪方法繪制按鈕,主體區顯示按鈕文本,選擇區畫一個小箭頭

在CMenuButton類中用ClassWizard添加函數:PreSubclassWindow()和DrawItem()。

PreSubclassWindow()函數在建立按鈕時執行,可用于做一些準備工作。在這裡我給按鈕添加自繪屬性:

void CMenuButton::PreSubclassWindow() { ModifyStyle( 0, BS_OWNERDRAW ); //設定按鈕屬性為自繪式

CButton::PreSubclassWindow(); }

DrawItem()函數用于繪制按鈕,左邊繪制按鈕文字,作為主體區,右邊繪制一個小箭頭,作為選擇區。實際應用中,可根據具體需要繪制想要的形狀和内容。

void CMenuButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { CDC *pDC = CDC::FromHandle( lpDrawItemStruct->hDC ); m_ButRect = lpDrawItemStruct->rcItem; //擷取按鈕尺寸 int nSavedDC = pDC->SaveDC(); VERIFY( pDC );

DrawButton(pDC); //繪制按鈕

pDC->RestoreDC( nSavedDC ); }

其中m_ButRect都是CRect型對象,在頭檔案中進行定義。DrawButton()為繪制按鈕的函數,把它定義在外邊的目的是友善使用者修改,如果你想改變按鈕形狀,隻需修改DrawButton()函數即可。

void CMenuButton::DrawButton(CDC *pDC) { m_LRect.SetRect( m_ButRect.left, m_ButRect.top, m_ButRect.right-21, m_ButRect.bottom ); //按鈕主體區尺寸 m_RRect.SetRect( m_ButRect.right-20, m_ButRect.top, m_ButRect.right, m_ButRect.bottom ); //按鈕選擇區尺寸

CPen Pen; Pen.CreatePen(PS_SOLID, 1, RGB(192,192,192) ); pDC->SelectObject( &Pen ); pDC->FillSolidRect( m_ButRect, m_BackColor ); //畫背景 switch( m_State ) //不同狀态畫不同邊框 { case 0: //正常按鈕 pDC->DrawEdge( &m_LRect, BDR_RAISEDINNER, BF_RECT ); pDC->DrawEdge( &m_RRect, BDR_RAISEDINNER, BF_RECT ); break; case 1: //滑鼠進入時的按鈕 pDC->DrawEdge( &m_LRect, BDR_RAISEDINNER, BF_RECT ); pDC->DrawEdge( &m_RRect, BDR_RAISEDINNER, BF_RECT ); pDC->MoveTo( m_ButRect.TopLeft() ); pDC->LineTo( m_ButRect.right, m_ButRect.top ); break; case 2: //單擊按鈕主體區時的按鈕 pDC->DrawEdge( &m_RRect, BDR_RAISEDINNER, BF_RECT ); break; case 3: //單擊按鈕選擇區時的按鈕 pDC->DrawEdge( &m_LRect, BDR_RAISEDINNER, BF_RECT ); break; } POINT m_pt[3], m_ptCentre; //箭頭坐标(三個頂點) m_ptCentre = m_RRect.CenterPoint(); //選擇區中點位置 m_pt[0].x = m_ptCentre.x-3; //計算箭頭坐标 m_pt[0].y = m_ptCentre.y-2; m_pt[1].x = m_ptCentre.x+4; m_pt[1].y = m_ptCentre.y-2; m_pt[2].x = m_ptCentre.x; m_pt[2].y = m_ptCentre.y+2; pDC->SelectStockObject( BLACK_BRUSH ); //定義畫刷(黑色) CRgn rgn; rgn.CreatePolygonRgn( m_pt, 3, ALTERNATE ); pDC->PaintRgn( &rgn ); //畫選擇區箭頭

pDC->SetTextColor( m_ForeColor ); //畫主體區文字 pDC->SetBkMode( TRANSPARENT ); pDC->DrawText( m_strText, &m_LRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS); }

m_State是個标志,其值為0表示正常按鈕;1表示滑鼠進入按鈕,繪制暗線邊框;2表示在按鈕主體區按下滑鼠左鍵;3表示在按鈕選擇區按下滑鼠左鍵。

在m_State的不同取值下,繪制不同的按鈕邊框,可以增加按鈕的動态效果。

三、添加滑鼠響應函數

在CMenuButton類中用ClassWizard添加函數:OnMouseMove()、OnLButtonDown()、OnLButtonUp()。

OnMouseMove()函數用于響應滑鼠移動消息,當滑鼠進入按鈕時,設定相應标志,并重繪按鈕邊框,當滑鼠離開按鈕時,清除标志,恢複原邊框。