| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/base/win/shell.h" | 5 #include "ui/base/win/shell.h" |
| 6 | 6 |
| 7 #include <dwmapi.h> | 7 #include <dwmapi.h> |
| 8 #include <shlobj.h> // Must be before propkey. | 8 #include <shlobj.h> // Must be before propkey. |
| 9 #include <propkey.h> | 9 #include <propkey.h> |
| 10 #include <shellapi.h> | 10 #include <shellapi.h> |
| 11 | 11 |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
| 14 #include "base/native_library.h" | 14 #include "base/native_library.h" |
| 15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 16 #include "base/win/metro.h" | 16 #include "base/win/metro.h" |
| 17 #include "base/win/scoped_comptr.h" | 17 #include "base/win/scoped_comptr.h" |
| 18 #include "base/win/win_util.h" | 18 #include "base/win/win_util.h" |
| 19 #include "base/win/windows_version.h" | 19 #include "base/win/windows_version.h" |
| 20 #include "ui/base/ui_base_switches.h" | 20 #include "ui/base/ui_base_switches.h" |
| 21 | 21 |
| 22 namespace ui { | 22 namespace ui { |
| 23 namespace win { | 23 namespace win { |
| 24 | 24 |
| 25 // Show the Windows "Open With" dialog box to ask the user to pick an app to | 25 // Show the Windows "Open With" dialog box to ask the user to pick an app to |
| 26 // open the file with. | 26 // open the file with. |
| 27 bool OpenItemWithExternalApp(const string16& full_path) { | 27 bool OpenItemWithExternalApp(const base::string16& full_path) { |
| 28 SHELLEXECUTEINFO sei = { sizeof(sei) }; | 28 SHELLEXECUTEINFO sei = { sizeof(sei) }; |
| 29 sei.fMask = SEE_MASK_FLAG_DDEWAIT; | 29 sei.fMask = SEE_MASK_FLAG_DDEWAIT; |
| 30 sei.nShow = SW_SHOWNORMAL; | 30 sei.nShow = SW_SHOWNORMAL; |
| 31 sei.lpVerb = L"openas"; | 31 sei.lpVerb = L"openas"; |
| 32 sei.lpFile = full_path.c_str(); | 32 sei.lpFile = full_path.c_str(); |
| 33 return (TRUE == ::ShellExecuteExW(&sei)); | 33 return (TRUE == ::ShellExecuteExW(&sei)); |
| 34 } | 34 } |
| 35 | 35 |
| 36 bool OpenAnyViaShell(const string16& full_path, | 36 bool OpenAnyViaShell(const base::string16& full_path, |
| 37 const string16& directory, | 37 const base::string16& directory, |
| 38 const string16& args, | 38 const base::string16& args, |
| 39 DWORD mask) { | 39 DWORD mask) { |
| 40 SHELLEXECUTEINFO sei = { sizeof(sei) }; | 40 SHELLEXECUTEINFO sei = { sizeof(sei) }; |
| 41 sei.fMask = mask; | 41 sei.fMask = mask; |
| 42 sei.nShow = SW_SHOWNORMAL; | 42 sei.nShow = SW_SHOWNORMAL; |
| 43 sei.lpFile = full_path.c_str(); | 43 sei.lpFile = full_path.c_str(); |
| 44 sei.lpDirectory = directory.c_str(); | 44 sei.lpDirectory = directory.c_str(); |
| 45 if (!args.empty()) | 45 if (!args.empty()) |
| 46 sei.lpParameters = args.c_str(); | 46 sei.lpParameters = args.c_str(); |
| 47 | 47 |
| 48 if (::ShellExecuteExW(&sei)) | 48 if (::ShellExecuteExW(&sei)) |
| 49 return true; | 49 return true; |
| 50 if (::GetLastError() == ERROR_NO_ASSOCIATION) | 50 if (::GetLastError() == ERROR_NO_ASSOCIATION) |
| 51 return OpenItemWithExternalApp(full_path); | 51 return OpenItemWithExternalApp(full_path); |
| 52 return false; | 52 return false; |
| 53 } | 53 } |
| 54 | 54 |
| 55 bool OpenItemViaShell(const base::FilePath& full_path) { | 55 bool OpenItemViaShell(const base::FilePath& full_path) { |
| 56 return OpenAnyViaShell(full_path.value(), full_path.DirName().value(), | 56 return OpenAnyViaShell(full_path.value(), full_path.DirName().value(), |
| 57 string16(), 0); | 57 base::string16(), 0); |
| 58 } | 58 } |
| 59 | 59 |
| 60 bool OpenItemViaShellNoZoneCheck(const base::FilePath& full_path) { | 60 bool OpenItemViaShellNoZoneCheck(const base::FilePath& full_path) { |
| 61 return OpenAnyViaShell(full_path.value(), string16(), string16(), | 61 return OpenAnyViaShell(full_path.value(), base::string16(), base::string16(), |
| 62 SEE_MASK_NOZONECHECKS | SEE_MASK_FLAG_DDEWAIT); | 62 SEE_MASK_NOZONECHECKS | SEE_MASK_FLAG_DDEWAIT); |
| 63 } | 63 } |
| 64 | 64 |
| 65 bool PreventWindowFromPinning(HWND hwnd) { | 65 bool PreventWindowFromPinning(HWND hwnd) { |
| 66 // This functionality is only available on Win7+. It also doesn't make sense | 66 // This functionality is only available on Win7+. It also doesn't make sense |
| 67 // to do this for Chrome Metro. | 67 // to do this for Chrome Metro. |
| 68 if (base::win::GetVersion() < base::win::VERSION_WIN7 || | 68 if (base::win::GetVersion() < base::win::VERSION_WIN7 || |
| 69 base::win::IsMetroProcess()) | 69 base::win::IsMetroProcess()) |
| 70 return false; | 70 return false; |
| 71 base::win::ScopedComPtr<IPropertyStore> pps; | 71 base::win::ScopedComPtr<IPropertyStore> pps; |
| 72 HRESULT result = SHGetPropertyStoreForWindow( | 72 HRESULT result = SHGetPropertyStoreForWindow( |
| 73 hwnd, __uuidof(*pps), reinterpret_cast<void**>(pps.Receive())); | 73 hwnd, __uuidof(*pps), reinterpret_cast<void**>(pps.Receive())); |
| 74 if (FAILED(result)) | 74 if (FAILED(result)) |
| 75 return false; | 75 return false; |
| 76 | 76 |
| 77 return base::win::SetBooleanValueForPropertyStore( | 77 return base::win::SetBooleanValueForPropertyStore( |
| 78 pps, PKEY_AppUserModel_PreventPinning, true); | 78 pps, PKEY_AppUserModel_PreventPinning, true); |
| 79 } | 79 } |
| 80 | 80 |
| 81 // TODO(calamity): investigate moving this out of the UI thread as COM | 81 // TODO(calamity): investigate moving this out of the UI thread as COM |
| 82 // operations may spawn nested message loops which can cause issues. | 82 // operations may spawn nested message loops which can cause issues. |
| 83 void SetAppDetailsForWindow(const string16& app_id, | 83 void SetAppDetailsForWindow(const base::string16& app_id, |
| 84 const string16& app_icon, | 84 const base::string16& app_icon, |
| 85 const string16& relaunch_command, | 85 const base::string16& relaunch_command, |
| 86 const string16& relaunch_display_name, | 86 const base::string16& relaunch_display_name, |
| 87 HWND hwnd) { | 87 HWND hwnd) { |
| 88 // This functionality is only available on Win7+. It also doesn't make sense | 88 // This functionality is only available on Win7+. It also doesn't make sense |
| 89 // to do this for Chrome Metro. | 89 // to do this for Chrome Metro. |
| 90 if (base::win::GetVersion() < base::win::VERSION_WIN7 || | 90 if (base::win::GetVersion() < base::win::VERSION_WIN7 || |
| 91 base::win::IsMetroProcess()) | 91 base::win::IsMetroProcess()) |
| 92 return; | 92 return; |
| 93 base::win::ScopedComPtr<IPropertyStore> pps; | 93 base::win::ScopedComPtr<IPropertyStore> pps; |
| 94 HRESULT result = SHGetPropertyStoreForWindow( | 94 HRESULT result = SHGetPropertyStoreForWindow( |
| 95 hwnd, __uuidof(*pps), reinterpret_cast<void**>(pps.Receive())); | 95 hwnd, __uuidof(*pps), reinterpret_cast<void**>(pps.Receive())); |
| 96 if (S_OK == result) { | 96 if (S_OK == result) { |
| 97 if (!app_id.empty()) | 97 if (!app_id.empty()) |
| 98 base::win::SetAppIdForPropertyStore(pps, app_id.c_str()); | 98 base::win::SetAppIdForPropertyStore(pps, app_id.c_str()); |
| 99 if (!app_icon.empty()) { | 99 if (!app_icon.empty()) { |
| 100 base::win::SetStringValueForPropertyStore( | 100 base::win::SetStringValueForPropertyStore( |
| 101 pps, PKEY_AppUserModel_RelaunchIconResource, app_icon.c_str()); | 101 pps, PKEY_AppUserModel_RelaunchIconResource, app_icon.c_str()); |
| 102 } | 102 } |
| 103 if (!relaunch_command.empty()) { | 103 if (!relaunch_command.empty()) { |
| 104 base::win::SetStringValueForPropertyStore( | 104 base::win::SetStringValueForPropertyStore( |
| 105 pps, PKEY_AppUserModel_RelaunchCommand, relaunch_command.c_str()); | 105 pps, PKEY_AppUserModel_RelaunchCommand, relaunch_command.c_str()); |
| 106 } | 106 } |
| 107 if (!relaunch_display_name.empty()) { | 107 if (!relaunch_display_name.empty()) { |
| 108 base::win::SetStringValueForPropertyStore( | 108 base::win::SetStringValueForPropertyStore( |
| 109 pps, PKEY_AppUserModel_RelaunchDisplayNameResource, | 109 pps, PKEY_AppUserModel_RelaunchDisplayNameResource, |
| 110 relaunch_display_name.c_str()); | 110 relaunch_display_name.c_str()); |
| 111 } | 111 } |
| 112 } | 112 } |
| 113 } | 113 } |
| 114 | 114 |
| 115 void SetAppIdForWindow(const string16& app_id, HWND hwnd) { | 115 void SetAppIdForWindow(const base::string16& app_id, HWND hwnd) { |
| 116 SetAppDetailsForWindow(app_id, string16(), string16(), string16(), hwnd); | 116 SetAppDetailsForWindow(app_id, |
| 117 base::string16(), |
| 118 base::string16(), |
| 119 base::string16(), |
| 120 hwnd); |
| 117 } | 121 } |
| 118 | 122 |
| 119 void SetAppIconForWindow(const string16& app_icon, HWND hwnd) { | 123 void SetAppIconForWindow(const base::string16& app_icon, HWND hwnd) { |
| 120 SetAppDetailsForWindow(string16(), app_icon, string16(), string16(), hwnd); | 124 SetAppDetailsForWindow(base::string16(), |
| 125 app_icon, |
| 126 base::string16(), |
| 127 base::string16(), |
| 128 hwnd); |
| 121 } | 129 } |
| 122 | 130 |
| 123 void SetRelaunchDetailsForWindow(const string16& relaunch_command, | 131 void SetRelaunchDetailsForWindow(const base::string16& relaunch_command, |
| 124 const string16& display_name, | 132 const base::string16& display_name, |
| 125 HWND hwnd) { | 133 HWND hwnd) { |
| 126 SetAppDetailsForWindow(string16(), | 134 SetAppDetailsForWindow(base::string16(), |
| 127 string16(), | 135 base::string16(), |
| 128 relaunch_command, | 136 relaunch_command, |
| 129 display_name, | 137 display_name, |
| 130 hwnd); | 138 hwnd); |
| 131 } | 139 } |
| 132 | 140 |
| 133 bool IsAeroGlassEnabled() { | 141 bool IsAeroGlassEnabled() { |
| 134 // For testing in Win8 (where it is not possible to disable composition) the | 142 // For testing in Win8 (where it is not possible to disable composition) the |
| 135 // user can specify this command line switch to mimic the behavior. In this | 143 // user can specify this command line switch to mimic the behavior. In this |
| 136 // mode, cross-HWND transparency is not supported and various types of | 144 // mode, cross-HWND transparency is not supported and various types of |
| 137 // widgets fallback to more simplified rendering behavior. | 145 // widgets fallback to more simplified rendering behavior. |
| 138 if (CommandLine::ForCurrentProcess()->HasSwitch( | 146 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 139 switches::kDisableDwmComposition)) | 147 switches::kDisableDwmComposition)) |
| 140 return false; | 148 return false; |
| 141 | 149 |
| 142 if (base::win::GetVersion() < base::win::VERSION_VISTA) | 150 if (base::win::GetVersion() < base::win::VERSION_VISTA) |
| 143 return false; | 151 return false; |
| 144 // If composition is not enabled, we behave like on XP. | 152 // If composition is not enabled, we behave like on XP. |
| 145 BOOL enabled = FALSE; | 153 BOOL enabled = FALSE; |
| 146 return SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled; | 154 return SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled; |
| 147 } | 155 } |
| 148 | 156 |
| 149 } // namespace win | 157 } // namespace win |
| 150 } // namespace ui | 158 } // namespace ui |
| OLD | NEW |