12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef UI_SHELL_DIALOGS_BASE_SHELL_DIALOG_WIN_H_ 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define UI_SHELL_DIALOGS_BASE_SHELL_DIALOG_WIN_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shlobj.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/shell_dialogs/base_shell_dialog.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/shell_dialogs/shell_dialogs_export.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Thread; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A base class for all shell dialog implementations that handles showing a 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// shell dialog modally on its own thread. 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SHELL_DIALOGS_EXPORT BaseShellDialogImpl { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BaseShellDialogImpl(); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~BaseShellDialogImpl(); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Represents a run of a dialog. 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct RunState { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Owning HWND, may be null. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HWND owner; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Thread dialog is run on. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread* dialog_thread; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called at the beginning of a modal dialog run. Disables the owner window 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and tracks it. Returns the message loop of the thread that the dialog will 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be run on. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunState BeginRun(HWND owner); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cleans up after a dialog run. If the run_state has a valid HWND this makes 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sure that the window is enabled. This is essential because BeginRun 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // aggressively guards against multiple modal dialogs per HWND. Must be called 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the UI thread after the result of the dialog has been determined. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In addition this deletes the Thread in RunState. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EndRun(RunState run_state); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if a modal shell dialog is currently active for the specified 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // owner. Must be called on the UI thread. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsRunningDialogForOwner(HWND owner) const; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disables the window |owner|. Can be run from either the ui or the dialog 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread. Can be called on either the UI or the dialog thread. This function 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is called on the dialog thread after the modal Windows Common dialog 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // functions return because Windows automatically re-enables the owning 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // window when those functions return, but we don't actually want them to be 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // re-enabled until the response of the dialog propagates back to the UI 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread, so we disable the owner manually after the Common dialog function 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DisableOwner(HWND owner); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::set<HWND> Owners; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a thread to run a shell dialog on. Each dialog requires its own 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread otherwise in some situations where a singleton owns a single 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instance of this object we can have a situation where a modal dialog in 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // one window blocks the appearance of a modal dialog in another. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static base::Thread* CreateDialogThread(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enables the window |owner_|. Can only be run from the ui thread. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EnableOwner(HWND owner); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A list of windows that currently own active shell dialogs for this 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instance. For example, if the DownloadManager owns an instance of this 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object and there are two browser windows open both with Save As dialog 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // boxes active, this list will consist of the two browser windows' HWNDs. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The derived class must call EndRun once the dialog is done showing to 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // remove the owning HWND from this list. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This object is static since it is maintained for all instances of this 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object - i.e. you can't have two file pickers open for the 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // same owner, even though they might be represented by different instances 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of this object. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This set only contains non-null HWNDs. NULL hwnds are not added to this 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // list. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static Owners owners_; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int instance_count_; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BaseShellDialogImpl); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // UI_SHELL_DIALOGS_BASE_SHELL_DIALOG_WIN_H_ 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 99