#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2019 Nuclex Development Labs
This library is free software; you can redistribute it and/or
modify it under the terms of the IBM Common Public License as
published by the IBM Corporation; either version 1.0 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
IBM Common Public License for more details.
You should have received a copy of the IBM Common Public
License along with this library
*/
#endregion
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace Nuclex.Windows.Forms {
  /// 
  ///   Proxy stand-in to delay checking for the main window until it has been created
  /// 
  /// 
  ///   
  ///     The issue: when the view model for the main window is created, the main window
  ///     may only exist as a .NET object, without the underlying operating system window
  ///     (done in  checkable via
  ///     ). Not only will things
  ///     like  fail, we can't
  ///     even locate the main window at that stage.
  ///   
  ///   
  ///     Thus, if the main window cannot be found at the time a view model is created,
  ///     this late-checking synchronizer will jump into its place and re-check for
  ///     the main window only when something needs to be executed in the UI thread.
  ///   
  /// 
  class LateCheckedSynchronizer : ISynchronizeInvoke {
    /// Initializes a new late-checked main window synchronizer
    /// 
    public LateCheckedSynchronizer(Action uiContextFoundCallback) {
      this.uiContextFoundCallback = uiContextFoundCallback;
    }
    /// Finds the application's main window
    /// Main window of the application or null if none has been created
    /// 
    ///   The application's main window, if it has been created yet
    /// 
    public static Form GetMainWindow() {
      IntPtr mainWindowHandle = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
      // We can get two things: a list of all open windows and the handle of
      // the window that the process has registered as main window. Use the latter
      // to pick the correct window from the former.
      FormCollection openForms = Application.OpenForms;
      int openFormCount = openForms.Count;
      for(int index = 0; index < openFormCount; ++index) {
        Form form = openForms[index];
        IntPtr handle;
        if(form.InvokeRequired) {
          handle = (IntPtr)form.Invoke(new Func