MFC自绘控件与界面美化2

35 篇文章 0 订阅

3.3 使用Windows的消息机制 
  
使用MFC类的既有函数来美化界面,其功能是有限的。既然Windows是通过消息机制进行通讯的,那么我们就可以通过截获一些有用的消息来美化我们的界面,以下是一些有用的Windows消息: 
WM_PAINT 
WM_ERASEBKGND 
WM_CTLCOLOR* 
WM_DRAWITEM* 
WM_MEASUREITEM* 
NM_CUSTOMDRAW* 
注意,标注*的消息是子元素发送给父窗口的通知消息,其它的为窗口或者子元素自身的消息。 
 
 
3.3.1 WM_PAINT 
  
WM_PAINT消息相信大家都很熟悉,一个窗口要重绘了,就会有一个WM_PAINT消息发送给窗口。 
可以响应窗口的WM_PAINT,以更改它们的模样。WM_PAINT的映射函数原型如下: 
afx_msg void OnPaint(); 
控件也是窗口,所以控件也有WM_PAINT消息,通过消息映射我们完全可以定义控件的界面。如图5所示: 
图5 利用WM_ PAINT消息美化界面 
实现代码也很简单: 

[cpp] view plaincopy

  1. void CLazyStatic::OnPaint()   
  2. {  
  3.     CPaintDC dc(this); // device context for painting  
  4.       
  5.     //什么都不输出,仅仅画一个矩形框   
  6.     CRect rc;  
  7.     GetClientRect(&rc);  
  8.     dc.Rectangle(rc);     
  9. }  

[cpp] view plaincopy

  1. void CLazyStatic::OnPaint()   
  2. {  
  3.     CPaintDC dc(this); // device context for painting  
  4.       
  5.     //什么都不输出,仅仅画一个矩形框  
  6.     CRect rc;  
  7.     GetClientRect(&rc);  
  8.     dc.Rectangle(rc);     
  9. }  

哈哈,简单吧?不过WM_PAINT确实绝了点,它要求应用程序完成元素界面的所有绘制过程,想象一下如何画出一个完整的列表控件?太烦了吧。一般来说,很少有人喜欢使用WM_PAINT,还有其它更细致的消息。 
 
 
3.3.2 WM_ERASEBKGND 
  
Windows在向窗口发送WM_PAINT消息之前,总会发送一个WM_ERASEBKGND消息通知该窗口擦除背景,默认情况下,Windows将以窗口的背景色清除该窗口。 
可以响应窗口(包括子元素)的WM_ERASEBKGND,以更改它们的背景。WM_ERASEBKGND的映射函数原型如下: 
afx_msg BOOL OnEraseBkgnd( CDC* pDC ); 
返回值: 
指定背景是否已清除,如果为FALSE,系统将自动清除 
参数: 
pDC指定了绘制操作所使用的设备环境。 
图6是个简单的例子,通过OnEraseBkgnd为对话框加载了一副位图背景: 
 
图6 利用WM_ ERASEBKGND消息美化界面
实现代码也很简单: 

[cpp] view plaincopy

  1. BOOL CUi4Dlg::OnInitDialog()  
  2. {  
  3. //…   
  4.     //加载位图   
  5.     //CBitmap m_Back;   
  6.     m_Back.LoadBitmap(IDB_BACK);  
  7.     //…   
  8. }  
  9.   
  10. BOOL CUi4Dlg::OnEraseBkgnd(CDC* pDC)   
  11. {  
  12.     CDC dc;  
  13.     dc.CreateCompatibleDC(pDC);  
  14.     dc.SelectObject(&m_Back);  
  15.   
  16.     //获取BITMAP对象   
  17.     BITMAP hb;  
  18.     m_Back.GetBitmap(&hb);  
  19.   
  20.     //获取窗口大小   
  21.     CRect rt;  
  22.     GetClientRect(&rt);  
  23.     //显示位图   
  24.     pDC->StretchBlt(0, 0, rt.Width(), rt.Height(),  
  25.         &dc, 0, 0, hb.bmWidth, hb.bmHeight, SRCCOPY);  
  26.   
  27.     return TRUE;  
  28. }  
  29.   
  30. HBRUSH CUi4Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)   
  31. {  
  32.     //设置透明背景模式   
  33.     pDC->SetBkMode(TRANSPARENT);  
  34.     //设置背景刷子为空   
  35.     return (HBRUSH)::GetStockObject(HOLLOW_BRUSH);  
  36. }  

[cpp] view plaincopy

  1. BOOL CUi4Dlg::OnInitDialog()  
  2. {  
  3. //…  
  4.     //加载位图  
  5.     //CBitmap m_Back;  
  6.     m_Back.LoadBitmap(IDB_BACK);  
  7.     //…  
  8. }  
  9.   
  10. BOOL CUi4Dlg::OnEraseBkgnd(CDC* pDC)   
  11. {  
  12.     CDC dc;  
  13.     dc.CreateCompatibleDC(pDC);  
  14.     dc.SelectObject(&m_Back);  
  15.   
  16.     //获取BITMAP对象  
  17.     BITMAP hb;  
  18.     m_Back.GetBitmap(&hb);  
  19.   
  20.     //获取窗口大小  
  21.     CRect rt;  
  22.     GetClientRect(&rt);  
  23.     //显示位图  
  24.     pDC->StretchBlt(0, 0, rt.Width(), rt.Height(),  
  25.         &dc, 0, 0, hb.bmWidth, hb.bmHeight, SRCCOPY);  
  26.   
  27.     return TRUE;  
  28. }  
  29.   
  30. HBRUSH CUi4Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)   
  31. {  
  32.     //设置透明背景模式  
  33.     pDC->SetBkMode(TRANSPARENT);  
  34.     //设置背景刷子为空  
  35.     return (HBRUSH)::GetStockObject(HOLLOW_BRUSH);  
  36. }  



