2012-08-01 24 views
5

Ciao Al momento eseguo Visual Studio 2010 e ho un'estensione della shell del menu di scelta rapida che funziona a 32 bit su una macchina a 32 bit, quindi esistono tutti i metodi. È un progetto ATL. Nessun errore o persino avvertimento sul 32 bit.Progetto VS COM Compila a 32 bit ma genera l'errore C2259 quando si tenta di compilare 64 bit

Ecco il problema. Quando vado in Configuration Manager sotto Visual Studio e cambio la piattaforma di soluzione attiva da Win32 a x64 e provo a compilare, ottengo l'errore "Errore C2259: 'ATL :: CCOMObject: impossibile istanziare la classe astratta".

Poiché questo stesso esatto progetto si compila ed esegue in 32 bit perché mi restituisce quell'errore per x64?

Qualsiasi idea o un punto nella giusta direzione sarebbe apprezzato.
I metodi principali che sono necessari e vengono applicate come segue:

STDMETHODIMP Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY); 
STDMETHODIMP GetCommandString(UINT, UINT, UINT*, LPSTR, UINT); 
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO); 
STDMETHODIMP QueryContextMenu(HMENU, UINT, UINT, UINT, UINT); 

Per salvare spazio di codice Creare un progetto ATL. Una volta che gli articoli iniziali sono stati creati, aggiungi una nuova classe "TestingContextMenu". Il resto del codice farà riferimento a questo.

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 solo le parti che sono state aggiunte/modificate saranno inclusi

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

Il resto delle funzioni sono disponibili su richiesta. Tuttavia ho notato qualcosa di nuovo. Se hai implementato la funzione e il codice sopra indicati e il gestore di configurazione impostato per creare x64 ottieni l'errore iniziale che sto riscontrando. Ciò significa anche non implementare il comando QueryContextMenu, GetCommandString o il comando invoke. L'unico errore che otterrai con questa configurazione è il mio originale, che è quello che ci aspetteremmo dal momento che non sono implementati. Tuttavia, riconvertire il gestore di configurazione in Win32 e ottenere gli errori previsti, ad esempio 3 elementi esterni non risolti e 3 errori che seguono la denominazione di GetCommandString, InvokeCommand e QueryContextMenu. Prevedibilmente, se non sono implementati, ma perché il compilatore su x64 riconosce solo il mio errore originale che è quello che molte persone presumono che sia, non metodi implementati, ma sul set win32 mostra gli errori completi quando non è implementato.

Il paragrafo precedente era solo qualcosa che ho notato. Ho tutti e 3 i metodi implementati correttamente e compila correttamente in Win32 ma non x64.

+0

Qual è il resto del messaggio di errore? Di solito c'è una lista di membri non implementati. Altrimenti, pubblica una replica minimale che mostri il problema. –

+0

Questo è l'intero messaggio di errore. Si verifica all'interno di altcom.h in questa riga ATLTRY (p = new T1 (pv)) – Rob

+1

Cerca nella finestra Output per il messaggio completo, ti dice quale membro della classe è il troublemaker. –

risposta

6

I parametri GetCommandString non corrispondono a quelli definiti dal metodo di interfaccia.

tuo

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

deve essere

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

Nel Win32 la mancata corrispondenza non è tanto importante (i tipi di parametri risolvono allo stesso tipo), in x64 è diventa importante. L'output di compilazione del compilatore avrebbe dovuto darti un suggerimento su questo, incluso il nome del metodo mancante.

+0

Questo era il problema. L'errore non veniva visualizzato per ottenere la stringa di comando. Ho letto i commenti dei Passanti e ho aggiunto le nuove informazioni. Ho provato la correzione che suggerisci e funziona. Compilazioni e programmi sono stati testati e funzionano su una macchina a 64 bit. Imparare così tanto su C++ da questi errori. Avrei votato su te e su Passant se avessi il rappresentante. – Rob