我使用的是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 exceptCoGetMalloc
, to get a pointer to the standard allocator, and the memory allocation functions. Otherwise, the COM function will returnCO_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/