请教一个比较关于对话框棘手的问题?(大拿们进来看看)

clxye 2009-11-10 05:14:52
其实这个问题我以前也提过,但总得不到实质性的答案。今天再发一次,希望能够真正解决问题,这个问题对我来说很重要,而且也困扰了我好长时间。问题的核心就是模式对话框与非模式对话框。

我做的是一个POS机,就是刷卡消费的那种。当我点击对话框的某个功能按钮时会弹出来一个“请插入会员卡”的提示。这种对话框功能上应该是:用户插入磁卡时对话框关闭或消失,如果没有插卡则一直显示一段时间,到了设定的超时则关闭或隐藏对话框。

按照对话框的功能来说,这时选择非模式对话框是再合适不过了。但如果对话框的层数只是一层的话还好办,这时点击那个功能按钮时可以通过ShowWindow来显示或隐藏非模式对话框,但如果点击这个按钮时不光是弹出非模式对话框,弹出后还需要弹出一个模式对话框,而在这个新弹出的模式对话框上还有按钮,点击上面的按钮还有弹出非模式和模式对话框...。因为弹出的非模式对话框总是同一个对话框(这是一个全局变量),当模式对话框弹出时,那个非模式对话框将处于Disable的状态,此时它不接受用户的鼠标和键盘输入,这就是问题之所在。

我自己做了一些测试程序,用在弹出子模式对话框时对父对话框GetParent()->EnableWindow( TRUE );则模式对话框可用,但这只是一层,如果是多层DoModal则很难管理,而且我试图在我的代码上使用此方法也没有成功。

如果改用模式对话框,弹出的对话框不会处于Disable状态,但调用DoModal后程序无法继续往下执行,就好像插卡对话框,根本无法实现用户插入磁卡后对话框自动消失,除非这个读卡和关闭功能在那个模式对话框内部实现。但是如果功能比较多的话就很麻烦了,因为不可能把功能处理放在这个模式对话框里,这个对话框其实主要起一个提示作用。提示插卡,提示数据处理,仅此而已。

说了这么多也不知道大家明不明白我的意思,希望能够得到一些建议!!
...全文
200 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
clxye 2009-11-11
  • 打赏
  • 举报
回复
我先做个测试程序试试看。
ezhuyin 2009-11-11
  • 打赏
  • 举报
回复
可否这样做:将这个模式对话框封装起来,放到一个独立线程中。这样主线程可以选择在合适的时候显示或者隐藏或者关闭对话框。
clxye 2009-11-11
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 gotooker 的回复:]
模式对话框往主窗口发消息
肯定收不到消息的,模式对话框有自己的消息循环,回不到主窗口了。除非模式对话框关闭了。

SendMessage( MY_MESSAGE, 0, 0 );
直接调用回调函数,是不会从PreTranslateMessage里执行的。
[/Quote]

我也认同这个观点。

[Quote=引用 26 楼 gotooker 的回复:]
建议可以把插卡动作检测放到模式对话框里。插卡后销毁模式对话框,然后再对卡读写。
[/Quote]
我也曾这么想过,但是读卡只是我的功能之一,当写卡的时候也需要用这个提示框来提示“数据处理中...”这样的字段,而且也需要做相应的操作;有时候读取网络数据、读取网络数据提示等待等都需要用这个提示框。如果采用这种方式的话,那这个对话框就不是简单的一个提示功能了,而是揉进了各个模块部分处理功能的大锅炉了。这样程序逻辑太乱,而且扩展性也不好,所以我放弃了。
clxye 2009-11-11
  • 打赏
  • 举报
回复
因为他原来的框架用的就不标准。他原来虽说是单文档程序,但只有框架而没有文档和视图类(我想他想显示的是对话框,所以他就把这两个部分去掉了)。我刚接手的时候也是搞得很头疼,有些功能他原来的代码完全是乱用,感觉就是那种刚学了一点技术就用上,而不管用的地方对不对。所以代码很乱。

因为他的逻辑不是很清晰,所以都是函数套函数,的确很难帖啊。
gotooker 2009-11-11
  • 打赏
  • 举报
回复
建议可以把插卡动作检测放到模式对话框里。插卡后销毁模式对话框,然后再对卡读写。
gotooker 2009-11-11
  • 打赏
  • 举报
回复
模式对话框往主窗口发消息
肯定收不到消息的,模式对话框有自己的消息循环,回不到主窗口了。除非模式对话框关闭了。

SendMessage( MY_MESSAGE, 0, 0 );
直接调用回调函数,是不会从PreTranslateMessage里执行的。
快乐鹦鹉 2009-11-11
  • 打赏
  • 举报
