修改窗口光标、图标、背景等外观的两种方法

窗口创建之前修改


对于窗口的类型和大小,是在创建窗口时设定的,而图标、光标和背景是在设计窗口类时指定的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,到此修改窗口外观两种方法就介绍完毕了。

原文地址:https://www.cnblogs.com/jinxiang1224/p/8468360.html