首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使子进程窗口在我的进程中显示模式?

如何使子进程窗口在我的进程中显示模式?
EN

Stack Overflow用户
提问于 2009-03-05 03:46:48
回答 6查看 6.8K关注 0票数 8

我有一个应用程序,它调用其他实用程序来为特定设备设置一些设置。使用ShellExecuteEx调用该实用程序。

为了避免混淆用户,最好将实用程序应用程序的窗口设置为我的主窗口。一个人是怎么做到的?

我尝试过的事情:

  1. WaitForSingleObjectEx对进程后的ShellExecuteEx,无限超时窗口是模态的,但是主应用程序不会重新绘制(因为它在等待单个对象!)
  2. WaitForSingleObjectEx对进程进行了ShellExecuteEx后,一些小超时,然后调用Peekmessage和DispatchMessage -重新绘制现在工作,但实用程序不再是“模式”。主应用程序响应鼠标单击、按钮单击等。
  3. EnableWindow(FALSE),然后执行方法#2,然后是EnableWindow(真)!,但是在这之后,我的应用程序的z顺序发生了变化。(它现在在其他窗户下面)。为什么?!
EN

回答 6

Stack Overflow用户

发布于 2009-03-10 20:42:01

你有两件事要模拟:所有权和情态。

要模拟所有权:您需要将新子进程窗口的所有者设置为您的窗口。这将缓解任何z排序问题。虽然我不知道这是否从另一个过程起作用。如果没有,那么您可能必须附加线程输入队列,然后调用它。或者使用其他代码注入技术。

代码语言:javascript
复制
SetWindowLong <target window handle>, GWL_HWNDPARENT, <new owner handle>

为了模拟模态,我认为您在正确的轨道上使用EnableWindow和WaitForSingleObjectEx。

票数 4
EN

Stack Overflow用户

发布于 2009-03-10 01:23:12

简单的回答是,即使线程处于相同的进程中,也无法无缝地为线程A中的窗口创建线程B模式的窗口。如果您拥有这两个窗口的代码,您可能会接近,但在这种情况下,您将获得更好的结果,通过将您的所有UI放在一个线程。

如果您试图向用户建议线程B的窗口是线程A的模式,那么就有许多微妙的Z顺序和激活行为,您必须纠正(正如您已经注意到的),以免遭受某种不可思议的山谷效应,在用户看来,线程B的窗口显然是试图成为某种东西--它不是这样的,因此看起来是坏的。

为了避免这种情况,我会采取这样的做法:

  1. 用户单击caner.exe主窗口中的"FDA检查“。canner.exe显示一个模态对话框,表明它正在打开一个外部程序(“打开肉毒杆菌中毒设置.”)。这将禁用主窗口等,以便用户知道正在进行的模态交互。
  2. canner.exe调用ShellExecuteEx启动botulism.exe。
  3. canner.exe对从ShellExecuteEx()返回的句柄调用WaitForInputIdle。WaitForInputIdle()将在botulsim.exe为用户交互做好准备时返回(大约,但通常足够接近)。如果botulism.exe通常需要5秒钟或更长的时间来显示它的UI,那么我可以在循环中对WaitforInputIdle()使用一个短暂的超时,并偶尔使用PeekMessage()/ProcessMessage()处理任何挂起的消息。
  4. canner.exe更改其对话框文本以反映它正在等待用户关闭botulism.exe (“关闭肉毒杆菌中毒设置以继续.”)。
  5. canner.exe在循环中调用MsgWaitForMultipleObjects以等待botulsim.exe关闭。当传递的句柄发出信号或线程队列中有消息等待时,MsgWaitForMultipleObjects()将返回。
  6. 如果用户在canner.exe等待时单击caner.exe模式对话框中的“关闭”框,则canner.exe会提示用户botulism.exe仍在运行(“僵尸中毒设置仍然打开,继续吗?”、“是的,我知道”或“不,我还没有完成”)。如果确认,canner.exe将关闭对话框并取消在步骤1中开始的原始FDA检查,并返回主窗口的消息循环。
  7. 当MsgWaitForMultipleObjects()指示botulism.exe完成时,canner.exe关闭对话框并继续正常进行步骤1中开始的FDA检查。

这样,如果一切正常而迅速地进行,交互很可能是无缝的,但是如果子进程出了问题,或者Z顺序发生了变化等等,就会清楚父进程等待的原因,以及用户需要做什么才能取消或继续他开始的任务。

票数 3
EN

Stack Overflow用户

发布于 2009-03-11 14:09:22

EnableWindow是正确的,这通常是消息框和其他“模式”窗口所做的事情。对于zorder更改,您可以拦截WM_WINDOWPOSCHANGING消息并设置SWP_NOZORDER标志以防止zorder更改。请确保只在设置EnableWindow(false)时才执行此操作。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/613513

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档