利用AfxRegisterWndClass, Create代替LoadFrame创建MFC框架
对于MFC单文档程序(SDI), 在CWinApp的InitInstance函数的初始化中, 利用LoadFrame函数创建主框架确实简单方便。 但是灵活性却很差,如果软件有特殊需求的话,还是用AfxRegisterWndClass创建比较灵活, 随心所欲。 关键有3步:
1. 利用AfxRegisterWndClass注册主窗口, 可以根据需要,传入HICON的句柄;
2. 用CFrameWnd类或其子类的对象的Create函数创建窗口, 此时可以根据需要传入HMENU加载菜单栏;
3. 最后不要忘记向所有的子窗口发送WM_INITUPDATE消息, 在头文件<afxpriv.h>中。
好了, 直接贴代码直观些:
1 CMainFrame* pFrame = new CMainFrame; 2 if (!pFrame) 3 return FALSE; 4 m_pMainWnd = pFrame; 5 // 创建并加载框架及其资源 6 // pFrame->LoadFrame(IDR_MAINFRAME,WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,NULL); // 方便的方式 // 即CWnd::CreateEx(hMenu...) 7 8 // 如果做全屏的软件, 不许加载菜单,工具栏, 就可以使用AfRegisterWndClass 9 10 // 1. 11 HICON hIcon = LoadIcon(IDR_MAINFRAME); 12 LPCTSTR lzClass = AfxRegisterWndClass(CS_DBLCLKS|CS_VREDRAW|CS_HREDRAW,NULL,NULL,hIcon ); 13 /* 14 // 2. 15 pFrame->Create(lzClass, _T("员工管理系统")); // 此时是没有菜单栏的 而且没有向自敞口发送消息。 16 HMENU hMenu = LoadMenu(m_hInstance, MAKEINTRESOURCE(IDR_MAINFRAME)); 17 ::SetMenu(pFrame->m_hWnd, hMenu); 18 */ 19 // 3. 可以这样: 20 pFrame->Create(lzClass, _T("员工管理系统"),WS_OVERLAPPEDWINDOW,CFrameWnd::rectDefault,NULL,MAKEINTRESOURCE(IDR_MAINFRAME)); 21 pFrame->LoadAccelTable(MAKEINTRESOURCE(IDR_MAINFRAME)); // 加载快捷键 22 pFrame->SendMessageToDescendants(WM_INITIALUPDATE,0,0,TRUE,TRUE); // 消息分发机制, TRUE表示发给所有子窗口 23 24 // 从1到3 MFC只需要LoadFrame函数就可以搞定, 所以很方便, 但是不灵活, 如果软件有特殊需求的话, 就用上面的code
SendMessageToDescendants()回向所有子孙们发送WM_INITUPDATE消息了, 类似对话框程序的OnInitDialog()。
OK,以上只是在CWinApp中创建CMainFrame框架类, 我们也可以根据自己要求, 在CMainFrame类中创建自己的CView视图类。 这个大概可以分成2个步骤吧, 我理解的:
1. 创建自己的视图类, 可以继承自CEditView,CRichEditView,CListView, CTreeView, CFormView,CHtmlView等等, 根据需要来定, 然后要重写里面的OnInitUpdate()函数啊, 就是一些初始化工作了;
2. 就需要创建我们的视图类了, 可以在CMainFrame的OnCreate函数中, 也可以在OnCreateClient中, 一般在后者中吧:
1 BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 2 { 3 CCreateContext cc; 4 cc.m_pNewViewClass = RUNTIME_CLASS(CMainView); 5 m_pMainView = (CMainView*)CreateView(&cc); // 将frame与view紧密结合 与LoadFrame函数同样都是加载视图。 6 7 return CFrameWnd::OnCreateClient(lpcs, pContext); 8 }
具体呢, 就是先创建上下文CCreateContext结构体, 然后填充你的新View类:
1 struct CCreateContext // Creation information structure 2 // All fields are optional and may be NULL 3 { 4 // for creating new views 5 CRuntimeClass* m_pNewViewClass; // runtime class of view to create or NULL 6 CDocument* m_pCurrentDoc; 7 8 // for creating MDI children (CMDIChildWnd::LoadFrame) 9 CDocTemplate* m_pNewDocTemplate; 10 11 // for sharing view/frame state from the original view/frame 12 CView* m_pLastView; 13 CFrameWnd* m_pCurrentFrame; 14 15 // Implementation 16 CCreateContext(); 17 };
我的CMainView就是继承自CListView, 可以在里面获取CListCtrl控件对象。 你可以用CreateView来创建View(如果你要记录CMainView指针的话), 也可以把
cc对象传给父类CFrameWnd::OnCreateClient(lpcs, pContext);的pContext来创建。
记录在册。
都会有相应, 即使一点点, 不问是当下。