0

I have an app that runs continuously. Users can open things like 'Options' or 'Print' etc but often walk away leaving them unused and open. Hence I now have timeouts on everything but the PrintDialog is giving me grief.

The thread at Get modal dialog handle for PrintDialog has been a huge help and gets me the PrintDialog handle so I can kill that off but it does not address closing the PrintDialog children such as 'Preferences' etc.

Although user32.dll GetActiveWindow() correctly gives me the handle to the PrintDialog, it does not seem to get the Preferences child and returns a value of 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);
}

How can I find any PrintDialog children handles so as to kill them via user32.dll DestroyWindow() before I kill off the PrintDialog itself?

Malcom
  • 61
  • 1
  • 9
  • Find general "kill the dialog" code in [this post](https://stackoverflow.com/a/12092142/17034). It looks at all the windows so finds the "Printing preferences" dialog as well. There is however a wrinkle, the printer driver manufacturer *might* have used a custom toolkit to implement that dialog. Have a look-see with the 64-bit version of Spy++. – Hans Passant May 23 '19 at 23:58
  • Thanks Hans. I gave the links DialogCloser class and the CloseAllDialogs a go but again they can't deal with the dialog children. Once you close the children, the main dialogue quits. – Malcom May 24 '19 at 02:26

0 Answers0