1 // Copyright (c) 2012 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.
5 #include "ui/base/win/shell.h"
8 #include <shlobj.h> // Must be before propkey.
12 #include "base/command_line.h"
13 #include "base/files/file_path.h"
14 #include "base/native_library.h"
15 #include "base/strings/string_util.h"
16 #include "base/win/metro.h"
17 #include "base/win/scoped_comptr.h"
18 #include "base/win/win_util.h"
19 #include "base/win/windows_version.h"
20 #include "ui/base/ui_base_switches.h"
27 // Show the Windows "Open With" dialog box to ask the user to pick an app to
28 // open the file with.
29 bool OpenItemWithExternalApp(const base::string16
& full_path
) {
30 SHELLEXECUTEINFO sei
= { sizeof(sei
) };
31 sei
.fMask
= SEE_MASK_FLAG_DDEWAIT
;
32 sei
.nShow
= SW_SHOWNORMAL
;
33 sei
.lpVerb
= L
"openas";
34 sei
.lpFile
= full_path
.c_str();
35 return (TRUE
== ::ShellExecuteExW(&sei
));
40 bool OpenAnyViaShell(const base::string16
& full_path
,
41 const base::string16
& directory
,
42 const base::string16
& args
,
44 SHELLEXECUTEINFO sei
= { sizeof(sei
) };
46 sei
.nShow
= SW_SHOWNORMAL
;
47 sei
.lpFile
= full_path
.c_str();
48 sei
.lpDirectory
= directory
.c_str();
50 sei
.lpParameters
= args
.c_str();
52 if (::ShellExecuteExW(&sei
))
54 if (::GetLastError() == ERROR_NO_ASSOCIATION
)
55 return OpenItemWithExternalApp(full_path
);
59 bool OpenItemViaShell(const base::FilePath
& full_path
) {
60 return OpenAnyViaShell(full_path
.value(), full_path
.DirName().value(),
64 bool PreventWindowFromPinning(HWND hwnd
) {
65 // This functionality is only available on Win7+. It also doesn't make sense
66 // to do this for Chrome Metro.
67 if (base::win::GetVersion() < base::win::VERSION_WIN7
||
68 base::win::IsMetroProcess())
70 base::win::ScopedComPtr
<IPropertyStore
> pps
;
71 HRESULT result
= SHGetPropertyStoreForWindow(
72 hwnd
, __uuidof(*pps
), reinterpret_cast<void**>(pps
.Receive()));
76 return base::win::SetBooleanValueForPropertyStore(
77 pps
, PKEY_AppUserModel_PreventPinning
, true);
80 // TODO(calamity): investigate moving this out of the UI thread as COM
81 // operations may spawn nested message loops which can cause issues.
82 void SetAppDetailsForWindow(const base::string16
& app_id
,
83 const base::string16
& app_icon
,
84 const base::string16
& relaunch_command
,
85 const base::string16
& relaunch_display_name
,
87 // This functionality is only available on Win7+. It also doesn't make sense
88 // to do this for Chrome Metro.
89 if (base::win::GetVersion() < base::win::VERSION_WIN7
||
90 base::win::IsMetroProcess())
92 base::win::ScopedComPtr
<IPropertyStore
> pps
;
93 HRESULT result
= SHGetPropertyStoreForWindow(
94 hwnd
, __uuidof(*pps
), reinterpret_cast<void**>(pps
.Receive()));
97 base::win::SetAppIdForPropertyStore(pps
, app_id
.c_str());
98 if (!app_icon
.empty()) {
99 base::win::SetStringValueForPropertyStore(
100 pps
, PKEY_AppUserModel_RelaunchIconResource
, app_icon
.c_str());
102 if (!relaunch_command
.empty()) {
103 base::win::SetStringValueForPropertyStore(
104 pps
, PKEY_AppUserModel_RelaunchCommand
, relaunch_command
.c_str());
106 if (!relaunch_display_name
.empty()) {
107 base::win::SetStringValueForPropertyStore(
108 pps
, PKEY_AppUserModel_RelaunchDisplayNameResource
,
109 relaunch_display_name
.c_str());
114 void SetAppIdForWindow(const base::string16
& app_id
, HWND hwnd
) {
115 SetAppDetailsForWindow(app_id
,
122 void SetAppIconForWindow(const base::string16
& app_icon
, HWND hwnd
) {
123 SetAppDetailsForWindow(base::string16(),
130 void SetRelaunchDetailsForWindow(const base::string16
& relaunch_command
,
131 const base::string16
& display_name
,
133 SetAppDetailsForWindow(base::string16(),
140 bool IsAeroGlassEnabled() {
141 // For testing in Win8 (where it is not possible to disable composition) the
142 // user can specify this command line switch to mimic the behavior. In this
143 // mode, cross-HWND transparency is not supported and various types of
144 // widgets fallback to more simplified rendering behavior.
145 if (CommandLine::ForCurrentProcess()->HasSwitch(
146 switches::kDisableDwmComposition
))
149 if (base::win::GetVersion() < base::win::VERSION_VISTA
)
151 // If composition is not enabled, we behave like on XP.
152 BOOL enabled
= FALSE
;
153 return SUCCEEDED(DwmIsCompositionEnabled(&enabled
)) && enabled
;