蜗居

路漫漫
心从这里经过
走过漫漫长夜
寻找属于我的蓝天



本站域名:blog.bluefantasy.cn
本Blog中本人拍摄的照片及网络编程类中的文章著作权归我本人所有,转载请发书面申请给我,否则是对我的著作权侵害,我保留对转载者和发布者追究法律责任的权力。

歪酷博客

« 上一篇: 在一个MFC工程中调用Word ActiveX自动化 下一篇: 将ActiveX控件标记为脚本安全和初始化安全 »
漫漫长夜中的蜗牛 @ 2005-05-18 20:39

需求:启动一个WORD进程给用户操作,用户关闭进程后进行后续操作
一般处理方法,用ShellExecuteEx或者CreateProcess函数启动进程,然后等待进程退出。代码如下:

m_localFilePath="C:\DocExc006926.doc";
SHELLEXECUTEINFO ShExecInfo ;
memset(&ShExecInfo,0,sizeof(SHELLEXECUTEINFO));
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "open";
ShExecInfo.lpFile =(LPCTSTR)m_localFilePath;
ShExecInfo.lpParameters = NULL;
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_NORMAL;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINATE);

但是在用这种方式处理WORD的时间出现了一个大问题,当关闭WORD的时候,WORD进入了不响应状态,CPU占用率90%+,界面无法绘制,调用程序也失去响应。
在网上找资料,在大富翁论坛上有人讲到这个问题,他们是DELPHI的实现。把WaitForSingleObject的参数INFINATE改成一个特定的值,循环检测。

  While (WaitForSingleObject(ShExecInfo.hProcess,1000)=WAIT_TIMEOUT) do
    Application.ProcessMessages();
  End

我比葫芦画瓢,只是C++中并没有Application.ProcessMessages这样的函数,我用Sleep(1000)来代替,发现并没有效果,而如果我在循环里面用MessageBox函数弹一个模式窗口而且不关掉这个窗口的话Word就可以正常关闭。看来原因不是在循环检测上面,而是在ProcessMessages处理了消息队列。由此猜测WORD关闭的时候要向调用者发消息并等待响应的原因,所以解决这个问题关键在于处理消息队列,即实现ProcessMessages的功能。
在BBS上一位仁兄的启发下我找到Delphi CLX框架的源码,然后读之,发现了三个关键的Windows API函数。

BOOL PeekMessage(
 LPMSG lpMsg,         // message information
 HWND hWnd,           // handle to window
 UINT wMsgFilterMin,  // first message
 UINT wMsgFilterMax,  // last message
 UINT wRemoveMsg      // removal options
);

这个函数是分派收到的消息,检查线程的消息队列,并获取消息

BOOL TranslateMessage(
 CONST MSG *lpMsg   // message information
);

这个函数是翻译实际的键盘消息为字符消息,字符消息送到该线程消息队列,用于下次调用GetMessage或者PeekMessage时读取。

LRESULT DispatchMessage(
 CONST MSG *lpmsg   // message information
);

这个函数将消息分派到窗口处理程序段。

最终的处理程序如下,这次没有WaitForSingleObject,而是使用了GetExitCodeProcess函数进程退出结果达到同样的轮询效果。

    m_localFilePath="C:\DocExc006926.doc";
SHELLEXECUTEINFO ShExecInfo ;
memset(&ShExecInfo,0,sizeof(SHELLEXECUTEINFO));
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "open";
ShExecInfo.lpFile =(LPCTSTR)m_localFilePath;
ShExecInfo.lpParameters = NULL;
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_NORMAL;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
DWORD exCode;
GetExitCodeProcess(ShExecInfo.hProcess,&exCode);

while(exCode==STILL_ACTIVE)
{
Sleep(10);
MSG msg;
memset(&msg,0,sizeof(MSG));
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

GetExitCodeProcess(ShExecInfo.hProcess,&exCode);
}


最新评论


刘宝森

2007-10-31 19:31 匿名 221.6.*.*

有才啊!


评论 / 个人网页 / 扔小纸条
* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 


 

分类小组论坛
杂谈 , 娱乐、八卦 , 文学、艺术 , 体育 , 旅游、同城 , 象牙塔 , 情感 , 时尚、生活 , 星座 , 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定

网志文件夹
· 所有网志 · 情感 · 网络编程 · 神的水途(原创连载) · 多媒体制作 · 考研路 · 未分类 ·
搜 索
友 情 链 接
· 歪酷博客 · 管理我的Blog · SoSoSo信息服务 · 我的个人主页 · 抽屉外的日记(firekey) · 女祭祀的魔镜(curio) · Dior-等待春天(huaxiao) · 山上的朋友你们好吗(five) · 一种怀念(asvic) · 人间四月天(clings) · 行.摄.笔记(rick) · 原来你也在这里(xinerfang) · 在天涯寻觅你 (fifid) · Songs and Silhouettes(icrainbow) · 小念珠(laowantong) · 麦兜的故事(未定) · 星语星愿(titi) · 雨落忘川(lucern) · 谁的明天谁的歌(cos) · 心情涂鸦(yumm) · 夏日的麽麽茶(mmtea) · 哇哈哈二世的殿堂(帮主的blog,兄弟姐妹们一定要捧场) ·

订阅 RSS

0068183

歪酷博客