回复
无语。
clxye 2009-11-11
  • 打赏
  • 举报
回复
整个程序的代码相对有点多,而且有些代码是别人写的,风格等更方面都不太好,所以没法帖。
要是方便的话可以加我QQ:273667359聊或远程我机子(呵呵,不是我拽,要你加我,而是像你这样的牛人可能也不想轻易公布你的QQ,所以方便的话就直接加我吧)。

程序运行需要联网、连POS机,不然我就直接把源程序给你发过去了,这样看起来也方便。

clxye 2009-11-11
  • 打赏
  • 举报
回复
模式对话框往主窗口发消息

::EnableWindow( AfxGetApp()->m_pMainWnd->m_hWnd, true );
::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输出。
shesh 2009-11-11
  • 打赏
  • 举报
回复
pos机器操作基本上是单流程,还是模式对话框好,你可以用全局变量记录模式对话框的窗口句柄,一般检查用户是否刷卡可以用一个线程去监控,可以在线程里直接发消息将那模式对话框关闭就行;
我以前就这么做的,虽然笨,但原理简单;
快乐鹦鹉 2009-11-11
  • 打赏
  • 举报
回复
你把你发消息的代码贴出来。完整的。
快乐鹦鹉 2009-11-11
  • 打赏
  • 举报
回复
我早晨试了一下,我发消息那个框架窗口收不到消息啊。我想之所以收不到是不是因为主线程的消息泵被弹出的模式对话框阻塞了?
==没有这样的事。
clxye 2009-11-11
  • 打赏
  • 举报
回复
呵呵,happyparrot早上好啊。你刚才说的那点我觉得说得很好,我也喜欢你的做法。

我早晨试了一下,我发消息那个框架窗口收不到消息啊。我想之所以收不到是不是因为主线程的消息泵被弹出的模式对话框阻塞了?

我想,如果说框架能够收到消息的话,说得通俗点也就是主框架是活的,那么这时候的那个非模式对话框也应该可以响应鼠标键盘消息才对,不知我说的对不对?
快乐鹦鹉 2009-11-11
  • 打赏
  • 举报
回复
全局变量是方便了,可是你的编程水平就没有进步了。现在面向对象编程很重要的一点就是模块化,讲究封装。全局变量,就我的程序来说是禁止的,与goto一样。方便但会让程序可读性和封装性大大降低。要学会消息驱动的好处。
clxye 2009-11-11
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 shinefen 的回复:]
??你不是说~把那个共用的非模式对话框设置为全局变量了吗?
那么任何子地方的对象,,你在程序中都不用再getparent去寻找拉,直接用对话框全局变量的指针,把它showwindow,enablewindows都可以的呀...


??
[/Quote]

我记得我曾经这样试过,好像是不行的。不上上面的兄弟有没有这样试过,如果可以的话我会再好好检查一下是不是自己哪部分出了问题。这种方式如果可以的话我觉得是最简单也最方便的。

clxye 2009-11-11
  • 打赏
  • 举报
回复
呵呵,谢谢你的帮助了,我这个只是测试程序通过了,还没有放在我自己的程序里测试,我想应该是可以的。原来不行主要是因为主线程消息阻塞,我现在是单独一个线程,所以我想应该不会出现这个问题。也希望老大到我博客里看一下那篇文章,看看有没有什么问题。

结贴!
快乐鹦鹉 2009-11-11
  • 打赏
  • 举报
回复
解决了好啊。我都好郁闷了。
快乐鹦鹉 2009-11-11
  • 打赏
  • 举报
回复
希望你的解决方案不要让你的下一任出现和你现在一样的困扰。
clxye 2009-11-11
  • 打赏
  • 举报
回复
哈哈哈,终于解决了。
感谢ezhuyin(碧海蓝天)的建议,我采取多线程的方式,果然实现了。实现后对非模式对话框的控制非常灵活,只需要发送消息就可以控制对话框的显示和隐藏。做好后感觉有点像happyparrot说的那样,只不过我是采用多线程来实现。

我会把我的具体实现写在我的博客里,感兴趣的朋友可以看看:http://hi.baidu.com/clxye/blog/item/70b747fa629d0314a8d311c0.html

最后再次感谢happyparrot、ezhuyin、gotooker。
shinefen 2009-11-10
  • 打赏
  • 举报
回复
??你不是说~把那个共用的非模式对话框设置为全局变量了吗?
那么任何子地方的对象,,你在程序中都不用再getparent去寻找拉,直接用对话框全局变量的指针,把它showwindow,enablewindows都可以的呀...


??
加载更多回复(14)

16,551

社区成员

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

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

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