15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright (c) 2014 The Chromium Authors. All rights reserved.
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file.
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/base/win/open_file_name_win.h"
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/files/file_path.h"
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/strings/string_util.h"
903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/win/windows_version.h"
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace ui {
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace win {
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace {
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Ensures that the Save As dialog is on-screen.
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)UINT_PTR CALLBACK SaveAsDialogHook(HWND dialog, UINT message,
1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   WPARAM wparam, LPARAM lparam) {
1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  static const UINT kPrivateMessage = 0x2F3F;
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  switch (message) {
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    case WM_INITDIALOG: {
2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // Do nothing here. Just post a message to defer actual processing.
2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ::PostMessage(dialog, kPrivateMessage, 0, 0);
2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return TRUE;
2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    case kPrivateMessage: {
2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // The dialog box is the parent of the current handle.
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      HWND real_dialog = ::GetParent(dialog);
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // Retrieve the final size.
3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      RECT dialog_rect;
3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ::GetWindowRect(real_dialog, &dialog_rect);
3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // Verify that the upper left corner is visible.
3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      POINT point = { dialog_rect.left, dialog_rect.top };
3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      HMONITOR monitor1 = ::MonitorFromPoint(point, MONITOR_DEFAULTTONULL);
3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      point.x = dialog_rect.right;
3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      point.y = dialog_rect.bottom;
3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // Verify that the lower right corner is visible.
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      HMONITOR monitor2 = ::MonitorFromPoint(point, MONITOR_DEFAULTTONULL);
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      if (monitor1 && monitor2)
4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        return 0;
4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // Some part of the dialog box is not visible, fix it by moving is to the
4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // client rect position of the browser window.
4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      HWND parent_window = ::GetParent(real_dialog);
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      if (!parent_window)
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        return 0;
5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      WINDOWINFO parent_info;
5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      parent_info.cbSize = sizeof(WINDOWINFO);
5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ::GetWindowInfo(parent_window, &parent_info);
5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ::SetWindowPos(
5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          real_dialog,
5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          NULL,
5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          parent_info.rcClient.left,
5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          parent_info.rcClient.top,
5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          0,
5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          0,  // Size.
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return 0;
6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return 0;
6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)OpenFileName::OpenFileName(HWND parent_window, DWORD flags) {
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ::ZeroMemory(&openfilename_, sizeof(openfilename_));
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  openfilename_.lStructSize = sizeof(openfilename_);
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // According to http://support.microsoft.com/?scid=kb;en-us;222003&x=8&y=12,
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The lpstrFile Buffer MUST be NULL Terminated.
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  filename_buffer_[0] = 0;
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  openfilename_.lpstrFile = filename_buffer_;
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  openfilename_.nMaxFile = arraysize(filename_buffer_);
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  openfilename_.Flags = flags;
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  openfilename_.hwndOwner = parent_window;
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)OpenFileName::~OpenFileName() {
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void OpenFileName::SetFilters(
886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const std::vector<Tuple2<base::string16, base::string16> >& filters) {
896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  openfilename_.lpstrFilter = NULL;
906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  filter_buffer_.clear();
916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (filters.empty())
926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return;
936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (std::vector<Tuple2<base::string16, base::string16> >::const_iterator
946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)           it = filters.begin();
956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       it != filters.end();
966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       ++it) {
976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    filter_buffer_.append(it->a);
986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    filter_buffer_.push_back(0);
996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    filter_buffer_.append(it->b);
1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    filter_buffer_.push_back(0);
1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  filter_buffer_.push_back(0);
1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  openfilename_.lpstrFilter = filter_buffer_.c_str();
1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void OpenFileName::SetInitialSelection(const base::FilePath& initial_directory,
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       const base::FilePath& initial_filename) {
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // First reset to the default case.
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // According to http://support.microsoft.com/?scid=kb;en-us;222003&x=8&y=12,
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The lpstrFile Buffer MUST be NULL Terminated.
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  filename_buffer_[0] = 0;
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  openfilename_.lpstrFile = filename_buffer_;
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  openfilename_.nMaxFile = arraysize(filename_buffer_);
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  openfilename_.lpstrInitialDir = NULL;
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  initial_directory_buffer_.clear();
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (initial_directory.empty())
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  initial_directory_buffer_ = initial_directory.value();
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  openfilename_.lpstrInitialDir = initial_directory_buffer_.c_str();
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (initial_filename.empty())
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The filename is ignored if no initial directory is supplied.
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::wcslcpy(filename_buffer_,
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                initial_filename.value().c_str(),
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                arraysize(filename_buffer_));
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void OpenFileName::MaybeInstallWindowPositionHookForSaveAsOnXP() {
13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (base::win::GetVersion() >= base::win::VERSION_VISTA)
13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return;
13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  openfilename_.Flags |= OFN_ENABLEHOOK;
13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(!openfilename_.lpfnHook);
13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  openfilename_.lpfnHook = &SaveAsDialogHook;
13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)base::FilePath OpenFileName::GetSingleResult() {
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::FilePath directory;
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::vector<base::FilePath> filenames;
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GetResult(&directory, &filenames);
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (filenames.size() != 1)
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return base::FilePath();
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return directory.Append(filenames[0]);
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void OpenFileName::GetResult(base::FilePath* directory,
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             std::vector<base::FilePath>* filenames) {
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(filenames->empty());
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const wchar_t* selection = openfilename_.lpstrFile;
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  while (*selection) {  // Empty string indicates end of list.
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    filenames->push_back(base::FilePath(selection));
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Skip over filename and null-terminator.
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    selection += filenames->back().value().length() + 1;
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (filenames->size() == 1) {
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // When there is one file, it contains the path and filename.
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *directory = (*filenames)[0].DirName();
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    (*filenames)[0] = (*filenames)[0].BaseName();
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else if (filenames->size() > 1) {
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Otherwise, the first string is the path, and the remainder are
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // filenames.
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *directory = (*filenames)[0];
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    filenames->erase(filenames->begin());
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// static
1726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void OpenFileName::SetResult(const base::FilePath& directory,
1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             const std::vector<base::FilePath>& filenames,
1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             OPENFILENAME* openfilename) {
1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::string16 filename_value;
1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (filenames.size() == 1) {
1776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    filename_value = directory.Append(filenames[0]).value();
1786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  } else {
1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    filename_value = directory.value();
1806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    filename_value.push_back(0);
1816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    for (std::vector<base::FilePath>::const_iterator it = filenames.begin();
1826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         it != filenames.end();
1836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         ++it) {
1846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      filename_value.append(it->value());
1856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      filename_value.push_back(0);
1866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (filename_value.size() + 1 < openfilename->nMaxFile) {
1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Because the result has embedded nulls, we must memcpy.
1906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    memcpy(openfilename->lpstrFile,
1916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)           filename_value.c_str(),
1926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)           (filename_value.size() + 1) * sizeof(filename_value[0]));
1936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  } else if (openfilename->nMaxFile) {
1946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    openfilename->lpstrFile[0] = 0;
1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// static
1996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)std::vector<Tuple2<base::string16, base::string16> > OpenFileName::GetFilters(
2006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const OPENFILENAME* openfilename) {
2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::vector<Tuple2<base::string16, base::string16> > filters;
2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const base::char16* display_string = openfilename->lpstrFilter;
2046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!display_string)
2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return filters;
2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  while (*display_string) {
2086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const base::char16* display_string_end = display_string;
2096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    while (*display_string_end)
2106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ++display_string_end;
2116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const base::char16* pattern = display_string_end + 1;
2126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const base::char16* pattern_end = pattern;
2136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    while (*pattern_end)
2146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ++pattern_end;
2156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    filters.push_back(
2166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        MakeTuple(base::string16(display_string, display_string_end),
2176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                  base::string16(pattern, pattern_end)));
2186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    display_string = pattern_end + 1;
2196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
2206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return filters;
2226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
2236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace win
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace ui
226