2012-08-01 17 views
5

Hola Actualmente estoy ejecutando Visual Studio 2010 y tengo una extensión de shell de menú contextual que funciona completamente en 32 bits en una máquina de 32 bits, por lo que existen todos los métodos. Es un proyecto ATL. Sin errores ni advertencias en los 32 bits.Proyecto VS COM Compila en 32 bits pero arroja el error C2259 al intentar compilar 64bit

Aquí está el problema. Cuando entro en Configuration Manager en Visual Studio y cambio la plataforma de solución activa de Win32 a x64 y trato de compilar, obtengo el error "error C2259: 'ATL :: CCOMObject: no puede instanciar clase abstracta".

Dado que este mismo proyecto se compila y se ejecuta en 32 bits, ¿por qué me lanza ese error para x64?

Cualquier idea o un punto en la dirección correcta sería apreciada.
métodos principales que son necesarios y están implementados como sigue:

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

para ahorrar espacio Código Crear un proyecto ATL. Una vez que se han creado los elementos iniciales, agregue una nueva clase "TestingContextMenu". Rest of Code hará referencia a esto.

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 Sólo las piezas que se han añadido/Cambiado se incluirán

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

El resto de las funciones están disponibles bajo petición. Sin embargo, he notado algo nuevo. Si tiene implementada la función y el código anteriores y el administrador de configuración configurado para compilar x64, obtendrá el error inicial que estoy teniendo. Esto incluso significa no implementar QueryContextMenu, GetCommandString o el comando invoke. El único error que obtendrá con esta configuración es mi original, que es lo que esperaríamos ya que no están implementados. Sin embargo, cambie ese administrador de configuraciones de nuevo a Win32 y obtendrá los errores esperados, como 3 elementos externos no resueltos, y 3 errores siguientes al nombrar GetCommandString, InvokeCommand y QueryContextMenu. Se espera otra vez si no se implementan, pero ¿por qué el compilador de x64 reconoce solo mi error original, que es lo que mucha gente supondría que es, métodos no implementados, pero en el conjunto de win32 muestra los errores completos cuando no se implementan.

El párrafo anterior fue algo que noté. Tengo los 3 métodos implementados correctamente y compila correctamente en Win32 pero no en x64.

+0

¿Cuál es el resto del mensaje de error? Por lo general, hay una lista de miembros no implementados. De lo contrario, publique una reproducción mínima que demuestre el problema. –

+0

Ese es el mensaje de error completo. Ocurre dentro de altcom.h en esta línea ATLTRY (p = new T1 (pv)) – Rob

+1

Mire en la ventana Salida el mensaje completo, le dice qué miembro de la clase es el alborotador. –

Respuesta

6

Sus parámetros GetCommandString no coinciden con los definidos por el método de interfaz.

Su

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

es necesario que haya

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

En Win32 la falta de coincidencia no es tanto importante (los tipos de parámetros se resuelven al mismo tipo), y en x64 es llega a ser importante. El resultado de compilación del compilador debería haberle dado una pista sobre esto, incluido el nombre del método faltante.

+0

Ese fue el problema. El error no aparecía para obtener la cadena de comando. Leí los comentarios de los pasantes y agregué la nueva información. Probé la solución que sugieres y funciona. Compila y programa ha sido probado y operando en una máquina de 64 bits. Aprendiendo mucho sobre C++ de estos errores. Yo recomendaría tanto a usted como a Passant si tuviera el representante. – Rob

Cuestiones relacionadas