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; |