惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
大猫的无限游戏
大猫的无限游戏
B
Blog
阮一峰的网络日志
阮一峰的网络日志
IT之家
IT之家
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
Jina AI
Jina AI
博客园 - 聂微东
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
L
LangChain Blog
M
MIT News - Artificial intelligence
Blog — PlanetScale
Blog — PlanetScale
腾讯CDC
酷 壳 – CoolShell
酷 壳 – CoolShell
Y
Y Combinator Blog
F
Fortinet All Blogs
H
Help Net Security
B
Blog RSS Feed
J
Java Code Geeks
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Apple Machine Learning Research
Apple Machine Learning Research
S
SegmentFault 最新的问题

博客园 - 无锋不起浪

沪牌-上海牌照-拍牌经验分享: 我是如何三次拍中的? 沪牌学院-沪拍拍课堂4: 实拍前的演练 沪牌学院-沪拍拍课堂3: 网络优化 沪牌学院-沪拍拍课堂2: 出价策略 沪牌学院-沪拍拍课堂1: 估价策略 沪牌学院-沪拍拍课堂: 2018年4月回顾 (内附幺蛾子应对策略) 如何将 DVD 转成 ISO 雅虎天气-城市代码列表 发布 PM2.5 数据的城市列表 中国天气网城市代码 Install MongoDB driver for PHP on XAMPP for Mac OSX jQuery 语法总结和注意事项 XCode 4 编译错误大全整理 Xcode 快捷键大全 ODA(Open Design Alliance)介绍 VMWare安装黑苹果Mac OS C# 字符串驻留机制 AutoCAD WS for iPhone, iPod toch, and iPad NAnt.Core.Ext: MailLogger2 and MailTask2
Modal dialog block the GUI thread
无锋不起浪 · 2011-07-30 · via 博客园 - 无锋不起浪

在GUI中,如果你使用了模态窗口,并且想从模态窗口中暂时中断,回到主窗口进行一些交互操作,然后再继续模态窗口中的任务,该如何操作?典型的就是 modal progress bar。也许你第一个会想到把窗口 Hide,

modalForm.Hide();
while(...) //等待主窗口的交互结果
{

    ... 

    Application.DoEvent();

}

modalForm.ShowDialog(); //Continue 

结果可能会让你失望,modalForm是Hide 了,但焦点却无论如何不能回到主窗口了。

我们可以通过win32的API 将焦点重新设到主窗口。首先要得到modalForm 的Handle,当然这个也可用win32 API。 

/// <summary>
/// The FindWindow function retrieves the handle to the top-level window whose class name and window name match the specified strings. 
/// This function does not search child windows.
/// </summary>
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

 1 string progressBarText = "ModelDialog";
 2 IntPtr progressBar =Win32Wrapper.FindWindowEx(IntPtr.Zero, IntPtr.Zero, null, progressBarText);
 3 
 4 // 1. Hide the modal progress bar.
 5 Win32Wrapper.ShowWindow(progressBar, Win32Wrapper.WindowShowStyle.Hide);
 6 
 7 // 2. Send focus to AutoCAD main window.
 8 IntPtr mainWindows = Autodesk.AutoCAD.ApplicationServices.Application.MainWindow.Handle;
 9 
10 Win32Wrapper.EnableWindow(mainWindows, true);
11 Win32Wrapper.SetFocus(mainWindows);
12 Win32Wrapper.ShowWindow(mainWindows, Win32Wrapper.WindowShowStyle.Show);
13 
14 // 3. Wait for user's interaction.
15 while (...)
16 {
17     // Do interaction
18 }
19 
20 // 4. Show the modal progress bar again.
21 Win32Wrapper.ShowWindow(progressBar, Win32Wrapper.WindowShowStyle.Show);
22 Win32Wrapper.SetFocus(progressBar);

在ObjectARX中其实已经考虑到这种情况的应用了,并且提供了相应的API,这个就简单多了。 

1 // Re-enable the AutoCAD main window by using StartUserInteraction
2 Autodesk.AutoCAD.ApplicationServices.Document doc =
3         Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
4 Editor ed = doc.Editor;
5 interaction = ed.StartUserInteraction(System.Windows.Forms.Control);
6 //...主窗口中交互操作
7 interaction.Dispose();

模态窗口中的操作可能会和当前的Document 相关,你当然不希望用户在中间的交互过程中更改当前活动的Document,否则的话会引起Crash,那么ObjectARX 中的 Application.DocumentManager.DocumentActivationEnabled 就是控制是否允许用户更改活动窗口(Switch drawing)的。

Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.DocumentActivationEnabled = enable;