修改窗口光标、图标、背景等外观的两种方法
窗口创建之前修改
对于窗口的类型和大小,是在创建窗口时设定的,而图标、光标和背景是在设计窗口类时指定的,WNDCLASS 结构体就是我们所说的窗口类, 该结构体指定了窗口的相关属性,包括图标,光标,背景以及窗口类的名字,具体参数含义如下:
typedef struct { UINT style; //这一类型窗口的样式 WNDPROC lpfnWndProc; //指向窗口过程的函数指针 int cbClsExtra; //类附加内存 int cbWndExtra; //窗口附加内存 HINSTANCE hInstance; //实例句柄 HICON hIcon; //窗口类的图标句柄 HCURSOR hCursor; //窗口类的光标句柄 HBRUSH hbrBackground; //窗口类的背景 LPCTSTR lpszMenuName; //菜单名字 LPCTSTR lpszClassName; //窗口类名字 } WNDCLASS;
我们知道窗口类的设计和注册由MFC底层代码帮助我们完成的,我们不应该去修改MFC的底层代码。但我们可以设计自己的窗口类并注册,让随后的窗口按照我们设计的窗口类去创建,实现方式如下介绍。
例如:
在框架窗口类中有PreCreateWindow函数,其入参CREATESTRUCT类型的引用,其函数声明如下:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
我们可以指定cs.lpszClass参数值,这个就是窗口类的名称,我们改变了这个值,随后的窗口也就会按照我们设计的窗口类去创建窗口了。
一个SDI应用程序包含两个窗口:应用程序框架窗口和视类窗口,视类窗口在框架窗口的前面,修改图标需要在框架窗口中实现,修改光标和背景由视类窗口实现。
代码如下:
//修改图标 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; cs.lpszClass = "TestMainFrame";//举例说明,框架窗口的窗口类名字 return TRUE; } //修改光标和背景 BOOL CWndStyleView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: 在此处通过修改 // CREATESTRUCT cs 来修改窗口类或样式 cs.lpszClass = "TestViewFrame";//举例说明,框架窗口的窗口类名字 return CView::PreCreateWindow(cs); }我们利用MFC提供的全局函数AfxRegisterWndClass函数来设定窗口的类型、光标、图标以及背景色,其函数原型声明如下:
LPCTSTR AFXAPI AfxRegisterWndClass( UINT nClassStyle, //指定Windows的类风格 HCURSOR hCursor = 0, //指定了一个鼠标光标资源句柄,缺省是IDC_ARROW光标。 HBRUSH hbrBackground = 0, //指定了一个刷子资源句柄,缺省是Null背景刷子 HICON hIcon = 0 //指定了一个图标资源句柄,缺省是波浪标志的Windows徽标。 );该函数的返回值是一个以null结尾的字符串的窗口类名,即WNDCLASS中的lpszClassName,该窗口类的名字在调用的同时就被注册给系统了。
修改窗口的光标、图标、背景具体代码如下:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; cs.style &= ~FWS_ADDTOTITLE ; //自定义标题 cs.lpszName = "HelloWorld"; cs.lpszClass = AfxRegisterWndClass(CS_VREDRAW |CS_HREDRAW, 0, //默认 0, //默认 LoadIcon(NULL, IDI_QUESTION) ); return TRUE; }
BOOL CWndStyleView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: 在此处通过修改 // CREATESTRUCT cs 来修改窗口类或样式 cs.lpszClass = AfxRegisterWndClass(CS_VREDRAW |CS_HREDRAW, LoadCursor(NULL, IDC_CROSS), //光标样式 (HBRUSH)GetStockObject(BLACK_BRUSH),//黑色背景 0 //默认 ); return CView::PreCreateWindow(cs); }
运行效果:
窗口创建之后修改
在窗口创建完成之后,即在OnCreate函数返回之前,我们还可以修改窗口的光标、图标等消息,我们可以利用全局API函数SetClassLong来实现,该函数用来重新指定窗口所属窗口类的WNDCLASSEX结构体(WNDCLASS的扩展结构)中的指定成员的属性。其函数声明如下:
DWORD SetClassLong(HWND hWnd,int nlndex,LONG dwNewLong)参数:
hWnd:
窗口句柄及间接给出的窗口所属的类。
nlndex:
可以是下面的取值之一:
GCL_HERBACKGROUND:替换与类有关的背景刷子的句柄。
GCL_HCURSOR:替换与类有关的光标的句柄。
GCL_HICON:替换与类有关的图标的句柄。
GCL_STYLE:替换窗口类的风格位。
dwNewLong:
指定替换值。
上面仅是部分SetClassLong的取值信息,更多内容请参考msdn,到此修改窗口外观两种方法就介绍完毕了。