如何用MFC创建非模式对话框为主窗口

HeLiang7 2009-01-16 12:06:41
原由:想在主线程的空闲时间向对话框中的列表框写入文本,此外对主线程进行一些控制,主要是模拟一个样例程序,当然那个程序是用SDK做的。
SDK的程序主框架如下,Dialog中的消息循环和处理之类的就不列出了。

int WINAPI _tWinMain(HINSTANCE hInstExe, HINSTANCE, PTSTR pszCmdLine, int) {

HWND hWnd =
CreateDialog(hInstExe, MAKEINTRESOURCE(IDD_SCHEDLAB), NULL, Dlg_Proc);
BOOL fQuit = FALSE;

while (!fQuit) {
MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (!IsDialogMessage(hWnd, &msg)) {
if (msg.message == WM_QUIT) {
fQuit = TRUE;
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
} else {

//这里运行自己的代码,写对话框中的列表
}
}

DestroyWindow(hWnd);
return(0);
}


这样最方便的是生成对话框为主窗口程序,但如果直接用向导生成的对话框为主窗口的MFC程序,则对话框是模式的。这里我有两个问题。

1.模式对话框中如何控制消息,并在没有消息时执行自己的代码?

2.如何生成非模式对话框为主窗口的程序?

问题1,我完全没有头绪,问题2我研究了一下,但还是没有解决。

我的想法是直接用CWinApp的OnIdle处理自己的代码就可以了,但模式对话框是中断在DoModle那里了,OnIdle是执行不了的。
我想自己写个(或改一下)以非模式对话框为主窗口的MFC代码,但发现一些的问题。先把代码写一下


BOOL CMyApp::InitInstance()
{
MyDlg dlg = new MyDlg();
m_pMainWnd = &dlg;
dlg.Create(IDD_DIALOG1);
dlg.ShowWindow(SW_SHOW);

return TRUE;
}


但程序是直接返回,并不运行,跟踪到MFC源码(appcore.cpp)中发现

int CWinApp::Run()
{
if (m_pMainWnd == NULL && AfxOleGetUserCtrl())
{
// Not launched /Embedding or /Automation, but has no main window!
TRACE(traceAppMsg, 0, "Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application.\n");
AfxPostQuitMessage(0);
}
return CWinThread::Run();
}


因为MyDlg dlg = new MyDlg()后的&dlg竟然为Ox00000000,所以在Run()里面m_pMainWnd == NULL,直接被发消息中止程序了。
至此,第2个问题发现原因是new CDialog地址为空,但不知如何可以解决掉。

2个问题,请朋友们说下怎么处理比较好,先谢过了。
...全文
270 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
aa3000 2009-01-19
  • 打赏
  • 举报
回复
DoModal 只是在里面使用了一个消息循环,跟外面的消息循环差不多,机制是一样的。
HeLiang7 2009-01-16
  • 打赏
  • 举报
回复
谢谢楼上的大虾,果然可行,相当于直接自己处理这个消息循环,不让给MFC框架处理了,呵呵,受教了。
另外,可不可以把第一个问题回答一下,就是,如果直接用模式对话框,这个消息循环的处理是否也可行呢,CDialog类里面有很多虚拟方法可以用,但不知道一些具体的样例。
给出一点链接资料也可以,先谢过了。

帖子分数我会马上给,希望多知道一个问题的答案,呵呵。
aa3000 2009-01-16
  • 打赏
  • 举报
回复
BOOL CMyApp::InitInstance()
{
MyDlg dlg = new MyDlg();
m_pMainWnd = &dlg;
dlg.Create(IDD_DIALOG1);
dlg.ShowWindow(SW_SHOW);

while (!fQuit) {
MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (!IsDialogMessage(hWnd, &msg)) {
if (msg.message == WM_QUIT) {
fQuit = TRUE;
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
} else {

//这里运行自己的代码,写对话框中的列表
}
}


return TRUE;
}
No.4 简单的MFC对话框演示程序 “MultiDialog” 演示如何在工程中拥有多个对话框,及如何在一个对话框中调用另一个对话框。 重点:1、多个对话框类的建立;2、对话框模式(Modal)调用方法;3、Spin控件的使用。 新建一个基于对话框MFC工程, 通过菜单"Insert>>Resource"打开添加资源对话框, 在其中选择Dialog后点击New创建一个新的对话框 按Ctrl+W打开ClassWizard,系统会提示刚才创建了一个新的对话框资源,是否建立对应的类, 选择建立,然后在New Class窗口中Class Name栏输入它的名称:CSubClass1, 确定后系统会自动生成SubClass1.h和SubClass1.cpp并加入工程中,其中有已经创建好的CSubClass1的类的基本代码。 把这个对话框的Caption属性改为“难度选择”,在它上面画三个Radio“简单”、“标准”、“困难”, 并建立相关联的变量m_Option1。(要注意的是在ClassWizard中注意Class Name中应该选CSubClass1而不是之前的主对话框类) 按照相同方法建立第二个新对话框,类名“CSubClass2”,Caption为“关卡选择”。 在上面画一个Edit和一个Spin,注意先画Edit后画Spin,将Spin的Auto buddy和Set buddy integer勾上。 按Ctrl+W打开ClassWizard,为Edit建立关联变量,不过注意是int型而不是CString型, 也为Spin建立关联变量m_Spin1,注意这次是Control型变量CSpinButtonCtrl。 下面为这两个对话框添加代码。 双击“难度选择”对话框的OK按钮,建立对话框的OnOK映射。 在其中加入(在CDialog::OnOK();之前): UpdateData(TRUE); if ((m_Option1>2) ||(m_Option1<0)) { MessageBox("错误的选择!","提示",MB_OK); return; } 下面对“关卡选择”对话框添加初始化代码, 由于关卡的有效值只有1到6,因此需要在初始化时设置Spin控件的有效值范围。 按Ctrl+W打开ClassWizard,在左侧列表选择这个对话框类CSubDialog2, 在右侧列表中选择WM_INITDIALOG,点击右边的“Add Function...”按钮, 接着点击右边的“Edit Code”按钮,在其中中加入(在CDialog::OnInitDialog()那句之后,在return TRUE那句之前): m_Spin1.SetRange(1,6); m_Text1=1; m_Spin1.SetPos(1); 其中CSpinButtonCtrl::SetRange()函数的作用是设置和他关联的Spin控件的范围,两个参数分别是下界和上界。 而CSpinButtonCtrl::SetPos()是设定Spin的当前位置。 两个新的对话框都已建立完毕,下来是如何在主对话框中使用的问题。 首先,两个新对话框都有各自的类,分别在SubDialog1.h和SubDialog2.h中有定义。(类的细节则在对应的cpp中定义) 因此,主对话框想要调用这两个新对话框,需要先包含这两个头文件, 在你要使用的地方(本例是MultiDialogDlg.cpp中)文件前面加上 #include "SubDialog1.h" #include "SubDialog2.h" 然后在想要调用的地方就可以使用了。 本例中,首先为主窗口的两个Edit建立CString型关联变量m_Text1和m_Text2, 然后在两个按钮的消息映射函数中分别加入: CSubDialog1 dialog1; //定义CSubDialog1型对话框的一个新对象 dialog1.DoModal(); //使用“模式”调用,显示对话框 m_Text1.Format("%d",dialog1.m_Option1); //此句在上面对话框没有关闭前不会执行到 UpdateData(FALSE); 和 CSubDialog2 dialog1; dialog1.DoModal(); m_Text2.Format("%d",dialog1.m_Text1); UpdateData(FALSE); 其中第一句均为定义对话框新实例的语句,定义一个你想要的类型的对话框。 第二句是通过调用CDialog::DoModal()方法,来显示这个对话框,并进入“模式”(Modal)状态 在“模式”状态,当子对话框没有关闭之前,调用它的父对话框不能被响应, 并且其语句执行会停留在刚才的DoModal语句上等待,直到子对话框关闭才接着执行下一个语句。 第三第四句将子对话框得到的数据(即类的成员变量)显示在父对话框的Edit上。 四句执行完后退出该函数,这时刚才定义的CSubDialog1等对话框类变量被销毁,因此创建的话框也被销毁。
MFC的视图打印/预览功能基于CView::OnFilePrint和CView::OnFilePrintPreview这两个函数。 如果要对用户自定义对话框(模态)内的子视图进行打印,直接调用该视图的CView::OnFilePrint即可,弹出的“选择打印机”对话框同样也是模态对话框,覆盖在用户对话框上。 如果要对用户对话框内的视图进行预览,直接调用该视图的CView::OnFilePrintPreview后,预览视图(MFC CPreviewView类实例)内虽然预览正常,但是挡住了用户对话框。由于用户对话框是模态的,导致预览视图上的“打印...”、“上一页”、“下一页”、“放大”、“缩小”、“单页/双页”和“关闭”等按钮均无法响应鼠标点击,处于“假死”状态。 解决方法: 第一个解决方法是先关闭用户对话框,再启动预览,详见http://download.csdn.net/detail/oliver_zheng/7639379 第二个解决方法仍然保持用户对话框,但是由于对话框为模态,无法利用主框架窗口CMainFrame作为预览框架,因此要另外创建并显示一个框架窗口(CFrameWnd的派生类),作为预览窗口。 另外创建的框架窗口类名为CPrintPreviewFrameWnd,其对应的单文档视图是CViewPrintPreview类,利用这些关联信息创建一个单文档模板,利用此单文档模板创建框架窗口,并在其内嵌视图(CViewPrintPreview类)中保存原主框架(CMainFrame)、用户对话框和其上需要打印的视图(CTestView)。然后基于CViewPrintPreview类启动预览和打印(具体过程详见第一个解决办法)。由于CViewPrintPreview的各个相关虚函数诸如OnPreparePrinting、OnBeginPrinting、OnPrepareDC、OnPrint和OnEndPrinting都被重载,用于调用真正需要打印的视图CTestView的各自函数,因此CViewPrintPreview实际上只是个“中介”视图,是连接预览视图(MFC CPreviewView类)和CTestView的桥梁。 当打印或者预览结束后,关闭自行创建的框架窗口CPrintPreviewFrameWnd,利用CViewPrintPreview类中实现保存的信息恢复主框架和用户对话框,恢复打印/预览前的环境。 代码(实现了第二个解决方法)在VC2010下编译通过。第一个解决方法的源码详见http://download.csdn.net/detail/oliver_zheng/7639379
光 盘 说 明 1.本书第4~16章所附代码的运行环境: Visual C++ 6.0及以上版本 最低配置为:CPU:P 233以上.32MB以上内存 2.本书所附光盘范例 第4章 项目ExTest,“不做任何事情”的应用程序。 第5章 项目ExTest,在客户区中央显示“HELLO!”; 项目ExMyMessage,自定义消息。 第6章 项目ExMDI,“不做任何事情”的多文档应用程序; 项目ExSDI,验证文档视图结构中的命令消息处理顺序。 第7章 项目ExMouseCapture,鼠标捕获; 项目ExCursor,改变客户区光标为I形光标; 项目ExMK,鼠标光标位置坐标在状态栏的显示和客户区点击鼠标左键,弹出鼠标光标位置信息对话框; 项目ExChar,只有在当前窗口下输入字符“A”或“a”时,才弹出对话框。 第8章 项目ExTest,修改系统菜单的相关操作; 项目ExPdMenu,添加下拉菜单并实现命令响应,以及工具栏和状态栏的操作; 项目ExPuMenu,弹出菜单的创建、载入与功能实现; 项目ExMyDT,菜单、工具栏、状态栏综合操作,实现一个简单的绘图板。 第9章 项目ExMdMl,反映模式对话框模式对话框的几点不同; 项目ExDlgTest(C4),北京奥运金牌榜首的投票对话框,单选按钮、复选框、下压按钮与组框操作; 项目ExDlgTest(C5),个人信息录入对话框,列表框、组合框与滚动条操作; 项目ExDlgTS,通过改变选项卡所包含的颜色滑块实现单文档主窗口所包含图形的色彩变化,选项卡和滑块操作。 第10章 项目ExPen,画笔操作; 项目ExBrush,画刷操作; 项目ExFont,字体操作; 项目MyDraw,位图操作; 项目ExArc,对预设圆左上1/4部分的截取,绘制曲线操作; 项目ExBezier,利用贝塞尔函数绘制图形; 项目ExPie,绘制饼状楔形图; 项目ExDrawText,绘制文本; 项目ExMapMode,设定映射模式并基于设定的映射模式完成绘图。 第11章 项目ExFileStatus,使用类CFile提供的方法实现文件信息获取; 项目ExArTest,利用串行化机制执行读写操作。 第12章 项目ExThread,创建工作线程,计算1+2+…+n; 项目ExMultithreading,创建两个线程,分别用于对一个已有数组的读和写操作,多线程编程。 第13章 项目Calculate和项目ExTestCal,分别用于创建和使用静态链接库; 项目CalSquare和项目ExTestCalSquare,分别用于创建和使用规则动态链接库; 项目CalGCD和项目ExTestCalGCD,分别用于创建和使用扩展动态链接库。 第14章 项目ExMyAccess,MFC ODBC数据库程序创建与操作。 第15章 项目ExSocket和项目ExClient,通过Socket编程实现数据收发; 项目ExGetIP,网络应用程序,IP获取。 第16章 项目SampleCtrl和项目ActiveXTester,创建和使用ActiveX控件。
光 盘 说 明 1.本书第4~16章所附代码的运行环境: Visual C++ 6.0及以上版本 最低配置为:CPU:P 233以上.32MB以上内存 2.本书所附光盘范例 第4章 项目ExTest,“不做任何事情”的应用程序。 第5章 项目ExTest,在客户区中央显示“HELLO!”; 项目ExMyMessage,自定义消息。 第6章 项目ExMDI,“不做任何事情”的多文档应用程序; 项目ExSDI,验证文档视图结构中的命令消息处理顺序。 第7章 项目ExMouseCapture,鼠标捕获; 项目ExCursor,改变客户区光标为I形光标; 项目ExMK,鼠标光标位置坐标在状态栏的显示和客户区点击鼠标左键,弹出鼠标光标位置信息对话框; 项目ExChar,只有在当前窗口下输入字符“A”或“a”时,才弹出对话框。 第8章 项目ExTest,修改系统菜单的相关操作; 项目ExPdMenu,添加下拉菜单并实现命令响应,以及工具栏和状态栏的操作; 项目ExPuMenu,弹出菜单的创建、载入与功能实现; 项目ExMyDT,菜单、工具栏、状态栏综合操作,实现一个简单的绘图板。 第9章 项目ExMdMl,反映模式对话框模式对话框的几点不同; 项目ExDlgTest(C4),北京奥运金牌榜首的投票对话框,单选按钮、复选框、下压按钮与组框操作; 项目ExDlgTest(C5),个人信息录入对话框,列表框、组合框与滚动条操作; 项目ExDlgTS,通过改变选项卡所包含的颜色滑块实现单文档主窗口所包含图形的色彩变化,选项卡和滑块操作。 第10章 项目ExPen,画笔操作; 项目ExBrush,画刷操作; 项目ExFont,字体操作; 项目MyDraw,位图操作; 项目ExArc,对预设圆左上1/4部分的截取,绘制曲线操作; 项目ExBezier,利用贝塞尔函数绘制图形; 项目ExPie,绘制饼状楔形图; 项目ExDrawText,绘制文本; 项目ExMapMode,设定映射模式并基于设定的映射模式完成绘图。 第11章 项目ExFileStatus,使用类CFile提供的方法实现文件信息获取; 项目ExArTest,利用串行化机制执行读写操作。 第12章 项目ExThread,创建工作线程,计算1+2+…+n; 项目ExMultithreading,创建两个线程,分别用于对一个已有数组的读和写操作,多线程编程。 第13章 项目Calculate和项目ExTestCal,分别用于创建和使用静态链接库; 项目CalSquare和项目ExTestCalSquare,分别用于创建和使用规则动态链接库; 项目CalGCD和项目ExTestCalGCD,分别用于创建和使用扩展动态链接库。 第14章 项目ExMyAccess,MFC ODBC数据库程序创建与操作。 第15章 项目ExSocket和项目ExClient,通过Socket编程实现数据收发; 项目ExGetIP,网络应用程序,IP获取。 第16章 项目SampleCtrl和项目ActiveXTester,创建和使用ActiveX控件。

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