VC内部培训资料——第9章 修改框架程序的显示效果

更新时间:2023-06-06 08:29:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

修改框架程序的显示效果

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:

第9章 修改框架程序的显示效果

本章将讲述如何修改MFC AppWizard自动生成的应用程序的外观,在学习本章内容之前,读者有必要回头复习一下第二章中讲过的创建一个窗口的过程。

9.1修改Windows应用程序外观样式

我们可以通过不同的方法来修改应用程序的背景、标题、光标、图标以及框架是否具有最大、最小对话框等信息。我们知道由于视图类覆盖在框架窗口上,因此,我们通常在MainFrame中修改图标、标题及是否具有最大、最小框的属性;而背景及光标等信息就需要在View类中修改。

9.1.1 在框架类中修改程序外观

本节内容所讲的实例都包含在光盘例子代码EX09_00中。新建一个MFC序,工程名为EX09_00或用户自定义。

1. 在CMainFrame::PreCreateWindow中修改。

在窗口产生之前,会调用它的成员函数PreCreateWindow于一栋大楼修建之前,在它的设计图纸上修改它的式样,修改方法有以下几种:

直接修改CREATESTRUCT结构,代码如下:

{

if( !CFrameWnd::PreCreateWindow(cs) )

return FALSE;

// the CREATESTRUCT cs

去掉窗口的最大化按钮 允许添加自己的标题 cs.lpszName="Visual C++教学";

return TRUE; }

其中style是结构CREATESTRUCT的数据成员,分别表示框架窗口的样式和style的

"Visual C++教学",结果如图9-00所示。

修改框架程序的显示效果

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:

图9-00 去掉了最大化按钮及添加新标题

重新设计、填写WNDCLASS,代码如清单9-00所示:

清单9-00 CMainFrame::PreCreateWindow函数代码

1 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) 2 3 4 5 6 7 8

