c++ - MFC 应用程序在 CRecentFileList::Add 命令行 FileOpen 处断言失败

标签 c++ visual-studio visual-studio-2010 com mfc

我使用的是VS2010和Windows 7,我的应用程序是SDI共享DLL,从VC6升级。安装我的应用程序后,如果用户双击注册的文件类型,应用程序将在 MFC 函数处崩溃:

void CRecentFileList::Add(LPCTSTR lpszPathName, LPCTSTR lpszAppID)
{
 // ...
#if (WINVER >= 0x0601)
// ...
#ifdef UNICODE
// ...
#endif
ENSURE(SUCCEEDED(hr));    // Crash here: "hr = 0x800401f0 CoInitialize has not been called."

这是从 InitInstance() 函数调用的:

// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);

//CString str = cmdInfo.m_strFileName + '\n';
//MessageBox(NULL,str, "MyApp", MB_OK|MB_ICONWARNING);

// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
    return FALSE;

用户选择的文件已正确传递(正如我使用 MessageBox 所检查的那样)。

hr = 0x800401f0 似乎是 COM 问题 ( here ),但我没有使用 COM 或 ATL。该断言与 this 相同,但出于不同的原因。德国人和我有同样的问题(here),但我无法理解谷歌翻译(here)!我不认为这是 WINVER 问题( here ),并且我不想解析我自己的东西( like this ),只需在用户双击文件时打开应用程序即可。

感谢您提供的任何帮助:)

最佳答案

您在代码中插入的注释包含答案:

// Crash here: "hr = 0x800401f0 CoInitialize has not been called."

HRESULT 值告诉您需要调用 CoInitialize function以便为应用程序的线程初始化 COM 库。

当然,该消息有点过时了。正如您将在上面链接的文档中看到的,所有新应用程序都应调用 CoInitializeEx function反而。不过不用担心:它的功能与它的哥哥基本相同。

正如文档的“备注”部分所示:

CoInitializeEx must be called at least once, and is usually called only once, for each thread that uses the COM library. [. . . ] You need to initialize the COM library on a thread before you call any of the library functions except CoGetMalloc, to get a pointer to the standard allocator, and the memory allocation functions. Otherwise, the COM function will return CO_E_NOTINITIALIZED.

您说您没有使用 COM,但这是不正确的。您可能没有明确使用它,但 Windows 和 MFC 框架肯定在“幕后”使用它。所有文件类型注册功能都依赖于 COM。 Visual Studio 2010 中的 MFC 项目向导生成的框架代码会自动插入适当的 COM 注册代码,但由于您从 VC++ 6 升级了现有项目,因此您似乎错过了这一重要步骤。

在 MFC 中,AfxOleInit function还为调用应用程序的当前单元初始化 COM,就像 OleInitialize function 一样。内部做。确保您重写的 InitInstance 函数包含对这些函数之一的调用。

例如,在 VS 2010 向导创建的全新 MFC 项目中,InitInstance 函数如下所示:

BOOL CTestApp::InitInstance()
{
    // InitCommonControlsEx() is required on Windows XP if an application
    // manifest specifies use of ComCtl32.dll version 6 or later to enable
    // visual styles.  Otherwise, any window creation will fail.
    INITCOMMONCONTROLSEX InitCtrls;
    InitCtrls.dwSize = sizeof(InitCtrls);
    // Set this to include all the common control classes you want to use
    // in your application.
    InitCtrls.dwICC = ICC_WIN95_CLASSES;
    InitCommonControlsEx(&InitCtrls);

    CWinApp::InitInstance();

    // Initialize OLE libraries
    if (!AfxOleInit())                   // ** MAKE SURE THAT YOU CALL THIS!! **
    {
        AfxMessageBox(IDP_OLE_INIT_FAILED);
        return FALSE;
    }

    AfxEnableControlContainer();

    // . . . 
    // a bunch more boring initialization stuff...

    // The one and only window has been initialized, so show and update it
    pFrame->ShowWindow(SW_SHOW);
    pFrame->UpdateWindow();
    return TRUE;
}

关于c++ - MFC 应用程序在 CRecentFileList::Add 命令行 FileOpen 处断言失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6633515/

相关文章:

c++ - 如何读取包含空格的数据

c++ - 使用 Windows taskschd.msc 编程 C++ Win32 非控制台应用程序,不工作

c++ - 'Excel.exe' 的调试信息找不到或不匹配

c++ - 如何比较if语句中的字符串?

c# - 使用 2 个变量从文本文件创建 ListBox 项

c++ - "assimp/config.h"未找到,但它在文件夹中

visual-studio-2010 - Visual Studio 禁用拼写检查

visual-studio-2010 - 在 Visual Studio 2010 中同时运行两个项目 - 不想

c++ - 字符串接受接口(interface)应该是什么样子的?

c++ - 链接器错误 : undefined reference to class: :'methods' in C++