Rob*_*Rob 5 c++ atl contextmenu shell-extensions visual-studio-2010
您好我正在运行Visual Studio 2010并且在32位计算机上具有完全在32位上运行的上下文菜单shell扩展,因此存在所有方法.这是一个ATL项目.32位没有错误甚至警告.
这是问题所在.当我进入visual studio下的配置管理器并将活动解决方案平台从Win32切换到x64并尝试编译时我得到错误"错误C2259:'ATL :: CCOMObject:无法实例化抽象类".
由于这个完全相同的项目在32位编译和运行,为什么它会让我误解为x64?
任何想法或正确方向的一点将不胜感激.
主要方法是必需的并且实施如下:
STDMETHODIMP Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY);
STDMETHODIMP GetCommandString(UINT, UINT, UINT*, LPSTR, UINT);
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO);
STDMETHODIMP QueryContextMenu(HMENU, UINT, UINT, UINT, UINT);
Run Code Online (Sandbox Code Playgroud)
保存代码空间创建Atl项目.一旦创建了初始项,添加一个新类"TestingContextMenu"其余的代码将引用它.
stdafk.h
#include "resource.h"
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>
#include <shlobj.h>
#include <comdef.h>
#include <string>
#include <list>
typedef std::list< std::basic_string<TCHAR> > string_list;
Run Code Online (Sandbox Code Playgroud)
TestingContextMenu.h仅包含已添加/更改的部分
#include "stdafx.h"
using namespace std;
class ATL_NO_VTABLE CTestingContextMenu:
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CTestingContextMenu, &CLSID_TestingContextMenu>,
public IShellExtInit,
public IContextMenu
{
// Comment out or remove IDispatch
BEGIN_COM_MAP(CMainMagnimbusContextMenu)
//COM_INTERFACE_ENTRY(ITestingContextMenu)
//COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY(IContextMenu)
END_COM_MAP()
protected:
TCHAR m_szFile[MAX_PATH];
list<string> Filenames;
list<string> FilenamesCopier;
public:
STDMETHODIMP Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY);
STDMETHODIMP GetCommandString(UINT, UINT, UINT*, LPSTR, UINT);
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO);
STDMETHODIMP QueryContextMenu(HMENU, UINT, UINT, UINT, UINT);
}; //There is other code within this but it is autogenerated
Run Code Online (Sandbox Code Playgroud)
TestingContextMenu.cpp
#include "stdafx.h"
#include "TestingContextMenu"
#include <sstream>
using namespace std;
#pragma comment(lib, "comsuppw")
STDMETHODIMP CMainMagnimbusContextMenu::Initialize (
LPCITEMIDLIST pidlFolder,
LPDATAOBJECT pDataObj,
HKEY hProgID )
{
FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stg = { TYMED_HGLOBAL };
HDROP hDrop;
if ( FAILED( pDataObj->GetData ( &fmt, &stg ) ))
return E_INVALIDARG;
hDrop = (HDROP) GlobalLock ( stg.hGlobal );
UINT uNumFiles = DragQueryFile ( hDrop, 0xFFFFFFFF, NULL, 0 );
HRESULT hr = S_OK;
if ( 0 == uNumFiles )
{
GlobalUnlock ( stg.hGlobal );
ReleaseStgMedium ( &stg );
return E_INVALIDARG;
}
UINT counter = 0;
// Get the name of the every file and store it in our member variable m_szFile.
for(counter = 0; counter < uNumFiles; counter++)
{
if ( 0 == DragQueryFile ( hDrop, counter, m_szFile, MAX_PATH ) )
{
hr = E_INVALIDARG;
}
wchar_t* t = _wcsdup(m_szFile);
char ch[260];
char DefChar = ' ';
WideCharToMultiByte(CP_ACP,0,t,-1, ch,260,&DefChar, NULL);
string ss(ch);
Filenames.push_back(ss);
FilenamesCopier.push_back(ss);
}
GlobalUnlock ( stg.hGlobal );
ReleaseStgMedium ( &stg );
return hr;
}
Run Code Online (Sandbox Code Playgroud)
其余功能可根据要求提供.但是我注意到了一些新的东西.如果您只是实现了上述功能和代码,并且Config管理器设置为构建x64,则会出现我遇到的初始错误.这甚至意味着不实现QueryContextMenu,GetCommandString或invoke命令.只有这个设置才能得到的错误是我原来的,这是我们所期望的,因为它们没有实现.但是,将配置管理器切换回Win32并获得预期的错误,例如3个未解析的外部,以及命名GetCommandString,InvokeCommand和QueryContextMenu后的3个错误.再次预计,如果它们没有实现,但为什么x64上的编译器只识别我的原始错误,这是许多人会认为是,而不是实现的方法,但在win32集上它显示未实现时的完整错误.
前一段只是我注意到的事情.我确实正确地实现了所有3个方法并在Win32中正确编译但不是x64.
您的GetCommandString参数与接口方法定义的参数不匹配.
您的
STDMETHODIMP GetCommandString(UINT, UINT, UINT*, LPSTR, UINT)
Run Code Online (Sandbox Code Playgroud)
需要是
STDMETHODIMP GetCommandString(UINT_PTR, UINT, UINT*, LPSTR, UINT)
Run Code Online (Sandbox Code Playgroud)
在Win32不匹配中并不那么重要(参数类型解析为相同类型),并且x64变得非常重要.编译器构建输出应该给你一个提示,包括缺少的方法名称.
| 归档时间: |
|
| 查看次数: |
1184 次 |
| 最近记录: |