MFC应用程序声明失败在CRecentFileList ::添加在命令行FileOpen [英] MFC app Assert fail at CRecentFileList::Add on Command line FileOpen

查看:822
本文介绍了MFC应用程序声明失败在CRecentFileList ::添加在命令行FileOpen的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using VS2010 and Windows 7, and my app is SDI shared DLL, upgraded from VC6. After installing my application, if the user double-clicks the registered file type, the application crashes at the MFC function:

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()函数调用:

This is called from the InitInstance() function:

// 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检查的那样)。

The user's chosen file is correctly passed through (as I checked with the MessageBox).

hr = 0x800401f0似乎是一个COM问题(这里),但我不使用COM或ATL。断言与相同。,但是从不同的原因。德国人与我有同样的问题(这里),但我不能理解google翻译(这里)!我不认为这是一个WINVER问题(这里),我不想解析我自己的东西(喜欢这个),只需在用户双击文件时打开该应用程序。

The hr = 0x800401f0 seems to be a COM problem (here), but I'm not using COM or ATL. The assertion is the same as this, but from a different cause. The Germans had the same problem as me (here), but I can't understand the google translation (here)!! I don't think it's a WINVER issue (here) and I don't want to parse my own stuff (like this), just have the application open when a user double clicks a file.

感谢您提供任何帮助:)

Thanks for any help you can offer :)

推荐答案

您在代码中插入的评论包含以下答案:

The comment you inserted in your code contains the answer:

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

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

The HRESULT value is telling you that you need to call the CoInitialize function in order to initialize the COM library for your application's thread.

当然,消息有点过时。如上述链接文档中所示,所有新应用程序都应调用 CoInitializeEx 函数

Of course, the message is a little bit outdated. As you'll see in the above-linked documentation, all new applications should call the CoInitializeEx function instead. No worries, though: it does essentially the same thing as its older brother.

由于文档的备注部分指出:

As the "Remarks" section of the documentation indicates:


必须至少调用一次CoInitializeEx ,对于使用COM库的每个线程,它通常只调用一次。 [。 。 。 ]您需要在调用任何除了 CoGetMalloc 的库函数之前初始化线程上的COM库,以获取指向标准分配器的指针和内存分配函数。否则,COM函数将返回 CO_E_NOTINITIALIZED

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升级现有项目后,您似乎缺少此重要步骤。

You say that you're not using COM, but this is incorrect. You may not be using it explicitly, but Windows and the MFC framework are definitely using it "behind the scenes". All of the file type registration functions rely on COM. The skeleton code produced by the MFC project wizard in Visual Studio 2010 would have automatically inserted the appropriate COM registration code, but since you upgraded an existing project from VC++ 6, you appear to be missing this vital step.

在MFC中, AfxOleInit 函数还会为调用应用程序的当前公寓初始化COM,正如 OleInitialize 函数。确保重载的 InitInstance 函数包含对这些函数之一的调用。

In MFC, the AfxOleInit function also initializes COM for the current apartment of the calling app, just as the OleInitialize function does internally. Make sure that your overridden InitInstance function contains a call to one of these functions.

例如, VS 2010向导创建的新MFC项目, InitInstance 函数看起来像这样:

For example, in a fresh new MFC project created by the VS 2010 wizard, the InitInstance function looks something like this:

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

这篇关于MFC应用程序声明失败在CRecentFileList ::添加在命令行FileOpen的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