{

if( !CFrameWnd::PreCreateWindow(cs) )

return FALSE;

// the CREATESTRUCT cs WNDCLASS wndClass;

wndClass.style=CS_HREDRAW;

wndClass.hIcon=LoadIcon(::AfxGetInstanceHandle(), wndClass.lpszMenuName=NULL; wndClass.lpszClassName="hello"; RegisterClass(&wndClass); cs.lpszClass="hello"; return TRUE;

9 10 11 12 13 14 15 16 17

18 19 20 22 23 24 25 26 }

第7~22行代码定义了一个新的窗体类wndClass并设计该类;,

第16~19行部分代码中自定义了一个LOGBRUSH结构类型的画刷lgbr,其中lbStyle、

lbColor和lbHatch是该结构体的三个数据成员,分别表示所定义的画刷的样式等属性,设

修改框架程序的显示效果

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:

置该画刷的属性为实心的黄色,新设计的窗口类的背景就采用这个画刷。

其中IDI_ICON1是我们在资源面板中新添加的一个图标资源的ID。

代码中的大部分内容在第二章都接触过,可能最后一句cs.lpszClass="hello";有的读者大概不理解该句代码的用意。我们知道,在CMainFrame::PreCreateWindow中,应用程序根据该函数传来的cs进行框架的显示,这个cs结构中的数据成员lpszClass包含框架生成

时采用的窗口类的名称,如果我们不添加最后一句代码将我们的窗口类赋给lpszClass数据成员,那么它还会采用原来系统默认的窗口类。

运行程序,读者会发现,框架的图标变了,但是背景和光标没有变,如图9-01那是由于视图类覆盖在框架类上了,应将此段代码拷入函数中,就可以看到效果了。

图9-01

1 2 3 4 5 6 7 8 9 12 13 14

利用GetClassInfo函数,所示:

清单函数代码

{

if( !CFrameWnd::PreCreateWindow(cs) )

wndclass.lpszClassName="hello"; ::RegisterClass(&wndclass); cs.lpszClass="hello"; return TRUE;

10 15 }

第7行首先定义一个窗口类对象wndclass,然后在第8行调用GetClassInfo函数将取得的当前使用的窗口类信息赋给对象wndclass,最后,通过9~11行修改wndclass,再由12、13行代码重新注册及加载修改后的窗口对象来实现,程序运行结果同图9-01一样。

函数GetClassInfo用于取得某一窗口类的信息,原形如下:

修改框架程序的显示效果

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:

BOOL GetClassInfo( HINSTANCE hInstance, LPCTSTR lpClassName, LPWNDCLASS lpWndClass);

第一个参数hInstance,表示创建窗口类的当前运行的应用程序实例。 第二个参数lpClassName,要获取的窗口类的类名。

第三个参数lpWndClass,指向WNDCLASS结构类型的对象,函数调用后获取的窗口类的信息存放到该参数中。

2. 在CMainFrame:: OnCreate中修改。

利用SetWindowLong函数,如下:

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {

SetWindowLong(m_hWnd,GWL_STYLE,

return 0; }

其中, GetWindowLong函数用于取得指定窗口的信息,LONG GetWindowLong( HWND hWnd, int nIndex);

第一个参数hWnd,表示要获取信息的窗口句柄,. 第二个参数nIndex,要获取的信息索引,

GWL_EXSTYLE 获取窗口的扩展风格 GWL_STYLE 获取窗口的样式

GWL_WNDPROC 获取窗口过程的回调函数

函数SetWindowLong,,该函数原形如下: LONG SetWindowLong( HWND hWnd, LONG dwNewLong); 第一个参数hWnd,,或窗口类所在的窗口. 第二个参数nIndex,,此参数可取下列值:

GWL_EXSTYLE GWL_STYLE 设置新的窗口样式

GWL_ID 分配一个新的窗口标识

第三个参数

GetWindowLong获取当前窗口的信息,然后去掉最大化,给窗口设置新的属性。

函数,如下:

SetClassLong(m_hWnd,GCL_HICON, (long)AfxGetApp()->LoadIcon(IDI_ICON1));

return 0; }

其中,函数SetClassLong用于重置当前窗口所包含的窗口类的WNDCLASS结构中的指定数据成员的属性,函数原形如下:

DWORD SetClassLong( HWND hWnd, int nIndex, LONG dwNewLong); 第一个参数hWnd,表示要设置新属性的窗口句柄,或窗口类所在的窗口. 第二个参数nIndex,要设置的属性的索引,此参数可取下列值:

修改框架程序的显示效果

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:

GCL_HBRBACKGROUND GCL_HCURSOR

设置新的背景画刷 设置新的光标

GCL_HICON 设置新的图标 GCL_STYLE 设置新的窗口样式 第三个参数dwNewLong,表示要设置的新的属性值。

9.1.2 在视图类中修改程序外观

1. 在EX09_00View::PreCreateWindow中修改 重新设计、填写WNDCLASS,代码如下:

BOOL CEX09_00View::PreCreateWindow(CREATESTRUCT& cs)

{ // the CREATESTRUCT cs //定义并设计新的窗口类wndClass WNDCLASS wndClass;

wndClass.style=CS_HREDRAW;

wndClass.cbClsExtra=0;

wndClass.cbWndExtra=0;

// LOGBRUSH lgbr;

lgbr.lbColor=RGB(255,255,0);

//

return CView::PreCreateWindow(cs);

该段代码放在框架窗口类中时,光标及背景并没有改变,将代码移到视图类中,就会看到如图9-02所示的效果。

修改框架程序的显示效果

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:

图9-02 修改了显示的光标及背景

利用AfxRegisterWndClass函数,代码如下:

BOOL CEX09_00View::PreCreateWindow(CREATESTRUCT& cs) {

}

运行程序结果如图9-03所示。

return CView::PreCreateWindow(cs);

图9-03 修改成十字光标和黑色背景

2. 在中修改。

函数,如下:

}

if (CView::OnCreate(lpCreateStruct) == -1) return -1;

// TODO: Add your specialized creation code here SetClassLong(m_hWnd,GCL_HCURSOR, (LONG)LoadCursor(NULL,IDC_UPARROW)); return 0;

运行结果如图9-04所示。

修改框架程序的显示效果

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:

图9-04 改回正常的光标

9.2 制作动画图标

实例将使应用程序框架上的图标不断的变化,用到的图标是事先拷贝到文件夹EX09_01\res下面的,EX09_01,具体操作步骤如下:

步骤1:新建一个MFC或用户自定义。

步骤2:在资源面板中导入五个图标。 五个图标的名称分别为FACE01.ICO、、FACE03.ICO、FACE04.ICO、FACE05.ICO

(包含在EX09_01\res文件夹下)Resource View页面,右击Icon文件夹,在弹出的快捷方式菜单中选择弹出如图9-05所示的Import Resource导入资源对话框,打开EX09_01\res 五个图标的ID均采用默认的、IDI_ICON2、IDI_ICON3、IDI_ICON4、IDI_ICON5。 步骤3: 在框架窗口类中添加成员变量m_hIcon[5]。

我们知道,因此,在CMainFrame类中添加HICON类型的成员变量,用来加载并保存图标资源。

修改框架程序的显示效果

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:

图9-05 导入图标资源

步骤4:在框架窗口类的OnCreate {

//加载图标资源

//改变框架的图标

SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcon[0]);

}

