其实这个问题我以前也提过,但总得不到实质性的答案。今天再发一次,希望能够真正解决问题,这个问题对我来说很重要,而且也困扰了我好长时间。问题的核心就是模式对话框与非模式对话框。我做的是一个POS机,就是刷卡消费的那种。当我点击对话框的某个功能按钮时会弹出来一个“请插入会员卡”的提示。这种对话框功能上应该是:用户插入磁卡时对话框关闭或消失,如果没有插卡则一直显示一段时间,到了设定的超时则关闭或隐藏对话框。按照对话框的功能来说,这时选择非模式对话框是再合适不过了。但如果对话框的层数只是一层的话还好办,这时点击那个功能按钮时可以通过ShowWindow来显示或隐藏非模式对话框,但如果点击这个按钮时不光是弹出非模式对话框,弹出后还需要弹出一个模式对话框,而在这个新弹出的模式对话框上还有按钮,点击上面的按钮还有弹出非模式和模式对话框...。因为弹出的非模式对话框总是同一个对话框(这是一个全局变量),当模式对话框弹出时,那个非模式对话框将处于Disable的状态,此时它不接受用户的鼠标和键盘输入,这就是问题之所在。我自己做了一些测试程序,用在弹出子模式对话框时对父对话框GetParent()->EnableWindow( TRUE );则模式对话框可用,但这只是一层,如果是多层DoModal则很难管理,而且我试图在我的代码上使用此方法也没有成功。如果改用模式对话框,弹出的对话框不会处于Disable状态,但调用DoModal后程序无法继续往下执行,就好像插卡对话框,根本无法实现用户插入磁卡后对话框自动消失,除非这个读卡和关闭功能在那个模式对话框内部实现。但是如果功能比较多的话就很麻烦了,因为不可能把功能处理放在这个模式对话框里,这个对话框其实主要起一个提示作用。提示插卡,提示数据处理,仅此而已。说了这么多也不知道大家明不明白我的意思,希望能够得到一些建议!!
简单点说就是一个对话框程序,在初始化时创建一个非模式对话框,开始是隐藏起来的。每次需要显示一些提示信息时就显示出来,不需要时就隐藏起来。如果说那个对话框为DialogParent,它上面有个按钮,点击时弹出(这里的弹出均是DoModal)一个新对话框为DialogChild1,DialogChild1上有个按钮,点击时弹出一个对话框DialogChild11 -> 再往下就是111,以此类推。
那个非模式对话框就叫做ModalLessDlg吧,它是在DialogParent窗口中创建的,初始处于隐藏状态ShowWindow( FALSE );请问在DialogChild1111中如何使ModalLessDlg显示并处于Enable状态(可接收鼠标和键盘响应)?不知这样明不明白?
==这还不简单么?给主对话框发消息就行了啊。真是简单的受不了的问题
嗯,基本是这个意思,其它理解正确,就是反复无止境这个有点出入,差不多只有三到四层吧。后面的对话框DoModal时会使非模式对话框无效的,我试过直接对那个非模式对话框调用EnableWindow( TRUE );,但没有效果。
这个整体框架是有点问题的,不知上次提没提过,它是用的单文档框架,然后在OnCreate中调用DoModal来显示主对话框,后续则是正常的对话框弹出等了。我是维护和增加新功能的,也没法改变这个框架了,所以好多不是复杂的问题搞得有点麻烦。请问往主对话框发送什么消息呢?是发送WM_ENABLE消息或者EnableWindow吗(这个我当时好像试过,好像不太行,我再试试)?像我目前这种情况是应该往那个单文档的窗口发消息吧?
那么任何子地方的对象,,你在程序中都不用再getparent去寻找拉,直接用对话框全局变量的指针,把它showwindow,enablewindows都可以的呀...
??
我以前就这么做的,虽然笨,但原理简单;
::PostMessage( AfxGetApp()->m_pMainWnd->m_hWnd, MY_MESSAGE, 0, 0 );
主框架BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
if( MY_MESSAGE == pMsg->message )
{
TRACE( "MainFrame Received MY_MESSAGE message...\n" );
}
return CFrameWnd::PreTranslateMessage(pMsg);
}
但是Debug窗口没有相应的输出。后来我又改了一下验证方法,证明这时候框架窗口的确是收不到消息的:int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
...
SetTimer( 1, 1000, NULL );
...
...
}void CMainFrame::OnTimer(UINT nIDEvent)
{
SendMessage( MY_MESSAGE, 0, 0 );
CFrameWnd::OnTimer(nIDEvent);
}BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
TRACE( "message loop...\n" );
return CFrameWnd::PreTranslateMessage(pMsg);
}当我弹出非模式对话框时,也没有TRACE输出。
要是方便的话可以加我QQ:273667359聊或远程我机子(呵呵,不是我拽,要你加我,而是像你这样的牛人可能也不想轻易公布你的QQ,所以方便的话就直接加我吧)。程序运行需要联网、连POS机,不然我就直接把源程序给你发过去了,这样看起来也方便。
肯定收不到消息的,模式对话框有自己的消息循环,回不到主窗口了。除非模式对话框关闭了。SendMessage( MY_MESSAGE, 0, 0 );
直接调用回调函数,是不会从PreTranslateMessage里执行的。
感谢ezhuyin(碧海蓝天)的建议,我采取多线程的方式,果然实现了。实现后对非模式对话框的控制非常灵活,只需要发送消息就可以控制对话框的显示和隐藏。做好后感觉有点像happyparrot说的那样,只不过我是采用多线程来实现。我会把我的具体实现写在我的博客里,感兴趣的朋友可以看看:http://hi.baidu.com/clxye/blog/item/70b747fa629d0314a8d311c0.html最后再次感谢happyparrot、ezhuyin、gotooker。