用对话框作为主窗口;IDD_FORMVIEW资源文件;

转自:http://blog.csdn.net/tcjiaan/article/details/8567053

前面我们在编写Win32应用程序的思路都是:

1、设计窗口类。2、注册窗口类。3、创建窗口。……

然而,当我们接触控件以后, 会发现一个问题,我们在窗口上放置控件实在不好弄,而资源中的对话框具有图形编辑器,操作起来相对方便。

于是,就有了一个想法:把对话框用作主窗口,那我们在布局控件时就轻松了。

 

其实这想法在网上已有牛人做了,不过,人家是用Win32汇编干的,当然,要把它变为C++就更简单了。

首先,介绍第一个法子,直接以桌面作为父窗口来创建对话框。

1、创建一个对话框资源,界面就发挥你的设计天赋了。

2、创建一个图标资源,既作为应用程序的图标(VS编译时会选择第一个添加到资源中的图标作为EXE的图标),也作为对话框的图标。

3、在代码中创建并显示对话框。

[cpp]  view plain  copy
 print ?
  1. #include <Windows.h>  
  2. #include "resource.h"  
  3. // 开启可视化效果  
  4. #pragma comment(linker,"\"/manifestdependency:type='win32' \  
  5. name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \  
  6. processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")  
  7.   
  8. INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);  
  9.   
  10. HINSTANCE hgInst;  
  11. int WINAPI WinMain(HINSTANCE hThisApp, HINSTANCE hPrevApp, LPSTR lpCmd, int nShow)  
  12. {  
  13.     hgInst = hThisApp;  
  14.     HWND hdlg = CreateDialog(hThisApp, MAKEINTRESOURCE(IDD_MY),GetDesktopWindow(),(DLGPROC)DlgProc);  
  15.     if(!hdlg)  
  16.     {  
  17.         return 0;  
  18.     }  
  19.     ShowWindow(hdlg,SW_SHOW);  
  20.     MSG msg;  
  21.     while(GetMessage(&msg,NULL,0,0))  
  22.     {  
  23.         TranslateMessage(&msg);  
  24.         DispatchMessage(&msg);  
  25.     }  
  26.     return 0;  
  27. }  
  28.   
  29. INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)  
  30. {  
  31.     switch(msg)  
  32.     {  
  33.     case WM_INITDIALOG:  
  34.         // 设置对话框的图标  
  35.         SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hgInst, MAKEINTRESOURCE(IDI_APP)));  
  36.         return 0;  
  37.     case WM_SYSCOMMAND:  
  38.         if(wParam == SC_CLOSE)  
  39.         {  
  40.             PostQuitMessage(0);//退出  
  41.         }  
  42.         return 0;  
  43.     }  
  44.     return (INT_PTR)FALSE;  
  45. }  

 

这样,我们可以运行一下。

 

=================================================================

第二种方法,我们还是遵照设计窗口类、注册窗口类、创建窗口等步骤,只是把对话框作为窗口的子级,对话框采用Form View视图。

在插入资源的对话框中,点击Dialog左边的图标,展开列表,在列表中选择IDD_FORMVIEW,然后点“新建”。

 

然后你看到一个没有边框和标题栏的对话框。

接下来我们可以放些控件上去。

最后,在响应WM_CREATE消息时,创建并显示对话框,父级是我们的主窗口。

[cpp]  view plain  copy
 print ?
  1. case WM_CREATE:  
  2.     {  
  3.         // 创建对话框  
  4.         HWND hdlg = CreateDialog(hgAppInst, MAKEINTRESOURCE(IDD_MYFORM), hwnd, (DLGPROC)DlgProc);  
  5.         // 显示对话框  
  6.         ShowWindow(hdlg, SW_SHOWNA);  
  7.     }  
  8.     return 0;  


最后运行结果如下:

 

 

完整的代码清单:

