beasone
beasone

Reputation: 1085

IFileOpenDialog pointer is null when it calls from CFileDialog

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)

Upvotes: 0

Views: 304

Answers (1)

zdan
zdan

Reputation: 29450

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

Upvotes: 2

Related Questions