0

I am working on a WIN32 (not MFC) project. Currently it uses the default XP and earlier file dialogs. In attempting to add the option, under Win7/Vista, to use the new-style file dialogs, I have come to a stumbling block.

The only code examples I can find come from here:
MSDN's Common Item Dialog article

The event handler creation code looks (with more meaningful variable names) like:

HRESULT result;
[...]
IFileDialogEvents *fileDialogEvents = NULL;
result = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&fileDialogEvents));

but the function CDialogEventHandler_CreateInstance does not exist. Others have complained in various MS forums but no resolution has ever been reported.

Searching *.* for CDialogEventHandler_CreateInstance in

C:\Program Files\Microsoft SDKs\Windows\v6.0A\Include

finds nothing.

I need to capture the result of the user changing the "Files of type" drop-down.

I must also add a button and capture user's button click but that is the next step.

1
Contributor
1
Reply
4
Views
5 Years
Discussion Span
Last Post by edgar5
0

I have resolved the issue by changing the MSDN demo source drastically and not using the non-existent:
CDialogEventHandler_CreateInstance
with something working; here is the whole Audacity-specific process:

class SaveFileDialogCallback : public IFileDialogEvents, public IFileDialogControlEvents {
public:
   SaveFileDialogCallback(FileDialog * pFileDialog) {mFileDialog = pFileDialog;}

   FileDialog * mFileDialog;

   // IUnknown
   IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv) {
      static const QITAB qit[] = {
         QITABENT(SaveFileDialogCallback, IFileDialogEvents),
         QITABENT(SaveFileDialogCallback, IFileDialogControlEvents),
         { 0 },
      };
      return QISearch(this, qit, riid, ppv);
   }

   // This class makes special assumptions about how it is used, specifically
   // 1) This class will only reside on the stack.
   // 2) Components that consume this object have well-defined reference lifetimes.
   //    In this case, this is only consumed by the file dialog advise and unadvise.
   //    Unadvising will release the file dialog's only reference to this object.
   //
   // Do not do this for heap allocated objects.
   IFACEMETHODIMP_(ULONG) AddRef()  { return 3; }
   IFACEMETHODIMP_(ULONG) Release() { return 2; }

   // IFileDialogEvents
   IFACEMETHODIMP OnFileOk(IFileDialog * /* pfd */) { return E_NOTIMPL; }
   IFACEMETHODIMP OnFolderChanging(IFileDialog * /* pfd */, IShellItem * /* psi */) { return E_NOTIMPL; }
   IFACEMETHODIMP OnFolderChange(IFileDialog * /* pfd */) { return E_NOTIMPL; }
   IFACEMETHODIMP OnSelectionChange(IFileDialog * /* pfd */) { return E_NOTIMPL; }
   IFACEMETHODIMP OnShareViolation(IFileDialog * /* pfd */, IShellItem * /* psi */, FDE_SHAREVIOLATION_RESPONSE * /* pResponse */) { return E_NOTIMPL; }
   IFACEMETHODIMP OnTypeChange(IFileDialog * /* pfd */) { return E_NOTIMPL; }
   IFACEMETHODIMP OnOverwrite(IFileDialog * /* pfd */, IShellItem * /* psi */ , FDE_OVERWRITE_RESPONSE * /* pResponse */) { return E_NOTIMPL;}

   // IFileDialogControlEvents
   IFACEMETHODIMP OnItemSelected(IFileDialogCustomize * /* pfdc */, DWORD /* dwIDCtl */, DWORD /* dwIDItem */)  { return E_NOTIMPL; }
   IFACEMETHODIMP OnButtonClicked(IFileDialogCustomize * pFileDialogCustomize, DWORD pIDControl);
   IFACEMETHODIMP OnCheckButtonToggled(IFileDialogCustomize * /* pfdc */, DWORD /* dwIDCtl */, BOOL /* bChecked */) { return E_NOTIMPL; }
   IFACEMETHODIMP OnControlActivating(IFileDialogCustomize * /* pfdc */, DWORD /* dwIDCtl */) { return E_NOTIMPL; }
};

IFACEMETHODIMP SaveFileDialogCallback::OnButtonClicked(IFileDialogCustomize * pFileDialogCustomize, DWORD pIDControl) {
   if (pIDControl == cOptionsButton) {
      IFileDialog *pFileDialog;
      HRESULT result = pFileDialogCustomize->QueryInterface(&pFileDialog);
      if (SUCCEEDED(result)) {
         unsigned int fileTypeIndex;
         result = pFileDialog->GetFileTypeIndex(&fileTypeIndex);
         if (SUCCEEDED(result)) {
            HWND   hwndDialog;
            hwndDialog = ::GetParent((HWND)mFileDialog->GetHWND());
            HWND w = GetFocus();
            EnableWindow(hwndDialog, false);
            mFileDialog->ClickButton(fileTypeIndex - 1, true);
            EnableWindow(hwndDialog, true);
            SetFocus(w);
            return S_OK;
         }
      }
   }
   return S_FALSE;
}