[cpp]  view plain  copy
 print ?
  1. #include <Windows.h>  
  2. #include "resource.h"  
  3. #pragma comment(linker,"\"/manifestdependency:type='win32' \  
  4. name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \  
  5. processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")  
  6.   
  7. LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);  
  8. INT_PTR CALLBACK DlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam);  
  9.   
  10. HINSTANCE hgAppInst;  
  11. int WINAPI WinMain(HINSTANCE hThisApp, HINSTANCE hPrevApp, LPSTR lpCmd, int nShow)  
  12. {  
  13.     // 设计窗口类  
  14.     WNDCLASS wc = { };  
  15.     wc.hbrBackground = (HBRUSH)COLOR_WINDOW;  
  16.     wc.lpfnWndProc = (WNDPROC)WindowProc;  
  17.     wc.lpszClassName = L"supper_man";  
  18.     wc.hInstance = hThisApp;  
  19.     wc.style = CS_HREDRAW | CS_VREDRAW;  
  20.     RegisterClass(&wc);  
  21.     hgAppInst = hThisApp;  
  22.     // 创建窗口  
  23.     HWND hwnd = CreateWindow(L"supper_man", L"超级应用",   
  24.         WS_OVERLAPPEDWINDOW, 40, 25, 380, 300, NULL, NULL, hThisApp, NULL);  
  25.     if(!hwnd)  
  26.         return 0;  
  27.     ShowWindow(hwnd, nShow);  
  28.     UpdateWindow(hwnd);  
  29.     // 消息循环  
  30.     MSG msg;  
  31.     while(GetMessage(&msg,NULL,0,0))  
  32.     {  
  33.         TranslateMessage(&msg);  
  34.         DispatchMessage(&msg);  
  35.     }  
  36.     return 0;  
  37. }  
  38.   
  39. LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)  
  40. {  
  41.     switch (msg)  
  42.     {  
  43.     case WM_CREATE:  
  44.         {  
  45.             // 创建对话框  
  46.             HWND hdlg = CreateDialog(hgAppInst, MAKEINTRESOURCE(IDD_MYFORM), hwnd, (DLGPROC)DlgProc);  
  47.             // 显示对话框  
  48.             ShowWindow(hdlg, SW_SHOWNA);  
  49.         }  
  50.         return 0;  
  51.     case WM_DESTROY:  
  52.         PostQuitMessage(0);  
  53.         return 0;  
  54.     default:  
  55.         return DefWindowProc(hwnd,msg,wParam,lParam);  
  56.     }  
  57.     return 0;  
  58. }  
  59.   
  60. // 处理对话框消息  
  61. INT_PTR CALLBACK DlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)  
  62. {  
  63.     /* .............. */  
  64.     return (INT_PTR)FALSE;  
  65. }  

