15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved. 25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Use of this source code is governed by a BSD-style license that can be 35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// found in the LICENSE file. 45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/ui/views/elevation_icon_setter.h" 65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/task_runner_util.h" 85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/public/browser/browser_thread.h" 95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/views/controls/button/label_button.h" 105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#if defined(OS_WIN) 125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <windows.h> 135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <shellapi.h> 145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/win/win_util.h" 155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/win/windows_version.h" 165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/gfx/icon_util.h" 175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif 185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Helpers -------------------------------------------------------------------- 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace { 235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuscoped_ptr<SkBitmap> GetElevationIcon() { 255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<SkBitmap> icon; 265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#if defined(OS_WIN) 275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if ((base::win::GetVersion() < base::win::VERSION_VISTA) || 285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu !base::win::UserAccountControlIsEnabled()) 295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return icon.Pass(); 305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SHSTOCKICONINFO icon_info = { sizeof(SHSTOCKICONINFO) }; 325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typedef HRESULT (STDAPICALLTYPE *GetStockIconInfo)(SHSTOCKICONID, 335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UINT, 345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SHSTOCKICONINFO*); 355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Even with the runtime guard above, we have to use GetProcAddress() 365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // here, because otherwise the loader will try to resolve the function 375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // address on startup, which will break on XP. 385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu GetStockIconInfo func = reinterpret_cast<GetStockIconInfo>( 395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu GetProcAddress(GetModuleHandle(L"shell32.dll"), "SHGetStockIconInfo")); 405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // TODO(pkasting): Run on a background thread since this call spins a nested 415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // message loop. 425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (FAILED((*func)(SIID_SHIELD, SHGSI_ICON | SHGSI_SMALLICON, &icon_info))) 435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return icon.Pass(); 445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu icon.reset(IconUtil::CreateSkBitmapFromHICON( 465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu icon_info.hIcon, 475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::Size(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)))); 485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DestroyIcon(icon_info.hIcon); 495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif 505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return icon.Pass(); 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} // namespace 545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// ElevationIconSetter -------------------------------------------------------- 575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuElevationIconSetter::ElevationIconSetter(views::LabelButton* button) 595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : button_(button), 605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu weak_factory_(this) { 615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::PostTaskAndReplyWithResult( 625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu content::BrowserThread::GetBlockingPool(), 635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FROM_HERE, 645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&GetElevationIcon), 655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&ElevationIconSetter::SetButtonIcon, 665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu weak_factory_.GetWeakPtr())); 675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuElevationIconSetter::~ElevationIconSetter() { 705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ElevationIconSetter::SetButtonIcon(scoped_ptr<SkBitmap> icon) { 735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (icon) { 745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu button_->SetImage(views::Button::STATE_NORMAL, 755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::ImageSkia::CreateFrom1xBitmap(*icon)); 765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu button_->SizeToPreferredSize(); 775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (button_->parent()) 785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu button_->parent()->Layout(); 795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 81