然而三种方法的原理是相同的,然后调用函数将框架的图标替换成第一个我们自己加载的图标,最后,设置计时

:在CMainFrame类中添加OnTimer函数,代码如下: }

// TODO: Add your message handler code here and/or call default static int iIndex=0;

iIndex=++iIndex%5;

SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcon[iIndex]); CFrameWnd::OnTimer(nIDEvent);

其中,定义了一个静态整型变量iIndex,用来标识图标数组变量的下标,静态变量在

修改框架程序的显示效果

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:

函数执行完毕时,内存空间不释放,并且变量的值仍然保留。第二句代码iIndex=++iIndex%5;的作用是将iIndex控制在0到4范围内,因为m_hIcon数组变量的下标为0到4。最后调用函数SetClassLong,在计时器触发时改变图标的显示。

9.3 将图片作为窗体背景

上一节中,我们介绍了如何修改MFC AppWizard生成的应用程序框架,包括窗口背景等属性,但是,上一节中修改后的窗口背景最对也只是改变了颜色,本节将向读者介绍如何将一幅图片作为窗口显示的背景。 通常情况下,将一幅位图选做窗口背景都经过以下几个步骤:

1. 创建一个兼容设备描述表

2. 创建及装入位图资源

3. 将位图选入兼容设备描述表

4. 将兼容设备描述表上的内容拷贝到当前设备描述表上

读者大概不能够很好的理解以上所说的几个步骤,不要紧,解释以上几个步骤,完整例程请参见光盘中例子代码EX09_02,

步骤1:新建一个MFC单文档应用程序,工程名为 步骤2:在资源面板中添加一幅位图资源。

图9-06 插入资源对话框

res文件夹里,命名为bitmap.bmp,然后打开工作台的Resource View页面,选择菜单Insert|Resource,弹出如图9-06所示插入资源Insert Resource对话框,在该对话框上选中Bitmap,然后单击对话框右边的Import按钮。 单击Import按钮后,弹出如图9-07所示的导入资源对话框,打开EX09_02\res文件夹,选中该文件夹下的bitmap.bmp文件,单击Import按钮将该位图导入到工程中。

修改框架程序的显示效果

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:

图9-07 导入bitmap.bmp

将位图导入到工程中时,会弹出如图9-08正确的导入到工程中了,但是由于位图的颜色大于256Visual C++的位图编辑器中,并且不能编辑该位图,因为我们并不想修改这个位图就应该至少是256位颜色以下的位图。

图9-08 消息提示框

ID号IDB_BITMAP1。 步骤3:在函数中贴图。 1. DC:

CDC类的成员函数CreateCompatibleDC用于创建兼容某一设备描述表的一个DC,函数原形如下:

BOOL CreateCompatibleDC( CDC* pDC ); 该函数只有一个参数pDC,指向要兼容的设备描述表,如果该参数为NULL,那么创建的兼容DC是兼容系统显示屏幕的。本例中兼容的DC就是CEX09_02View::OnDraw函数中由系统传来的pDC。 2. 创建及装入位图资源:

CBitmap bmp;

