MFC学习笔记之六————更改appwizard生成的窗口外观

   要更改应用程序的窗口的外观,我们可以在两个时候更改,一是在应用程序窗口创建之前,二是在应用程序窗口创建之后进行更改。本文将两种方式记录下来。

  在窗口创建之前修改:

我们之前已经知道,在应用程序窗口创建之前会调用一个叫PreCreateWindow()的函数,要想在窗口创建之前修改程序窗口的外观跟大小,就应该在CMainFrame类(SDI程序)中的PreCreateWindow()函数中进行。

virtual BOOL PreCreateWindow( CREATESTRUCT& cs ); //PrecreateWindow()函数原型,参数稍后作解释。

   PreCreateWindow()函数是一个虚函数,在MFC的底层代码中,当调用PreCreateWindow()函数时,如果传递了子类对象的指针,根据多态性的原理,那么就会调用子类对象的PreCreateWindow()函数。函数原型中的参数类型是一个CREAGTETRUCT结构,我们这里可以看一下这个结构体中含有哪些字段。

typedef struct tagCREATESTRUCTW {   LPVOID    lpCreateParams;
   HANDLE    hInstance;   HMENU     hMenu;   HWND      hwndParent;
   int       cy;   int       cx;   int       y;   int       x;
   LONG      style;   LPCSTR    lpszName;   LPCSTR    lpszClass;
   DWORD     dwExStyle;} CREATESTRUCTW, *PCREATESTRUCTW, *LPCREATESTRUCTW;//This structure defines the initialization parameters passed to the window procedure of an application.

  之前我们就应该知道了,CREATESTRUCT结构体中的字段跟CreateWindowEx()函数中的参数是完全一致的(只是顺序相反而已)。PreCreateWindow()函数中的参数是一个引用类型,这样,我们只要更改参数cs中的成员变量的值就能实现目的:因为这种改变会反映到MFC底层代码中,当MFC底层代码调用CrateWindowEx()创建窗口时,它会使用改变后的参数值去创建。


注意:我们修改cs.lpszName的值,在单文档程序的标题中不会体现出来,因为cs.Style默认窗口样式中含有FWS_ADDTOTITLE这种MFC特定的样式,需要将这个样式去掉我们的设置才能生效。如下:

cs.Style &= ~FWS_ADDTOTITLE;

  对于窗口的位置和大小,是在创建窗口的时候去设定的,那么我们可通过自己编写窗口类,而让窗口按我们设定的窗口类创建,而窗口的图标、光标和背景是

在设计窗口类的时候设定的,我们可以在CMainFrame::PreCreateWindow编写自己的窗口类。(即定义一个WNDCLASS 对象,对其成员变量赋值,然后使用RegisterClass()函数将其注册,WNDCLASS对象将MENU设为NULL并不会影响MENU的创建,即MENU还会生成)。

但是,由于SDI中含有MainFrame跟一个View的两个窗口(View在Frame之上)。CMainFrame类中的PreCreateWindow()函数中不能修改光标和背景。要改变这些,只能在View类中PreCrateWindow()函数中实现。

综上我们知道:在View类中只能修改客户区含有的内容,在MainFrame中只能修改window(主窗口)含有的内容。

当然,有时候为了能够更改一个光标的指针,就要重写整个的WNDCLASS窗口类,这样不划算!有没有方便的方式呢?MFC中有AfxRegisterWndClass()这个全局函数(Afx开头的都是MFC中的全局函数)。原型如下:

LPCTSTR AFXAPI AfxRegisterWndClass( UINT nClassStyle, HCURSOR hCursor = 0, 
HBRUSH hbrBackground = 0, HICON hIcon = 0 ); 

  在CMainFrame类中的PreCreateWindow()函数中使cs.lpszClass成员接收AfxRegisterWndClass()函数的返回值。并对AfxRegisterWndClass()函数参数进行设置就行了。

  在窗口创建之后修改:

在窗口创建之后利用SetWindowLong函数来改变窗口的外观,看看函数原型:

LONG SetWindowLong(  HWND hWnd,       // handle to window
  int nIndex,      // offset of value to set 
  LONG dwNewLong   // new value);

  我们可以在CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)调用该函数。与SetWindowLong函数相对应的还有GetWindowLong,用来获取指定窗口的信息。(了解一下)

而在窗口建立后修改光标,背景等,我们可以使用一个类似的函数---SetClassLong(),看看原型

DWORD SetClassLong(  HWND hWnd,       // handle to window
  int nIndex,      // index of value to change  
  LONG dwNewLong   // new value);

  至于参数中有那些符合的取值,MSDN中详细介绍。我们使用此函数在Viwe类中的OnCreate()函数调用它。        

PS:AfxGetInstanceHandle()获取程序句柄

宏MAKEINTRESOUCE将一个int型资源转换成与资源管理函数兼容的资源类型——是一个宏!!!

         记录下自己的所学,虽然浅薄!!!如果我是一只蜗牛,那就只能慢慢向上爬!奋斗

posted on 2011-08-04 02:02  Pe.潘义  阅读(1315)  评论(0编辑  收藏  举报

导航