Chromium Code Reviews| Index: ui/base/win/open_file_name_win.cc |
| diff --git a/ui/base/win/open_file_name_win.cc b/ui/base/win/open_file_name_win.cc |
| index b63eb47be640c772dbe5f2529eb9962dc0b9ae83..5b78a8e465198fd5376da96af3bcc7b4bd0dc625 100644 |
| --- a/ui/base/win/open_file_name_win.cc |
| +++ b/ui/base/win/open_file_name_win.cc |
| @@ -6,10 +6,67 @@ |
| #include "base/files/file_path.h" |
| #include "base/strings/string_util.h" |
| +#include "base/win/windows_version.h" |
| namespace ui { |
| namespace win { |
| +namespace { |
| + |
| +// Ensures that the Save As dialog is on-screen. |
| +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); |
|
sky
2014/08/19 17:02:51
Why not MonitorFromWindow, get the work area and c
erikwright (departed)
2014/08/19 17:09:15
I have no idea. This code is moved verbatim from i
|
| + 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 |
| + |
| OpenFileName::OpenFileName(HWND parent_window, DWORD flags) { |
| ::ZeroMemory(&openfilename_, sizeof(openfilename_)); |
| openfilename_.lStructSize = sizeof(openfilename_); |
| @@ -72,6 +129,15 @@ void OpenFileName::SetInitialSelection(const base::FilePath& initial_directory, |
| arraysize(filename_buffer_)); |
| } |
| +void OpenFileName::MaybeInstallWindowPositionHookForSaveAsOnXP() { |
| + if (base::win::GetVersion() >= base::win::VERSION_VISTA) |
| + return; |
| + |
| + openfilename_.Flags |= OFN_ENABLEHOOK; |
| + DCHECK(!openfilename_.lpfnHook); |
| + openfilename_.lpfnHook = &SaveAsDialogHook; |
| +} |
| + |
| base::FilePath OpenFileName::GetSingleResult() { |
| base::FilePath directory; |
| std::vector<base::FilePath> filenames; |