Modal dialog block the GUI thread

在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;

 

你可能感兴趣的:(Modal dialog block the GUI thread)