一般情况下开始学习MFC时都知道CWnd是MFC窗口类的基类,稍微深入学习后突然想从最基本的学起,即自己从CWnd派生一个窗口类而不是总通过AppWizard产生一个预先定义好的窗口类,其实更加赤裸点就是直接把CWnd做为窗口类,以下为范例程序:
#include <afxwin.h>
class CMyApp:public CWinApp
{
public:
BOOL InitInstance();
virtual int ExitInstance();
};
CMyApp theApp;
BOOL CMyApp::InitInstance()
{
CWnd* pMainWnd=new CWnd;
pMainWnd->CreateEx(0,0,"MyWnd",
WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL);
this->m_pMainWnd=pMainWnd;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return true;
}
int CMyApp::ExitInstance()
{
// TODO: 在此添加专用代码和/或调用基类
if(m_pMainWnd)delete m_pMainWnd;
return CWinApp::ExitInstance();
}
但是运行后发现该界面会像卡机一样的将背景界面作为自己的背景,郁闷了很久,也问过一些人发现问题还是没有解决,今天闲着没事又拿来试试,由于看过一点深入浅出MFC上面有讲到那个窗口类注册的过程,今天对着MFC的源代码发现这样一段:
// for child windows
BOOL CWnd::PreCreateWindow(CREATESTRUCT& cs)
{
if (cs.lpszClass == NULL)
{
// make sure the default window class is registered
VERIFY(AfxDeferRegisterClass(AFX_WND_REG));
// no WNDCLASS provided - use child window default
ASSERT(cs.style & WS_CHILD);
cs.lpszClass = _afxWnd;
}
return TRUE;
}
由于我的CreateEx函数中的lpszClassName是0,也就是NULL所以CWnd的PreCreateWindow会执行完。VERIFY(AfxDeferRegisterClass(AFX_WND_REG));首先注册一个AFX_WND_REG类型的窗口类,它的特征可以从这里看出:
// Child windows - no brush, no icon, safest default class styles
wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndcls.lpszClassName = _afxWnd;
if (AfxRegisterClass(&wndcls))
fRegisteredClasses |= AFX_WND_REG;
是一个子窗口,而且没有背景刷子没有图标,这和我运行的结果差不多, 接着是断言ASSERT(cs.style & WS_CHILD);显然如果是Debug模式下断言会失败,因为我没有在任何地方给样式添加了WS_CHILD了,很显然MFC的原意应该是将CWnd或者说没有自己注册窗口类的从CWnd派生的类设置为子窗口使用,看来以后使用CWnd或者其直接派生类时还是应该老老实实的注册自己的窗口类。
刚刚又看到MSDN上的一段讲解:
In previous versions of MFC (before MFC 4.0), there were a number of predefined Window classes provided. These Window classes are no longer provided by default because of technical problems related to versioning (multiple versions of MFC loaded in one address space) as well as concerns relating to the fact that both MFC applications and OLE Controls may use the MFC DLLs.
The following reference is provided to help migrate code that uses these previously provided WNDCLASSes. Applications should use AfxRegisterWndClass (with the appropriate parameters) in place of these classes.
The following shows the classes and their attributes:
· "AfxWnd" is used for all child windows created with CWnd::Create.
· class style : CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW
· no icon
· arrow cursor
· no background color
· "AfxFrameOrView" is used for frame windows and views (including stand-alone CFrameWnds and CMDIChildWnds).
· class style : CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
· icon AFX_IDI_STD_FRAME
· arrow cursor
· COLOR_WINDOW background color
· "AfxMDIFrame" is used for the MDI frame window (that is, the parent) created with CMDIFrameWnd::Create.
· class style : CS_DBLCLKS [ reduces flash during resizing ]
· icon AFX_IDI_STD_MDIFRAME
· arrow cursor
· no background color
· "AfxControlBar" is used for the standard control bar implementation.
· class style : 0 [ reduces flash during resizing, no double clicks ]
· no icon
· arrow cursor
· gray background color (COLOR_BTNFACE)
If the application provides a resource with the specified resource ID (for example, AFX_IDI_STD_FRAME) ID, MFC will use that resource. Otherwise the default resource is used. For the icon, the standard application icon is used, and for the cursor, the standard arrow cursor is used.
There are two icons that support MDI applications with single document types (one icon for the main application, the other icon for iconic document/MDIChild windows). For multiple document types with different icons, you must register additional WNDCLASSes or use the CFrameWnd::LoadFrame function.
CFrameWnd::LoadFrame will automatically register a WNDCLASS using the standard "AfxFrameOrView" attributes but using the icon ID you specify as the first parameter to LoadFrame.
The values for background color and cursor for the MDIFrameWnd are not used since the client area of the MDIFrameWnd is completely covered by the "MDICLIENT" window. Microsoft does not encourage subclassing the "MDICLIENT" window so use the standard colors and cursor types when possible.
评论