Home | History | Annotate | Download | only in shell_dialogs
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef UI_SHELL_DIALOGS_BASE_SHELL_DIALOG_WIN_H_
      6 #define UI_SHELL_DIALOGS_BASE_SHELL_DIALOG_WIN_H_
      7 
      8 #include <shlobj.h>
      9 #include <set>
     10 
     11 #include "ui/shell_dialogs/base_shell_dialog.h"
     12 #include "ui/shell_dialogs/shell_dialogs_export.h"
     13 
     14 namespace base {
     15 class Thread;
     16 }
     17 
     18 namespace ui {
     19 
     20 ///////////////////////////////////////////////////////////////////////////////
     21 // A base class for all shell dialog implementations that handles showing a
     22 // shell dialog modally on its own thread.
     23 class SHELL_DIALOGS_EXPORT BaseShellDialogImpl {
     24  public:
     25   BaseShellDialogImpl();
     26   virtual ~BaseShellDialogImpl();
     27 
     28  protected:
     29   // Represents a run of a dialog.
     30   struct RunState {
     31     // Owning HWND, may be null.
     32     HWND owner;
     33 
     34     // Thread dialog is run on.
     35     base::Thread* dialog_thread;
     36   };
     37 
     38   // Called at the beginning of a modal dialog run. Disables the owner window
     39   // and tracks it. Returns the message loop of the thread that the dialog will
     40   // be run on.
     41   RunState BeginRun(HWND owner);
     42 
     43   // Cleans up after a dialog run. If the run_state has a valid HWND this makes
     44   // sure that the window is enabled. This is essential because BeginRun
     45   // aggressively guards against multiple modal dialogs per HWND. Must be called
     46   // on the UI thread after the result of the dialog has been determined.
     47   //
     48   // In addition this deletes the Thread in RunState.
     49   void EndRun(RunState run_state);
     50 
     51   // Returns true if a modal shell dialog is currently active for the specified
     52   // owner. Must be called on the UI thread.
     53   bool IsRunningDialogForOwner(HWND owner) const;
     54 
     55   // Disables the window |owner|. Can be run from either the ui or the dialog
     56   // thread. Can be called on either the UI or the dialog thread. This function
     57   // is called on the dialog thread after the modal Windows Common dialog
     58   // functions return because Windows automatically re-enables the owning
     59   // window when those functions return, but we don't actually want them to be
     60   // re-enabled until the response of the dialog propagates back to the UI
     61   // thread, so we disable the owner manually after the Common dialog function
     62   // returns.
     63   void DisableOwner(HWND owner);
     64 
     65  private:
     66   typedef std::set<HWND> Owners;
     67 
     68   // Creates a thread to run a shell dialog on. Each dialog requires its own
     69   // thread otherwise in some situations where a singleton owns a single
     70   // instance of this object we can have a situation where a modal dialog in
     71   // one window blocks the appearance of a modal dialog in another.
     72   static base::Thread* CreateDialogThread();
     73 
     74   // Enables the window |owner_|. Can only be run from the ui thread.
     75   void EnableOwner(HWND owner);
     76 
     77   // A list of windows that currently own active shell dialogs for this
     78   // instance. For example, if the DownloadManager owns an instance of this
     79   // object and there are two browser windows open both with Save As dialog
     80   // boxes active, this list will consist of the two browser windows' HWNDs.
     81   // The derived class must call EndRun once the dialog is done showing to
     82   // remove the owning HWND from this list.
     83   // This object is static since it is maintained for all instances of this
     84   // object - i.e. you can't have two file pickers open for the
     85   // same owner, even though they might be represented by different instances
     86   // of this object.
     87   // This set only contains non-null HWNDs. NULL hwnds are not added to this
     88   // list.
     89   static Owners owners_;
     90   static int instance_count_;
     91 
     92   DISALLOW_COPY_AND_ASSIGN(BaseShellDialogImpl);
     93 };
     94 
     95 }  // namespace ui
     96 
     97 #endif  // UI_SHELL_DIALOGS_BASE_SHELL_DIALOG_WIN_H_
     98 
     99