2012-08-01 9 views
5

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.

+0

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. –

+0

To jest cały komunikat o błędzie. Występuje w altcom.h w tej linii ATLTRY (p = nowy T1 (pv)) – Rob

+1

Sprawdź w oknie wyjściowym pełną wiadomość, która mówi, który członek klasy jest wichrzycielem. –

Odpowiedz

6

Parametry użytkownika GetCommandString są niezgodne z parametrami zdefiniowanymi w metodzie interfejsu.

Twój

STDMETHODIMP GetCommandString(UINT, UINT, UINT*, LPSTR, UINT) 

musi być

STDMETHODIMP GetCommandString(UINT_PTR, UINT, UINT*, LPSTR, UINT) 

W Win32 niedopasowanie nie jest tak bardzo ważne (typy parametrów rozwiązać do tego samego typu), w x64 to staje się ważne. Wyniki kompilacji kompilatora powinny dać ci wskazówkę, w tym brak nazwy metody.

+0

To był problem. Błąd nie pojawiał się dla ciągu polecenia get. Przeczytałem komentarz Pasażystów i dodałem nowe informacje. Próbowałem sugerować poprawkę i to działa. Kompilacje i program został przetestowany i działa na maszynie 64-bitowej. Uczenie się tak dużo o C++ z tych błędów. Chciałbym przegłosować zarówno ciebie, jak i Passanta, gdybym miał przedstawiciela. – Rob

Powiązane problemy