bmp.LoadBitmap(IDB_BITMAP1);

代码中首先创建一个CBitmap类的对象bmp,然后调用CBitmap类的成员函数

修改框架程序的显示效果

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:

LoadBitmap,将位图资源载入对象bmp中。 3. 将位图选入兼容DC 4.

dcCompatible.SelectObject(&bmp); 将兼容DC上的内容拷入当前DC上 CRect rect;

GetClientRect(&rect);

pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcCompatible, 函数GetClientRect用于获取客户区的矩形大小,该函数只有一个参数为类或RECT 函数BitBlt,用于将源DC上的位图拷贝到目的DC,函数原形如下:

BOOL BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC,

int ySrc, DWORD dwRop );

第一个参数x,表示目的DC的左上角的x坐标。 第二个参数y,表示目的DC的左上角的y坐标。 第三个参数nWidth,表示目的DC或源位图的宽度。 第四个参数nHeight,表示目的DC第五个参数pSrcDC,指向包含位图的源DC。

第六、七个参数xSrc、ySrcy坐标。

第八个参数dwRop,表示贴图的模式,值,表示直接将源位图拷贝到目的DC中。

图9-09 使用BitBlt函数将位图作为背景

编译运行该程序,结果如图9-09所示。可以看出BitBlt函数是按1:1的比例将位图

拷入到DC中的,当视图窗口最大化时可以看到整个位图,当视图窗口尺寸变小时,就只能

修改框架程序的显示效果

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:

看到位图的一部分,如果想在视图窗口上显示整个位图而不管视图窗口多大时,可以用StretchBlt函数。

步骤4:修改CEX09_02View::OnDraw函数代码,将位图拉伸显示,代码如下: void CEX09_02View::OnDraw(CDC* pDC) { CEX09_02Doc* pDoc = GetDocument(); }

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here //产生一个兼容DC CDC dcCompatible;

dcCompatible.CreateCompatibleDC(pDC); //创建及装入位图资源 CBitmap bmp;

bmp.LoadBitmap(IDB_BITMAP1); //将位图选入兼容DC

dcCompatible.SelectObject(&bmp); //将兼容DC上的内容拷入当前DC上 CRect rect;

GetClientRect(&rect); //获取位图信息

BITMAP bitmap;

bmp.GetBitmap(&bitmap);

可以看出,函数的语句去掉了,而且又添加最后的三条代码。

新加的代码中首先定义了一个BITMAP结构类型的对象bitmap,BITMAP结构包含很多数据成员,如bmType、、bmHeight等等,这些数据成员包含位图的相关信息。

代码是将位图bmp的信息及属性取出放到先前定义的bitmap变量中。

StretchBlt将位图贴到视图窗口,并且调节位图大小来适应视

int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc,

, int nSrcWidth, int nSrcHeight, DWORD dwRop );

x和y,分别表示目的矩形的左上角的x坐标和y坐标。 nWidth和nHeight,分别表示目的矩形的宽度和高度。

第五个参数pSrcDC,指向包含位图的源DC。

第六、七个参数xSrc、ySrc,分别表示源矩形(即源DC)左上角的x和y坐标。 第八、九个参数nSrcWidth、nSrcHeight,分别表示源矩形(即源DC)的宽度和高度,本例中通过调用bitmap.bmWidth,bitmap.bmHeight取得位图的宽度和高度,这两个值也就是源DC的高度和宽度。其中bmWidth和bmHeight就是BITMAP结构中用来表示位图宽度和高度的两个数据成员。

编译运行程序,结果如图9-10所示,不管视图窗口怎么样改变,都可以显示完整的位

修改框架程序的显示效果

VC++培训教程草稿(2000年撰写) 张孝祥、袁龙友著 网址:

图图片,只是看起来效果不太好。

图9-10 使用函数将位图作为背景

系统在发出WM_PAINTWM_EARSEBKGND消息,在该消息处理函数OnEraseBkgndCEX09_02View::OnDraw函数中的代码剪贴到WM_EARSEBKGNDCEX09_02View::OnEraseBkgnd中去,然后将原来的改为return true;

本文来源:https://www.bwwdw.com/article/9f11.html

Top