From 4a0765a6e06b2e188c68999a52b3fea976e72c40 Mon Sep 17 00:00:00 2001 From: "ben@chromium.org" Date: Fri, 8 May 2009 23:12:25 +0000 Subject: Move win_util.h from common to app. http://crbug.com/11387 Review URL: http://codereview.chromium.org/113169 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15694 0039d316-1c4b-4281-b951-d872f2087c98 --- app/DEPS | 8 +- app/app.vcproj | 534 ++++++------- app/gfx/icon_util.cc | 2 +- app/gfx/text_elider.cc | 2 - app/os_exchange_data.cc | 1 - app/os_exchange_data_unittest.cc | 2 +- app/win_util.cc | 824 +++++++++++++++++++++ app/win_util.h | 295 ++++++++ app/win_util_unittest.cc | 94 +++ .../autocomplete/autocomplete_edit_view_win.cc | 2 +- chrome/browser/browser.cc | 3 +- chrome/browser/browser_main.cc | 2 +- chrome/browser/browser_main_win.cc | 7 +- chrome/browser/download/download_file.cc | 2 +- chrome/browser/download/download_manager.cc | 2 +- chrome/browser/download/save_file.cc | 1 - chrome/browser/download/save_package.cc | 5 - .../browser/extensions/extension_error_reporter.cc | 5 +- chrome/browser/external_tab_container.cc | 2 +- chrome/browser/hang_monitor/hung_plugin_action.cc | 2 +- chrome/browser/importer/firefox_importer_utils.cc | 8 +- chrome/browser/importer/ie_importer.cc | 2 +- chrome/browser/importer/importer.cc | 4 +- chrome/browser/importer/importer_unittest.cc | 2 +- chrome/browser/plugin_process_host.cc | 2 +- chrome/browser/printing/printed_document.cc | 2 +- chrome/browser/process_singleton_win.cc | 2 +- .../renderer_host/browser_render_process_host.cc | 4 +- chrome/browser/renderer_host/render_widget_host.cc | 1 - .../renderer_host/render_widget_host_view_win.cc | 1 - chrome/browser/sandbox_policy.cc | 2 +- chrome/browser/shell_integration.cc | 6 +- .../tab_contents/render_view_context_menu.cc | 4 +- .../autocomplete_popup_contents_view.cc | 2 +- .../views/autocomplete/autocomplete_popup_win.cc | 2 +- chrome/browser/views/bookmark_bar_view.cc | 2 +- chrome/browser/views/bookmark_manager_view.cc | 1 - chrome/browser/views/constrained_window_impl.cc | 2 +- chrome/browser/views/download_item_view.cc | 2 +- chrome/browser/views/frame/browser_frame.cc | 2 +- chrome/browser/views/frame/browser_view.cc | 2 +- .../views/frame/opaque_browser_frame_view.cc | 2 +- chrome/browser/views/info_bubble.cc | 2 +- chrome/browser/views/location_bar_view.cc | 2 +- chrome/browser/views/options/cookies_view.cc | 1 - chrome/browser/views/page_info_window.cc | 2 +- chrome/browser/views/shell_dialogs_win.cc | 2 +- chrome/browser/views/tabs/tab_renderer.cc | 2 +- chrome/browser/views/tabs/tab_strip.cc | 2 +- chrome/browser/views/toolbar_view.cc | 1 - chrome/browser/visitedlink_master.cc | 8 +- chrome/chrome.gyp | 6 +- chrome/common/common.vcproj | 8 - chrome/common/platform_util_win.cc | 2 +- chrome/common/win_safe_util.cc | 2 +- chrome/common/win_util.cc | 824 --------------------- chrome/common/win_util.h | 295 -------- chrome/common/win_util_unittest.cc | 94 --- chrome/plugin/plugin_main.cc | 6 +- chrome/plugin/webplugin_delegate_stub.cc | 1 - chrome/plugin/webplugin_proxy.cc | 4 +- chrome/renderer/webplugin_delegate_proxy.cc | 1 - .../test/automated_ui_tests/automated_ui_tests.cc | 1 - chrome/test/startup/feature_startup_test.cc | 2 +- chrome/test/unit/unittests.vcproj | 26 +- chrome/tools/crash_service/crash_service.cc | 1 - chrome/worker/worker_main.cc | 1 - views/DEPS | 3 - views/controls/button/menu_button.cc | 2 +- views/controls/text_field.cc | 2 +- views/drag_utils.cc | 1 - views/widget/tooltip_manager.cc | 2 +- views/widget/widget_win.cc | 2 +- views/window/custom_frame_view.cc | 2 +- views/window/non_client_view.cc | 2 +- views/window/window_win.cc | 2 +- 76 files changed, 1581 insertions(+), 1585 deletions(-) create mode 100644 app/win_util.cc create mode 100644 app/win_util.h create mode 100644 app/win_util_unittest.cc delete mode 100644 chrome/common/win_util.cc delete mode 100644 chrome/common/win_util.h delete mode 100644 chrome/common/win_util_unittest.cc diff --git a/app/DEPS b/app/DEPS index b3eb1d8..8770ca2 100644 --- a/app/DEPS +++ b/app/DEPS @@ -8,18 +8,12 @@ include_rules = [ "+chrome/common/chrome_paths.h", "+chrome/common/chrome_switches.h", "+chrome/common/gtk_util.h", - # text_elider.cc - "+chrome/common/pref_names.h", - "+chrome/common/pref_service.h", - + # TODO(beng): l10n_util_unittest.cc: "+chrome/test/data/resource.h", # TODO(beng): resource_bundle.cc: Sever this link after glen fixes it. "+chrome/browser/extensions/extension.h", - # TODO(beng): os_exchange_data[_unittest].cc, icon_util.cc: - "+chrome/common/win_util.h", - "+skia", ] diff --git a/app/app.vcproj b/app/app.vcproj index cb2892f..507a28a 100644 --- a/app/app.vcproj +++ b/app/app.vcproj @@ -1,263 +1,271 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/gfx/icon_util.cc b/app/gfx/icon_util.cc index 1e9e3c9..5efa8e4 100644 --- a/app/gfx/icon_util.cc +++ b/app/gfx/icon_util.cc @@ -4,10 +4,10 @@ #include "app/gfx/icon_util.h" +#include "app/win_util.h" #include "base/file_util.h" #include "base/gfx/size.h" #include "base/logging.h" -#include "chrome/common/win_util.h" #include "skia/ext/image_operations.h" #include "skia/include/SkBitmap.h" diff --git a/app/gfx/text_elider.cc b/app/gfx/text_elider.cc index 527f804..6e20314 100644 --- a/app/gfx/text_elider.cc +++ b/app/gfx/text_elider.cc @@ -7,8 +7,6 @@ #include "base/file_path.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/pref_service.h" #include "googleurl/src/gurl.h" #include "net/base/escape.h" #include "net/base/net_util.h" diff --git a/app/os_exchange_data.cc b/app/os_exchange_data.cc index 489539ff..c9e2311 100644 --- a/app/os_exchange_data.cc +++ b/app/os_exchange_data.cc @@ -14,7 +14,6 @@ #include "base/scoped_handle.h" #include "base/stl_util-inl.h" #include "base/string_util.h" -#include "chrome/common/win_util.h" #include "googleurl/src/gurl.h" #include "grit/generated_resources.h" #include "net/base/net_util.h" diff --git a/app/os_exchange_data_unittest.cc b/app/os_exchange_data_unittest.cc index 6911985..13a28a9 100644 --- a/app/os_exchange_data_unittest.cc +++ b/app/os_exchange_data_unittest.cc @@ -10,8 +10,8 @@ #include "base/pickle.h" #include "base/ref_counted.h" #include "base/scoped_handle.h" +#include "base/scoped_ptr.h" #include "base/string_util.h" -#include "chrome/common/win_util.h" #include "googleurl/src/gurl.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/app/win_util.cc b/app/win_util.cc new file mode 100644 index 0000000..511b965 --- /dev/null +++ b/app/win_util.cc @@ -0,0 +1,824 @@ +// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "app/win_util.h" + +#include +#include +#include +#include +#include +#include + +#include "app/l10n_util.h" +#include "app/l10n_util_win.h" +#include "base/file_util.h" +#include "base/gfx/gdi_util.h" +#include "base/gfx/png_encoder.h" +#include "base/logging.h" +#include "base/registry.h" +#include "base/scoped_handle.h" +#include "base/string_util.h" +#include "base/win_util.h" +#include "grit/generated_resources.h" +#include "net/base/mime_util.h" + +// Ensure that we pick up this link library. +#pragma comment(lib, "dwmapi.lib") + +namespace win_util { + +const int kAutoHideTaskbarThicknessPx = 2; + +namespace { + +// Enforce visible dialog box. +UINT_PTR CALLBACK SaveAsDialogHook(HWND dialog, UINT message, + WPARAM wparam, LPARAM lparam) { + static const UINT kPrivateMessage = 0x2F3F; + switch (message) { + case WM_INITDIALOG: { + // Do nothing here. Just post a message to defer actual processing. + PostMessage(dialog, kPrivateMessage, 0, 0); + return TRUE; + } + case kPrivateMessage: { + // The dialog box is the parent of the current handle. + HWND real_dialog = GetParent(dialog); + + // Retrieve the final size. + RECT dialog_rect; + GetWindowRect(real_dialog, &dialog_rect); + + // Verify that the upper left corner is visible. + POINT point = { dialog_rect.left, dialog_rect.top }; + HMONITOR monitor1 = MonitorFromPoint(point, MONITOR_DEFAULTTONULL); + point.x = dialog_rect.right; + point.y = dialog_rect.bottom; + + // Verify that the lower right corner is visible. + HMONITOR monitor2 = MonitorFromPoint(point, MONITOR_DEFAULTTONULL); + if (monitor1 && monitor2) + return 0; + + // Some part of the dialog box is not visible, fix it by moving is to the + // client rect position of the browser window. + HWND parent_window = GetParent(real_dialog); + if (!parent_window) + return 0; + WINDOWINFO parent_info; + parent_info.cbSize = sizeof(WINDOWINFO); + GetWindowInfo(parent_window, &parent_info); + SetWindowPos(real_dialog, NULL, + parent_info.rcClient.left, + parent_info.rcClient.top, + 0, 0, // Size. + SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | + SWP_NOZORDER); + + return 0; + } + } + return 0; +} + +} // namespace + +std::wstring FormatSystemTime(const SYSTEMTIME& time, + const std::wstring& format) { + // If the format string is empty, just use the default format. + LPCTSTR format_ptr = NULL; + if (!format.empty()) + format_ptr = format.c_str(); + + int buffer_size = GetTimeFormat(LOCALE_USER_DEFAULT, NULL, &time, format_ptr, + NULL, 0); + + std::wstring output; + GetTimeFormat(LOCALE_USER_DEFAULT, NULL, &time, format_ptr, + WriteInto(&output, buffer_size), buffer_size); + + return output; +} + +std::wstring FormatSystemDate(const SYSTEMTIME& date, + const std::wstring& format) { + // If the format string is empty, just use the default format. + LPCTSTR format_ptr = NULL; + if (!format.empty()) + format_ptr = format.c_str(); + + int buffer_size = GetDateFormat(LOCALE_USER_DEFAULT, NULL, &date, format_ptr, + NULL, 0); + + std::wstring output; + GetDateFormat(LOCALE_USER_DEFAULT, NULL, &date, format_ptr, + WriteInto(&output, buffer_size), buffer_size); + + return output; +} + +bool ConvertToLongPath(const std::wstring& short_path, + std::wstring* long_path) { + wchar_t long_path_buf[MAX_PATH]; + DWORD return_value = GetLongPathName(short_path.c_str(), long_path_buf, + MAX_PATH); + if (return_value != 0 && return_value < MAX_PATH) { + *long_path = long_path_buf; + return true; + } + + return false; +} + +bool IsDoubleClick(const POINT& origin, + const POINT& current, + DWORD elapsed_time) { + // The CXDOUBLECLK and CYDOUBLECLK system metrics describe the width and + // height of a rectangle around the origin position, inside of which clicks + // within the double click time are considered double clicks. + return (elapsed_time <= GetDoubleClickTime()) && + (abs(current.x - origin.x) <= (GetSystemMetrics(SM_CXDOUBLECLK) / 2)) && + (abs(current.y - origin.y) <= (GetSystemMetrics(SM_CYDOUBLECLK) / 2)); +} + +bool IsDrag(const POINT& origin, const POINT& current) { + // The CXDRAG and CYDRAG system metrics describe the width and height of a + // rectangle around the origin position, inside of which motion is not + // considered a drag. + return (abs(current.x - origin.x) > (GetSystemMetrics(SM_CXDRAG) / 2)) || + (abs(current.y - origin.y) > (GetSystemMetrics(SM_CYDRAG) / 2)); +} + +bool ShouldUseVistaFrame() { + if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) + return false; + // If composition is not enabled, we behave like on XP. + BOOL f; + DwmIsCompositionEnabled(&f); + return !!f; +} + +// Open an item via a shell execute command. Error code checking and casting +// explanation: http://msdn2.microsoft.com/en-us/library/ms647732.aspx +bool OpenItemViaShell(const FilePath& full_path, bool ask_for_app) { + HINSTANCE h = ::ShellExecuteW( + NULL, NULL, full_path.value().c_str(), NULL, + full_path.DirName().value().c_str(), SW_SHOWNORMAL); + + LONG_PTR error = reinterpret_cast(h); + if (error > 32) + return true; + + if ((error == SE_ERR_NOASSOC) && ask_for_app) + return OpenItemWithExternalApp(full_path.value()); + + return false; +} + +bool OpenItemViaShellNoZoneCheck(const FilePath& full_path, + bool ask_for_app) { + SHELLEXECUTEINFO sei = { sizeof(sei) }; + sei.fMask = SEE_MASK_NOZONECHECKS | SEE_MASK_FLAG_DDEWAIT; + sei.nShow = SW_SHOWNORMAL; + sei.lpVerb = NULL; + sei.lpFile = full_path.value().c_str(); + if (::ShellExecuteExW(&sei)) + return true; + LONG_PTR error = reinterpret_cast(sei.hInstApp); + if ((error == SE_ERR_NOASSOC) && ask_for_app) + return OpenItemWithExternalApp(full_path.value()); + return false; +} + +// Show the Windows "Open With" dialog box to ask the user to pick an app to +// open the file with. +bool OpenItemWithExternalApp(const std::wstring& full_path) { + SHELLEXECUTEINFO sei = { sizeof(sei) }; + sei.fMask = SEE_MASK_FLAG_DDEWAIT; + sei.nShow = SW_SHOWNORMAL; + sei.lpVerb = L"openas"; + sei.lpFile = full_path.c_str(); + return (TRUE == ::ShellExecuteExW(&sei)); +} + +// Get the file type description from the registry. This will be "Text Document" +// for .txt files, "JPEG Image" for .jpg files, etc. If the registry doesn't +// have an entry for the file type, we return false, true if the description was +// found. 'file_ext' must be in form ".txt". +static bool GetRegistryDescriptionFromExtension(const std::wstring& file_ext, + std::wstring* reg_description) { + DCHECK(reg_description); + RegKey reg_ext(HKEY_CLASSES_ROOT, file_ext.c_str(), KEY_READ); + std::wstring reg_app; + if (reg_ext.ReadValue(NULL, ®_app) && !reg_app.empty()) { + RegKey reg_link(HKEY_CLASSES_ROOT, reg_app.c_str(), KEY_READ); + if (reg_link.ReadValue(NULL, reg_description)) + return true; + } + return false; +} + +std::wstring FormatFilterForExtensions( + const std::vector& file_ext, + const std::vector& ext_desc, + bool include_all_files) { + const std::wstring all_ext = L"*.*"; + const std::wstring all_desc = l10n_util::GetString(IDS_SAVEAS_ALL_FILES); + + DCHECK(file_ext.size()>=ext_desc.size()); + + std::wstring result; + + for (size_t i=0; i(1, file_ext), + std::vector(), + true); + unsigned index = 1; + return SaveFileAsWithFilter(owner, + suggested_name, + filter, + L"", + false, + &index, + final_name); +} + +bool SaveFileAsWithFilter(HWND owner, + const std::wstring& suggested_name, + const std::wstring& filter, + const std::wstring& def_ext, + bool ignore_suggested_ext, + unsigned* index, + std::wstring* final_name) { + DCHECK(final_name); + // Having an empty filter makes for a bad user experience. We should always + // specify a filter when saving. + DCHECK(!filter.empty()); + std::wstring file_part = file_util::GetFilenameFromPath(suggested_name); + + // The size of the in/out buffer in number of characters we pass to win32 + // GetSaveFileName. From MSDN "The buffer must be large enough to store the + // path and file name string or strings, including the terminating NULL + // character. ... The buffer should be at least 256 characters long.". + // _IsValidPathComDlg does a copy expecting at most MAX_PATH, otherwise will + // result in an error of FNERR_INVALIDFILENAME. So we should only pass the + // API a buffer of at most MAX_PATH. + wchar_t file_name[MAX_PATH]; + base::wcslcpy(file_name, file_part.c_str(), arraysize(file_name)); + + OPENFILENAME save_as; + // We must do this otherwise the ofn's FlagsEx may be initialized to random + // junk in release builds which can cause the Places Bar not to show up! + ZeroMemory(&save_as, sizeof(save_as)); + save_as.lStructSize = sizeof(OPENFILENAME); + save_as.hwndOwner = owner; + save_as.hInstance = NULL; + + save_as.lpstrFilter = filter.empty() ? NULL : filter.c_str(); + + save_as.lpstrCustomFilter = NULL; + save_as.nMaxCustFilter = 0; + save_as.nFilterIndex = *index; + save_as.lpstrFile = file_name; + save_as.nMaxFile = arraysize(file_name); + save_as.lpstrFileTitle = NULL; + save_as.nMaxFileTitle = 0; + + // Set up the initial directory for the dialog. + std::wstring directory = file_util::GetDirectoryFromPath(suggested_name); + save_as.lpstrInitialDir = directory.c_str(); + save_as.lpstrTitle = NULL; + save_as.Flags = OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_ENABLESIZING | + OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST; + save_as.lpstrDefExt = &def_ext[0]; + save_as.lCustData = NULL; + + if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) { + // The save as on Windows XP remembers its last position, + // and if the screen resolution changed, it will be off screen. + save_as.Flags |= OFN_ENABLEHOOK; + save_as.lpfnHook = &SaveAsDialogHook; + } + + // Must be NULL or 0. + save_as.pvReserved = NULL; + save_as.dwReserved = 0; + + if (!GetSaveFileName(&save_as)) { + // Zero means the dialog was closed, otherwise we had an error. + DWORD error_code = CommDlgExtendedError(); + if (error_code != 0) { + NOTREACHED() << "GetSaveFileName failed with code: " << error_code; + } + return false; + } + + // Return the user's choice. + final_name->assign(save_as.lpstrFile); + *index = save_as.nFilterIndex; + + // Figure out what filter got selected from the vector with embedded nulls. + // NOTE: The filter contains a string with embedded nulls, such as: + // JPG Image\0*.jpg\0All files\0*.*\0\0 + // The filter index is 1-based index for which pair got selected. So, using + // the example above, if the first index was selected we need to skip 1 + // instance of null to get to "*.jpg". + std::vector filters; + if (!filter.empty() && save_as.nFilterIndex > 0) + SplitString(filter, '\0', &filters); + std::wstring filter_selected; + if (!filters.empty()) + filter_selected = filters[(2 * (save_as.nFilterIndex - 1)) + 1]; + + // Get the extension that was suggested to the user (when the Save As dialog + // was opened). For saving web pages, we skip this step since there may be + // 'extension characters' in the title of the web page. + std::wstring suggested_ext; + if (!ignore_suggested_ext) + suggested_ext = file_util::GetFileExtensionFromPath(suggested_name); + + // If we can't get the extension from the suggested_name, we use the default + // extension passed in. This is to cover cases like when saving a web page, + // where we get passed in a name without an extension and a default extension + // along with it. + if (suggested_ext.empty()) + suggested_ext = def_ext; + + *final_name = + AppendExtensionIfNeeded(*final_name, filter_selected, suggested_ext); + return true; +} + +std::wstring AppendExtensionIfNeeded(const std::wstring& filename, + const std::wstring& filter_selected, + const std::wstring& suggested_ext) { + std::wstring return_value = filename; + + // Get the extension the user ended up selecting. + std::wstring selected_ext = file_util::GetFileExtensionFromPath(filename); + + if (filter_selected.empty() || filter_selected == L"*.*") { + // If the user selects 'All files' we respect any extension given to us from + // the File Save dialog. We also strip any trailing dots, which matches + // Windows Explorer and is needed because Windows doesn't allow filenames + // to have trailing dots. The GetSaveFileName dialog will not return a + // string with only one or more dots. + size_t index = return_value.find_last_not_of(L'.'); + if (index < return_value.size() - 1) + return_value.resize(index + 1); + } else { + // User selected a specific filter (not *.*) so we need to check if the + // extension provided has the same mime type. If it doesn't we append the + // extension. + std::string suggested_mime_type, selected_mime_type; + if (suggested_ext != selected_ext && + (!net::GetMimeTypeFromExtension(suggested_ext, &suggested_mime_type) || + !net::GetMimeTypeFromExtension(selected_ext, &selected_mime_type) || + suggested_mime_type != selected_mime_type)) { + return_value.append(L"."); + return_value.append(suggested_ext); + } + } + + return return_value; +} + +// Adjust the window to fit, returning true if the window was resized or moved. +static bool AdjustWindowToFit(HWND hwnd, const RECT& bounds) { + // Get the monitor. + HMONITOR hmon = MonitorFromRect(&bounds, MONITOR_DEFAULTTONEAREST); + if (!hmon) { + NOTREACHED() << "Unable to find default monitor"; + // No monitor available. + return false; + } + + MONITORINFO mi; + mi.cbSize = sizeof(mi); + GetMonitorInfo(hmon, &mi); + gfx::Rect window_rect(bounds); + gfx::Rect monitor_rect(mi.rcWork); + gfx::Rect new_window_rect = window_rect.AdjustToFit(monitor_rect); + if (!new_window_rect.Equals(window_rect)) { + // Window doesn't fit on monitor, move and possibly resize. + SetWindowPos(hwnd, 0, new_window_rect.x(), new_window_rect.y(), + new_window_rect.width(), new_window_rect.height(), + SWP_NOACTIVATE | SWP_NOZORDER); + return true; + } else { + return false; + } +} + +void AdjustWindowToFit(HWND hwnd) { + // Get the window bounds. + RECT r; + GetWindowRect(hwnd, &r); + AdjustWindowToFit(hwnd, r); +} + +void CenterAndSizeWindow(HWND parent, HWND window, const SIZE& pref, + bool pref_is_client) { + DCHECK(window && pref.cx > 0 && pref.cy > 0); + // Calculate the ideal bounds. + RECT window_bounds; + RECT center_bounds = {0}; + if (parent) { + // If there is a parent, center over the parents bounds. + ::GetWindowRect(parent, ¢er_bounds); + } else { + // No parent. Center over the monitor the window is on. + HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST); + if (monitor) { + MONITORINFO mi = {0}; + mi.cbSize = sizeof(mi); + GetMonitorInfo(monitor, &mi); + center_bounds = mi.rcWork; + } else { + NOTREACHED() << "Unable to get default monitor"; + } + } + window_bounds.left = center_bounds.left + + (center_bounds.right - center_bounds.left - pref.cx) / 2; + window_bounds.right = window_bounds.left + pref.cx; + window_bounds.top = center_bounds.top + + (center_bounds.bottom - center_bounds.top - pref.cy) / 2; + window_bounds.bottom = window_bounds.top + pref.cy; + + // If we're centering a child window, we are positioning in client + // coordinates, and as such we need to offset the target rectangle by the + // position of the parent window. + if (::GetWindowLong(window, GWL_STYLE) & WS_CHILD) { + DCHECK(parent && ::GetParent(window) == parent); + POINT topleft = { window_bounds.left, window_bounds.top }; + ::MapWindowPoints(HWND_DESKTOP, parent, &topleft, 1); + window_bounds.left = topleft.x; + window_bounds.top = topleft.y; + window_bounds.right = window_bounds.left + pref.cx; + window_bounds.bottom = window_bounds.top + pref.cy; + } + + // Get the WINDOWINFO for window. We need the style to calculate the size + // for the window. + WINDOWINFO win_info = {0}; + win_info.cbSize = sizeof(WINDOWINFO); + GetWindowInfo(window, &win_info); + + // Calculate the window size needed for the content size. + + if (!pref_is_client || + AdjustWindowRectEx(&window_bounds, win_info.dwStyle, FALSE, + win_info.dwExStyle)) { + if (!AdjustWindowToFit(window, window_bounds)) { + // The window fits, reset the bounds. + SetWindowPos(window, 0, window_bounds.left, window_bounds.top, + window_bounds.right - window_bounds.left, + window_bounds.bottom - window_bounds.top, + SWP_NOACTIVATE | SWP_NOZORDER); + } // else case, AdjustWindowToFit set the bounds for us. + } else { + NOTREACHED() << "Unable to adjust window to fit"; + } +} + +bool EdgeHasTopmostAutoHideTaskbar(UINT edge, HMONITOR monitor) { + APPBARDATA taskbar_data = { 0 }; + taskbar_data.cbSize = sizeof APPBARDATA; + taskbar_data.uEdge = edge; + HWND taskbar = reinterpret_cast(SHAppBarMessage(ABM_GETAUTOHIDEBAR, + &taskbar_data)); + return ::IsWindow(taskbar) && (monitor != NULL) && + (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONULL) == monitor) && + (GetWindowLong(taskbar, GWL_EXSTYLE) & WS_EX_TOPMOST); +} + +HANDLE GetSectionFromProcess(HANDLE section, HANDLE process, bool read_only) { + HANDLE valid_section = NULL; + DWORD access = STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ; + if (!read_only) + access |= FILE_MAP_WRITE; + DuplicateHandle(process, section, GetCurrentProcess(), &valid_section, access, + FALSE, 0); + return valid_section; +} + +bool DoesWindowBelongToActiveWindow(HWND window) { + DCHECK(window); + HWND top_window = ::GetAncestor(window, GA_ROOT); + if (!top_window) + return false; + + HWND active_top_window = ::GetAncestor(::GetForegroundWindow(), GA_ROOT); + return (top_window == active_top_window); +} + +void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect, + gfx::Rect* child_rect, + int padding) { + DCHECK(child_rect); + + // We use padding here because it allows some of the original web page to + // bleed through around the edges. + int twice_padding = padding * 2; + + // FIRST, clamp width and height so we don't open child windows larger than + // the containing parent. + if (child_rect->width() > (parent_rect.width() + twice_padding)) + child_rect->set_width(std::max(0, parent_rect.width() - twice_padding)); + if (child_rect->height() > parent_rect.height() + twice_padding) + child_rect->set_height(std::max(0, parent_rect.height() - twice_padding)); + + // SECOND, clamp x,y position to padding,padding so we don't position child + // windows in hyperspace. + // TODO(mpcomplete): I don't see what the second check in each 'if' does that + // isn't handled by the LAST set of 'ifs'. Maybe we can remove it. + if (child_rect->x() < parent_rect.x() || + child_rect->x() > parent_rect.right()) { + child_rect->set_x(parent_rect.x() + padding); + } + if (child_rect->y() < parent_rect.y() || + child_rect->y() > parent_rect.bottom()) { + child_rect->set_y(parent_rect.y() + padding); + } + + // LAST, nudge the window back up into the client area if its x,y position is + // within the parent bounds but its width/height place it off-screen. + if (child_rect->bottom() > parent_rect.bottom()) + child_rect->set_y(parent_rect.bottom() - child_rect->height() - padding); + if (child_rect->right() > parent_rect.right()) + child_rect->set_x(parent_rect.right() - child_rect->width() - padding); +} + +void SetChildBounds(HWND child_window, HWND parent_window, + HWND insert_after_window, const gfx::Rect& bounds, + int padding, unsigned long flags) { + DCHECK(IsWindow(child_window)); + + // First figure out the bounds of the parent. + RECT parent_rect = {0}; + if (parent_window) { + GetClientRect(parent_window, &parent_rect); + } else { + // If there is no parent, we consider the bounds of the monitor the window + // is on to be the parent bounds. + + // If the child_window isn't visible yet and we've been given a valid, + // visible insert after window, use that window to locate the correct + // monitor instead. + HWND window = child_window; + if (!IsWindowVisible(window) && IsWindow(insert_after_window) && + IsWindowVisible(insert_after_window)) + window = insert_after_window; + + POINT window_point = { bounds.x(), bounds.y() }; + HMONITOR monitor = MonitorFromPoint(window_point, + MONITOR_DEFAULTTONEAREST); + if (monitor) { + MONITORINFO mi = {0}; + mi.cbSize = sizeof(mi); + GetMonitorInfo(monitor, &mi); + parent_rect = mi.rcWork; + } else { + NOTREACHED() << "Unable to get default monitor"; + } + } + + gfx::Rect actual_bounds = bounds; + EnsureRectIsVisibleInRect(gfx::Rect(parent_rect), &actual_bounds, padding); + + SetWindowPos(child_window, insert_after_window, actual_bounds.x(), + actual_bounds.y(), actual_bounds.width(), + actual_bounds.height(), flags); +} + +gfx::Rect GetMonitorBoundsForRect(const gfx::Rect& rect) { + RECT p_rect = rect.ToRECT(); + HMONITOR monitor = MonitorFromRect(&p_rect, MONITOR_DEFAULTTONEAREST); + if (monitor) { + MONITORINFO mi = {0}; + mi.cbSize = sizeof(mi); + GetMonitorInfo(monitor, &mi); + return gfx::Rect(mi.rcWork); + } + NOTREACHED(); + return gfx::Rect(); +} + +bool IsNumPadDigit(int key_code, bool extended_key) { + if (key_code >= VK_NUMPAD0 && key_code <= VK_NUMPAD9) + return true; + + // Check for num pad keys without NumLock. + // Note: there is no easy way to know if a the key that was pressed comes from + // the num pad or the rest of the keyboard. Investigating how + // TranslateMessage() generates the WM_KEYCHAR from an + // ALT + it appears it looks at the extended key flag + // (which is on if the key pressed comes from one of the 3 clusters to + // the left of the numeric keypad). So we use it as well. + return !extended_key && + ((key_code >= VK_PRIOR && key_code <= VK_DOWN) || // All keys but 5 + // and 0. + (key_code == VK_CLEAR) || // Key 5. + (key_code == VK_INSERT)); // Key 0. +} + +void GrabWindowSnapshot(HWND window_handle, + std::vector* png_representation) { + // Create a memory DC that's compatible with the window. + CWindowDC window_hdc(window_handle); + CDC mem_hdc(::CreateCompatibleDC(window_hdc)); + + // Create a DIB that's the same size as the window. + RECT content_rect = {0, 0, 0, 0}; + ::GetWindowRect(window_handle, &content_rect); + content_rect.right++; // Match what PrintWindow wants. + int width = content_rect.right - content_rect.left; + int height = content_rect.bottom - content_rect.top; + BITMAPINFOHEADER hdr; + gfx::CreateBitmapHeader(width, height, &hdr); + unsigned char *bit_ptr = NULL; + CBitmap bitmap(::CreateDIBSection(mem_hdc, + reinterpret_cast(&hdr), + DIB_RGB_COLORS, + reinterpret_cast(&bit_ptr), + NULL, 0)); + + mem_hdc.SelectBitmap(bitmap); + // Clear the bitmap to white (so that rounded corners on windows + // show up on a white background, and strangely-shaped windows + // look reasonable). Not capturing an alpha mask saves a + // bit of space. + mem_hdc.PatBlt(0, 0, width, height, WHITENESS); + // Grab a copy of the window + // First, see if PrintWindow is defined (it's not in Windows 2000). + typedef BOOL (WINAPI *PrintWindowPointer)(HWND, HDC, UINT); + PrintWindowPointer print_window = + reinterpret_cast( + GetProcAddress(GetModuleHandle(L"User32.dll"), "PrintWindow")); + + // If PrintWindow is defined, use it. It will work on partially + // obscured windows, and works better for out of process sub-windows. + // Otherwise grab the bits we can get with BitBlt; it's better + // than nothing and will work fine in the average case (window is + // completely on screen). + if (print_window) + (*print_window)(window_handle, mem_hdc, 0); + else + mem_hdc.BitBlt(0, 0, width, height, window_hdc, 0, 0, SRCCOPY); + + // We now have a copy of the window contents in a DIB, so + // encode it into a useful format for posting to the bug report + // server. + PNGEncoder::Encode(bit_ptr, PNGEncoder::FORMAT_BGRA, + width, height, width * 4, true, + png_representation); +} + +bool IsWindowActive(HWND hwnd) { + WINDOWINFO info; + return ::GetWindowInfo(hwnd, &info) && + ((info.dwWindowStatus & WS_ACTIVECAPTION) != 0); +} + +bool IsReservedName(const std::wstring& filename) { + // This list is taken from the MSDN article "Naming a file" + // http://msdn2.microsoft.com/en-us/library/aa365247(VS.85).aspx + // I also added clock$ because GetSaveFileName seems to consider it as a + // reserved name too. + static const wchar_t* const known_devices[] = { + L"con", L"prn", L"aux", L"nul", L"com1", L"com2", L"com3", L"com4", L"com5", + L"com6", L"com7", L"com8", L"com9", L"lpt1", L"lpt2", L"lpt3", L"lpt4", + L"lpt5", L"lpt6", L"lpt7", L"lpt8", L"lpt9", L"clock$" + }; + std::wstring filename_lower = StringToLowerASCII(filename); + + for (int i = 0; i < arraysize(known_devices); ++i) { + // Exact match. + if (filename_lower == known_devices[i]) + return true; + // Starts with "DEVICE.". + if (filename_lower.find(std::wstring(known_devices[i]) + L".") == 0) + return true; + } + + static const wchar_t* const magic_names[] = { + // These file names are used by the "Customize folder" feature of the shell. + L"desktop.ini", + L"thumbs.db", + }; + + for (int i = 0; i < arraysize(magic_names); ++i) { + if (filename_lower == magic_names[i]) + return true; + } + + return false; +} + +bool IsShellIntegratedExtension(const std::wstring& extension) { + std::wstring extension_lower = StringToLowerASCII(extension); + + static const wchar_t* const integrated_extensions[] = { + // See . + L"local", + // Right-clicking on shortcuts can be magical. + L"lnk", + }; + + for (int i = 0; i < arraysize(integrated_extensions); ++i) { + if (extension_lower == integrated_extensions[i]) + return true; + } + + // See . + // That vulnerability report is not exactly on point, but files become magical + // if their end in a CLSID. Here we block extensions that look like CLSIDs. + if (extension_lower.size() > 0 && extension_lower.at(0) == L'{' && + extension_lower.at(extension_lower.length() - 1) == L'}') + return true; + + return false; +} + +// In addition to passing the RTL flags to ::MessageBox if we are running in an +// RTL locale, we need to make sure that LTR strings are rendered correctly by +// adding the appropriate Unicode directionality marks. +int MessageBox(HWND hwnd, + const std::wstring& text, + const std::wstring& caption, + UINT flags) { + UINT actual_flags = flags; + if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) + actual_flags |= MB_RIGHT | MB_RTLREADING; + + std::wstring localized_text; + const wchar_t* text_ptr = text.c_str(); + if (l10n_util::AdjustStringForLocaleDirection(text, &localized_text)) + text_ptr = localized_text.c_str(); + + std::wstring localized_caption; + const wchar_t* caption_ptr = caption.c_str(); + if (l10n_util::AdjustStringForLocaleDirection(caption, &localized_caption)) + caption_ptr = localized_caption.c_str(); + + return ::MessageBox(hwnd, text_ptr, caption_ptr, actual_flags); +} + +ChromeFont GetWindowTitleFont() { + NONCLIENTMETRICS ncm; + win_util::GetNonClientMetrics(&ncm); + l10n_util::AdjustUIFont(&(ncm.lfCaptionFont)); + ScopedHFONT caption_font(CreateFontIndirect(&(ncm.lfCaptionFont))); + return ChromeFont::CreateFont(caption_font); +} + +} // namespace win_util diff --git a/app/win_util.h b/app/win_util.h new file mode 100644 index 0000000..1c384c9 --- /dev/null +++ b/app/win_util.h @@ -0,0 +1,295 @@ +// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef APP_WIN_UTIL_H_ +#define APP_WIN_UTIL_H_ + +#include + +#include +#include + +#include "app/gfx/chrome_font.h" +#include "base/fix_wp64.h" +#include "base/gfx/rect.h" +#include "base/scoped_handle.h" + +class FilePath; + +namespace win_util { + +// Import ScopedHandle and friends into this namespace for backwards +// compatibility. TODO(darin): clean this up! +using ::ScopedHandle; +using ::ScopedFindFileHandle; +using ::ScopedHDC; +using ::ScopedBitmap; +using ::ScopedHRGN; + +// Simple scoped memory releaser class for COM allocated memory. +// Example: +// CoMemReleaser file_item; +// SHGetSomeInfo(&file_item, ...); +// ... +// return; <-- memory released +template +class CoMemReleaser { + public: + explicit CoMemReleaser() : mem_ptr_(NULL) {} + + ~CoMemReleaser() { + if (mem_ptr_) + CoTaskMemFree(mem_ptr_); + } + + T** operator&() { + return &mem_ptr_; + } + + operator T*() { + return mem_ptr_; + } + + private: + T* mem_ptr_; + + DISALLOW_COPY_AND_ASSIGN(CoMemReleaser); +}; + +// Initializes COM in the constructor (STA), and uninitializes COM in the +// destructor. +class ScopedCOMInitializer { + public: + ScopedCOMInitializer() : hr_(CoInitialize(NULL)) { + } + + ScopedCOMInitializer::~ScopedCOMInitializer() { + if (SUCCEEDED(hr_)) + CoUninitialize(); + } + + // Returns the error code from CoInitialize(NULL) + // (called in constructor) + inline HRESULT error_code() const { + return hr_; + } + + protected: + HRESULT hr_; + + private: + DISALLOW_COPY_AND_ASSIGN(ScopedCOMInitializer); +}; + +// Creates a string interpretation of the time of day represented by the given +// SYSTEMTIME that's appropriate for the user's default locale. +// Format can be an empty string (for the default format), or a "format picture" +// as specified in the Windows documentation for GetTimeFormat(). +std::wstring FormatSystemTime(const SYSTEMTIME& time, + const std::wstring& format); + +// Creates a string interpretation of the date represented by the given +// SYSTEMTIME that's appropriate for the user's default locale. +// Format can be an empty string (for the default format), or a "format picture" +// as specified in the Windows documentation for GetDateFormat(). +std::wstring FormatSystemDate(const SYSTEMTIME& date, + const std::wstring& format); + +// Returns the long path name given a short path name. A short path name +// is a path that follows the 8.3 convention and has ~x in it. If the +// path is already a long path name, the function returns the current +// path without modification. +bool ConvertToLongPath(const std::wstring& short_path, std::wstring* long_path); + +// Returns true if the current point is close enough to the origin point in +// space and time that it would be considered a double click. +bool IsDoubleClick(const POINT& origin, + const POINT& current, + DWORD elapsed_time); + +// Returns true if the current point is far enough from the origin that it +// would be considered a drag. +bool IsDrag(const POINT& origin, const POINT& current); + +// Returns true if we are on Windows Vista and composition is enabled +bool ShouldUseVistaFrame(); + +// Open or run a file via the Windows shell. In the event that there is no +// default application registered for the file specified by 'full_path', +// ask the user, via the Windows "Open With" dialog, for an application to use +// if 'ask_for_app' is true. +// Returns 'true' on successful open, 'false' otherwise. +bool OpenItemViaShell(const FilePath& full_path, bool ask_for_app); + +// The download manager now writes the alternate data stream with the +// zone on all downloads. This function is equivalent to OpenItemViaShell +// without showing the zone warning dialog. +bool OpenItemViaShellNoZoneCheck(const FilePath& full_path, + bool ask_for_app); + +// Ask the user, via the Windows "Open With" dialog, for an application to use +// to open the file specified by 'full_path'. +// Returns 'true' on successful open, 'false' otherwise. +bool OpenItemWithExternalApp(const std::wstring& full_path); + +// Set up a filter for a Save/Open dialog, which will consist of |file_ext| file +// extensions (internally separated by semicolons), |ext_desc| as the text +// descriptions of the |file_ext| types (optional), and (optionally) the default +// 'All Files' view. The purpose of the filter is to show only files of a +// particular type in a Windows Save/Open dialog box. The resulting filter is +// returned. The filters created here are: +// 1. only files that have 'file_ext' as their extension +// 2. all files (only added if 'include_all_files' is true) +// Example: +// file_ext: { "*.txt", "*.htm;*.html" } +// ext_desc: { "Text Document" } +// returned: "Text Document\0*.txt\0HTML Document\0*.htm;*.html\0" +// "All Files\0*.*\0\0" (in one big string) +// If a description is not provided for a file extension, it will be retrieved +// from the registry. If the file extension does not exist in the registry, it +// will be omitted from the filter, as it is likely a bogus extension. +std::wstring FormatFilterForExtensions( + const std::vector& file_ext, + const std::vector& ext_desc, + bool include_all_files); + +// Prompt the user for location to save a file. 'suggested_name' is a full path +// that gives the dialog box a hint as to how to initialize itself. +// For example, a 'suggested_name' of: +// "C:\Documents and Settings\jojo\My Documents\picture.png" +// will start the dialog in the "C:\Documents and Settings\jojo\My Documents\" +// directory, and filter for .png file types. +// 'owner' is the window to which the dialog box is modal, NULL for a modeless +// dialog box. +// On success, returns true and 'final_name' contains the full path of the file +// that the user chose. On error, returns false, and 'final_name' is not +// modified. +// NOTE: DO NOT CALL THIS FUNCTION DIRECTLY! Instead use the helper objects in +// browser/shell_dialogs.cc to do this asynchronously on a different +// thread so that the app isn't jankified if the Windows shell dialog +// takes a long time to display. +bool SaveFileAs(HWND owner, + const std::wstring& suggested_name, + std::wstring* final_name); + +// Prompt the user for location to save a file. +// Callers should provide the filter string, and also a filter index. +// The parameter |index| indicates the initial index of filter description +// and filter pattern for the dialog box. If |index| is zero or greater than +// the number of total filter types, the system uses the first filter in the +// |filter| buffer. |index| is used to specify the initial selected extension, +// and when done contains the extension the user chose. The parameter +// |final_name| returns the file name which contains the drive designator, +// path, file name, and extension of the user selected file name. |def_ext| is +// the default extension to give to the file if the user did not enter an +// extension. If |ignore_suggested_ext| is true, any file extension contained in +// |suggested_name| will not be used to generate the file name. This is useful +// in the case of saving web pages, where we know the extension type already and +// where |suggested_name| may contain a '.' character as a valid part of the +// name, thus confusing our extension detection code. +bool SaveFileAsWithFilter(HWND owner, + const std::wstring& suggested_name, + const std::wstring& filter, + const std::wstring& def_ext, + bool ignore_suggested_ext, + unsigned* index, + std::wstring* final_name); + +// This function takes the output of a SaveAs dialog: a filename, a filter and +// the extension originally suggested to the user (shown in the dialog box) and +// returns back the filename with the appropriate extension tacked on. For +// example, if you pass in 'foo' as filename with filter '*.jpg' this function +// will return 'foo.jpg'. It respects MIME types, so if you pass in 'foo.jpeg' +// with filer '*.jpg' it will return 'foo.jpeg' (will not append .jpg). +// |filename| should contain the filename selected in the SaveAs dialog box and +// may include the path, |filter_selected| should be '*.something', for example +// '*.*' or it can be blank (which is treated as *.*). |suggested_ext| should +// contain the extension without the dot (.) in front, for example 'jpg'. +std::wstring AppendExtensionIfNeeded(const std::wstring& filename, + const std::wstring& filter_selected, + const std::wstring& suggested_ext); + +// If the window does not fit on the default monitor, it is moved and possibly +// resized appropriately. +void AdjustWindowToFit(HWND hwnd); + +// Sizes the window to have a client or window size (depending on the value of +// |pref_is_client|) of pref, then centers the window over parent, ensuring the +// window fits on screen. +void CenterAndSizeWindow(HWND parent, HWND window, const SIZE& pref, + bool pref_is_client); + +// Returns true if edge |edge| (one of ABE_LEFT, TOP, RIGHT, or BOTTOM) of +// monitor |monitor| has an auto-hiding taskbar that's always-on-top. +bool EdgeHasTopmostAutoHideTaskbar(UINT edge, HMONITOR monitor); + +// Duplicates a section handle from another process to the current process. +// Returns the new valid handle if the function succeed. NULL otherwise. +HANDLE GetSectionFromProcess(HANDLE section, HANDLE process, bool read_only); + +// Returns true if the specified window is the current active top window or one +// of its children. +bool DoesWindowBelongToActiveWindow(HWND window); + +// Adjusts the value of |child_rect| if necessary to ensure that it is +// completely visible within |parent_rect|. +void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect, + gfx::Rect* child_rect, + int padding); + +// Ensures that the child window stays within the boundaries of the parent +// before setting its bounds. If |parent_window| is NULL, the bounds of the +// parent are assumed to be the bounds of the monitor that |child_window| is +// nearest to. If |child_window| isn't visible yet and |insert_after_window| +// is non-NULL and visible, the monitor |insert_after_window| is on is used +// as the parent bounds instead. +void SetChildBounds(HWND child_window, HWND parent_window, + HWND insert_after_window, const gfx::Rect& bounds, + int padding, unsigned long flags); + +// Returns the bounds for the monitor that contains the largest area of +// intersection with the specified rectangle. +gfx::Rect GetMonitorBoundsForRect(const gfx::Rect& rect); + +// Returns true if the virtual key code is a digit coming from the numeric +// keypad (with or without NumLock on). |extended_key| should be set to the +// extended key flag specified in the WM_KEYDOWN/UP where the |key_code| +// originated. +bool IsNumPadDigit(int key_code, bool extended_key); + +// Grabs a snapshot of the designated window and stores a PNG representation +// into a byte vector. +void GrabWindowSnapshot(HWND window_handle, + std::vector* png_representation); + +// Returns whether the specified window is the current active window. +bool IsWindowActive(HWND hwnd); + +// Returns whether the specified file name is a reserved name on windows. +// This includes names like "com2.zip" (which correspond to devices) and +// desktop.ini and thumbs.db which have special meaning to the windows shell. +bool IsReservedName(const std::wstring& filename); + +// Returns whether the specified extension is automatically integrated into the +// windows shell. +bool IsShellIntegratedExtension(const std::wstring& eextension); + +// A wrapper around Windows' MessageBox function. Using a Chrome specific +// MessageBox function allows us to control certain RTL locale flags so that +// callers don't have to worry about adding these flags when running in a +// right-to-left locale. +int MessageBox(HWND hwnd, + const std::wstring& text, + const std::wstring& caption, + UINT flags); + +// Returns the system set window title font. +ChromeFont GetWindowTitleFont(); + +// The thickness of an auto-hide taskbar in pixels. +extern const int kAutoHideTaskbarThicknessPx; + +} // namespace win_util + +#endif // APP_WIN_UTIL_H_ diff --git a/app/win_util_unittest.cc b/app/win_util_unittest.cc new file mode 100644 index 0000000..18fb0d0 --- /dev/null +++ b/app/win_util_unittest.cc @@ -0,0 +1,94 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "app/win_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +TEST(WinUtilTest, EnsureRectIsVisibleInRect) { + gfx::Rect parent_rect(0, 0, 500, 400); + + { + // Child rect x < 0 + gfx::Rect child_rect(-50, 20, 100, 100); + win_util::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + EXPECT_EQ(gfx::Rect(10, 20, 100, 100), child_rect); + } + + { + // Child rect y < 0 + gfx::Rect child_rect(20, -50, 100, 100); + win_util::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + EXPECT_EQ(gfx::Rect(20, 10, 100, 100), child_rect); + } + + { + // Child rect right > parent_rect.right + gfx::Rect child_rect(450, 20, 100, 100); + win_util::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + EXPECT_EQ(gfx::Rect(390, 20, 100, 100), child_rect); + } + + { + // Child rect bottom > parent_rect.bottom + gfx::Rect child_rect(20, 350, 100, 100); + win_util::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + EXPECT_EQ(gfx::Rect(20, 290, 100, 100), child_rect); + } + + { + // Child rect width > parent_rect.width + gfx::Rect child_rect(20, 20, 700, 100); + win_util::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + EXPECT_EQ(gfx::Rect(20, 20, 480, 100), child_rect); + } + + { + // Child rect height > parent_rect.height + gfx::Rect child_rect(20, 20, 100, 700); + win_util::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + EXPECT_EQ(gfx::Rect(20, 20, 100, 380), child_rect); + } +} + +static const struct filename_case { + const wchar_t* filename; + const wchar_t* filter_selected; + const wchar_t* suggested_ext; + const wchar_t* result; +} filename_cases[] = { + // Test a specific filter (*.jpg). + {L"f", L"*.jpg", L"jpg", L"f.jpg"}, + {L"f.", L"*.jpg", L"jpg", L"f..jpg"}, + {L"f..", L"*.jpg", L"jpg", L"f...jpg"}, + {L"f.jpeg", L"*.jpg", L"jpg", L"f.jpeg"}, + // Further guarantees. + {L"f.jpg.jpg", L"*.jpg", L"jpg", L"f.jpg.jpg"}, + {L"f.exe.jpg", L"*.jpg", L"jpg", L"f.exe.jpg"}, + {L"f.jpg.exe", L"*.jpg", L"jpg", L"f.jpg.exe.jpg"}, + {L"f.exe..", L"*.jpg", L"jpg", L"f.exe...jpg"}, + {L"f.jpg..", L"*.jpg", L"jpg", L"f.jpg...jpg"}, + // Test the All Files filter (*.jpg). + {L"f", L"*.*", L"jpg", L"f"}, + {L"f.", L"*.*", L"jpg", L"f"}, + {L"f..", L"*.*", L"jpg", L"f"}, + {L"f.jpg", L"*.*", L"jpg", L"f.jpg"}, + {L"f.jpeg", L"*.*", L"jpg", L"f.jpeg"}, // Same MIME type (diff. ext). + // Test the empty filter, which should behave identically to the + // All Files filter. + {L"f", L"", L"jpg", L"f"}, + {L"f.", L"", L"jpg", L"f"}, + {L"f..", L"", L"jpg", L"f"}, + {L"f.jpg", L"", L"jpg", L"f.jpg"}, + {L"f.jpeg", L"", L"jpg", L"f.jpeg"}, +}; + +TEST(WinUtilTest, AppendingExtensions) { + for (unsigned int i = 0; i < arraysize(filename_cases); ++i) { + const filename_case& value = filename_cases[i]; + std::wstring result = + win_util::AppendExtensionIfNeeded(value.filename, value.filter_selected, + value.suggested_ext); + EXPECT_EQ(value.result, result); + } +} diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc index 7a2ce8b..88facc6 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc @@ -10,6 +10,7 @@ #include "app/l10n_util.h" #include "app/l10n_util_win.h" #include "app/os_exchange_data.h" +#include "app/win_util.h" #include "base/base_drag_source.h" #include "base/base_drop_target.h" #include "base/basictypes.h" @@ -35,7 +36,6 @@ #include "chrome/browser/views/location_bar_view.h" #include "chrome/common/gfx/utils.h" #include "chrome/common/notification_service.h" -#include "chrome/common/win_util.h" #include "googleurl/src/url_util.h" #include "grit/generated_resources.h" #include "skia/ext/skia_utils_win.h" diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index e0b4aad..955a3af 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -60,6 +60,7 @@ #include #include +#include "app/win_util.h" #include "chrome/browser/automation/ui_controls.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_url_handler.h" @@ -75,8 +76,6 @@ #include "chrome/browser/views/location_bar_view.h" #include "chrome/browser/window_sizer.h" #include "chrome/common/child_process_host.h" -#include "chrome/common/win_util.h" - #endif // OS_WIN using base::TimeDelta; diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index 9824586..28b8144 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -69,6 +69,7 @@ #include #include +#include "app/win_util.h" #include "base/registry.h" #include "base/win_util.h" #include "chrome/browser/browser.h" @@ -83,7 +84,6 @@ #include "chrome/browser/rlz/rlz.h" #include "chrome/browser/views/user_data_dir_dialog.h" #include "chrome/common/env_vars.h" -#include "chrome/common/win_util.h" #include "chrome/installer/util/google_update_settings.h" #include "chrome/installer/util/helper.h" #include "chrome/installer/util/install_util.h" diff --git a/chrome/browser/browser_main_win.cc b/chrome/browser/browser_main_win.cc index 28c849b..b86df5f 100644 --- a/chrome/browser/browser_main_win.cc +++ b/chrome/browser/browser_main_win.cc @@ -2,15 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/common/win_util.h" +#include "chrome/browser/browser_main_win.h" -#include #include - -#include "chrome/browser/browser_main_win.h" +#include #include "app/l10n_util.h" #include "app/message_box_flags.h" +#include "app/win_util.h" #include "base/command_line.h" #include "base/path_service.h" #include "base/win_util.h" diff --git a/chrome/browser/download/download_file.cc b/chrome/browser/download/download_file.cc index 6a93398..069fc58 100644 --- a/chrome/browser/download/download_file.cc +++ b/chrome/browser/download/download_file.cc @@ -24,7 +24,7 @@ #include "net/url_request/url_request_context.h" #if defined(OS_WIN) -#include "chrome/common/win_util.h" +#include "app/win_util.h" #include "chrome/common/win_safe_util.h" #elif defined(OS_MACOSX) #include "chrome/common/quarantine_mac.h" diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc index 0081a2d..a037fa01 100644 --- a/chrome/browser/download/download_manager.cc +++ b/chrome/browser/download/download_manager.cc @@ -42,11 +42,11 @@ #include "net/url_request/url_request_context.h" #if defined(OS_WIN) +#include "app/win_util.h" // TODO(port): some of these need porting. #include "base/registry.h" #include "base/win_util.h" #include "chrome/browser/download/download_util.h" -#include "chrome/common/win_util.h" #endif #if defined(OS_LINUX) diff --git a/chrome/browser/download/save_file.cc b/chrome/browser/download/save_file.cc index 5ee2ab8..cb83a87 100644 --- a/chrome/browser/download/save_file.cc +++ b/chrome/browser/download/save_file.cc @@ -11,7 +11,6 @@ #include "base/string_util.h" #include "chrome/browser/download/save_types.h" #if defined(OS_WIN) -#include "chrome/common/win_util.h" #include "chrome/common/win_safe_util.h" #endif diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc index d9af3ea..85c3003 100644 --- a/chrome/browser/download/save_package.cc +++ b/chrome/browser/download/save_package.cc @@ -38,11 +38,6 @@ #include "net/url_request/url_request_context.h" #include "webkit/glue/dom_serializer_delegate.h" -#if defined(OS_WIN) -#include "base/win_util.h" -#include "chrome/common/win_util.h" -#endif - using base::Time; // This structure is for storing parameters which we will use to create a diff --git a/chrome/browser/extensions/extension_error_reporter.cc b/chrome/browser/extensions/extension_error_reporter.cc index 8a17f26..c3a028c 100644 --- a/chrome/browser/extensions/extension_error_reporter.cc +++ b/chrome/browser/extensions/extension_error_reporter.cc @@ -4,11 +4,10 @@ #include "chrome/browser/extensions/extension_error_reporter.h" -#include "base/string_util.h" - #if defined(OS_WIN) -#include "chrome/common/win_util.h" +#include "app/win_util.h" #endif +#include "base/string_util.h" // No AddRef required when using ExtensionErrorReporter with RunnableMethod. // This is okay since the ExtensionErrorReporter is a singleton that lives until diff --git a/chrome/browser/external_tab_container.cc b/chrome/browser/external_tab_container.cc index 339fd29..f71129e 100644 --- a/chrome/browser/external_tab_container.cc +++ b/chrome/browser/external_tab_container.cc @@ -4,6 +4,7 @@ #include "chrome/browser/external_tab_container.h" +#include "app/win_util.h" #include "base/logging.h" #include "base/win_util.h" #include "chrome/browser/automation/automation_provider.h" @@ -15,7 +16,6 @@ #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/views/tab_contents_container_view.h" #include "chrome/common/chrome_constants.h" -#include "chrome/common/win_util.h" #include "chrome/test/automation/automation_messages.h" // Included for SetRootViewForHWND. #include "views/widget/widget_win.h" diff --git a/chrome/browser/hang_monitor/hung_plugin_action.cc b/chrome/browser/hang_monitor/hung_plugin_action.cc index 82d5fc9..5bed393 100644 --- a/chrome/browser/hang_monitor/hung_plugin_action.cc +++ b/chrome/browser/hang_monitor/hung_plugin_action.cc @@ -7,9 +7,9 @@ #include "chrome/browser/hang_monitor/hung_plugin_action.h" #include "app/l10n_util.h" +#include "app/win_util.h" #include "base/win_util.h" #include "chrome/common/logging_chrome.h" -#include "chrome/common/win_util.h" #include "grit/generated_resources.h" #include "webkit/glue/plugins/webplugin_delegate_impl.h" diff --git a/chrome/browser/importer/firefox_importer_utils.cc b/chrome/browser/importer/firefox_importer_utils.cc index c595659..1003b90 100644 --- a/chrome/browser/importer/firefox_importer_utils.cc +++ b/chrome/browser/importer/firefox_importer_utils.cc @@ -8,8 +8,10 @@ #if defined(OS_WIN) #include -#endif +#include "app/win_util.h" +#include "base/registry.h" +#endif #include "base/file_util.h" #include "base/logging.h" #include "base/string_util.h" @@ -20,10 +22,6 @@ #include "googleurl/src/gurl.h" #include "net/base/base64.h" -#if defined(OS_WIN) -#include "base/registry.h" -#include "chrome/common/win_util.h" -#endif namespace { diff --git a/chrome/browser/importer/ie_importer.cc b/chrome/browser/importer/ie_importer.cc index dde6c19..fe27b12 100644 --- a/chrome/browser/importer/ie_importer.cc +++ b/chrome/browser/importer/ie_importer.cc @@ -13,6 +13,7 @@ #include #include "app/l10n_util.h" +#include "app/win_util.h" #include "base/file_util.h" #include "base/registry.h" #include "base/string_util.h" @@ -23,7 +24,6 @@ #include "chrome/browser/search_engines/template_url_model.h" #include "chrome/common/time_format.h" #include "chrome/common/url_constants.h" -#include "chrome/common/win_util.h" #include "googleurl/src/gurl.h" #include "grit/generated_resources.h" diff --git a/chrome/browser/importer/importer.cc b/chrome/browser/importer/importer.cc index c97e9e1..66aa8ed 100644 --- a/chrome/browser/importer/importer.cc +++ b/chrome/browser/importer/importer.cc @@ -9,6 +9,9 @@ #include "app/gfx/favicon_size.h" #include "app/l10n_util.h" +#if defined(OS_WIN) +#include "app/win_util.h" +#endif #include "base/file_util.h" #include "base/gfx/png_encoder.h" #include "base/string_util.h" @@ -39,7 +42,6 @@ // TODO(port): Port these files. #if defined(OS_WIN) #include "chrome/browser/views/importer_lock_view.h" -#include "chrome/common/win_util.h" #include "views/window/window.h" #endif diff --git a/chrome/browser/importer/importer_unittest.cc b/chrome/browser/importer/importer_unittest.cc index 01b75cd..ebe23c8 100644 --- a/chrome/browser/importer/importer_unittest.cc +++ b/chrome/browser/importer/importer_unittest.cc @@ -13,6 +13,7 @@ #include #include +#include "app/win_util.h" #include "base/file_util.h" #include "base/path_service.h" #include "chrome/browser/importer/ie_importer.h" @@ -20,7 +21,6 @@ #include "chrome/browser/password_manager/ie7_password.h" #include "chrome/browser/profile.h" #include "chrome/common/chrome_paths.h" -#include "chrome/common/win_util.h" class ImporterTest : public testing::Test { public: diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index 51306f3..36d01c6 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -43,9 +43,9 @@ #include "webkit/glue/plugins/plugin_constants_win.h" #if defined(OS_WIN) +#include "app/win_util.h" #include "base/win_util.h" #include "chrome/browser/sandbox_policy.h" -#include "chrome/common/win_util.h" #include "sandbox/src/sandbox.h" #endif diff --git a/chrome/browser/printing/printed_document.cc b/chrome/browser/printing/printed_document.cc index c408513..08dc09f 100644 --- a/chrome/browser/printing/printed_document.cc +++ b/chrome/browser/printing/printed_document.cc @@ -8,6 +8,7 @@ #include "app/gfx/chrome_font.h" #include "app/gfx/text_elider.h" +#include "app/win_util.h" #include "base/message_loop.h" #include "base/time.h" #include "chrome/browser/printing/page_number.h" @@ -17,7 +18,6 @@ #include "chrome/common/gfx/emf.h" #include "chrome/common/time_format.h" #include "chrome/common/notification_service.h" -#include "chrome/common/win_util.h" #include "printing/units.h" #include "skia/ext/platform_device.h" diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc index cffd597..a02becc 100644 --- a/chrome/browser/process_singleton_win.cc +++ b/chrome/browser/process_singleton_win.cc @@ -5,6 +5,7 @@ #include "chrome/browser/process_singleton.h" #include "app/l10n_util.h" +#include "app/win_util.h" #include "base/base_paths.h" #include "base/command_line.h" #include "base/process_util.h" @@ -16,7 +17,6 @@ #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/result_codes.h" -#include "chrome/common/win_util.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index 0517ee3..f43e06ba 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -11,6 +11,9 @@ #include +#if defined(OS_WIN) +#include "app/win_util.h" +#endif #include "base/command_line.h" #include "base/linked_ptr.h" #include "base/logging.h" @@ -57,7 +60,6 @@ using WebKit::WebCache; // Once the above TODO is finished, then this block is all Windows-specific // files. #include "base/win_util.h" -#include "chrome/common/win_util.h" #include "chrome/browser/sandbox_policy.h" #include "sandbox/src/sandbox.h" #elif defined(OS_POSIX) diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc index cbbbad7..7519e3d 100644 --- a/chrome/browser/renderer_host/render_widget_host.cc +++ b/chrome/browser/renderer_host/render_widget_host.cc @@ -20,7 +20,6 @@ #if defined(OS_WIN) #include "base/gfx/gdi_util.h" #include "chrome/app/chrome_dll_resource.h" -#include "chrome/common/win_util.h" #endif // defined(OS_WIN) using base::Time; diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc index ee995e0..c0c8c8d 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_win.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc @@ -26,7 +26,6 @@ #include "chrome/common/native_web_keyboard_event.h" #include "chrome/common/plugin_messages.h" #include "chrome/common/render_messages.h" -#include "chrome/common/win_util.h" #include "grit/webkit_resources.h" #include "skia/ext/skia_utils_win.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" diff --git a/chrome/browser/sandbox_policy.cc b/chrome/browser/sandbox_policy.cc index 24d3c2e..32c1f44 100644 --- a/chrome/browser/sandbox_policy.cc +++ b/chrome/browser/sandbox_policy.cc @@ -4,6 +4,7 @@ #include "chrome/browser/sandbox_policy.h" +#include "app/win_util.h" #include "base/command_line.h" #include "base/debug_util.h" #include "base/file_util.h" @@ -21,7 +22,6 @@ #include "chrome/common/debug_flags.h" #include "chrome/common/ipc_logging.h" #include "chrome/common/notification_service.h" -#include "chrome/common/win_util.h" #include "sandbox/src/sandbox.h" #include "webkit/glue/plugins/plugin_list.h" diff --git a/chrome/browser/shell_integration.cc b/chrome/browser/shell_integration.cc index 9732305..0c45d56 100644 --- a/chrome/browser/shell_integration.cc +++ b/chrome/browser/shell_integration.cc @@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/browser/shell_integration.h" + #include #include #include -#include "chrome/browser/shell_integration.h" - +#include "app/win_util.h" #include "base/command_line.h" #include "base/file_util.h" #include "base/message_loop.h" @@ -17,7 +18,6 @@ #include "base/task.h" #include "base/win_util.h" #include "chrome/common/chrome_constants.h" -#include "chrome/common/win_util.h" #include "chrome/installer/util/browser_distribution.h" #include "chrome/installer/util/create_reg_key_work_item.h" #include "chrome/installer/util/set_reg_value_work_item.h" diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc index 8708487..0f01ea7 100644 --- a/chrome/browser/tab_contents/render_view_context_menu.cc +++ b/chrome/browser/tab_contents/render_view_context_menu.cc @@ -4,6 +4,9 @@ #include "chrome/browser/tab_contents/render_view_context_menu.h" +#if defined(OS_WIN) +#include "app/win_util.h" +#endif #include "app/l10n_util.h" #include "base/clipboard.h" #include "base/command_line.h" @@ -26,7 +29,6 @@ #if defined(OS_WIN) #include "chrome/browser/views/options/fonts_languages_window_view.h" #include "chrome/browser/views/page_info_window.h" -#include "chrome/common/win_util.h" #endif RenderViewContextMenu::RenderViewContextMenu( diff --git a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc index 2dddc6f..c133ee7 100644 --- a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc +++ b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc @@ -12,10 +12,10 @@ #include "app/gfx/path.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" +#include "app/win_util.h" #include "chrome/browser/autocomplete/autocomplete_edit_view_win.h" #include "chrome/browser/autocomplete/autocomplete_popup_model.h" #include "chrome/browser/views/autocomplete/autocomplete_popup_win.h" -#include "chrome/common/win_util.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "skia/include/SkShader.h" diff --git a/chrome/browser/views/autocomplete/autocomplete_popup_win.cc b/chrome/browser/views/autocomplete/autocomplete_popup_win.cc index 469561e..6dfbfee 100644 --- a/chrome/browser/views/autocomplete/autocomplete_popup_win.cc +++ b/chrome/browser/views/autocomplete/autocomplete_popup_win.cc @@ -5,10 +5,10 @@ #include "chrome/browser/views/autocomplete/autocomplete_popup_win.h" #include "app/gfx/insets.h" +#include "app/win_util.h" #include "chrome/browser/autocomplete/autocomplete_edit_view_win.h" #include "chrome/browser/autocomplete/autocomplete_popup_model.h" #include "chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h" -#include "chrome/common/win_util.h" //////////////////////////////////////////////////////////////////////////////// // AutocompletePopupWin, public: diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc index 5604db7..51beca0a 100644 --- a/chrome/browser/views/bookmark_bar_view.cc +++ b/chrome/browser/views/bookmark_bar_view.cc @@ -11,6 +11,7 @@ #include "app/l10n_util.h" #include "app/os_exchange_data.h" #include "app/resource_bundle.h" +#include "app/win_util.h" #include "base/string_util.h" #include "base/base_drag_source.h" #include "chrome/browser/bookmarks/bookmark_context_menu.h" @@ -31,7 +32,6 @@ #include "chrome/common/page_transition_types.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" -#include "chrome/common/win_util.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "skia/ext/skia_utils.h" diff --git a/chrome/browser/views/bookmark_manager_view.cc b/chrome/browser/views/bookmark_manager_view.cc index 41df839..d635932 100644 --- a/chrome/browser/views/bookmark_manager_view.cc +++ b/chrome/browser/views/bookmark_manager_view.cc @@ -24,7 +24,6 @@ #include "chrome/browser/views/bookmark_table_view.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" -#include "chrome/common/win_util.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" #include "skia/ext/skia_utils.h" diff --git a/chrome/browser/views/constrained_window_impl.cc b/chrome/browser/views/constrained_window_impl.cc index ca4f35c..cde0327 100644 --- a/chrome/browser/views/constrained_window_impl.cc +++ b/chrome/browser/views/constrained_window_impl.cc @@ -10,6 +10,7 @@ #include "app/gfx/text_elider.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" +#include "app/win_util.h" #include "base/gfx/rect.h" #include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/browser_process.h" @@ -24,7 +25,6 @@ #include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" -#include "chrome/common/win_util.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/views/download_item_view.cc b/chrome/browser/views/download_item_view.cc index aa74f2fa1..915e78f 100644 --- a/chrome/browser/views/download_item_view.cc +++ b/chrome/browser/views/download_item_view.cc @@ -10,13 +10,13 @@ #include "app/gfx/text_elider.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" +#include "app/win_util.h" #include "base/file_path.h" #include "base/string_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_util.h" #include "chrome/browser/views/download_shelf_view.h" -#include "chrome/common/win_util.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "views/controls/button/native_button.h" diff --git a/chrome/browser/views/frame/browser_frame.cc b/chrome/browser/views/frame/browser_frame.cc index 60187d8..c022b6a 100644 --- a/chrome/browser/views/frame/browser_frame.cc +++ b/chrome/browser/views/frame/browser_frame.cc @@ -8,12 +8,12 @@ #include #include "app/resource_bundle.h" +#include "app/win_util.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/views/frame/browser_root_view.h" #include "chrome/browser/views/frame/browser_view.h" #include "chrome/browser/views/frame/glass_browser_frame_view.h" #include "chrome/browser/views/frame/opaque_browser_frame_view.h" -#include "chrome/common/win_util.h" #include "grit/theme_resources.h" #include "views/window/window_delegate.h" diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index e1f8cc0..a3acb80 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -9,6 +9,7 @@ #include "app/l10n_util.h" #include "app/os_exchange_data.h" #include "app/resource_bundle.h" +#include "app/win_util.h" #include "base/command_line.h" #include "base/file_version_info.h" #include "base/time.h" @@ -54,7 +55,6 @@ #include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" -#include "chrome/common/win_util.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/views/frame/opaque_browser_frame_view.cc b/chrome/browser/views/frame/opaque_browser_frame_view.cc index a132119..10c604c 100644 --- a/chrome/browser/views/frame/opaque_browser_frame_view.cc +++ b/chrome/browser/views/frame/opaque_browser_frame_view.cc @@ -9,10 +9,10 @@ #include "app/gfx/path.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" +#include "app/win_util.h" #include "chrome/browser/views/frame/browser_frame.h" #include "chrome/browser/views/frame/browser_view.h" #include "chrome/browser/views/tabs/tab_strip.h" -#include "chrome/common/win_util.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/views/info_bubble.cc b/chrome/browser/views/info_bubble.cc index 674141c..b31a8f6 100644 --- a/chrome/browser/views/info_bubble.cc +++ b/chrome/browser/views/info_bubble.cc @@ -7,12 +7,12 @@ #include "app/gfx/chrome_canvas.h" #include "app/gfx/path.h" #include "app/resource_bundle.h" +#include "app/win_util.h" #include "base/win_util.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/views/frame/browser_view.h" #include "chrome/common/notification_service.h" #include "chrome/common/notification_type.h" -#include "chrome/common/win_util.h" #include "grit/theme_resources.h" #include "views/widget/root_view.h" #include "views/window/window.h" diff --git a/chrome/browser/views/location_bar_view.cc b/chrome/browser/views/location_bar_view.cc index 7683626..c1354f1 100644 --- a/chrome/browser/views/location_bar_view.cc +++ b/chrome/browser/views/location_bar_view.cc @@ -7,6 +7,7 @@ #include "app/gfx/chrome_canvas.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" +#include "app/win_util.h" #include "base/path_service.h" #include "base/string_util.h" #include "chrome/app/chrome_dll_resource.h" @@ -26,7 +27,6 @@ #include "chrome/browser/views/info_bubble.h" #include "chrome/browser/views/first_run_bubble.h" #include "chrome/browser/views/page_info_window.h" -#include "chrome/common/win_util.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "views/background.h" diff --git a/chrome/browser/views/options/cookies_view.cc b/chrome/browser/views/options/cookies_view.cc index 2b5ab0f..593487b 100644 --- a/chrome/browser/views/options/cookies_view.cc +++ b/chrome/browser/views/options/cookies_view.cc @@ -13,7 +13,6 @@ #include "base/string_util.h" #include "base/time_format.h" #include "chrome/browser/profile.h" -#include "chrome/common/win_util.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/views/page_info_window.cc b/chrome/browser/views/page_info_window.cc index 7f73092..b2f8a68 100644 --- a/chrome/browser/views/page_info_window.cc +++ b/chrome/browser/views/page_info_window.cc @@ -9,6 +9,7 @@ #include "app/l10n_util.h" #include "app/resource_bundle.h" +#include "app/win_util.h" #include "base/string_util.h" #include "base/time_format.h" #include "chrome/browser/browser_process.h" @@ -18,7 +19,6 @@ #include "chrome/browser/ssl/ssl_manager.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" -#include "chrome/common/win_util.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/views/shell_dialogs_win.cc b/chrome/browser/views/shell_dialogs_win.cc index 99664a1..c211660 100644 --- a/chrome/browser/views/shell_dialogs_win.cc +++ b/chrome/browser/views/shell_dialogs_win.cc @@ -14,12 +14,12 @@ #include "app/gfx/chrome_font.h" #include "app/l10n_util.h" +#include "app/win_util.h" #include "base/file_util.h" #include "base/registry.h" #include "base/string_util.h" #include "base/thread.h" #include "chrome/browser/browser_process.h" -#include "chrome/common/win_util.h" #include "grit/generated_resources.h" // Helpers to show certain types of Windows shell dialogs in a way that doesn't diff --git a/chrome/browser/views/tabs/tab_renderer.cc b/chrome/browser/views/tabs/tab_renderer.cc index 9bb88ae..87d0d01 100644 --- a/chrome/browser/views/tabs/tab_renderer.cc +++ b/chrome/browser/views/tabs/tab_renderer.cc @@ -10,11 +10,11 @@ #include "app/gfx/chrome_font.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" +#include "app/win_util.h" #include "chrome/browser/browser.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tabs/tab_strip_model.h" -#include "chrome/common/win_util.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "skia/ext/image_operations.h" diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc index 365e000..73c19e4a 100644 --- a/chrome/browser/views/tabs/tab_strip.cc +++ b/chrome/browser/views/tabs/tab_strip.cc @@ -11,6 +11,7 @@ #include "app/os_exchange_data.h" #include "app/resource_bundle.h" #include "app/slide_animation.h" +#include "app/win_util.h" #include "base/gfx/size.h" #include "base/stl_util-inl.h" #include "chrome/browser/metrics/user_metrics.h" @@ -22,7 +23,6 @@ #include "chrome/browser/views/tabs/tab.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/pref_names.h" -#include "chrome/common/win_util.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "views/controls/image_view.h" diff --git a/chrome/browser/views/toolbar_view.cc b/chrome/browser/views/toolbar_view.cc index 38cc412..c3c98d2 100644 --- a/chrome/browser/views/toolbar_view.cc +++ b/chrome/browser/views/toolbar_view.cc @@ -37,7 +37,6 @@ #include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" -#include "chrome/common/win_util.h" #ifdef CHROME_PERSONALIZATION #include "chrome/personalization/personalization.h" #endif diff --git a/chrome/browser/visitedlink_master.cc b/chrome/browser/visitedlink_master.cc index c22e866..54a3a22 100644 --- a/chrome/browser/visitedlink_master.cc +++ b/chrome/browser/visitedlink_master.cc @@ -13,6 +13,9 @@ #include +#if defined(OS_WIN) +#include "app/win_util.h" +#endif #include "base/file_util.h" #include "base/logging.h" #include "base/message_loop.h" @@ -25,9 +28,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/history/history.h" #include "chrome/browser/profile.h" -#if defined(OS_WIN) -#include "chrome/common/win_util.h" -#endif using file_util::ScopedFILE; using file_util::OpenFile; @@ -95,7 +95,7 @@ class AsyncWriter : public Task { // The write may not make it to the kernel (stdlib may buffer the write) // until the next fseek/fclose call. If we crash, it's easy for our used - // item count to be out of sync with the number of hashes we write. + // item count to be out of sync with the number of hashes we write. // Protect against this by calling fflush. int ret = fflush(file); DCHECK_EQ(0, ret); diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index de01a3e..6941455 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -169,6 +169,8 @@ '../app/slide_animation.h', '../app/throb_animation.cc', '../app/throb_animation.h', + '../app/win_util.cc', + '../app/win_util.h', ], 'direct_dependent_settings': { 'include_dirs': [ @@ -419,8 +421,6 @@ 'common/webkit_param_traits.h', 'common/win_safe_util.cc', 'common/win_safe_util.h', - 'common/win_util.cc', - 'common/win_util.h', 'common/worker_thread_ticker.cc', 'common/worker_thread_ticker.h', 'common/x11_util.cc', @@ -2633,7 +2633,7 @@ 'common/resource_dispatcher_unittest.cc', 'common/time_format_unittest.cc', 'common/unzip_unittest.cc', - 'common/win_util_unittest.cc', + '../app/win_util_unittest.cc', 'common/worker_thread_ticker_unittest.cc', 'renderer/extensions/extension_api_client_unittest.cc', 'renderer/extensions/greasemonkey_api_unittest.cc', diff --git a/chrome/common/common.vcproj b/chrome/common/common.vcproj index 5c6c28f..5ca07ee 100644 --- a/chrome/common/common.vcproj +++ b/chrome/common/common.vcproj @@ -734,14 +734,6 @@ > - - - - diff --git a/chrome/common/platform_util_win.cc b/chrome/common/platform_util_win.cc index 923904d..e0ee665 100644 --- a/chrome/common/platform_util_win.cc +++ b/chrome/common/platform_util_win.cc @@ -11,12 +11,12 @@ #include #include +#include "app/win_util.h" #include "base/file_path.h" #include "base/file_util.h" #include "base/gfx/native_widget_types.h" #include "base/logging.h" #include "base/string_util.h" -#include "chrome/common/win_util.h" namespace platform_util { diff --git a/chrome/common/win_safe_util.cc b/chrome/common/win_safe_util.cc index 4abf633..2187d30 100644 --- a/chrome/common/win_safe_util.cc +++ b/chrome/common/win_safe_util.cc @@ -8,11 +8,11 @@ #include "chrome/common/win_safe_util.h" +#include "app/win_util.h" #include "base/file_path.h" #include "base/logging.h" #include "base/path_service.h" #include "base/string_util.h" -#include "chrome/common/win_util.h" namespace win_util { diff --git a/chrome/common/win_util.cc b/chrome/common/win_util.cc deleted file mode 100644 index 95fc132..0000000 --- a/chrome/common/win_util.cc +++ /dev/null @@ -1,824 +0,0 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/common/win_util.h" - -#include -#include -#include -#include -#include -#include - -#include "app/l10n_util.h" -#include "app/l10n_util_win.h" -#include "base/file_util.h" -#include "base/gfx/gdi_util.h" -#include "base/gfx/png_encoder.h" -#include "base/logging.h" -#include "base/registry.h" -#include "base/scoped_handle.h" -#include "base/string_util.h" -#include "base/win_util.h" -#include "grit/generated_resources.h" -#include "net/base/mime_util.h" - -// Ensure that we pick up this link library. -#pragma comment(lib, "dwmapi.lib") - -namespace win_util { - -const int kAutoHideTaskbarThicknessPx = 2; - -namespace { - -// Enforce visible dialog box. -UINT_PTR CALLBACK SaveAsDialogHook(HWND dialog, UINT message, - WPARAM wparam, LPARAM lparam) { - static const UINT kPrivateMessage = 0x2F3F; - switch (message) { - case WM_INITDIALOG: { - // Do nothing here. Just post a message to defer actual processing. - PostMessage(dialog, kPrivateMessage, 0, 0); - return TRUE; - } - case kPrivateMessage: { - // The dialog box is the parent of the current handle. - HWND real_dialog = GetParent(dialog); - - // Retrieve the final size. - RECT dialog_rect; - GetWindowRect(real_dialog, &dialog_rect); - - // Verify that the upper left corner is visible. - POINT point = { dialog_rect.left, dialog_rect.top }; - HMONITOR monitor1 = MonitorFromPoint(point, MONITOR_DEFAULTTONULL); - point.x = dialog_rect.right; - point.y = dialog_rect.bottom; - - // Verify that the lower right corner is visible. - HMONITOR monitor2 = MonitorFromPoint(point, MONITOR_DEFAULTTONULL); - if (monitor1 && monitor2) - return 0; - - // Some part of the dialog box is not visible, fix it by moving is to the - // client rect position of the browser window. - HWND parent_window = GetParent(real_dialog); - if (!parent_window) - return 0; - WINDOWINFO parent_info; - parent_info.cbSize = sizeof(WINDOWINFO); - GetWindowInfo(parent_window, &parent_info); - SetWindowPos(real_dialog, NULL, - parent_info.rcClient.left, - parent_info.rcClient.top, - 0, 0, // Size. - SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | - SWP_NOZORDER); - - return 0; - } - } - return 0; -} - -} // namespace - -std::wstring FormatSystemTime(const SYSTEMTIME& time, - const std::wstring& format) { - // If the format string is empty, just use the default format. - LPCTSTR format_ptr = NULL; - if (!format.empty()) - format_ptr = format.c_str(); - - int buffer_size = GetTimeFormat(LOCALE_USER_DEFAULT, NULL, &time, format_ptr, - NULL, 0); - - std::wstring output; - GetTimeFormat(LOCALE_USER_DEFAULT, NULL, &time, format_ptr, - WriteInto(&output, buffer_size), buffer_size); - - return output; -} - -std::wstring FormatSystemDate(const SYSTEMTIME& date, - const std::wstring& format) { - // If the format string is empty, just use the default format. - LPCTSTR format_ptr = NULL; - if (!format.empty()) - format_ptr = format.c_str(); - - int buffer_size = GetDateFormat(LOCALE_USER_DEFAULT, NULL, &date, format_ptr, - NULL, 0); - - std::wstring output; - GetDateFormat(LOCALE_USER_DEFAULT, NULL, &date, format_ptr, - WriteInto(&output, buffer_size), buffer_size); - - return output; -} - -bool ConvertToLongPath(const std::wstring& short_path, - std::wstring* long_path) { - wchar_t long_path_buf[MAX_PATH]; - DWORD return_value = GetLongPathName(short_path.c_str(), long_path_buf, - MAX_PATH); - if (return_value != 0 && return_value < MAX_PATH) { - *long_path = long_path_buf; - return true; - } - - return false; -} - -bool IsDoubleClick(const POINT& origin, - const POINT& current, - DWORD elapsed_time) { - // The CXDOUBLECLK and CYDOUBLECLK system metrics describe the width and - // height of a rectangle around the origin position, inside of which clicks - // within the double click time are considered double clicks. - return (elapsed_time <= GetDoubleClickTime()) && - (abs(current.x - origin.x) <= (GetSystemMetrics(SM_CXDOUBLECLK) / 2)) && - (abs(current.y - origin.y) <= (GetSystemMetrics(SM_CYDOUBLECLK) / 2)); -} - -bool IsDrag(const POINT& origin, const POINT& current) { - // The CXDRAG and CYDRAG system metrics describe the width and height of a - // rectangle around the origin position, inside of which motion is not - // considered a drag. - return (abs(current.x - origin.x) > (GetSystemMetrics(SM_CXDRAG) / 2)) || - (abs(current.y - origin.y) > (GetSystemMetrics(SM_CYDRAG) / 2)); -} - -bool ShouldUseVistaFrame() { - if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) - return false; - // If composition is not enabled, we behave like on XP. - BOOL f; - DwmIsCompositionEnabled(&f); - return !!f; -} - -// Open an item via a shell execute command. Error code checking and casting -// explanation: http://msdn2.microsoft.com/en-us/library/ms647732.aspx -bool OpenItemViaShell(const FilePath& full_path, bool ask_for_app) { - HINSTANCE h = ::ShellExecuteW( - NULL, NULL, full_path.value().c_str(), NULL, - full_path.DirName().value().c_str(), SW_SHOWNORMAL); - - LONG_PTR error = reinterpret_cast(h); - if (error > 32) - return true; - - if ((error == SE_ERR_NOASSOC) && ask_for_app) - return OpenItemWithExternalApp(full_path.value()); - - return false; -} - -bool OpenItemViaShellNoZoneCheck(const FilePath& full_path, - bool ask_for_app) { - SHELLEXECUTEINFO sei = { sizeof(sei) }; - sei.fMask = SEE_MASK_NOZONECHECKS | SEE_MASK_FLAG_DDEWAIT; - sei.nShow = SW_SHOWNORMAL; - sei.lpVerb = NULL; - sei.lpFile = full_path.value().c_str(); - if (::ShellExecuteExW(&sei)) - return true; - LONG_PTR error = reinterpret_cast(sei.hInstApp); - if ((error == SE_ERR_NOASSOC) && ask_for_app) - return OpenItemWithExternalApp(full_path.value()); - return false; -} - -// Show the Windows "Open With" dialog box to ask the user to pick an app to -// open the file with. -bool OpenItemWithExternalApp(const std::wstring& full_path) { - SHELLEXECUTEINFO sei = { sizeof(sei) }; - sei.fMask = SEE_MASK_FLAG_DDEWAIT; - sei.nShow = SW_SHOWNORMAL; - sei.lpVerb = L"openas"; - sei.lpFile = full_path.c_str(); - return (TRUE == ::ShellExecuteExW(&sei)); -} - -// Get the file type description from the registry. This will be "Text Document" -// for .txt files, "JPEG Image" for .jpg files, etc. If the registry doesn't -// have an entry for the file type, we return false, true if the description was -// found. 'file_ext' must be in form ".txt". -static bool GetRegistryDescriptionFromExtension(const std::wstring& file_ext, - std::wstring* reg_description) { - DCHECK(reg_description); - RegKey reg_ext(HKEY_CLASSES_ROOT, file_ext.c_str(), KEY_READ); - std::wstring reg_app; - if (reg_ext.ReadValue(NULL, ®_app) && !reg_app.empty()) { - RegKey reg_link(HKEY_CLASSES_ROOT, reg_app.c_str(), KEY_READ); - if (reg_link.ReadValue(NULL, reg_description)) - return true; - } - return false; -} - -std::wstring FormatFilterForExtensions( - const std::vector& file_ext, - const std::vector& ext_desc, - bool include_all_files) { - const std::wstring all_ext = L"*.*"; - const std::wstring all_desc = l10n_util::GetString(IDS_SAVEAS_ALL_FILES); - - DCHECK(file_ext.size()>=ext_desc.size()); - - std::wstring result; - - for (size_t i=0; i(1, file_ext), - std::vector(), - true); - unsigned index = 1; - return SaveFileAsWithFilter(owner, - suggested_name, - filter, - L"", - false, - &index, - final_name); -} - -bool SaveFileAsWithFilter(HWND owner, - const std::wstring& suggested_name, - const std::wstring& filter, - const std::wstring& def_ext, - bool ignore_suggested_ext, - unsigned* index, - std::wstring* final_name) { - DCHECK(final_name); - // Having an empty filter makes for a bad user experience. We should always - // specify a filter when saving. - DCHECK(!filter.empty()); - std::wstring file_part = file_util::GetFilenameFromPath(suggested_name); - - // The size of the in/out buffer in number of characters we pass to win32 - // GetSaveFileName. From MSDN "The buffer must be large enough to store the - // path and file name string or strings, including the terminating NULL - // character. ... The buffer should be at least 256 characters long.". - // _IsValidPathComDlg does a copy expecting at most MAX_PATH, otherwise will - // result in an error of FNERR_INVALIDFILENAME. So we should only pass the - // API a buffer of at most MAX_PATH. - wchar_t file_name[MAX_PATH]; - base::wcslcpy(file_name, file_part.c_str(), arraysize(file_name)); - - OPENFILENAME save_as; - // We must do this otherwise the ofn's FlagsEx may be initialized to random - // junk in release builds which can cause the Places Bar not to show up! - ZeroMemory(&save_as, sizeof(save_as)); - save_as.lStructSize = sizeof(OPENFILENAME); - save_as.hwndOwner = owner; - save_as.hInstance = NULL; - - save_as.lpstrFilter = filter.empty() ? NULL : filter.c_str(); - - save_as.lpstrCustomFilter = NULL; - save_as.nMaxCustFilter = 0; - save_as.nFilterIndex = *index; - save_as.lpstrFile = file_name; - save_as.nMaxFile = arraysize(file_name); - save_as.lpstrFileTitle = NULL; - save_as.nMaxFileTitle = 0; - - // Set up the initial directory for the dialog. - std::wstring directory = file_util::GetDirectoryFromPath(suggested_name); - save_as.lpstrInitialDir = directory.c_str(); - save_as.lpstrTitle = NULL; - save_as.Flags = OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_ENABLESIZING | - OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST; - save_as.lpstrDefExt = &def_ext[0]; - save_as.lCustData = NULL; - - if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) { - // The save as on Windows XP remembers its last position, - // and if the screen resolution changed, it will be off screen. - save_as.Flags |= OFN_ENABLEHOOK; - save_as.lpfnHook = &SaveAsDialogHook; - } - - // Must be NULL or 0. - save_as.pvReserved = NULL; - save_as.dwReserved = 0; - - if (!GetSaveFileName(&save_as)) { - // Zero means the dialog was closed, otherwise we had an error. - DWORD error_code = CommDlgExtendedError(); - if (error_code != 0) { - NOTREACHED() << "GetSaveFileName failed with code: " << error_code; - } - return false; - } - - // Return the user's choice. - final_name->assign(save_as.lpstrFile); - *index = save_as.nFilterIndex; - - // Figure out what filter got selected from the vector with embedded nulls. - // NOTE: The filter contains a string with embedded nulls, such as: - // JPG Image\0*.jpg\0All files\0*.*\0\0 - // The filter index is 1-based index for which pair got selected. So, using - // the example above, if the first index was selected we need to skip 1 - // instance of null to get to "*.jpg". - std::vector filters; - if (!filter.empty() && save_as.nFilterIndex > 0) - SplitString(filter, '\0', &filters); - std::wstring filter_selected; - if (!filters.empty()) - filter_selected = filters[(2 * (save_as.nFilterIndex - 1)) + 1]; - - // Get the extension that was suggested to the user (when the Save As dialog - // was opened). For saving web pages, we skip this step since there may be - // 'extension characters' in the title of the web page. - std::wstring suggested_ext; - if (!ignore_suggested_ext) - suggested_ext = file_util::GetFileExtensionFromPath(suggested_name); - - // If we can't get the extension from the suggested_name, we use the default - // extension passed in. This is to cover cases like when saving a web page, - // where we get passed in a name without an extension and a default extension - // along with it. - if (suggested_ext.empty()) - suggested_ext = def_ext; - - *final_name = - AppendExtensionIfNeeded(*final_name, filter_selected, suggested_ext); - return true; -} - -std::wstring AppendExtensionIfNeeded(const std::wstring& filename, - const std::wstring& filter_selected, - const std::wstring& suggested_ext) { - std::wstring return_value = filename; - - // Get the extension the user ended up selecting. - std::wstring selected_ext = file_util::GetFileExtensionFromPath(filename); - - if (filter_selected.empty() || filter_selected == L"*.*") { - // If the user selects 'All files' we respect any extension given to us from - // the File Save dialog. We also strip any trailing dots, which matches - // Windows Explorer and is needed because Windows doesn't allow filenames - // to have trailing dots. The GetSaveFileName dialog will not return a - // string with only one or more dots. - size_t index = return_value.find_last_not_of(L'.'); - if (index < return_value.size() - 1) - return_value.resize(index + 1); - } else { - // User selected a specific filter (not *.*) so we need to check if the - // extension provided has the same mime type. If it doesn't we append the - // extension. - std::string suggested_mime_type, selected_mime_type; - if (suggested_ext != selected_ext && - (!net::GetMimeTypeFromExtension(suggested_ext, &suggested_mime_type) || - !net::GetMimeTypeFromExtension(selected_ext, &selected_mime_type) || - suggested_mime_type != selected_mime_type)) { - return_value.append(L"."); - return_value.append(suggested_ext); - } - } - - return return_value; -} - -// Adjust the window to fit, returning true if the window was resized or moved. -static bool AdjustWindowToFit(HWND hwnd, const RECT& bounds) { - // Get the monitor. - HMONITOR hmon = MonitorFromRect(&bounds, MONITOR_DEFAULTTONEAREST); - if (!hmon) { - NOTREACHED() << "Unable to find default monitor"; - // No monitor available. - return false; - } - - MONITORINFO mi; - mi.cbSize = sizeof(mi); - GetMonitorInfo(hmon, &mi); - gfx::Rect window_rect(bounds); - gfx::Rect monitor_rect(mi.rcWork); - gfx::Rect new_window_rect = window_rect.AdjustToFit(monitor_rect); - if (!new_window_rect.Equals(window_rect)) { - // Window doesn't fit on monitor, move and possibly resize. - SetWindowPos(hwnd, 0, new_window_rect.x(), new_window_rect.y(), - new_window_rect.width(), new_window_rect.height(), - SWP_NOACTIVATE | SWP_NOZORDER); - return true; - } else { - return false; - } -} - -void AdjustWindowToFit(HWND hwnd) { - // Get the window bounds. - RECT r; - GetWindowRect(hwnd, &r); - AdjustWindowToFit(hwnd, r); -} - -void CenterAndSizeWindow(HWND parent, HWND window, const SIZE& pref, - bool pref_is_client) { - DCHECK(window && pref.cx > 0 && pref.cy > 0); - // Calculate the ideal bounds. - RECT window_bounds; - RECT center_bounds = {0}; - if (parent) { - // If there is a parent, center over the parents bounds. - ::GetWindowRect(parent, ¢er_bounds); - } else { - // No parent. Center over the monitor the window is on. - HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST); - if (monitor) { - MONITORINFO mi = {0}; - mi.cbSize = sizeof(mi); - GetMonitorInfo(monitor, &mi); - center_bounds = mi.rcWork; - } else { - NOTREACHED() << "Unable to get default monitor"; - } - } - window_bounds.left = center_bounds.left + - (center_bounds.right - center_bounds.left - pref.cx) / 2; - window_bounds.right = window_bounds.left + pref.cx; - window_bounds.top = center_bounds.top + - (center_bounds.bottom - center_bounds.top - pref.cy) / 2; - window_bounds.bottom = window_bounds.top + pref.cy; - - // If we're centering a child window, we are positioning in client - // coordinates, and as such we need to offset the target rectangle by the - // position of the parent window. - if (::GetWindowLong(window, GWL_STYLE) & WS_CHILD) { - DCHECK(parent && ::GetParent(window) == parent); - POINT topleft = { window_bounds.left, window_bounds.top }; - ::MapWindowPoints(HWND_DESKTOP, parent, &topleft, 1); - window_bounds.left = topleft.x; - window_bounds.top = topleft.y; - window_bounds.right = window_bounds.left + pref.cx; - window_bounds.bottom = window_bounds.top + pref.cy; - } - - // Get the WINDOWINFO for window. We need the style to calculate the size - // for the window. - WINDOWINFO win_info = {0}; - win_info.cbSize = sizeof(WINDOWINFO); - GetWindowInfo(window, &win_info); - - // Calculate the window size needed for the content size. - - if (!pref_is_client || - AdjustWindowRectEx(&window_bounds, win_info.dwStyle, FALSE, - win_info.dwExStyle)) { - if (!AdjustWindowToFit(window, window_bounds)) { - // The window fits, reset the bounds. - SetWindowPos(window, 0, window_bounds.left, window_bounds.top, - window_bounds.right - window_bounds.left, - window_bounds.bottom - window_bounds.top, - SWP_NOACTIVATE | SWP_NOZORDER); - } // else case, AdjustWindowToFit set the bounds for us. - } else { - NOTREACHED() << "Unable to adjust window to fit"; - } -} - -bool EdgeHasTopmostAutoHideTaskbar(UINT edge, HMONITOR monitor) { - APPBARDATA taskbar_data = { 0 }; - taskbar_data.cbSize = sizeof APPBARDATA; - taskbar_data.uEdge = edge; - HWND taskbar = reinterpret_cast(SHAppBarMessage(ABM_GETAUTOHIDEBAR, - &taskbar_data)); - return ::IsWindow(taskbar) && (monitor != NULL) && - (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONULL) == monitor) && - (GetWindowLong(taskbar, GWL_EXSTYLE) & WS_EX_TOPMOST); -} - -HANDLE GetSectionFromProcess(HANDLE section, HANDLE process, bool read_only) { - HANDLE valid_section = NULL; - DWORD access = STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ; - if (!read_only) - access |= FILE_MAP_WRITE; - DuplicateHandle(process, section, GetCurrentProcess(), &valid_section, access, - FALSE, 0); - return valid_section; -} - -bool DoesWindowBelongToActiveWindow(HWND window) { - DCHECK(window); - HWND top_window = ::GetAncestor(window, GA_ROOT); - if (!top_window) - return false; - - HWND active_top_window = ::GetAncestor(::GetForegroundWindow(), GA_ROOT); - return (top_window == active_top_window); -} - -void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect, - gfx::Rect* child_rect, - int padding) { - DCHECK(child_rect); - - // We use padding here because it allows some of the original web page to - // bleed through around the edges. - int twice_padding = padding * 2; - - // FIRST, clamp width and height so we don't open child windows larger than - // the containing parent. - if (child_rect->width() > (parent_rect.width() + twice_padding)) - child_rect->set_width(std::max(0, parent_rect.width() - twice_padding)); - if (child_rect->height() > parent_rect.height() + twice_padding) - child_rect->set_height(std::max(0, parent_rect.height() - twice_padding)); - - // SECOND, clamp x,y position to padding,padding so we don't position child - // windows in hyperspace. - // TODO(mpcomplete): I don't see what the second check in each 'if' does that - // isn't handled by the LAST set of 'ifs'. Maybe we can remove it. - if (child_rect->x() < parent_rect.x() || - child_rect->x() > parent_rect.right()) { - child_rect->set_x(parent_rect.x() + padding); - } - if (child_rect->y() < parent_rect.y() || - child_rect->y() > parent_rect.bottom()) { - child_rect->set_y(parent_rect.y() + padding); - } - - // LAST, nudge the window back up into the client area if its x,y position is - // within the parent bounds but its width/height place it off-screen. - if (child_rect->bottom() > parent_rect.bottom()) - child_rect->set_y(parent_rect.bottom() - child_rect->height() - padding); - if (child_rect->right() > parent_rect.right()) - child_rect->set_x(parent_rect.right() - child_rect->width() - padding); -} - -void SetChildBounds(HWND child_window, HWND parent_window, - HWND insert_after_window, const gfx::Rect& bounds, - int padding, unsigned long flags) { - DCHECK(IsWindow(child_window)); - - // First figure out the bounds of the parent. - RECT parent_rect = {0}; - if (parent_window) { - GetClientRect(parent_window, &parent_rect); - } else { - // If there is no parent, we consider the bounds of the monitor the window - // is on to be the parent bounds. - - // If the child_window isn't visible yet and we've been given a valid, - // visible insert after window, use that window to locate the correct - // monitor instead. - HWND window = child_window; - if (!IsWindowVisible(window) && IsWindow(insert_after_window) && - IsWindowVisible(insert_after_window)) - window = insert_after_window; - - POINT window_point = { bounds.x(), bounds.y() }; - HMONITOR monitor = MonitorFromPoint(window_point, - MONITOR_DEFAULTTONEAREST); - if (monitor) { - MONITORINFO mi = {0}; - mi.cbSize = sizeof(mi); - GetMonitorInfo(monitor, &mi); - parent_rect = mi.rcWork; - } else { - NOTREACHED() << "Unable to get default monitor"; - } - } - - gfx::Rect actual_bounds = bounds; - EnsureRectIsVisibleInRect(gfx::Rect(parent_rect), &actual_bounds, padding); - - SetWindowPos(child_window, insert_after_window, actual_bounds.x(), - actual_bounds.y(), actual_bounds.width(), - actual_bounds.height(), flags); -} - -gfx::Rect GetMonitorBoundsForRect(const gfx::Rect& rect) { - RECT p_rect = rect.ToRECT(); - HMONITOR monitor = MonitorFromRect(&p_rect, MONITOR_DEFAULTTONEAREST); - if (monitor) { - MONITORINFO mi = {0}; - mi.cbSize = sizeof(mi); - GetMonitorInfo(monitor, &mi); - return gfx::Rect(mi.rcWork); - } - NOTREACHED(); - return gfx::Rect(); -} - -bool IsNumPadDigit(int key_code, bool extended_key) { - if (key_code >= VK_NUMPAD0 && key_code <= VK_NUMPAD9) - return true; - - // Check for num pad keys without NumLock. - // Note: there is no easy way to know if a the key that was pressed comes from - // the num pad or the rest of the keyboard. Investigating how - // TranslateMessage() generates the WM_KEYCHAR from an - // ALT + it appears it looks at the extended key flag - // (which is on if the key pressed comes from one of the 3 clusters to - // the left of the numeric keypad). So we use it as well. - return !extended_key && - ((key_code >= VK_PRIOR && key_code <= VK_DOWN) || // All keys but 5 - // and 0. - (key_code == VK_CLEAR) || // Key 5. - (key_code == VK_INSERT)); // Key 0. -} - -void GrabWindowSnapshot(HWND window_handle, - std::vector* png_representation) { - // Create a memory DC that's compatible with the window. - CWindowDC window_hdc(window_handle); - CDC mem_hdc(::CreateCompatibleDC(window_hdc)); - - // Create a DIB that's the same size as the window. - RECT content_rect = {0, 0, 0, 0}; - ::GetWindowRect(window_handle, &content_rect); - content_rect.right++; // Match what PrintWindow wants. - int width = content_rect.right - content_rect.left; - int height = content_rect.bottom - content_rect.top; - BITMAPINFOHEADER hdr; - gfx::CreateBitmapHeader(width, height, &hdr); - unsigned char *bit_ptr = NULL; - CBitmap bitmap(::CreateDIBSection(mem_hdc, - reinterpret_cast(&hdr), - DIB_RGB_COLORS, - reinterpret_cast(&bit_ptr), - NULL, 0)); - - mem_hdc.SelectBitmap(bitmap); - // Clear the bitmap to white (so that rounded corners on windows - // show up on a white background, and strangely-shaped windows - // look reasonable). Not capturing an alpha mask saves a - // bit of space. - mem_hdc.PatBlt(0, 0, width, height, WHITENESS); - // Grab a copy of the window - // First, see if PrintWindow is defined (it's not in Windows 2000). - typedef BOOL (WINAPI *PrintWindowPointer)(HWND, HDC, UINT); - PrintWindowPointer print_window = - reinterpret_cast( - GetProcAddress(GetModuleHandle(L"User32.dll"), "PrintWindow")); - - // If PrintWindow is defined, use it. It will work on partially - // obscured windows, and works better for out of process sub-windows. - // Otherwise grab the bits we can get with BitBlt; it's better - // than nothing and will work fine in the average case (window is - // completely on screen). - if (print_window) - (*print_window)(window_handle, mem_hdc, 0); - else - mem_hdc.BitBlt(0, 0, width, height, window_hdc, 0, 0, SRCCOPY); - - // We now have a copy of the window contents in a DIB, so - // encode it into a useful format for posting to the bug report - // server. - PNGEncoder::Encode(bit_ptr, PNGEncoder::FORMAT_BGRA, - width, height, width * 4, true, - png_representation); -} - -bool IsWindowActive(HWND hwnd) { - WINDOWINFO info; - return ::GetWindowInfo(hwnd, &info) && - ((info.dwWindowStatus & WS_ACTIVECAPTION) != 0); -} - -bool IsReservedName(const std::wstring& filename) { - // This list is taken from the MSDN article "Naming a file" - // http://msdn2.microsoft.com/en-us/library/aa365247(VS.85).aspx - // I also added clock$ because GetSaveFileName seems to consider it as a - // reserved name too. - static const wchar_t* const known_devices[] = { - L"con", L"prn", L"aux", L"nul", L"com1", L"com2", L"com3", L"com4", L"com5", - L"com6", L"com7", L"com8", L"com9", L"lpt1", L"lpt2", L"lpt3", L"lpt4", - L"lpt5", L"lpt6", L"lpt7", L"lpt8", L"lpt9", L"clock$" - }; - std::wstring filename_lower = StringToLowerASCII(filename); - - for (int i = 0; i < arraysize(known_devices); ++i) { - // Exact match. - if (filename_lower == known_devices[i]) - return true; - // Starts with "DEVICE.". - if (filename_lower.find(std::wstring(known_devices[i]) + L".") == 0) - return true; - } - - static const wchar_t* const magic_names[] = { - // These file names are used by the "Customize folder" feature of the shell. - L"desktop.ini", - L"thumbs.db", - }; - - for (int i = 0; i < arraysize(magic_names); ++i) { - if (filename_lower == magic_names[i]) - return true; - } - - return false; -} - -bool IsShellIntegratedExtension(const std::wstring& extension) { - std::wstring extension_lower = StringToLowerASCII(extension); - - static const wchar_t* const integrated_extensions[] = { - // See . - L"local", - // Right-clicking on shortcuts can be magical. - L"lnk", - }; - - for (int i = 0; i < arraysize(integrated_extensions); ++i) { - if (extension_lower == integrated_extensions[i]) - return true; - } - - // See . - // That vulnerability report is not exactly on point, but files become magical - // if their end in a CLSID. Here we block extensions that look like CLSIDs. - if (extension_lower.size() > 0 && extension_lower.at(0) == L'{' && - extension_lower.at(extension_lower.length() - 1) == L'}') - return true; - - return false; -} - -// In addition to passing the RTL flags to ::MessageBox if we are running in an -// RTL locale, we need to make sure that LTR strings are rendered correctly by -// adding the appropriate Unicode directionality marks. -int MessageBox(HWND hwnd, - const std::wstring& text, - const std::wstring& caption, - UINT flags) { - UINT actual_flags = flags; - if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) - actual_flags |= MB_RIGHT | MB_RTLREADING; - - std::wstring localized_text; - const wchar_t* text_ptr = text.c_str(); - if (l10n_util::AdjustStringForLocaleDirection(text, &localized_text)) - text_ptr = localized_text.c_str(); - - std::wstring localized_caption; - const wchar_t* caption_ptr = caption.c_str(); - if (l10n_util::AdjustStringForLocaleDirection(caption, &localized_caption)) - caption_ptr = localized_caption.c_str(); - - return ::MessageBox(hwnd, text_ptr, caption_ptr, actual_flags); -} - -ChromeFont GetWindowTitleFont() { - NONCLIENTMETRICS ncm; - win_util::GetNonClientMetrics(&ncm); - l10n_util::AdjustUIFont(&(ncm.lfCaptionFont)); - ScopedHFONT caption_font(CreateFontIndirect(&(ncm.lfCaptionFont))); - return ChromeFont::CreateFont(caption_font); -} - -} // namespace win_util diff --git a/chrome/common/win_util.h b/chrome/common/win_util.h deleted file mode 100644 index 282fe2a3..0000000 --- a/chrome/common/win_util.h +++ /dev/null @@ -1,295 +0,0 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_COMMON_WIN_UTIL_H_ -#define CHROME_COMMON_WIN_UTIL_H_ - -#include - -#include -#include - -#include "app/gfx/chrome_font.h" -#include "base/fix_wp64.h" -#include "base/gfx/rect.h" -#include "base/scoped_handle.h" - -class FilePath; - -namespace win_util { - -// Import ScopedHandle and friends into this namespace for backwards -// compatibility. TODO(darin): clean this up! -using ::ScopedHandle; -using ::ScopedFindFileHandle; -using ::ScopedHDC; -using ::ScopedBitmap; -using ::ScopedHRGN; - -// Simple scoped memory releaser class for COM allocated memory. -// Example: -// CoMemReleaser file_item; -// SHGetSomeInfo(&file_item, ...); -// ... -// return; <-- memory released -template -class CoMemReleaser { - public: - explicit CoMemReleaser() : mem_ptr_(NULL) {} - - ~CoMemReleaser() { - if (mem_ptr_) - CoTaskMemFree(mem_ptr_); - } - - T** operator&() { - return &mem_ptr_; - } - - operator T*() { - return mem_ptr_; - } - - private: - T* mem_ptr_; - - DISALLOW_COPY_AND_ASSIGN(CoMemReleaser); -}; - -// Initializes COM in the constructor (STA), and uninitializes COM in the -// destructor. -class ScopedCOMInitializer { - public: - ScopedCOMInitializer() : hr_(CoInitialize(NULL)) { - } - - ScopedCOMInitializer::~ScopedCOMInitializer() { - if (SUCCEEDED(hr_)) - CoUninitialize(); - } - - // Returns the error code from CoInitialize(NULL) - // (called in constructor) - inline HRESULT error_code() const { - return hr_; - } - - protected: - HRESULT hr_; - - private: - DISALLOW_COPY_AND_ASSIGN(ScopedCOMInitializer); -}; - -// Creates a string interpretation of the time of day represented by the given -// SYSTEMTIME that's appropriate for the user's default locale. -// Format can be an empty string (for the default format), or a "format picture" -// as specified in the Windows documentation for GetTimeFormat(). -std::wstring FormatSystemTime(const SYSTEMTIME& time, - const std::wstring& format); - -// Creates a string interpretation of the date represented by the given -// SYSTEMTIME that's appropriate for the user's default locale. -// Format can be an empty string (for the default format), or a "format picture" -// as specified in the Windows documentation for GetDateFormat(). -std::wstring FormatSystemDate(const SYSTEMTIME& date, - const std::wstring& format); - -// Returns the long path name given a short path name. A short path name -// is a path that follows the 8.3 convention and has ~x in it. If the -// path is already a long path name, the function returns the current -// path without modification. -bool ConvertToLongPath(const std::wstring& short_path, std::wstring* long_path); - -// Returns true if the current point is close enough to the origin point in -// space and time that it would be considered a double click. -bool IsDoubleClick(const POINT& origin, - const POINT& current, - DWORD elapsed_time); - -// Returns true if the current point is far enough from the origin that it -// would be considered a drag. -bool IsDrag(const POINT& origin, const POINT& current); - -// Returns true if we are on Windows Vista and composition is enabled -bool ShouldUseVistaFrame(); - -// Open or run a file via the Windows shell. In the event that there is no -// default application registered for the file specified by 'full_path', -// ask the user, via the Windows "Open With" dialog, for an application to use -// if 'ask_for_app' is true. -// Returns 'true' on successful open, 'false' otherwise. -bool OpenItemViaShell(const FilePath& full_path, bool ask_for_app); - -// The download manager now writes the alternate data stream with the -// zone on all downloads. This function is equivalent to OpenItemViaShell -// without showing the zone warning dialog. -bool OpenItemViaShellNoZoneCheck(const FilePath& full_path, - bool ask_for_app); - -// Ask the user, via the Windows "Open With" dialog, for an application to use -// to open the file specified by 'full_path'. -// Returns 'true' on successful open, 'false' otherwise. -bool OpenItemWithExternalApp(const std::wstring& full_path); - -// Set up a filter for a Save/Open dialog, which will consist of |file_ext| file -// extensions (internally separated by semicolons), |ext_desc| as the text -// descriptions of the |file_ext| types (optional), and (optionally) the default -// 'All Files' view. The purpose of the filter is to show only files of a -// particular type in a Windows Save/Open dialog box. The resulting filter is -// returned. The filters created here are: -// 1. only files that have 'file_ext' as their extension -// 2. all files (only added if 'include_all_files' is true) -// Example: -// file_ext: { "*.txt", "*.htm;*.html" } -// ext_desc: { "Text Document" } -// returned: "Text Document\0*.txt\0HTML Document\0*.htm;*.html\0" -// "All Files\0*.*\0\0" (in one big string) -// If a description is not provided for a file extension, it will be retrieved -// from the registry. If the file extension does not exist in the registry, it -// will be omitted from the filter, as it is likely a bogus extension. -std::wstring FormatFilterForExtensions( - const std::vector& file_ext, - const std::vector& ext_desc, - bool include_all_files); - -// Prompt the user for location to save a file. 'suggested_name' is a full path -// that gives the dialog box a hint as to how to initialize itself. -// For example, a 'suggested_name' of: -// "C:\Documents and Settings\jojo\My Documents\picture.png" -// will start the dialog in the "C:\Documents and Settings\jojo\My Documents\" -// directory, and filter for .png file types. -// 'owner' is the window to which the dialog box is modal, NULL for a modeless -// dialog box. -// On success, returns true and 'final_name' contains the full path of the file -// that the user chose. On error, returns false, and 'final_name' is not -// modified. -// NOTE: DO NOT CALL THIS FUNCTION DIRECTLY! Instead use the helper objects in -// browser/shell_dialogs.cc to do this asynchronously on a different -// thread so that the app isn't jankified if the Windows shell dialog -// takes a long time to display. -bool SaveFileAs(HWND owner, - const std::wstring& suggested_name, - std::wstring* final_name); - -// Prompt the user for location to save a file. -// Callers should provide the filter string, and also a filter index. -// The parameter |index| indicates the initial index of filter description -// and filter pattern for the dialog box. If |index| is zero or greater than -// the number of total filter types, the system uses the first filter in the -// |filter| buffer. |index| is used to specify the initial selected extension, -// and when done contains the extension the user chose. The parameter -// |final_name| returns the file name which contains the drive designator, -// path, file name, and extension of the user selected file name. |def_ext| is -// the default extension to give to the file if the user did not enter an -// extension. If |ignore_suggested_ext| is true, any file extension contained in -// |suggested_name| will not be used to generate the file name. This is useful -// in the case of saving web pages, where we know the extension type already and -// where |suggested_name| may contain a '.' character as a valid part of the -// name, thus confusing our extension detection code. -bool SaveFileAsWithFilter(HWND owner, - const std::wstring& suggested_name, - const std::wstring& filter, - const std::wstring& def_ext, - bool ignore_suggested_ext, - unsigned* index, - std::wstring* final_name); - -// This function takes the output of a SaveAs dialog: a filename, a filter and -// the extension originally suggested to the user (shown in the dialog box) and -// returns back the filename with the appropriate extension tacked on. For -// example, if you pass in 'foo' as filename with filter '*.jpg' this function -// will return 'foo.jpg'. It respects MIME types, so if you pass in 'foo.jpeg' -// with filer '*.jpg' it will return 'foo.jpeg' (will not append .jpg). -// |filename| should contain the filename selected in the SaveAs dialog box and -// may include the path, |filter_selected| should be '*.something', for example -// '*.*' or it can be blank (which is treated as *.*). |suggested_ext| should -// contain the extension without the dot (.) in front, for example 'jpg'. -std::wstring AppendExtensionIfNeeded(const std::wstring& filename, - const std::wstring& filter_selected, - const std::wstring& suggested_ext); - -// If the window does not fit on the default monitor, it is moved and possibly -// resized appropriately. -void AdjustWindowToFit(HWND hwnd); - -// Sizes the window to have a client or window size (depending on the value of -// |pref_is_client|) of pref, then centers the window over parent, ensuring the -// window fits on screen. -void CenterAndSizeWindow(HWND parent, HWND window, const SIZE& pref, - bool pref_is_client); - -// Returns true if edge |edge| (one of ABE_LEFT, TOP, RIGHT, or BOTTOM) of -// monitor |monitor| has an auto-hiding taskbar that's always-on-top. -bool EdgeHasTopmostAutoHideTaskbar(UINT edge, HMONITOR monitor); - -// Duplicates a section handle from another process to the current process. -// Returns the new valid handle if the function succeed. NULL otherwise. -HANDLE GetSectionFromProcess(HANDLE section, HANDLE process, bool read_only); - -// Returns true if the specified window is the current active top window or one -// of its children. -bool DoesWindowBelongToActiveWindow(HWND window); - -// Adjusts the value of |child_rect| if necessary to ensure that it is -// completely visible within |parent_rect|. -void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect, - gfx::Rect* child_rect, - int padding); - -// Ensures that the child window stays within the boundaries of the parent -// before setting its bounds. If |parent_window| is NULL, the bounds of the -// parent are assumed to be the bounds of the monitor that |child_window| is -// nearest to. If |child_window| isn't visible yet and |insert_after_window| -// is non-NULL and visible, the monitor |insert_after_window| is on is used -// as the parent bounds instead. -void SetChildBounds(HWND child_window, HWND parent_window, - HWND insert_after_window, const gfx::Rect& bounds, - int padding, unsigned long flags); - -// Returns the bounds for the monitor that contains the largest area of -// intersection with the specified rectangle. -gfx::Rect GetMonitorBoundsForRect(const gfx::Rect& rect); - -// Returns true if the virtual key code is a digit coming from the numeric -// keypad (with or without NumLock on). |extended_key| should be set to the -// extended key flag specified in the WM_KEYDOWN/UP where the |key_code| -// originated. -bool IsNumPadDigit(int key_code, bool extended_key); - -// Grabs a snapshot of the designated window and stores a PNG representation -// into a byte vector. -void GrabWindowSnapshot(HWND window_handle, - std::vector* png_representation); - -// Returns whether the specified window is the current active window. -bool IsWindowActive(HWND hwnd); - -// Returns whether the specified file name is a reserved name on windows. -// This includes names like "com2.zip" (which correspond to devices) and -// desktop.ini and thumbs.db which have special meaning to the windows shell. -bool IsReservedName(const std::wstring& filename); - -// Returns whether the specified extension is automatically integrated into the -// windows shell. -bool IsShellIntegratedExtension(const std::wstring& eextension); - -// A wrapper around Windows' MessageBox function. Using a Chrome specific -// MessageBox function allows us to control certain RTL locale flags so that -// callers don't have to worry about adding these flags when running in a -// right-to-left locale. -int MessageBox(HWND hwnd, - const std::wstring& text, - const std::wstring& caption, - UINT flags); - -// Returns the system set window title font. -ChromeFont GetWindowTitleFont(); - -// The thickness of an auto-hide taskbar in pixels. -extern const int kAutoHideTaskbarThicknessPx; - -} // namespace win_util - -#endif // CHROME_COMMON_WIN_UTIL_H_ diff --git a/chrome/common/win_util_unittest.cc b/chrome/common/win_util_unittest.cc deleted file mode 100644 index 2452c31..0000000 --- a/chrome/common/win_util_unittest.cc +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/common/win_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(WinUtilTest, EnsureRectIsVisibleInRect) { - gfx::Rect parent_rect(0, 0, 500, 400); - - { - // Child rect x < 0 - gfx::Rect child_rect(-50, 20, 100, 100); - win_util::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); - EXPECT_EQ(gfx::Rect(10, 20, 100, 100), child_rect); - } - - { - // Child rect y < 0 - gfx::Rect child_rect(20, -50, 100, 100); - win_util::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); - EXPECT_EQ(gfx::Rect(20, 10, 100, 100), child_rect); - } - - { - // Child rect right > parent_rect.right - gfx::Rect child_rect(450, 20, 100, 100); - win_util::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); - EXPECT_EQ(gfx::Rect(390, 20, 100, 100), child_rect); - } - - { - // Child rect bottom > parent_rect.bottom - gfx::Rect child_rect(20, 350, 100, 100); - win_util::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); - EXPECT_EQ(gfx::Rect(20, 290, 100, 100), child_rect); - } - - { - // Child rect width > parent_rect.width - gfx::Rect child_rect(20, 20, 700, 100); - win_util::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); - EXPECT_EQ(gfx::Rect(20, 20, 480, 100), child_rect); - } - - { - // Child rect height > parent_rect.height - gfx::Rect child_rect(20, 20, 100, 700); - win_util::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); - EXPECT_EQ(gfx::Rect(20, 20, 100, 380), child_rect); - } -} - -static const struct filename_case { - const wchar_t* filename; - const wchar_t* filter_selected; - const wchar_t* suggested_ext; - const wchar_t* result; -} filename_cases[] = { - // Test a specific filter (*.jpg). - {L"f", L"*.jpg", L"jpg", L"f.jpg"}, - {L"f.", L"*.jpg", L"jpg", L"f..jpg"}, - {L"f..", L"*.jpg", L"jpg", L"f...jpg"}, - {L"f.jpeg", L"*.jpg", L"jpg", L"f.jpeg"}, - // Further guarantees. - {L"f.jpg.jpg", L"*.jpg", L"jpg", L"f.jpg.jpg"}, - {L"f.exe.jpg", L"*.jpg", L"jpg", L"f.exe.jpg"}, - {L"f.jpg.exe", L"*.jpg", L"jpg", L"f.jpg.exe.jpg"}, - {L"f.exe..", L"*.jpg", L"jpg", L"f.exe...jpg"}, - {L"f.jpg..", L"*.jpg", L"jpg", L"f.jpg...jpg"}, - // Test the All Files filter (*.jpg). - {L"f", L"*.*", L"jpg", L"f"}, - {L"f.", L"*.*", L"jpg", L"f"}, - {L"f..", L"*.*", L"jpg", L"f"}, - {L"f.jpg", L"*.*", L"jpg", L"f.jpg"}, - {L"f.jpeg", L"*.*", L"jpg", L"f.jpeg"}, // Same MIME type (diff. ext). - // Test the empty filter, which should behave identically to the - // All Files filter. - {L"f", L"", L"jpg", L"f"}, - {L"f.", L"", L"jpg", L"f"}, - {L"f..", L"", L"jpg", L"f"}, - {L"f.jpg", L"", L"jpg", L"f.jpg"}, - {L"f.jpeg", L"", L"jpg", L"f.jpeg"}, -}; - -TEST(WinUtilTest, AppendingExtensions) { - for (unsigned int i = 0; i < arraysize(filename_cases); ++i) { - const filename_case& value = filename_cases[i]; - std::wstring result = - win_util::AppendExtensionIfNeeded(value.filename, value.filter_selected, - value.suggested_ext); - EXPECT_EQ(value.result, result); - } -} diff --git a/chrome/plugin/plugin_main.cc b/chrome/plugin/plugin_main.cc index 7b21066..1bbb624 100644 --- a/chrome/plugin/plugin_main.cc +++ b/chrome/plugin/plugin_main.cc @@ -2,6 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "build/build_config.h" + +#if defined(OS_WIN) +#include "app/win_util.h" +#endif #include "base/command_line.h" #include "base/message_loop.h" #include "base/string_util.h" @@ -15,7 +20,6 @@ #include "chrome/plugin/plugin_thread.h" #if defined(OS_WIN) -#include "chrome/common/win_util.h" #include "chrome/test/injection_test_dll.h" #include "sandbox/src/sandbox.h" #endif diff --git a/chrome/plugin/webplugin_delegate_stub.cc b/chrome/plugin/webplugin_delegate_stub.cc index dcf7505..b76fc14 100644 --- a/chrome/plugin/webplugin_delegate_stub.cc +++ b/chrome/plugin/webplugin_delegate_stub.cc @@ -21,7 +21,6 @@ #if defined(OS_WIN) #include "chrome/common/gfx/emf.h" -#include "chrome/common/win_util.h" #endif class FinishDestructionTask : public Task { diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc index f3b7e86..38f3af6 100644 --- a/chrome/plugin/webplugin_proxy.cc +++ b/chrome/plugin/webplugin_proxy.cc @@ -5,6 +5,9 @@ #include "chrome/plugin/webplugin_proxy.h" #include "app/gfx/chrome_canvas.h" +#if defined(OS_WIN) +#include "app/win_util.h" +#endif #include "base/scoped_handle.h" #include "base/shared_memory.h" #include "base/singleton.h" @@ -22,7 +25,6 @@ #if defined(OS_WIN) #include "base/gfx/gdi_util.h" -#include "chrome/common/win_util.h" #endif typedef std::map ContextMap; diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc index 9b2f8a3..4e05f1d 100644 --- a/chrome/renderer/webplugin_delegate_proxy.cc +++ b/chrome/renderer/webplugin_delegate_proxy.cc @@ -35,7 +35,6 @@ #if defined(OS_WIN) #include "chrome/common/gfx/emf.h" -#include "chrome/common/win_util.h" #endif // Proxy for WebPluginResourceClient. The object owns itself after creation, diff --git a/chrome/test/automated_ui_tests/automated_ui_tests.cc b/chrome/test/automated_ui_tests/automated_ui_tests.cc index 098ddd7..c4a7686 100644 --- a/chrome/test/automated_ui_tests/automated_ui_tests.cc +++ b/chrome/test/automated_ui_tests/automated_ui_tests.cc @@ -19,7 +19,6 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/env_vars.h" #include "chrome/common/libxml_utils.h" -#include "chrome/common/win_util.h" #include "chrome/test/automated_ui_tests/automated_ui_tests.h" #include "chrome/test/automation/browser_proxy.h" #include "chrome/test/automation/tab_proxy.h" diff --git a/chrome/test/startup/feature_startup_test.cc b/chrome/test/startup/feature_startup_test.cc index cca5a0b..b1a22f4 100644 --- a/chrome/test/startup/feature_startup_test.cc +++ b/chrome/test/startup/feature_startup_test.cc @@ -4,13 +4,13 @@ #include +#include "app/win_util.h" #include "base/file_util.h" #include "base/path_service.h" #include "base/perftimer.h" #include "base/time.h" #include "chrome/app/chrome_dll_resource.h" #include "chrome/common/chrome_paths.h" -#include "chrome/common/win_util.h" #include "chrome/test/automation/browser_proxy.h" #include "chrome/test/ui/ui_test.h" #include "net/base/net_util.h" diff --git a/chrome/test/unit/unittests.vcproj b/chrome/test/unit/unittests.vcproj index 0904a9b..c0da965 100644 --- a/chrome/test/unit/unittests.vcproj +++ b/chrome/test/unit/unittests.vcproj @@ -1028,10 +1028,6 @@ > - - @@ -1111,6 +1107,28 @@ RelativePath="..\..\..\app\gfx\text_elider_unittest.cc" > + + + + + + + + diff --git a/chrome/tools/crash_service/crash_service.cc b/chrome/tools/crash_service/crash_service.cc index fc921b2..badfd33 100644 --- a/chrome/tools/crash_service/crash_service.cc +++ b/chrome/tools/crash_service/crash_service.cc @@ -18,7 +18,6 @@ #include "breakpad/src/client/windows/sender/crash_report_sender.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" -#include "chrome/common/win_util.h" // TODO(cpu): Bug 1169078. There is a laundry list of things to do for this // application. They will be addressed as they are required. diff --git a/chrome/worker/worker_main.cc b/chrome/worker/worker_main.cc index ad41a8b..e3846d4 100644 --- a/chrome/worker/worker_main.cc +++ b/chrome/worker/worker_main.cc @@ -11,7 +11,6 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/logging_chrome.h" #include "chrome/common/main_function_params.h" -#include "chrome/common/win_util.h" #include "chrome/worker/worker_thread.h" #if defined(OS_WIN) diff --git a/views/DEPS b/views/DEPS index 6f6c804..76a18aa 100644 --- a/views/DEPS +++ b/views/DEPS @@ -9,9 +9,6 @@ include_rules = [ # message_box_view.cc, text_field.cc, window_delegate.cc "+chrome/browser/browser_process.h", - # text_field.cc - "+chrome/common/win_util.h", - # widget_win.cc "+chrome/app/chrome_dll_resource.h", diff --git a/views/controls/button/menu_button.cc b/views/controls/button/menu_button.cc index 888137b..993cd9b 100644 --- a/views/controls/button/menu_button.cc +++ b/views/controls/button/menu_button.cc @@ -8,7 +8,7 @@ #include "app/gfx/chrome_canvas.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" -#include "chrome/common/win_util.h" +#include "app/win_util.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "views/controls/button/button.h" diff --git a/views/controls/text_field.cc b/views/controls/text_field.cc index 2981282..35e6d36 100644 --- a/views/controls/text_field.cc +++ b/views/controls/text_field.cc @@ -14,13 +14,13 @@ #include "app/gfx/insets.h" #include "app/l10n_util.h" #include "app/l10n_util_win.h" +#include "app/win_util.h" #include "base/clipboard.h" #include "base/gfx/native_theme.h" #include "base/scoped_clipboard_writer.h" #include "base/string_util.h" #include "base/win_util.h" #include "chrome/browser/browser_process.h" -#include "chrome/common/win_util.h" #include "grit/generated_resources.h" #include "skia/ext/skia_utils_win.h" #include "views/controls/hwnd_view.h" diff --git a/views/drag_utils.cc b/views/drag_utils.cc index 271e683..f312b14 100644 --- a/views/drag_utils.cc +++ b/views/drag_utils.cc @@ -17,7 +17,6 @@ #include "base/gfx/gdi_util.h" #include "base/gfx/point.h" #include "base/string_util.h" -#include "chrome/common/win_util.h" #include "googleurl/src/gurl.h" #include "grit/theme_resources.h" #include "views/controls/button/text_button.h" diff --git a/views/widget/tooltip_manager.cc b/views/widget/tooltip_manager.cc index 114a032..59612e4 100644 --- a/views/widget/tooltip_manager.cc +++ b/views/widget/tooltip_manager.cc @@ -9,9 +9,9 @@ #include "app/gfx/text_elider.h" #include "app/l10n_util.h" #include "app/l10n_util_win.h" +#include "app/win_util.h" #include "base/logging.h" #include "base/message_loop.h" -#include "chrome/common/win_util.h" #include "views/view.h" #include "views/widget/root_view.h" #include "views/widget/widget.h" diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index 2bc9b0c..c59f512 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -5,11 +5,11 @@ #include "views/widget/widget_win.h" #include "app/gfx/chrome_canvas.h" +#include "app/win_util.h" #include "base/gfx/native_theme.h" #include "base/string_util.h" #include "base/win_util.h" #include "chrome/app/chrome_dll_resource.h" -#include "chrome/common/win_util.h" #include "views/accessibility/view_accessibility.h" #include "views/controls/native_control_win.h" #include "views/fill_layout.h" diff --git a/views/window/custom_frame_view.cc b/views/window/custom_frame_view.cc index 8639340..1816fdc 100644 --- a/views/window/custom_frame_view.cc +++ b/views/window/custom_frame_view.cc @@ -9,8 +9,8 @@ #include "app/gfx/path.h" #include "app/resource_bundle.h" #if defined(OS_WIN) +#include "app/win_util.h" #include "base/win_util.h" -#include "chrome/common/win_util.h" #endif #include "grit/theme_resources.h" #include "views/window/client_view.h" diff --git a/views/window/non_client_view.cc b/views/window/non_client_view.cc index 6135a7b..5d5ac76 100644 --- a/views/window/non_client_view.cc +++ b/views/window/non_client_view.cc @@ -5,7 +5,7 @@ #include "views/window/non_client_view.h" #if defined(OS_WIN) -#include "chrome/common/win_util.h" +#include "app/win_util.h" #endif #include "views/widget/root_view.h" #include "views/widget/widget.h" diff --git a/views/window/window_win.cc b/views/window/window_win.cc index f41ef18..40ec924 100644 --- a/views/window/window_win.cc +++ b/views/window/window_win.cc @@ -12,9 +12,9 @@ #include "app/gfx/path.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" +#include "app/win_util.h" #include "base/win_util.h" #include "chrome/app/chrome_dll_resource.h" -#include "chrome/common/win_util.h" #include "grit/generated_resources.h" #include "views/widget/root_view.h" #include "views/window/client_view.h" -- cgit v1.1