• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 #include "chrome/browser/ui/views/elevation_icon_setter.h"
6 
7 #include "base/task_runner_util.h"
8 #include "content/public/browser/browser_thread.h"
9 #include "ui/views/controls/button/label_button.h"
10 
11 #if defined(OS_WIN)
12 #include <windows.h>
13 #include <shellapi.h>
14 #include "base/win/win_util.h"
15 #include "base/win/windows_version.h"
16 #include "ui/gfx/icon_util.h"
17 #endif
18 
19 
20 // Helpers --------------------------------------------------------------------
21 
22 namespace {
23 
GetElevationIcon()24 scoped_ptr<SkBitmap> GetElevationIcon() {
25   scoped_ptr<SkBitmap> icon;
26 #if defined(OS_WIN)
27   if ((base::win::GetVersion() < base::win::VERSION_VISTA) ||
28       !base::win::UserAccountControlIsEnabled())
29     return icon.Pass();
30 
31   SHSTOCKICONINFO icon_info = { sizeof(SHSTOCKICONINFO) };
32   typedef HRESULT (STDAPICALLTYPE *GetStockIconInfo)(SHSTOCKICONID,
33                                                      UINT,
34                                                      SHSTOCKICONINFO*);
35   // Even with the runtime guard above, we have to use GetProcAddress()
36   // here, because otherwise the loader will try to resolve the function
37   // address on startup, which will break on XP.
38   GetStockIconInfo func = reinterpret_cast<GetStockIconInfo>(
39       GetProcAddress(GetModuleHandle(L"shell32.dll"), "SHGetStockIconInfo"));
40   // TODO(pkasting): Run on a background thread since this call spins a nested
41   // message loop.
42   if (FAILED((*func)(SIID_SHIELD, SHGSI_ICON | SHGSI_SMALLICON, &icon_info)))
43     return icon.Pass();
44 
45   icon.reset(IconUtil::CreateSkBitmapFromHICON(
46       icon_info.hIcon,
47       gfx::Size(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON))));
48   DestroyIcon(icon_info.hIcon);
49 #endif
50   return icon.Pass();
51 }
52 
53 }  // namespace
54 
55 
56 // ElevationIconSetter --------------------------------------------------------
57 
ElevationIconSetter(views::LabelButton * button)58 ElevationIconSetter::ElevationIconSetter(views::LabelButton* button)
59     : button_(button),
60       weak_factory_(this) {
61   base::PostTaskAndReplyWithResult(
62       content::BrowserThread::GetBlockingPool(),
63       FROM_HERE,
64       base::Bind(&GetElevationIcon),
65       base::Bind(&ElevationIconSetter::SetButtonIcon,
66                  weak_factory_.GetWeakPtr()));
67 }
68 
~ElevationIconSetter()69 ElevationIconSetter::~ElevationIconSetter() {
70 }
71 
SetButtonIcon(scoped_ptr<SkBitmap> icon)72 void ElevationIconSetter::SetButtonIcon(scoped_ptr<SkBitmap> icon) {
73   if (icon) {
74     button_->SetImage(views::Button::STATE_NORMAL,
75                       gfx::ImageSkia::CreateFrom1xBitmap(*icon));
76     button_->SizeToPreferredSize();
77     if (button_->parent())
78       button_->parent()->Layout();
79   }
80 }
81