同时别忘了响应OnCtlColor,否则窗口里面的控件就不透明了。OnCtlColor的内容,详见3.3.3章节。 
 
 
3.3.3 WM_CTLCOLOR 
  
在控件显示之前,每一个控件都会向父对话框发送一个WM_CTLCOLOR消息要求获取绘制所需要的颜色。WM_CTLCOLOR消息缺省处理函数CWnd::OnCtlColor返回一个HBRUSH类型的句柄,这样,就可以设置前景和背景文本颜色,并为控件或者对话框的非文本区域选定一个刷子。 
WM_CTLCOLOR的映射函数原型如下: 
afx_msg HBRUSH OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor );
返回值: 
用以指定背景的刷子 
参数: 
pDC指定了绘制操作所使用的设备环境。 
pWnd 控件指针 
nCtlColor 指定控件类型,其取值如表2所示:
类型值 含义 
CTLCOLOR_BTN 按钮控件 
CTLCOLOR_DLG 对话框 
CTLCOLOR_EDIT  编辑控件 
CTLCOLOR_LISTBOX  列表框 
CTLCOLOR_MSGBOX  消息框 
CTLCOLOR_SCROLLBAR 滚动条 
CTLCOLOR_STATIC 静态控件 
表2 nCtlColor的类型值与含义
作为一个简单的例子,观察以下的代码: 

[cpp] view plaincopy

  1. BOOL CUi5Dlg::OnInitDialog()  
  2. {  
  3.     //…   
  4.     //创建字体   
  5.     //CFont CUi1View::m_Font1, CUi1View::m_Font2  
  6.     m_Font1.CreatePointFont(120, "Impact");  
  7.     m_Font3.CreatePointFont(120, "Arial");  
  8.       
  9.     return TRUE;  // return TRUE  unless you set the focus to a control   
  10. }  
  11.   
  12. HBRUSH CUi5Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)   
  13. {  
  14.     HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);  
  15.     if(nCtlColor == CTLCOLOR_STATIC)  
  16.     {  
  17.         //区分静态控件   
  18.         switch(pWnd->GetDlgCtrlID())  
  19.         {  
  20.             case IDC_STATIC1:  
  21.             {  
  22.                 pDC->SelectObject(&m_Font1);  
  23.                 pDC->SetTextColor(RGB(0, 0, 255));  
  24.                 break;  
  25.             }  
  26.             case IDC_STATIC2:  
  27.             {  
  28.                 pDC->SelectObject(&m_Font2);  
  29.                 pDC->SetTextColor(RGB(255, 0, 0));  
  30.                 break;  
  31.             }  
  32.         }  
  33.     }  
  34.   
  35.     return hbr;  
  36. }  

[cpp] view plaincopy

  1. BOOL CUi5Dlg::OnInitDialog()  
  2. {  
  3.     //…  
  4.     //创建字体  
  5.     //CFont CUi1View::m_Font1, CUi1View::m_Font2  
  6.     m_Font1.CreatePointFont(120, "Impact");  
  7.     m_Font3.CreatePointFont(120, "Arial");  
  8.       
  9.     return TRUE;  // return TRUE  unless you set the focus to a control   
  10. }  
  11.   
  12. HBRUSH CUi5Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)   
  13. {  
  14.     HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);  
  15.     if(nCtlColor == CTLCOLOR_STATIC)  
  16.     {  
  17.         //区分静态控件  
  18.         switch(pWnd->GetDlgCtrlID())  
  19.         {  
  20.             case IDC_STATIC1:  
  21.             {  
  22.                 pDC->SelectObject(&m_Font1);  
  23.                 pDC->SetTextColor(RGB(0, 0, 255));  
  24.                 break;  
  25.             }  
  26.             case IDC_STATIC2:  
  27.             {  
  28.                 pDC->SelectObject(&m_Font2);  
  29.                 pDC->SetTextColor(RGB(255, 0, 0));  
  30.                 break;  
  31.             }  
  32.         }  
  33.     }  
  34.   
  35.     return hbr;  
  36. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MFC(Microsoft Foundation Class)是一种基于Windows操作系统的软件开发框架,用于开发图形用户界面(GUI)应用程序。MFC包含了丰富的自绘Tab控件样式,可供开发人员选择和应用。 首先,MFC提供了丰富的颜色和字体样式选项。开发人员可以根据应用程序的需求自定义Tab控件的背景颜色、边框颜色、选中和未选中状态的文本颜色等。同时,也可以设置不同的字体样式,如字体、大小、加粗、倾斜等,以满足用户界面设计的需求。 其次,MFC还支持不同的Tab控件形状。除了常见的矩形形状外,还可以使用椭圆形状、圆角矩形形状等来美化Tab控件的外观。这些不同形状的Tab控件可以使应用程序的界面更加独特、吸引人。 此外,MFC还提供了不同的Tab控件标签布局选项。开发人员可以根据界面设计的需要选择标签的位置,如顶部、底部、左侧、右侧等。这可以使用户能够自由选择最适合其操作习惯的Tab控件风格。 最后,MFC还支持自定义Tab控件的图标。开发人员可以添加自定义的图标或者使用系统提供的图标作为Tab控件的标识。这可以帮助用户更直观地理解和导航应用程序的功能。 总之,MFC提供了丰富多样的自绘Tab控件样式,开发人员可以根据应用程序的需要选择和应用不同的样式。这些样式包括颜色和字体样式的调整、不同形状的Tab控件、不同的标签布局选项以及自定义的图标等。这些样式使得应用程序能够提供更好的用户界面体验,增强了应用程序的吸引力和易用性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值