CREATESTRUCT结构定义了传递给应用程序的窗口过程的初始化参数,它定义了窗口外观相关特性,CREATESTRUCT结构具有如下形式:
typedef struct tagCREATESTRUCT { LPVOID lpCreateParams; //指向将被用于创建窗口的数据的指针。 HANDLE hInstance; //标识了拥有新窗口的模块的模块实例的句柄。 HMENU hMenu; //标识了要被用于新窗口的菜单。如果是子窗口,则包含整数ID。 HWND hwndParent; //标识了拥有新窗口的窗口。如果新窗口是一个顶层窗口,这个参数可以为NULL。 int cy; //指定了新窗口的高。 int cx; //指定了新窗口的宽。 int y; //指定了新窗口的左上角的y轴坐标。 int x; //指定了新窗口的左上角的x轴坐标。 LONG style; //指定了新窗口的风格。 LPCSTR lpszName; //指向一个以null结尾的字符串,指定了新窗口的名字。 LPCSTR lpszClass; //指向一个以null结尾的字符串,指定了新窗口的Windows类名 DWORD dwExStyle; //指定了新窗口的扩展风格。 } CREATESTRUCT;
PreCreateWindow函数
PreCreateWindow函数从字面上看,就知道它是创建窗口有关系,它是在窗口创建之前进行外观修改,通过重载该函数,可以修改CREATESTRUCT结构,从而加入用户自定义的属性,其函数声明如下:
virtual BOOL PreCreateWindow( CREATESTRUCT& cs );在SDI程序CMainFrame类中,一般都会自带该函数的实现,代码如下:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; // TODO: 在此处通过修改 // CREATESTRUCT cs 来修改窗口类或样式 return TRUE; }
由于该函数是虚函数,因此MFC底层代码创创建窗口之前,先会调用该函数,从而实现默认属性修改,这里我们修改宽度和高度,增加水平和垂直的滚动条,以及删除可调边框属性。
例子1 修改外观
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; // TODO: 在此处通过修改 // CREATESTRUCT cs 来修改窗口类或样式 //改变大小 cs.cx = 500; cs.cy = 400; //增加水平和垂直滚动条 cs.style |= WS_HSCROLL | WS_VSCROLL; //去除可调边框属性 cs.style &= ~WS_THICKFRAME ; return TRUE; }运行效果对比:
例子2:修改窗口标题
在默认的单文档和多文档应用程序中,框架窗口stytle风格都包含有FWS_ADDTOTITLE这个属性,其含义是将文档的标题做为窗口的标题,如果需要自定义窗口标题,需要将这个属性删除,具体代码如下:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; // CREATESTRUCT cs 来修改窗口类或样式 //改变大小 cs.cx = 400; cs.cy = 300; //增加水平和垂直滚动条 cs.style |= WS_HSCROLL | WS_VSCROLL; //去除FWS_ADDTOTITLE属性 cs.style &= ~FWS_ADDTOTITLE ; //自定义标题 cs.lpszName = "HelloWorld"; return TRUE; }运行效果:
SetWindowLong函数
上面介绍的PreCreateWindow函数是在创建之前进行修改的,而SetWinowLong函数是在窗口创建之后进行修改的。
我们在发现框架类(CMainFrame)中有个OnCreate函数,该函数的功能是完成窗口的创建,其部分代码如下:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; ... // TODO: 如果不需要可停靠工具栏,则删除这三行 m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); return 0; }
LONG SetWindowLong(HWND hWnd,int nlndex,LONG dwNewLong)hWnd:窗口句柄及间接给出的窗口所属的类。
nlndex:指定将设定的大于等于0的偏移值。要设置其他任何值,可以指定下面值之一:
GWL_EXISTYLE:设定一个新的扩展风格。
GWL_STYLE:设定一个新的窗口风格。
GWL_WNDPROC:为窗口过程设定一个新的地址。GWL_ID:设置一个新的窗口标识符。
....
dwNewLong:指定的替换值。
对应的,MFC提供了GetWindowLong函数来获取指定窗口的信息,其函数声明如下:
LONG GetWindowLong(HWND hWnd,int nlndex)该函数的返回值就是窗口的信息,nIndex指定了要获取的内容,这个为GWL_STYLE,意为获得窗口风格,修改风格的具体代码如下:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; ... // TODO: 如果不需要可停靠工具栏,则删除这三行 m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); SetWindowLong(m_hWnd, GWL_STYLE, //获取风格 GetWindowLong(m_hWnd, GWL_STYLE) & ~WS_MAXIMIZEBOX);//修改风格 去除最大化属性。 return 0; }运行效果对比: