У меня есть приложение, которое работает постоянно.Пользователи могут открывать такие вещи, как «Параметры» или «Печать» и т. Д., Но часто уходят, оставляя их неиспользованными и открытыми.Следовательно, у меня теперь есть тайм-ауты для всего, но PrintDialog доставляет мне горе.
Поток в Получить модальный дескриптор диалога для PrintDialog очень помог мне и помог мне получить дескриптор PrintDialogубить это, но это не касается закрытия потомков PrintDialog, таких как «Предпочтения» и т. д.
Хотя user32.dll GetActiveWindow () правильно дает мне дескриптор PrintDialog, он, похоже, не получает дочерний объект Preferencesи возвращает значение 0.
public static IntPtr printDialogHandle;
[DllImport("user32.dll")]
static extern bool DestroyWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetActiveWindow();
private void btnPrint_Click(object sender, EventArgs e)
{
BeginInvoke(new MethodInvoker(TweakPrintDialog));
using (this.pdi = new PrintDialog())
{
this.pdi.PrinterSettings = Properties.Settings.Default.printSettings;
if (this.pdi.ShowDialog(this) == DialogResult.Cancel)
return;
//do the actual printing
printPages(false);
}
}
private void TweakPrintDialog()
{
// get handle for the just opened PrintDialog
printDialogHandle = GetActiveWindow();
// timeout timer
System.Windows.Forms.Timer tmr = new System.Windows.Forms.Timer();
tmr.Tick += new EventHandler(timer_Tick);
tmr.Interval = 60000;
tmr.Start();
}
private static void timer_Tick(object sender, EventArgs e)
{
System.Windows.Forms.Timer tmr = (System.Windows.Forms.Timer)sender;
tmr.Stop();
tmr.Dispose();
//any children? returns handles to heaps of unwanted stuff like controls
// System.Diagnostics.Process[] otherApps = System.Diagnostics.Process.GetProcessesByName("Printing Selected Papers");
// if (otherApps.Length == 0) return;
// if (otherApps[0] != null)
// {
// // var allChildWindows = new WindowHandleInfo(otherApps[0].MainWindowHandle).GetAllChildHandles();
// var allChildWindows = new WindowHandleInfo(printDialogHandle).GetAllChildHandles();
// }
// Works but unreliable. Other windows may be active by now
// SendKeys.Send("{ESC}");
// System.Threading.Thread.Sleep(50);
// SendKeys.Send("{ESC}");
// System.Threading.Thread.Sleep(50);
// SendKeys.Send("{ESC}");
// try and get handle to the PrintDialog Preferences form. Doesn't work, just returns 0
IntPtr child = GetActiveWindow();
if (child != printDialogHandle)
DestroyWindow(child);
// get rid of the PrintDialog
DestroyWindow(printDialogHandle);
}
Как найти любые дочерние дескрипторы PrintDialog, чтобы убить их с помощью user32.dll DestroyWindow () перед тем, как уничтожить сам PrintDialog?