HRESULT Win7SaveFileDialog(FileDialog * pFileDialog, OPENFILENAME & pFileDialogStruct, const wxString & pFilterStrings, const bool pDoingProject) {
   IFileSaveDialog * saveFileDialog;
   HRESULT result = CoCreateInstance (CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&saveFileDialog));

   FILEOPENDIALOGOPTIONS saveFileDialogOptions;
   result = saveFileDialog->GetOptions(&saveFileDialogOptions);
   if (SUCCEEDED(result)) {
      if (saveFileDialogOptions & FOS_OVERWRITEPROMPT) {
         saveFileDialogOptions -= FOS_OVERWRITEPROMPT;
         result = saveFileDialog->SetOptions(saveFileDialogOptions);
      }
   }

   if (FAILED(result)) {
      wxMessageBox(_("Could not CoCreateInstance for file save dialog"));
      return result;
   }
   else {
      wxString dialogTitle(pFileDialogStruct.lpstrTitle);
      if (!dialogTitle.IsEmpty())
         result = saveFileDialog->SetTitle(pFileDialogStruct.lpstrTitle);
      else
         result = saveFileDialog->SetTitle(_("Save"));

         unsigned int arraySize = 0;
         wxString defaultExtension = wxEmptyString;
         wxArrayString descriptions, extensions;
         COMDLG_FILTERSPEC * allowedTypes = 
            AllowedSaveFileTypes(pFilterStrings, &arraySize, pDoingProject, defaultExtension, descriptions, extensions);
         if (allowedTypes) {
            result = saveFileDialog->SetFileTypes(arraySize, allowedTypes);
            delete [] allowedTypes;
         }

      if (SUCCEEDED(result)) result = saveFileDialog->SetOkButtonLabel (_("Save"));

      if (SUCCEEDED(result)) {
         if (pDoingProject) result = saveFileDialog->SetDefaultExtension ( wxT("aup"));
         else result = saveFileDialog->SetDefaultExtension (pFileDialogStruct.lpstrDefExt);
      }
      if (SUCCEEDED(result)) {
         saveFileDialog->SetFileTypeIndex(pFileDialogStruct.nFilterIndex);
      }

      if (SUCCEEDED(result)) {
         wxString defaultFileName(pFileDialogStruct.lpstrFile);
         if (!defaultFileName.IsEmpty()) {
            wxFileName fileName(defaultFileName);;
            result = saveFileDialog->SetFileName(fileName.GetName());
         }
      }
      if (!pDoingProject && SUCCEEDED(result)) {
         IFileDialogCustomize * customize = NULL;
         result = saveFileDialog->QueryInterface(&customize);
         if (SUCCEEDED(result)) {
            customize->AddPushButton(cOptionsButton, _(" Export Format Settings "));
            saveFileDialog->Release();
         }
      }
      if (SUCCEEDED(result)) {
         SaveFileDialogCallback fileDialogCallback(pFileDialog);
         DWORD eventCookie;
         result = saveFileDialog->Advise(&fileDialogCallback, &eventCookie);
         if (SUCCEEDED(result)) {
            result = saveFileDialog->Show(pFileDialogStruct.hwndOwner);
            if (SUCCEEDED(result)) {
               IShellItem * shellItem;
               result = saveFileDialog->GetResult (&shellItem);
               if (SUCCEEDED(result)) {
                  LPOLESTR shellItemName = NULL;
                  result = shellItem->GetDisplayName (SIGDN_FILESYSPATH, &shellItemName);
                  if ( SUCCEEDED(result) ) {
                     unsigned int fileTypeIndex;
                     result = saveFileDialog->GetFileTypeIndex(&fileTypeIndex);
                     if (SUCCEEDED(result)) pFileDialogStruct.nFilterIndex = fileTypeIndex;
                     wxString itemName(shellItemName);
                     wxStrncpy(pFileDialogStruct.lpstrFile, shellItemName, itemName.Len());
                     CoTaskMemFree (shellItemName);
                  }
               }
            }
            saveFileDialog->Unadvise(eventCookie);
         }
      }
   }
   return result;
}
This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.