用VC实现对属性表按钮区的位图绘制.docx
- 文档编号:30282018
- 上传时间:2023-08-13
- 格式:DOCX
- 页数:14
- 大小:17.49KB
用VC实现对属性表按钮区的位图绘制.docx
《用VC实现对属性表按钮区的位图绘制.docx》由会员分享,可在线阅读,更多相关《用VC实现对属性表按钮区的位图绘制.docx(14页珍藏版)》请在冰豆网上搜索。
用VC实现对属性表按钮区的位图绘制
用VC实现对属性表按钮区的位图绘制
属性表类(CPropertySheetClass)在编写Windows应用程序时使用非常广
泛,如编写安装向导程序、应用程序配置等很多应用程序都必须使用属性表类
,但是如何实现用VC对属性表类的按钮区进行绘制却是一个比较困难的问题。
因为VC的MFC类库封装了属性表类,使得其外观表现一般不容易改变。
而在编
写应用程序的过程中却常常遇到要在属性表的按钮区域进行绘制的问题,如在
属性表按钮区加入公司的标识等等。
属性表按钮区是非窗口客户区,因此要对
其直接进行绘制需要采用一些特殊的处理。
我们在实际编程开发过程中,对此
问题进行了一些探索。
下面我们通过示例说明在VC5.0环境下实现对属性页按
钮区域位图绘制的方法。
1、实现非窗口区域绘制的基本思想:
要完成对属性表按钮区域(即非窗口客户区)的操作,必须得到相关的绘图设
备环境(CPaintDC),找出按钮区域的具体位置,才能够对其进行操作。
为
此,需要对MFC的CPropertySheet类进行继承,对其继承类的OnPaint消息处理
函数进行重载,在OnPaint消息处理函数中,直接以当前指针为变量定义一个
设备环境对象,这就是我们所需的绘图设备环境,再找出属性表类的制表控件
(tablecontrol)客户区位置和属性表类的缺省按钮位置,就能够计算出按
钮区域的具体位置。
只要完成上述两步,对属性表按钮区的操作也就不难实现
了。
2.示例程序具体实现
首先,用VC的Wizard代码生成器生成一个MFC应用程序框架,在自动生成的过程
中,选择应用程序是基于对话框的程序。
当生成完毕后,在将自动生成的对话
框类全部删除。
再手动添加一个从CPropertySheet类继承的子类
CPropertySheetWithLogoDlg类和一个基于CDialog类的CFirstPropertyPage类
,同时在程序App类的InitInstance方法中删除关于自动生成的对话框类的代码。
并加入如下代码:
CPropertySheetWithLogoDlgdlg("属性表按钮区绘制");
CFirstPropertyPageFirstPage;//进行类的实例化
dlg.SetLogoText("ExampleVision");//对要在按钮区域绘制的字符串进行赋值
dlg.AddPage(&FirstPage);//向属性表中添加属性页
intnResponse=dlg.DoModal();
if(nResponse==IDOK){}
elseif(nResponse==IDCANCEL){}
returnFALSE;
这段代码使由Wizard代码生成器生成的应用程序的主框架(mainframe)成为
一个属性表。
其中SetLogoText是CPropertySheetWithLogoDlg类的用户自定义
方法,它是给写在属性表按钮区的字符串赋值。
下面就是如何对按钮区域进行操作。
属性表按钮区是非窗口客户区,因此我们
不能通过重载CPropertySheetWithLogoDlg类的OnDraw方法来直接对属性表按
钮区进行操作。
而必须重载CPropertySheetWithLogoDlg类的OnPaint方法。
其
具体实现代码如下:
voidCPropertySheetWithLogoDlg:
:
OnPaint()
{
CPaintDCdc(this);//获得绘制的设备环境。
if(m_LogoText.IsEmpty())//判断字符串是否为空。
return;
CRectrectTabCtrl;
GetTabControl()->GetWindowRect(rectTabCtrl);//获得属性表的制表控件的客户区屏幕坐标。
ScreenToClient(rectTabCtrl);//屏幕坐标转换为窗口逻辑坐标。
CRectrectOk;
GetDlgItem(IDOK)->GetWindowRect(rectOk);//获得客户区最左按钮屏幕坐标。
ScreenToClient(rectOk);//屏幕坐标转换为窗口逻辑坐标。
dc.SetBkMode(TRANSPARENT);//背景模式设为透明。
CRectrectText;
rectText.left=rectTabCtrl.left;
rectText.top=rectOk.top;
rectText.bottom=rectOk.bottom;
rectText.right=rectOk.left;//获得所需绘制按钮区窗口逻辑坐标。
CFont*OldFont=dc.SelectObject(&m_fontLogo);//选择所需字体。
COLORREFOldColor=dc.SetTextColor(:
:
GetSysColor(COLOR_3DHILIGHT));//设置文本颜色。
dc.DrawText(m_LogoText,rectText+CPoint(1,1),DT_SINGLELINE|DT_LEFT|DT_VCENTER);//显示字符串。
dc.SetTextColor(:
:
GetSysColor(COLOR_3DSHADOW));
dc.DrawText(m_LogoText,rectText,DT_SINGLELINE|DT_LEFT|DT_VCENTER);//显示字符串3D阴影。
dc.SetTextColor(OldColor);//恢复原文本颜色。
dc.SelectObject(OldFont);//恢复原字体。
}
在这段代码中,首先通过定义一个以thhis指针为变量的
CPaintDC变量dc得到当前绘图设备环境。
然后是要找出按钮
区的具体位置。
按钮区操作的位置实际就是属性表的制表控
件客户区的最左端直到第一个按钮最左端为此的区域。
也就是
说,先需要得到属性表制表控件的指针,这可用CPropertySheet
类的方法GetTabCtrl()得到。
再通过WIN32API函数GetWindowRect()
得到控件客户区的屏幕坐标。
然后得到用GetDlgItem(IDOK)->GetWindowRect()
得到客户区最左OK按钮的屏幕坐标。
将它们都转换为窗口逻辑坐标,以控件
客户区的左坐标作为操作按钮区的左坐标,以最左OK按钮的上、下坐
标作为操作按钮区的上、下坐标,以最左OK按钮的左坐标作为操作按
钮区的右坐标。
就得到了所需按钮区的具体位置。
最后只需再选择字体
和文本颜色,用DrawText()进行显示即可在属性表按钮区绘出字符串。
如果我们要在按钮区显示一幅位图,只须对以上代码作出很少修改,
具体代码如下:
CBitmapbmp,*poldbmp;
CDCmemdc;
CRectrect;
bmp.LoadBitmap(IDB_BITMAPLOGO);//载入位图资源。
memdc.CreateCompatibleDC(&dc);//生成一个与当前设备环境兼容的内存设备
环境。
poldbmp=memdc.SelectObject(&bmp);//将位图写入内存设备环境。
GetClientRect(&rect);//获得属性表客户区的大小
//从内存设备环境向屏幕挎贝位图。
dc.BitBlt(left,rect.bottom-lower,w,h,&memdc,0,0,SRCCOPY);
//w,h为位图的宽度和高度。
Left为位图距属性页左边框的距离,lower为位图距下边框的距离。
memdc.SelectObject(poldbmp);
通过引入位图资源,再将其选入内存设备环境,最后用BitBlt函数显示到实
际设备环境,我们就在按钮区绘出了所选位图。
这一步骤与其它在正常窗口
显示位图的方法是基本一致的。
3.实现所需注意问题
需要注意的是,属性表有两种模式,一种是正常属性表模式,另一种是向导
模式(Wizard)。
我们可以通过加入如下代码检测属性表的模式:
BOOLbWizMode;
//从PROPSHEETHEADER结构中得到当前属性表的模式。
if(m_psh.dwFlags&PSH_WIZARD)
bWizMode=TRUE;//是向导模式
else
bWizMode=FALSE;//是正常属性表模式
其中,m_psh是CPropertySheet类的公有成员变量,它是PROPSHEETHEADER结构,
可以通过访问该成员变量获取属性表的基本属性。
在正常属性表模式下,上述获取属性表按钮区位置的方法可以正确通过。
而
在向导模式下,属性表没有制表控件,无法得到制表控件客户区位置。
在这时
,需要用属性表对话框窖口代替控件客户区。
可在原代码中加入如下代码:
if(bWizMode){
GetWindowRect(rectTabCtrl);//得到对话框窗口屏幕坐标。
rectTabCtrl.OffsetRect(14,0);//对窗口位置校正
}
else{
GetTabControl()->GetWindowRect(rectTabCtrl);
}
通过以上代码,我们就能够正确得到属性表按钮区域位置。
4.结论
由上述讨论可知,对于属性表按钮区进行操作,关键是要了解对非窗口客户区
进行绘制是不同于在一般窗口绘制的过程时,在一般窗口绘制位图或写入字符
时,只需重载窗口类的OnDraw方法,而对非窗口客户区进行绘制时,必须
重载OnPaint函数。
这一法则适用于对任何非窗口客户区的操作。
属性表类(CPropertySheetClass)在编写Windows应用程序时使用非常广
泛,如编写安装向导程序、应用程序配置等很多应用程序都必须使用属性表类
,但是如何实现用VC对属性表类的按钮区进行绘制却是一个比较困难的问题。
因为VC的MFC类库封装了属性表类,使得其外观表现一般不容易改变。
而在编
写应用程序的过程中却常常遇到要在属性表的按钮区域进行绘制的问题,如在
属性表按钮区加入公司的标识等等。
属性表按钮区是非窗口客户区,因此要对
其直接进行绘制需要采用一些特殊的处理。
我们在实际编程开发过程中,对此
问题进行了一些探索。
下面我们通过示例说明在VC5.0环境下实现对属性页按
钮区域位图绘制的方法。
1、实现非窗口区域绘制的基本思想:
要完成对属性表按钮区域(即非窗口客户区)的操作,必须得到相关的绘图设
备环境(CPaintDC),找出按钮区域的具体位置,才能够对其进行操作。
为
此,需要对MFC的CPropertySheet类进行继承,对其继承类的OnPaint消息处理
函数进行重载,在OnPaint消息处理函数中,直接以当前指针为变量定义一个
设备环境对象,这就是我们所需的绘图设备环境,再找出属性表类的制表控件
(tablecontrol)客户区位置和属性表类的缺省按钮位置,就能够计算出按
钮区域的具体位置。
只要完成上述两步,对属性表按钮区的操作也就不难实现
了。
2.示例程序具体实现
首先,用VC的Wizard代码生成器生成一个MFC应用程序框架,在自动生成的过程
中,选择应用程序是基于对话框的程序。
当生成完毕后,在将自动生成的对话
框类全部删除。
再手动添加一个从CPropertySheet类继承的子类
CPropertySheetWithLogoDlg类和一个基于CDialog类的CFirstPropertyPage类
,同时在程序App类的InitInstance方法中删除关于自动生成的对话框类的代码。
并加入如下代码:
CPropertySheetWithLogoDlgdlg("属性表按钮区绘制");
CFirstPropertyPageFirstPage;//进行类的实例化
dlg.SetLogoText("ExampleVision");//对要在按钮区域绘制的字符串进行赋值
dlg.AddPage(&FirstPage);//向属性表中添加属性页
intnResponse=dlg.DoModal();
if(nResponse==IDOK){}
elseif(nResponse==IDCANCEL){}
returnFALSE;
这段代码使由Wizard代码生成器生成的应用程序的主框架(mainframe)成为
一个属性表。
其中SetLogoText是CPropertySheetWithLogoDlg类的用户自定义
方法,它是给写在属性表按钮区的字符串赋值。
下面就是如何对按钮区域进行操作。
属性表按钮区是非窗口客户区,因此我们
不能通过重载CPropertySheetWithLogoDlg类的OnDraw方法来直接对属性表按
钮区进行操作。
而必须重载CPropertySheetWithLogoDlg类的OnPaint方法。
其
具体实现代码如下:
voidCPropertySheetWithLogoDlg:
:
OnPaint()
{
CPaintDCdc(this);//获得绘制的设备环境。
if(m_LogoText.IsEmpty())//判断字符串是否为空。
return;
CRectrectTabCtrl;
GetTabControl()->GetWindowRect(rectTabCtrl);//获得属性表的制表控件的客户区屏幕坐标。
ScreenToClient(rectTabCtrl);//屏幕坐标转换为窗口逻辑坐标。
CRectrectOk;
GetDlgItem(IDOK)->GetWindowRect(rectOk);//获得客户区最左按钮屏幕坐标。
ScreenToClient(rectOk);//屏幕坐标转换为窗口逻辑坐标。
dc.SetBkMode(TRANSPARENT);//背景模式设为透明。
CRectrectText;
rectText.left=rectTabCtrl.left;
rectText.top=rectOk.top;
rectText.bottom=rectOk.bottom;
rectText.right=rectOk.left;//获得所需绘制按钮区窗口逻辑坐标。
CFont*OldFont=dc.SelectObject(&m_fontLogo);//选择所需字体。
COLORREFOldColor=dc.SetTextColor(:
:
GetSysColor(COLOR_3DHILIGHT));//设置文本颜色。
dc.DrawText(m_LogoText,rectText+CPoint(1,1),DT_SINGLELINE|DT_LEFT|DT_VCENTER);//显示字符串。
dc.SetTextColor(:
:
GetSysColor(COLOR_3DSHADOW));
dc.DrawText(m_LogoText,rectText,DT_SINGLELINE|DT_LEFT|DT_VCENTER);//显示字符串3D阴影。
dc.SetTextColor(OldColor);//恢复原文本颜色。
dc.SelectObject(OldFont);//恢复原字体。
}
在这段代码中,首先通过定义一个以thhis指针为变量的
CPaintDC变量dc得到当前绘图设备环境。
然后是要找出按钮
区的具体位置。
按钮区操作的位置实际就是属性表的制表控
件客户区的最左端直到第一个按钮最左端为此的区域。
也就是
说,先需要得到属性表制表控件的指针,这可用CPropertySheet
类的方法GetTabCtrl()得到。
再通过WIN32API函数GetWindowRect()
得到控件客户区的屏幕坐标。
然后得到用GetDlgItem(IDOK)->GetWindowRect()
得到客户区最左OK按钮的屏幕坐标。
将它们都转换为窗口逻辑坐标,以控件
客户区的左坐标作为操作按钮区的左坐标,以最左OK按钮的上、下坐
标作为操作按钮区的上、下坐标,以最左OK按钮的左坐标作为操作按
钮区的右坐标。
就得到了所需按钮区的具体位置。
最后只需再选择字体
和文本颜色,用DrawText()进行显示即可在属性表按钮区绘出字符串。
如果我们要在按钮区显示一幅位图,只须对以上代码作出很少修改,
具体代码如下:
CBitmapbmp,*poldbmp;
CDCmemdc;
CRectrect;
bmp.LoadBitmap(IDB_BITMAPLOGO);//载入位图资源。
memdc.CreateCompatibleDC(&dc);//生成一个与当前设备环境兼容的内存设备
环境。
poldbmp=memdc.SelectObject(&bmp);//将位图写入内存设备环境。
GetClientRect(&rect);//获得属性表客户区的大小
//从内存设备环境向屏幕挎贝位图。
dc.BitBlt(left,rect.bottom-lower,w,h,&memdc,0,0,SRCCOPY);
//w,h为位图的宽度和高度。
Left为位图距属性页左边框的距离,lower为位图距下边框的距离。
memdc.SelectObject(poldbmp);
通过引入位图资源,再将其选入内存设备环境,最后用BitBlt函数显示到实
际设备环境,我们就在按钮区绘出了所选位图。
这一步骤与其它在正常窗口
显示位图的方法是基本一致的。
3.实现所需注意问题
需要注意的是,属性表有两种模式,一种是正常属性表模式,另一种是向导
模式(Wizard)。
我们可以通过加入如下代码检测属性表的模式:
BOOLbWizMode;
//从PROPSHEETHEADER结构中得到当前属性表的模式。
if(m_psh.dwFlags&PSH_WIZARD)
bWizMode=TRUE;//是向导模式
else
bWizMode=FALSE;//是正常属性表模式
其中,m_psh是CPropertySheet类的公有成员变量,它是PROPSHEETHEADER结构,
可以通过访问该成员变量获取属性表的基本属性。
在正常属性表模式下,上述获取属性表按钮区位置的方法可以正确通过。
而
在向导模式下,属性表没有制表控件,无法得到制表控件客户区位置。
在这时
,需要用属性表对话框窖口代替控件客户区。
可在原代码中加入如下代码:
if(bWizMode){
GetWindowRect(rectTabCtrl);//得到对话框窗口屏幕坐标。
rectTabCtrl.OffsetRect(14,0);//对窗口位置校正
}
else{
GetTabControl()->GetWindowRect(rectTabCtrl);
}
通过以上代码,我们就能够正确得到属性表按钮区域位置。
4.结论
由上述讨论可知,对于属性表按钮区进行操作,关键是要了解对非窗口客户区
进行绘制是不同于在一般窗口绘制的过程时,在一般窗口绘制位图或写入字符
时,只需重载窗口类的OnDraw方法,而对非窗口客户区进行绘制时,必须
重载OnPaint函数。
这一法则适用于对任何非窗口客户区的操作。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VC 实现 属性 按钮 位图 绘制