摘要:本文通过一个程序实例描述了在VC++6.0下如何在单文档程序中通过菜单动态控制多 个窗体的切换。    一、 引言    我们在编制程序中根据需求的不同会在程序风格上选择多文档、单文档或是对话框模式 ,对于单文档模式可能是我们使用比较多的,但有时我们想采用单文档的形式显示多个不同 的窗体,如作为数据库前台应用程序就会遇到此类问题,数据库由大量的表单组成,而同常 一个窗体内只用来显示一个表单,所以要显示其他的表单时就要用到切换窗体的技术了,下 面就通过一个程序说明该技术的实现方法。    二、 实现技术    新建一个基于CFormView的单文档应用程序,再添加一个窗体和与之对应的基于 CFormView的新视类,然后通过在框架类里添加控制代码和菜单控制实现这两个窗体的动态 切换,下面就是具体的实现过程:    (一) 用"MFC AppWizard(exe)"建立一个新项目"SwitchForm",并在第二步的创建类型上选 择为"Single documnet"单文档模式,第三、四、五、六步均取确省状态,最后一步选择 "CFormView"作为视类的基类。点按"完成"按钮,生成了初始工程"SwitchForm"。    (二) 点选菜单"Insert"、"Resource…",在弹出的"Insert Resource"对话框中"Dialog"树 里的"IDD_FORMVIEW",点击"New"按钮,生成了一个新的窗体,将其ID号改为"IDD_NEXTFORM"。 在原有的窗体上加一个静态框"这是第一个窗体";在新建的窗体上也添加一个静态框"这是第二 个窗体"。    (三) 在菜单源的"IDR_MAINFRAME"上添加一级菜单"窗体切换",及其二级菜单"第一个窗 体"、"第二个窗体",其标识号分别为"ID_FIRSTFORM"和"ID_SECONDFORM"。修该"第一个窗体" 的属性为"Checked",表明程序初始时显示的是第一个窗体。    (四) 在"ClassView"属性页里的"SwitchForm classes"上右键,在弹出菜单上选择 "New Class…",弹出"New Class"对话框,选择"Dialog ID:"为我们刚添加的新窗体 "IDD_NEXTFORM",选择"Base class:"为"CFormView",类名取为"CNextFormView",这样就把第 二个窗体对应的视图类添加到了工程。 (五) 在框架类里添加函数SwitchToForm(): void CMainFrame::SwitchToForm(int nForm) { file://获取原来的活动窗体的视图句柄 CView* pOldActiveView = GetActiveView(); file://获取由"nForm"标识的窗体所对应的视图句柄 CView* pNewActiveView = (CView*) GetDlgItem(nForm); file://若视图句柄为空,则创建一新的。 if (pNewActiveView == NULL) { if (nForm == IDD_SW99vCHFORM_FORM) pNewActiveView = (CView*)new CSwitchFormView; if (nForm == IDD_NEXTFORM) pNewActiveView = (CView*)new CNextFormView; CCreateContext context; context.m_pCurrentDoc = pOldActiveView->GetDocument(); pNewActiveView->Create(NULL,NULL,0L, CFrameWnd::rectDefault, this,nForm,&context); pNewActiveView->OnInitialUpdate(); } file://选择pNewActiveView为活动窗体 SetActiveView(pNewActiveView); file://显示活动窗体,隐藏非活动窗体 pNewActiveView->ShowWindow(SW_SHOW); pOldActiveView->ShowWindow(SW_HIDE); int ID; if(pOldActiveView->GetRuntimeClass() == RUNTIME_CLASS(CSwitchFormView)) ID=IDD_SW99vCHFORM_FORM; if(pOldActiveView->GetRuntimeClass() == RUNTIME_CLASS(CNextFormView)) ID=IDD_NEXTFORM; file://设置窗体的ID号 pOldActiveView->SetDlgCtrlID(ID); pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST); RecalcLayout(); }    (六)添加两个菜单相对应的命令响应函数和更新函数如下: void CMainFrame::OnFirstform() { file://通过IsKindOf函数确定当前活动窗口是否是第一个窗口,如是,则无须切换, file://否则将通过SwitchToForm函数将当前活动窗口切换到"IDD_SW99vCHFORM_FORM" file://标识的第二个窗体。 if (GetActiveView()->IsKindOf(RUNTIME_CLASS(CSwitchFormView))) return; SwitchToForm(IDD_SW99vCHFORM_FORM); } void CMainFrame::OnUpdateFirstform(CCmdUI* pCmdUI) { file://通过IsKindOf函数判断当前活动窗口是否是第一个窗体,如是则将其选中。 pCmdUI->SetCheck(GetActiveView()->IsKindOf(RUNTIME_CLASS(CSwitchFormView))); } void CMainFrame::OnSecondform() { if (GetActiveView()->IsKindOf(RUNTIME_CLASS(CNextFormView))) return; SwitchToForm(IDD_NEXTFORM); } void CMainFrame::OnUpdateSecondform(CCmdUI* pCmdUI) { pCmdUI->SetCheck(GetActiveView()->IsKindOf(RUNTIME_CLASS(CNextFormView))); }    然后再在该文件开始处添加对两个视图类的引用: #include "SwitchFormDoc.h" #include "SwitchFormView.h" #include "NextFormView.h"    在此须注意:应在两个视类的引用之前添加对文档类的引用,否则会引起编译错误。另外,由于视 类的构造函数在声明时都确省的声明为保护型的,在框架类中无法引用,所以还要将两个视类的类 声明改动如下: class CNextFormView : public CFormView { public: file://将protected 改为public. CNextFormView(); …… }; class CSwitchFormView : public CFormView { public: file://将protected 改为public. CSwitchFormView(); …… };    三、 编译运行    编译运行程序,开始时的窗体上有"这是第一个窗体的字样",菜单也只有"第一个窗体"是被选中的, 当前的活动窗体是第一个窗体;点击菜单"第二个窗体",视图中的窗体上的字样变成了"这是第二 个 窗体",同时选中的菜单也由"第一个窗体"变成了"第二个窗体",实现了通过菜单将窗体进行动态切换。    总结:此程序中关键的是SwitchToView函数,在此函数中,程序搜索所有当前文档的显示窗口来查找与CruntimeClass变量匹配的视图类。如果找到,该窗口被激活。通过与之类似的方法,还可以实现在多文档模式下的单档(文档)多视(视图),通过不同的视图以不同的方式显示来自同一份文档的数据,以更好的满足程序的需要。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值