发生这种问题主要是没有将typelib信息写到注册表,只要调用RegisterTypeLibServer函数则可添加相关信息,参考下面代码。
以下宏定义是我为了简化com控件开发定义的。
//-----------------------------------------------------------------
//EXPORTS
//
//DllGetClassObject PRIVATE
//DllCanUnloadNow PRIVATE
//DllRegisterServer PRIVATE
//DllUnregisterServer PRIVATE
//-----------------------------------------------------------------
#pragma once
#include <assert.h>
#include <tchar.h>
#include <strsafe.h>
#include <Shlwapi.h>
#include "streams.h"
#include <atlbase.h>
#pragma comment(lib,"winmm.lib")
//Node:If you reference baseclass library,runtime library must use mt or mtd mode,because usually we compile baseclass in mt/mtd mode.
#if defined(DEBUG) || defined(_DEBUG)
#pragma comment(lib,"strmbasd.lib")
#else
#pragma comment(lib,"strmbase.lib")
#endif
#define BEGIN_COM_DECLARE /
extern HMODULE g_hModule = NULL;/
CFactoryTemplate g_Templates[] = /
{
#define END_COM_DECLARE(clsid,version,libraryname) /
};/
const int CLSID_STRING_SIZE = 39 ;/
void CLSIDtoString(const CLSID& clsid, TCHAR* szCLSID, int length)/
{/
assert(length >= CLSID_STRING_SIZE) ;/
LPOLESTR wszCLSID = NULL ;/
HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;/
assert(SUCCEEDED(hr)) ;/
lstrcpy(szCLSID,wszCLSID);/
CoTaskMemFree(wszCLSID) ;/
}/
LONG DeleteKey(HKEY hKeyParent, const TCHAR* lpszKeyChild)/
{/
HKEY hKeyChild ;/
LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0,KEY_ALL_ACCESS, &hKeyChild) ;/
if (lRes != ERROR_SUCCESS)/
{/
return lRes ;/
}/
FILETIME time ;/
TCHAR szBuffer[256] ;/
DWORD dwSize = 256 ;/
while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,NULL, NULL, &time) == S_OK)/
{/
lRes = DeleteKey(hKeyChild, szBuffer) ;/
if (lRes != ERROR_SUCCESS)/
{/
RegCloseKey(hKeyChild) ;/
return lRes;/
}/
dwSize = 256 ;/
}/
RegCloseKey(hKeyChild) ;/
return RegDeleteKey(hKeyParent, lpszKeyChild) ;/
}/
BOOL SetKeyAndValue(const TCHAR* szKey,const TCHAR* szSubkey,const TCHAR* szValue)/
{/
TCHAR szKeyBuf[1024] ;/
lstrcpy(szKeyBuf, szKey) ;/
if (szSubkey != NULL)/
{/
lstrcat(szKeyBuf, L"//") ;/
lstrcat(szKeyBuf, szSubkey ) ;/
}/
HKEY hKey;/
long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,szKeyBuf, 0, NULL, REG_OPTION_NON_VOLATILE,/
KEY_ALL_ACCESS, NULL, &hKey, NULL) ;/
if (lResult != ERROR_SUCCESS)/
{/
return FALSE ;/
}/
if (szValue != NULL)/
{/
RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)szValue, 2*lstrlen(szValue)+1) ;/
}/
RegCloseKey(hKey) ;/
return TRUE ;/
}/
HRESULT RegisterTypeLibServer(const CLSID& clsid, const TCHAR *szVersion, const TCHAR *szLibraryName, const TCHAR *szTlbPath) /
{/
TCHAR szCLSID[CLSID_STRING_SIZE] ;/
CLSIDtoString(clsid, szCLSID, sizeof(szCLSID)) ;/
TCHAR szKey[MAX_PATH] ;/
lstrcpy(szKey, L"TypeLib//") ;/
lstrcat(szKey, szCLSID) ;/
SetKeyAndValue(szKey, NULL, NULL) ;/
SetKeyAndValue(szKey, szVersion, szLibraryName) ;/
lstrcat(szKey, L"//") ;/
lstrcat(szKey, szVersion) ;/
SetKeyAndValue(szKey, L"0", NULL) ;/
TCHAR szSubKey[MAX_PATH] ;/
memset(szSubKey,0,MAX_PATH);/
lstrcpy(szSubKey,szKey);/
lstrcat(szSubKey, L"//0") ;/
SetKeyAndValue(szSubKey, L"win32", szTlbPath) ;/
SetKeyAndValue(szKey, L"FLAGS", L"0") ;/
TCHAR szTlbDir[MAX_PATH];/
lstrcpy(szTlbDir,szTlbPath);/
PathRemoveFileSpec(szTlbDir);/
SetKeyAndValue(szKey, L"HELPDIR", szTlbDir) ;/
return S_OK ;/
}/
HRESULT UnregisterTypeLibServer(const CLSID& clsid)/
{/
TCHAR szCLSID[CLSID_STRING_SIZE] ;/
CLSIDtoString(clsid, szCLSID, sizeof(szCLSID)) ;/
TCHAR szKey[64] ;/
lstrcpy(szKey, L"TypeLib//") ;/
lstrcat(szKey, szCLSID) ;/
LONG lResult = DeleteKey(HKEY_CLASSES_ROOT, szKey) ;/
return lResult==ERROR_SUCCESS?S_OK:E_FAIL ;/
}/
int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]);/
STDAPI DllRegisterServer()/
{/
TCHAR szTlbDir[MAX_PATH];/
::GetModuleFileName(g_hModule,szTlbDir,MAX_PATH);/
PathRenameExtension(szTlbDir,L".tlb");/
RegisterTypeLibServer(clsid,version,libraryname,szTlbDir);/
return AMovieDllRegisterServer2( TRUE );/
}/
STDAPI DllUnregisterServer()/
{/
UnregisterTypeLibServer(clsid);/
return AMovieDllRegisterServer2( FALSE );/
} /
extern "C" VARIANT_BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);/
VARIANT_BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call, LPVOID lpReserved )/
{/
g_hModule = hModule;/
return DllEntryPoint((HINSTANCE)(hModule), ul_reason_for_call, lpReserved);/
}
#define DECLARE_COM_OBJECT /
DECLARE_IUNKNOWN/
static CUnknown * WINAPI CreateInstance (LPUNKNOWN punk, HRESULT *phr);/
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);/
#define IMPLEMENT_COM_INSTANCE(c,n,i) /
CUnknown * c::CreateInstance (LPUNKNOWN punk, HRESULT *phr)/
{/
CUnknown*pObj = new c(n,punk);/
*phr = pObj==NULL?E_OUTOFMEMORY:S_OK;/
return pObj;/
}/
STDMETHODIMP c::NonDelegatingQueryInterface(REFIID riid, void ** ppv)/
{/
if (riid == __uuidof(i)) {/
GetInterface((i*) this, ppv);/
return NOERROR;/
}
#define QUERY_INTERFACE(i) /
else if (riid == __uuidof(i)) {/
GetInterface((i*) this, ppv);/
return NOERROR;/
}
#define END_COM_OBJECT(p) /
else {/
return p::NonDelegatingQueryInterface(riid,ppv);/
}/
}