Witaj, pracuję obecnie z Visual Studio 2010 i mam rozszerzenie menu kontekstowego powłoki działające w 32-bitowym na 32-bitowym komputerze, więc wszystkie metody istnieją. To jest projekt ATL. Brak błędów, a nawet ostrzeżeń w 32-bitowym.Projekt VS COM Kompiluje się w wersji 32-bitowej, ale generuje błąd C2259 podczas próby skompilowania 64-bitowego kodu.
Tutaj jest problem. Kiedy wchodzę do Menedżera konfiguracji w visual studio i przełączam platformę aktywnego rozwiązania z Win32 na x64 i próbuję skompilować, pojawia się błąd "error C2259:" ATL :: CCOMObject: nie mogę utworzyć instancji klasy abstrakcyjnej ".
Ponieważ ten sam projekt jest kompilowany i uruchamiany w wersji 32-bitowej, dlaczego powoduje błąd w wersji x64?
Wszelkie pomysły lub punkt we właściwym kierunku zostaną docenione.
głównych metod, które są wymagane i są realizowane w następujący sposób:
STDMETHODIMP Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY);
STDMETHODIMP GetCommandString(UINT, UINT, UINT*, LPSTR, UINT);
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO);
STDMETHODIMP QueryContextMenu(HMENU, UINT, UINT, UINT, UINT);
Aby zapisać kod Przestrzeń utworzyć projekt Atl. Po utworzeniu początkowych elementów dodaj nową klasę "TestingContextMenu". Reszta kodu będzie się do tego odwoływała.
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;
TestingContextMenu.h tylko części, które zostały dodane/Zmienione zostaną włączone
#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
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;
}
Reszta funkcji są dostępne na życzenie. Jednak zauważyłem coś nowego. Jeśli posiadasz tylko powyższą funkcję i kod, a menedżer konfiguracji ustawił na x64, otrzymujesz początkowy błąd, który mam. Oznacza to nawet nie implementację QueryContextMenu, GetCommandString lub polecenia invoke. Tylko błąd, który otrzymasz dzięki tej konfiguracji, jest moim oryginałem, czego moglibyśmy się spodziewać, ponieważ nie są zaimplementowani. Jednak przełącz menedżera konfiguracji z powrotem na system Win32, a otrzymasz oczekiwane błędy, takie jak 3 nierozwiązane zewnętrzne i 3 błędy następujące po nazwie GetCommandString, InvokeCommand i QueryContextMenu. Ponownie się spodziewamy, jeśli nie zostaną zaimplementowane, ale dlaczego kompilator na x64 rozpozna tylko mój pierwotny błąd, który jest tym, co wielu ludzi założyłoby, że to nie zaimplementowane metody, ale w zestawie win32 pokazuje pełne błędy, gdy nie są zaimplementowane.
Poprzedni akapit był po prostu czymś, co zauważyłem. Mam wszystkie 3 metody zaimplementowane poprawnie i kompiluje poprawnie w Win32, ale nie x64.
Jaka jest pozostała część komunikatu o błędzie? Zwykle jest lista niezatwierdzonych członków. W przeciwnym razie opublikuj minimalne repro, które demonstruje problem. –
To jest cały komunikat o błędzie. Występuje w altcom.h w tej linii ATLTRY (p = nowy T1 (pv)) – Rob
Sprawdź w oknie wyjściowym pełną wiadomość, która mówi, który członek klasy jest wichrzycielem. –