1、在窗口的CWnd::Create()/CreateEx()调用返回前:
要先调用PreCreateWindow(),对Create()/CreateEx()中的风格参数进行预处理设置。
之后调用OnCreate进行实际的窗口创建,返回后,Create()/CreateEx()也返回,窗口创建结束。
CWnd::Create()/CreateEx()
{
PreCreateWindow();
OnCreate();
}
最后,一般会调用OnDraw()函数,绘制窗口上的控件!
1.2 创建一个Windows的子窗口,并将它连接到CWnd对象上。
你可以经过两步构造一个子窗口。
首先,调用构造函数,创建一个CWnd对象。
然后调用Create,创建一个Windows的子窗口,并将它连接到CWnd。
Create函数初始化窗口的类名、窗口名,并为它的风格、父窗口和ID注册值。
1.3 注意:
OnCreate()不产生窗口,只是在窗口显示前设置窗口的属性如风格、位置等,Create()负责注册并产生窗口。
OnCreate是一个消息响应函数,是响应WM_CREATE消息的一个函数。
2、PreCreateWindow()顾名思义就是在窗口创建之前执行的,它的主要任务是对所要创建的窗口进行一些风格或者其他方面的初始化或者说是设置,可以这么说,如果说窗口好比一栋建筑,那么PreCreateWindow()要做的就是在还没有建筑的时候将建筑的图纸画出来,而OnCreate()要做的就是根据图纸将建筑构建起来.
若要更改框架应用程序(用应用程序向导创建的)所使用的默认窗口属性,请重写窗口的 PreCreateWindow 虚拟成员函数。PreCreateWindow 允许应用程序访问通常由 CDocTemplate 类内部管理的创建进程。框架在即将创建窗口前调用 PreCreateWindow。通过修改传递给 PreCreateWindow 的结构 CREATESTRUCT,应用程序可以更改用于创建窗口的属性。例如,为了确保窗口不使用标题,使用以下按位操作。
// cs has been declared as CREATESTRUCT& cs;
cs.style &= ~WS_CAPTION;
CTRLBARS 示例应用程序论证了这项更改窗口属性的技术。根据应用程序在 PreCreateWindow 中的更改,可能有必要调用此函数的基类实现。
以下讨论适用于 SDI 情况和 MDI 情况。
2.1 SDI 情况
在单文档界面 (SDI) 应用程序中,框架中的默认窗口样式是 WS_OVERLAPPEDWINDOW 和 FWS_ADDTOTITLE 样式的组合。FWS_ADDTOTITLE 是 MFC 特定的样式,指示框架将文档标题添加到窗口标题。若要在 SDI 应用程序中更改窗口属性,请在从 CFrameWnd(应用程序向导给 CMainFrame 起的名称)派生的类中重写 PreCreateWindow 函数。例如:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
// Create a window without min/max buttons or sizable border
cs.style = WS_OVERLAPPED | WS_SYSMENU | WS_BORDER;
// Size the window to 1/3 screen size and center it
cs.cy = ::GetSystemMetrics(SM_CYSCREEN) / 3;
cs.cx = ::GetSystemMetrics(SM_CXSCREEN) / 3;
cs.y = ((cs.cy * 3) - cs.cy) / 2;
cs.x = ((cs.cx * 3) - cs.cx) / 2;
// Call the base-class version
return CFrameWnd::PreCreateWindow(cs);
}
此代码创建一个没有“最小化”按钮和“最大化”按钮,也没有大小可调边框的主框架窗口。此窗口最初在屏幕上居中。
2.2 MDI 情况
更改多文档界面 (MDI) 应用程序中的子窗口样式所需的工作多一些。默认情况下,用应用程序向导创建的 MDI 应用程序使用 MFC 中定义的默认 CMDIChildWnd 类。若要更改 MDI 子窗口的窗口样式,必须从 CMDIChildWnd 派生一个新类,并用对新类的引用替换项目中所有对 CMDIChildWnd 的引用。应用程序中仅有的对 CMDIChildWnd 的引用很可能位于应用程序的 InitInstance 成员函数中。
在 MDI 应用程序中使用的默认窗口样式是 WS_CHILD、WS_OVERLAPPEDWINDOW 和 FWS_ADDTOTITLE 样式的组合。若要更改 MDI 应用程序子窗口的窗口属性,请在从 CMDIChildWnd 派生的类中重写 PreCreateWindow 函数。例如:
BOOL CMyChildWnd::PreCreateWindow(CREATESTRUCT& cs)
{
// Create a child window without the maximize button
cs.style &= ~WS_MAXIMIZEBOX;
// Call the base-class version
return CMDIChildWnd::PreCreateWindow(cs);
}
此代码创建没有“最大化”按钮的 MDI 子窗口。