logo资料库

VC改变对话框按钮字体颜色和背景的解决方案.doc

第1页 / 共6页
第2页 / 共6页
第3页 / 共6页
第4页 / 共6页
第5页 / 共6页
第6页 / 共6页
资料共6页,全文预览结束
要想修改 CButton 类按钮背景颜色和文字颜色,必须利用自绘方法对按钮进行重新绘制。这 可以通过定义一个以 CButton 为基类的新按钮类来实现。以下为具体的实现方法: 方法一: 加入一个新类,类名:CMyButton,基类:CButton。 在头文件 MyButton.h 中加入以下变量和函数定义: private: int BOOL CString COLORREF COLORREF COLORREF CRect CFont* void //文本颜色 //背景色 //锁定按钮的文字颜色 m_ForeColor; m_BackColor; m_LockForeColor; //按钮尺寸 //字体 //画正常的按钮 //按钮形状(0-正常,1-当前,2-按下,3-锁定) DrawButton(CDC *pDC); m_ButRect; p_Font; m_Style; b_InRect; m_strText; //鼠标进入标志 //按钮文字 // 接口函数 public: void SetText(CString str); void SetForeColor(COLORREF color); void SetBkColor(COLORREF color); void SetTextFont(int FontHight,LPCTSTR FontName); //设置文本颜色 //设置背景颜色 //设置字体 在 MyButton.cpp 的构造函数中初始化变量: CMyButton::CMyButton() { //按钮形状风格 //鼠标进入标志 //按钮文字(使用默认文字) m_Style = 0; b_InRect = false; m_strText = _T(""); m_ForeColor = RGB(0,0,0); m_BackColor = RGB(243,243,243); m_LockForeColor = GetSysColor(COLOR_GRAYTEXT); //字体指针 p_Font = NULL; //文字颜色(黑色) //背景色(灰白色) //锁定按钮的文字颜色 } 用 ClassWizard 添加下列消息函数: PreSubclassWindow(); DrawItem(); onMouseMove(); OnLButtonDown(); OnLButtonUp(); 在各函数内加入代码: void CMyButton::PreSubclassWindow() { ModifyStyle( 0, BS_OWNERDRAW ); //设置按钮属性为自画式 CButton::PreSubclassWindow();
} PreSubclassWindow()在按钮创建前自动执行,所以我们可以在其中做一些初始工作。这里我 只做了一项工作,就是为按钮设置属性为“自绘”式,这样,用户在添加按钮后,就不需设置 “Owner draw”属性了。 void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { CDC *pDC = CDC::FromHandle( lpDrawItemStruct->hDC ); m_ButRect = lpDrawItemStruct->rcItem; if( m_strText.IsEmpty() ) //获取按钮尺寸 GetWindowText( m_strText ); int nSavedDC = pDC->SaveDC(); VERIFY( pDC ); DrawButton( pDC ); pDC->RestoreDC( nSavedDC ); //获取按钮文本 //绘制按钮 } DrawItem()函数是一个关键函数,按钮的绘制工作就在这里进行,它的作用相当于对话框中 的 OnPaint()函数和视图中的 OnDraw()函数。 这里我做了三项工作:获取按钮尺寸、获取按钮文本、绘制按钮。其中绘制工作在自定义函 数 DrawButton()中完成。以下就是绘制过程: void CMyButton::DrawButton(CDC *pDC) { //调整状态 if( m_Style==3 ) m_Style = 0; if( GetStyle() & WS_DISABLED ) //禁止状态 m_Style = 3; //bColor 为边框颜色,fColor 为文字颜色 //正常按钮 //鼠标进入时按钮 //按下的按钮 //锁定的按钮 //根据状态调整边框颜色和文字颜色 COLORREF bColor, fColor; switch( m_Style ) { case 0: bColor = RGB(192,192,192); fColor = m_ForeColor; break; case 1: bColor = RGB(255,255,255); fColor = m_ForeColor; break; case 2: bColor = RGB(192,192,192); fColor = m_ForeColor; break; case 3: bColor = m_BackColor; fColor = m_LockForeColor; break; } //绘制按钮背景 CBrush Brush; Brush.CreateSolidBrush( m_BackColor ); pDC->SelectObject( &Brush ); CPen Pen; Pen.CreatePen(PS_SOLID, 1, bColor ); pDC->SelectObject( &Pen ); pDC->RoundRect(&m_ButRect,CPoint(5,5)); //绘制按钮按下时的边框 if( m_Style!=2 ) //画圆角矩形 //背景刷
{ CRect Rect; Rect.SetRect( m_ButRect.bottom ); m_ButRect.left+2, m_ButRect.top+1, m_ButRect.right, pDC->DrawEdge( &Rect, BDR_RAISEDINNER, BF_RECT ); //画边框 } //绘制按钮文字 pDC->SetTextColor( fColor ); pDC->SetBkMode( TRANSPARENT ); pDC->DrawText( m_strText, &m_ButRect, DT_SINGLELINE | DT_CENTER //画文字 | DT_VCENTER | DT_END_ELLIPSIS); //绘制拥有焦点按钮的虚线框 if( GetFocus()==this ) { CRect Rect; Rect.SetRect( m_ButRect.bottom-2 ); m_ButRect.left+3, m_ButRect.top+2, m_ButRect.right-3, pDC->DrawFocusRect( &Rect ); //画拥有焦点的虚线框 } } 变量 m_Style 表征当前按钮状态,它的取值为:0-正常,1-当前,2-按下,3-锁定。不同状 态下按钮的边框颜色和文字颜色有所不同。m_Style 的值在鼠标响应函数中进行修改。 绘制工作主要利用 CDC 类的绘图函数完成,主要注意在 m_Style 不同取值下表现出来的差 别。 void CMyButton::onMouseMove(UINT nFlags, CPoint point) { if( !b_InRect || GetCapture()!=this ) { //鼠标进入按钮 b_InRect = true; SetCapture(); m_Style = 1; Invalidate(); //设置进入标志 //捕获鼠标 //设置按钮状态 //重绘按钮 } else { if ( !m_ButRect.PtInRect(point) ) { //鼠标离开按钮 b_InRect = false; ReleaseCapture(); m_Style = 0; Invalidate(); //清除进入标志 //释放捕获的鼠标 //设置按钮状态 //重绘按钮 } }
CButton::onMouseMove(nFlags, point); } onMouseMove()函数是鼠标移动消息函数,用于判定当前鼠标指针是否在按钮上。b_InRect 是个标志,为 true 表示鼠标指针进入了按钮区域,此时要捕获鼠标,让鼠标命令传送给按钮。 当鼠标指针离开按钮时,要清除 b_InRect 标志,并且释放捕获的鼠标,让其它窗口可以接 收鼠标命令。 Invalidate()函数用于更新按钮,它会自动调用 DrawItem()函数重新绘制按钮。 设置条件的目的是仅在鼠标指针进入按钮和离开按钮时更新按钮,这样可以防止鼠标在按钮 上移动时发生闪烁。 void CMyButton::OnLButtonDown(UINT nFlags, CPoint point) { m_Style = 2; Invalidate(); //重绘按钮 CButton::OnLButtonDown(nFlags, point); } OnLButtonDown()函数是单击鼠标左键时的消息函数。这里只是重新绘制按钮,具体的单击 响应应该在拥有按钮的对话框或视图中进行。 void CMyButton::OnLButtonUp(UINT nFlags, CPoint point) { m_Style = 1; Invalidate(); //重绘按钮 CButton::OnLButtonUp(nFlags, point); } OnLButtonUp()函数是单击鼠标左键后弹起时的消息函数。这里也只是重绘按钮,这样能使 按钮在按下和弹起时有所不同,使按钮看上去有动态效果。 接口函数是用 CMyButton 类 定义的按钮修改颜色、字体和按钮文字的接口,由以下函数组 成: //设置按钮文本 void CMyButton::SetText(CString str) { m_strText = _T(""); SetWindowText(str); } //设置文本颜色 void CMyButton::SetForeColor(COLORREF color) { m_ForeColor = color; Invalidate(); } //设置背景颜色 void CMyButton::SetBkColor(COLORREF color) {
m_BackColor = color; Invalidate(); } //设置字体(字体高度、字体名) void CMyButton::SetTextFont(int FontHight,LPCTSTR FontName) { delete p_Font; if ( p_Font ) p_Font = new CFont; p_Font->CreatePointFont( FontHight, FontName ); SetFont( p_Font ); //设置字体 //删除旧字体 //创建新字体 } 由于新字体由 new 生成,必须显式回收,这项工作可以在 CMyButton 类 的析构函数中进 行: CMyButton::~CMyButton() { if ( p_Font ) delete p_Font; //删除字体 } 这样一个可设置颜色、字体的按钮类就做好了。使用时,先在对话框中放置好按钮,再用 ClassWizard 为按钮添加控制变量,并且将变量的类型设置为 CMyButton。之后,可以用该 变量调用接口函数设置按钮颜色和字体。 以上测试过,太复杂。又生一类。 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 方法二: 添加 dlg 类的 WM_DRAWITEM 消息处理函数 void CBtncolorDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) { // TODO: Add your message handler code here and/or call default if(nIDCtl==IDC_BUTTON1) //checking for the button { CDC dc; RECT rect; dc.Attach(lpDrawItemStruct ->hDC); // Get the Button DC to CDC rect = lpDrawItemStruct->rcItem; //Store the Button rect to our local rect. dc.Draw3dRect(&rect,RGB(255,255,255),RGB(0,0,0)); dc.FillSolidRect(&rect,RGB(100,100,255));//Here you can define the required color to appear on the Button. UINT state=lpDrawItemStruct->itemState; //This defines the state of the Push button either pressed or not.
if((state & ODS_SELECTED)) { dc.DrawEdge(&rect,EDGE_SUNKEN,BF_RECT); } else { } dc.DrawEdge(&rect,EDGE_RAISED,BF_RECT); dc.SetBkColor(RGB(100,100,255)); dc.SetTextColor(RGB(255,0,0)); //Setting the Text Background color //Setting the Text Color TCHAR buffer[MAX_PATH]; ZeroMemory(buffer,MAX_PATH ); //To store the Caption of the button. //Intializing the buffer to zero ::GetWindowText(lpDrawItemStruct->hwndItem,buffer,MAX_PATH); //Get the Caption of Button Window dc.DrawText(buffer,&rect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);//Redraw the Caption of Button Window dc.Detach(); // Detach the Button DC } CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct); } 把要定义的按钮设置为 Owner Draw 即属性中所有者绘制
分享到:
收藏