Question

I recently ported the following code to wx3.0 under visual studio 2013:

void PanelFileControl::on_retrieve_clicked(wxCommandEvent &event)
{
   if(!chosen_files.empty())
   {
      Csi::ModalCounter counter;
      wxDirDialog query(
         this,
         make_wxString(my_strings[strid_choose_retrieve_dir]),
         make_wxString(wxGetApp().get_config()->get_last_prog_dir()));
      int rcd;

      query.CentreOnParent();
      rcd = query.ShowModal();
      if(rcd == wxID_OK)
      {
         // we need to generate an operation for every selected file. 
         StrAsc path(make_StrAsc(query.GetPath()));
         DlgFileControl::operations_type operations;

         if(path.last() != Csi::FileSystemObject::dir_separator())
            path.append(Csi::FileSystemObject::dir_separator());
         for(files_type::iterator fi = chosen_files.begin(); fi != chosen_files.end(); ++fi)
         {
            file_type const &file(*fi);
            StrAsc file_path(path + file.get_file_name());
            bool use_file(true);
            if(Csi::file_exists(file_path.c_str()))
            {
               OwxStringStream message;
               message << boost::format(my_strings[strid_overwrite_file_confirm].c_str()) %
                  file_path;

               wxMessageDialog overwrite_query(
                  this,
                  message.str(),
                  wxT(""),
                  wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
               int rcd;
               overwrite_query.CentreOnParent();
               rcd = overwrite_query.ShowModal();
               if(rcd != wxID_YES)
                  use_file = false;
            }
            if(use_file)
               operations.push_back(new ReceiveFileOperation(file, file_path));
         }

         // we can now display the operation dialogue
         if(!operations.empty())
         {
            DlgFileControl dialogue(this, device_name, operations);
            dialogue.show_modal();
         }
      }
   }
} // on_retrieve_clicked

Following this change (which didn't require any changes to the code above), I have received complaints that, if the user selects the desktop and then double clicks on a directory on the desktop, that the file save operation fails. This appears to be a result of the path produced by the wxDirDialog::GetPath() and has only been seen under windows vista. I have followed up some testing and I find that, under Vista, the last path component is mentioned twice in the string returned by GetPath().

Has anyone seen this issue? Are there any work arounds?

Was it helpful?

Solution

I found that I can address the issue by preventing the wxDirDialog from using the IFILEDIALOG interface from being used. My ShowModal() method now looks like this:

int wxDirDialog::ShowModal()
{
    WX_HOOK_MODAL_DIALOG();

    wxWindow* const parent = GetParent();
    WXHWND hWndParent = parent ? GetHwndOf(parent) : NULL;

    // Use IFileDialog under new enough Windows, it's more user-friendly.
    int rc;
#if wxUSE_IFILEDIALOG
    if ( wxGetWinVersion() > wxWinVersion_Vista )
    {
        rc = ShowIFileDialog(hWndParent);
    }
    else
    {
        rc = wxID_NONE;
    }

    if ( rc == wxID_NONE )
#endif // wxUSE_IFILEDIALOG
    {
        rc = ShowSHBrowseForFolder(hWndParent);
    }

    // change current working directory if asked so
    if ( rc == wxID_OK && HasFlag(wxDD_CHANGE_DIR) )
        wxSetWorkingDirectory(m_path);

    return rc;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top