15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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)#include "ui/shell_dialogs/base_shell_dialog_win.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_com_initializer.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BaseShellDialogImpl::Owners BaseShellDialogImpl::owners_; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BaseShellDialogImpl::instance_count_ = 0; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BaseShellDialogImpl::BaseShellDialogImpl() { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++instance_count_; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BaseShellDialogImpl::~BaseShellDialogImpl() { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All runs should be complete by the time this is called! 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (--instance_count_ == 0) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(owners_.empty()); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BaseShellDialogImpl::RunState BaseShellDialogImpl::BeginRun(HWND owner) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cannot run a modal shell dialog if one is already running for this owner. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsRunningDialogForOwner(owner)); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The owner must be a top level window, otherwise we could end up with two 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // entries in our map for the same top level window. 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!owner || owner == GetAncestor(owner, GA_ROOT)); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunState run_state; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) run_state.dialog_thread = CreateDialogThread(); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) run_state.owner = owner; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (owner) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owners_.insert(owner); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DisableOwner(owner); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return run_state; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BaseShellDialogImpl::EndRun(RunState run_state) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (run_state.owner) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsRunningDialogForOwner(run_state.owner)); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnableOwner(run_state.owner); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(owners_.find(run_state.owner) != owners_.end()); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owners_.erase(run_state.owner); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(run_state.dialog_thread); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete run_state.dialog_thread; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseShellDialogImpl::IsRunningDialogForOwner(HWND owner) const { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (owner && owners_.find(owner) != owners_.end()); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BaseShellDialogImpl::DisableOwner(HWND owner) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsWindow(owner)) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnableWindow(owner, FALSE); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Thread* BaseShellDialogImpl::CreateDialogThread() { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread* thread = new base::Thread("Chrome_ShellDialogThread"); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread->init_com_with_mta(false); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool started = thread->Start(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(started); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return thread; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BaseShellDialogImpl::EnableOwner(HWND owner) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsWindow(owner)) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnableWindow(owner, TRUE); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 79