base_shell_dialog_win.h 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. #ifndef UI_SHELL_DIALOGS_BASE_SHELL_DIALOG_WIN_H_
  5. #define UI_SHELL_DIALOGS_BASE_SHELL_DIALOG_WIN_H_
  6. #include <shlobj.h>
  7. #include <memory>
  8. #include <set>
  9. #include "base/memory/scoped_refptr.h"
  10. #include "ui/shell_dialogs/base_shell_dialog.h"
  11. #include "ui/shell_dialogs/shell_dialogs_export.h"
  12. namespace base {
  13. class SingleThreadTaskRunner;
  14. }
  15. namespace ui {
  16. ///////////////////////////////////////////////////////////////////////////////
  17. // A base class for all shell dialog implementations that handles showing a
  18. // shell dialog modally on its own thread.
  19. class SHELL_DIALOGS_EXPORT BaseShellDialogImpl {
  20. public:
  21. BaseShellDialogImpl();
  22. BaseShellDialogImpl(const BaseShellDialogImpl&) = delete;
  23. BaseShellDialogImpl& operator=(const BaseShellDialogImpl&) = delete;
  24. virtual ~BaseShellDialogImpl();
  25. // Disables the window |owner|. Can be run from either the ui or the dialog
  26. // thread. This function is called on the dialog thread after the modal
  27. // Windows Common dialog functions return because Windows automatically
  28. // re-enables the owning window when those functions return, but we don't
  29. // actually want them to be re-enabled until the response of the dialog
  30. // propagates back to the UI thread, so we disable the owner manually after
  31. // the Common dialog function returns.
  32. static void DisableOwner(HWND owner);
  33. protected:
  34. // Represents a run of a dialog.
  35. class SHELL_DIALOGS_EXPORT RunState {
  36. public:
  37. RunState();
  38. RunState(const RunState&) = delete;
  39. RunState& operator=(const RunState&) = delete;
  40. ~RunState();
  41. // Owning HWND, may be null.
  42. HWND owner;
  43. // Dedicated sequence on which the dialog runs.
  44. scoped_refptr<base::SingleThreadTaskRunner> dialog_task_runner;
  45. };
  46. // Called at the beginning of a modal dialog run. Disables the owner window
  47. // and tracks it. Returns the dedicated single-threaded sequence that the
  48. // dialog will be run on.
  49. std::unique_ptr<RunState> BeginRun(HWND owner);
  50. // Cleans up after a dialog run. If the run_state has a valid HWND this makes
  51. // sure that the window is enabled. This is essential because BeginRun
  52. // aggressively guards against multiple modal dialogs per HWND. Must be called
  53. // on the UI thread after the result of the dialog has been determined.
  54. void EndRun(std::unique_ptr<RunState> run_state);
  55. // Returns true if a modal shell dialog is currently active for the specified
  56. // owner. Must be called on the UI thread.
  57. bool IsRunningDialogForOwner(HWND owner) const;
  58. private:
  59. typedef std::set<HWND> Owners;
  60. // A list of windows that currently own active shell dialogs for this
  61. // instance. For example, if the DownloadManager owns an instance of this
  62. // object and there are two browser windows open both with Save As dialog
  63. // boxes active, this list will consist of the two browser windows' HWNDs.
  64. // The derived class must call EndRun once the dialog is done showing to
  65. // remove the owning HWND from this list.
  66. // This object is static since it is maintained for all instances of this
  67. // object - i.e. you can't have two file pickers open for the
  68. // same owner, even though they might be represented by different instances
  69. // of this object.
  70. // This set only contains non-null HWNDs. NULL hwnds are not added to this
  71. // list.
  72. static Owners& GetOwners();
  73. static int instance_count_;
  74. };
  75. } // namespace ui
  76. #endif // UI_SHELL_DIALOGS_BASE_SHELL_DIALOG_WIN_H_