【问题标题】:IFileOpenDialog pointer is null when it calls from CFileDialog从 CFileDialog 调用时,IFileOpenDialog 指针为空
【发布时间】:2018-10-18 17:50:01
【问题描述】:

我试图将CFileDialogIFileOpenDialog 包装在一个类中,代码如下:

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;
};

然后当我这样称呼它时:

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

然后我尝试直接调用CFileDialogIFileOpenDialog

IFileOpenDialog* fdlg = NULL;

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

fdlg = b->GetIFileOpenDialog();

fdlg->Show(NULL);

这部分代码完美运行。 任何人都知道为什么会发生崩溃? 这让我很困惑,因为我觉得它们是如此相似。

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(); 
};

上面的代码也不起作用(它定义了 IFileOpenDialog* GetDlg(); 在类声明之外)

【问题讨论】:

  • @Ripi2 对不起,我没有明白你的意思。你是什​​么意思 IFileOpenDialog* GetDlg(){... 是一个全局函数?它是非静态成员函数,如果我称它为 ITest* a = new test(TRUE, NULL, 0, OFN_ALLOWMULTISELECT | OFN_NOVALIDATE, LoadResourceString(IDS_FILTER_PLATE_AND_TUBE_EXPERIMENT), this); fdlg = test::GetDlg();视觉工作室会抱怨我正在调用非静态函数。
  • 我确实在派生的“测试”类中实现了它。 IFileOpenDialog* GetDlg(){ return dlg->GetIFileOpenDialog(); }; “你用的是全局变量。”,我还是不明白你的意思。
  • 您会收到调试消息,说明问题是未启用视觉样式。反正这个类比较复杂,用CFileDialogDoModal就行了

标签: c++ mfc cfiledialog


【解决方案1】:

来自help

仅在 Windows Vista 下对具有 bVistaStyle 设置为真。如果 CFileDialog 不是打开对话框,或者如果 bVistaStyle 设置为 false。

当你构造你的test 对象时:

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

您将留下构造函数的最后一个参数bVistaStyle,默认为FALSE。所以只需添加它:

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

【讨论】:

    猜你喜欢
    • 2013-02-01
    • 1970-01-01
    • 2013-10-14
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    相关资源
    最近更新 更多