0

I was trying to wrap CFileDialog and IFileOpenDialog in a class, here is the code:

class ITest
{
    public:
    virtual ~ITest(){};

    virtual INT_PTR DoModal() = 0;

    virtual IFileOpenDialog* GetDlg() = 0;
};

class test : public ITest
{
public:
   test(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
       LPCTSTR lpszDefExt = NULL,
       LPCTSTR lpszFileName = NULL,
       DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
       LPCTSTR lpszFilter = NULL,
       CWnd* pParentWnd = NULL,
       DWORD dwSize = 0,
       BOOL bVistaStyle = FALSE)
   {
       dlg = new CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd, dwSize, bVistaStyle);
   };
   ~test(){};

   INT_PTR DoModal(){ return S_OK; };

   IFileOpenDialog* GetDlg(){ return dlg->GetIFileOpenDialog(); };
private:
   CFileDialog* dlg;
};

Then when I call it like:

ITest* a = new test(TRUE, NULL, 0, OFN_ALLOWMULTISELECT | OFN_NOVALIDATE, LoadResourceString(IDS_MYSTRING), this);

fdlg = a->GetDlg();

fdlg->Show(NULL);//it crashes here since fdlg is NULL

Then I tried to call CFileDialog and IFileOpenDialog directly:

IFileOpenDialog* fdlg = NULL;

CFileDialog* b = new CFileDialog(TRUE, NULL, 0, OFN_ALLOWMULTISELECT | OFN_NOVALIDATE, LoadResourceString(IDS_MYSTRING), this);

fdlg = b->GetIFileOpenDialog();

fdlg->Show(NULL);

This part of code works perfectly. Anyone knows why the crash happens ? It confuses me so much since I feel they are so similar.

class test : public ITest
{
public:
test(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
    LPCTSTR lpszDefExt = NULL,
    LPCTSTR lpszFileName = NULL,
    DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
    LPCTSTR lpszFilter = NULL,
    CWnd* pParentWnd = NULL,
    DWORD dwSize = 0,
    BOOL bVistaStyle = FALSE)
{
    dlg = new CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd, dwSize, bVistaStyle);
};
~test(){};

INT_PTR DoModal(){ return S_OK; };

IFileOpenDialog* GetDlg();
private:
CFileDialog* dlg;
};

IFileOpenDialog* test::GetDlg()
{ 
return dlg->GetIFileOpenDialog(); 
};

The above code also doesn't work( it defines IFileOpenDialog* GetDlg(); outside of the class declartion)

trincot
  • 317,000
  • 35
  • 244
  • 286
beasone
  • 1,073
  • 1
  • 14
  • 32
  • @Ripi2 sorry, i didn;t get your point. What do you mean IFileOpenDialog* GetDlg(){... is a global function ? It is non-static member function, if I call it ITest* a = new test(TRUE, NULL, 0, OFN_ALLOWMULTISELECT | OFN_NOVALIDATE, LoadResourceString(IDS_FILTER_PLATE_AND_TUBE_EXPERIMENT), this); fdlg = test::GetDlg(); The visual studo will complaint that I am calling non static function. – beasone May 08 '18 at 17:45
  • I did implement it in the derived "test" class. IFileOpenDialog* GetDlg(){ return dlg->GetIFileOpenDialog(); }; "You used a global instead.", I still don't get your point. – beasone May 08 '18 at 17:51
  • You would get debug message explaining the problem is that Visual Style is not enabled. Anyway, this class is complicated, just use `CFileDialog` with `DoModal` – Barmak Shemirani May 08 '18 at 19:17

1 Answers1

2

From the help:

Use this function only under Windows Vista with an object that has bVistaStyle set to true. This function returns NULL if the CFileDialog is not an Open dialog box or if bVistaStyle is set to false.

When you construct your test object:

ITest* a = new test(TRUE, NULL, 0, OFN_ALLOWMULTISELECT | OFN_NOVALIDATE, LoadResourceString(IDS_MYSTRING), this);

you are leaving our the last parameter of your constructor, bVistaStyle, which defaults to FALSE. So just add it:

ITest* a = new test(TRUE, NULL, 0, OFN_ALLOWMULTISELECT | OFN_NOVALIDATE, LoadResourceString(IDS_MYSTRING), this, 0, 
               TRUE); // bVistaStyle
zdan
  • 28,667
  • 7
  • 60
  • 71