博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于在窗口消息处理函数中使用MessageBox造成消息重入的问题的研究及解决
阅读量:6107 次
发布时间:2019-06-21

本文共 2010 字,大约阅读时间需要 6 分钟。

原文地址:

这两天慢慢把这次实训的成果总结出来,这是第一篇日志。

最早碰到的一个报错问题,在窗口消息处理函数中使用MessageBox(包括A和W版),由于MessageBox特性,程序会被阻塞,此时由于窗口处理函数未返回,消息分发会继续分发这个“未处理”的消息,从而导致消息重入。

下面进行分析:

MessageBox是模态对话框,Msdn中对于Dialog的解释为:

The DialogBox macro uses the CreateWindowEx function to create the dialog box. DialogBox then sends a WM_INITDIALOG message (and a WM_SETFONT message if the template specifies the DS_SETFONT style) to the dialog box procedure. The function displays the dialog box (regardless of whether the template specifies the WS_VISIBLE style), disables the owner window, and starts its own message loop to retrieve and dispatch messages for the dialog box.

原因如下:

所有的输入型消息都被MessageBox先处理,有一些在处理完后直接被丢弃,并不会传递给所有者窗体以及其他兄弟窗体;而非输入型消息在此期间MessageBox并未做处理,而是根据消息信息直接传递给所有者窗体或其他兄弟窗体,此时虽然未点击MessageBox上的任何按钮关闭MessageBox,但是同样的消息处理函数有可能重入。

我自己的解决方法是写一个多线程的对话框函数:

DWORD WINAPI _MTMessageBox(LPVOID argv){ DWORD dwBtn; TCHAR* szText; TCHAR* szCaption; TCHAR* szMsg = (TCHAR*)argv; int iMsgLen = _tcslen(szMsg); TCHAR* szBuff = new TCHAR[iMsgLen + 1]; _tcscpy(szBuff,szMsg); for (int i=0;i

使用MultiThreadMessageBox就行了,同时支持ANSI和Unicode。

备注:原作者写的MultiThreadMessageBox存在一些问题。比如“delete szBuff;”需要修改为“delete [] szBuff;”,否则会泄露内存。

下面是我重新实现了一下:

typedef struct{    TCHAR text[MAX_PATH];    TCHAR caption[MAX_PATH];    UINT type;}MessageBoxData;DWORD WINAPI MessageBoxThread(LPVOID parameter){    MessageBoxData * message_box_data = static_cast
(parameter); MessageBox(NULL, message_box_data->text, message_box_data->caption, message_box_data->type); delete message_box_data; message_box_data = NULL; return 0;}void MultiThreadMessageBox(LPCTSTR lpText, LPCTSTR lpCaption, UINT uType){ MessageBoxData * message_box_data = new MessageBoxData; _tcscpy(message_box_data->text ,lpText); _tcscpy(message_box_data->caption, lpCaption); message_box_data->type = uType; HANDLE handle_thread = CreateThread(0, 0, MessageBoxThread, (LPVOID)message_box_data, 0, NULL); if (NULL != handle_thread) CloseHandle(handle_thread);}

 

转载地址:http://ebhza.baihongyu.com/

你可能感兴趣的文章
小程序: 查看正在写的页面
查看>>
dedecms生成文档数据库崩溃 mysql daemon failed to start
查看>>
Linux的50个基本命令
查看>>
Objective-C中创建单例方法的步骤
查看>>
[转]无法安装MVC3,一直卡在vs10-kb2483190
查看>>
Codeforces 520B:Two Buttons(思维,好题)
查看>>
web框架-(二)Django基础
查看>>
Jenkins持续集成环境部署
查看>>
emoji等表情符号存mysql的方法
查看>>
Excel到R中的日期转换
查看>>
检查磁盘利用率并且定期发送告警邮件
查看>>
MWeb 1.4 新功能介绍二:静态博客功能增强
查看>>
linux文本模式和文本替换功能
查看>>
Windows SFTP 的安装
查看>>
摄像机与绕任意轴旋转
查看>>
rsync 服务器配置过程
查看>>
预处理、const与sizeof相关面试题
查看>>
爬虫豆瓣top250项目-开发文档
查看>>
Elasticsearch增删改查
查看>>
oracle归档日志增长过快处理方法
查看>>