利用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来创建。

 

记录在册。
posted @ 2016-04-22 17:08  Burnet  阅读(1766)  评论(0编辑  收藏  举报