📄 if_ole.cpp
字号:
STDMETHOD(QueryInterface)(REFIID riid, void ** ppv);
STDMETHOD_(unsigned long, AddRef)(void);
STDMETHOD_(unsigned long, Release)(void);
STDMETHOD(CreateInstance)(IUnknown *punkOuter, REFIID riid, void ** ppv);
STDMETHOD(LockServer)(BOOL lock);
private:
// Constructor is private - create via Create()
CVimCF() : ref(0) {};
// Reference count
unsigned long ref;
};
/* Implementation
* --------------
*/
CVimCF *CVimCF::Create()
{
CVimCF *me = new CVimCF();
if (me == NULL)
MessageBox(0, "Cannot create class factory", "Vim Initialisation", 0);
return me;
}
STDMETHODIMP
CVimCF::QueryInterface(REFIID riid, void **ppv)
{
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
{
AddRef();
*ppv = this;
return S_OK;
}
*ppv = 0;
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG)
CVimCF::AddRef()
{
return ++ref;
}
STDMETHODIMP_(ULONG)
CVimCF::Release()
{
if (--ref == 0)
{
delete this;
return 0;
}
return ref;
}
STDMETHODIMP
CVimCF::CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv)
{
return app->QueryInterface(riid, ppv);
}
STDMETHODIMP
CVimCF::LockServer(BOOL lock)
{
return S_OK;
}
/*****************************************************************************
4. Registry manipulation code
*****************************************************************************/
// Internal use only
static void SetKeyAndValue(const char* path, const char* subkey, const char* value);
static void GUIDtochar(const GUID& guid, char* GUID, int length);
static void RecursiveDeleteKey(HKEY hKeyParent, const char* child);
static const int GUID_STRING_SIZE = 39;
// Register the component in the registry
//
// Note: There is little error checking in this code at present.
extern "C" void RegisterMe()
{
BOOL ok = TRUE;
// Get the application startup command
char module[MAX_PATH];
::GetModuleFileName(NULL, module, MAX_PATH);
// Unregister first (quietly)
UnregisterMe(FALSE);
// Convert the CLSID into a char
char clsid[GUID_STRING_SIZE];
GUIDtochar(MYCLSID, clsid, sizeof(clsid));
// Convert the LIBID into a char
char libid[GUID_STRING_SIZE];
GUIDtochar(MYLIBID, libid, sizeof(libid));
// Build the key CLSID\\{...}
char Key[MAX_CLSID_LEN];
strcpy(Key, "CLSID\\");
strcat(Key, clsid);
// Add the CLSID to the registry
SetKeyAndValue(Key, NULL, MYNAME);
SetKeyAndValue(Key, "LocalServer32", module);
SetKeyAndValue(Key, "ProgID", MYPROGID);
SetKeyAndValue(Key, "VersionIndependentProgID", MYVIPROGID);
SetKeyAndValue(Key, "TypeLib", libid);
// Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT
SetKeyAndValue(MYVIPROGID, NULL, MYNAME);
SetKeyAndValue(MYVIPROGID, "CLSID", clsid);
SetKeyAndValue(MYVIPROGID, "CurVer", MYPROGID);
// Add the versioned ProgID subkey under HKEY_CLASSES_ROOT
SetKeyAndValue(MYPROGID, NULL, MYNAME);
SetKeyAndValue(MYPROGID, "CLSID", clsid);
wchar_t w_module[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, module, -1, w_module, MAX_PATH);
ITypeLib *typelib = NULL;
if (FAILED(LoadTypeLib(w_module, &typelib)))
{
MessageBox(0, "Cannot load type library to register", "Vim Registration", 0);
ok = FALSE;
}
else
{
if (FAILED(RegisterTypeLib(typelib, w_module, NULL)))
{
MessageBox(0, "Cannot register type library", "Vim Registration", 0);
ok = FALSE;
}
typelib->Release();
}
if (ok)
MessageBox(0, "Registered successfully", "Vim", 0);
}
// Remove the component from the registry
//
// Note: There is little error checking in this code, to allow incomplete
// or failed registrations to be undone.
extern "C" void UnregisterMe(int bNotifyUser)
{
// Unregister the type library
ITypeLib *typelib;
if (SUCCEEDED(LoadRegTypeLib(MYLIBID, MAJORVER, MINORVER, LOCALE, &typelib)))
{
TLIBATTR *tla;
if (SUCCEEDED(typelib->GetLibAttr(&tla)))
{
UnRegisterTypeLib(tla->guid, tla->wMajorVerNum, tla->wMinorVerNum,
tla->lcid, tla->syskind);
typelib->ReleaseTLibAttr(tla);
}
typelib->Release();
}
// Convert the CLSID into a char
char clsid[GUID_STRING_SIZE];
GUIDtochar(MYCLSID, clsid, sizeof(clsid));
// Build the key CLSID\\{...}
char Key[MAX_CLSID_LEN];
strcpy(Key, "CLSID\\");
strcat(Key, clsid);
// Delete the CLSID Key - CLSID\{...}
RecursiveDeleteKey(HKEY_CLASSES_ROOT, Key);
// Delete the version-independent ProgID Key
RecursiveDeleteKey(HKEY_CLASSES_ROOT, MYVIPROGID);
// Delete the ProgID key
RecursiveDeleteKey(HKEY_CLASSES_ROOT, MYPROGID);
if (bNotifyUser)
MessageBox(0, "Unregistered successfully", "Vim", 0);
}
/****************************************************************************/
// Convert a GUID to a char string
static void GUIDtochar(const GUID& guid, char* GUID, int length)
{
// Get wide string version
LPOLESTR wGUID = NULL;
StringFromCLSID(guid, &wGUID);
// Covert from wide characters to non-wide
wcstombs(GUID, wGUID, length);
// Free memory
CoTaskMemFree(wGUID);
}
// Delete a key and all of its descendents
static void RecursiveDeleteKey(HKEY hKeyParent, const char* child)
{
// Open the child
HKEY hKeyChild;
LONG result = RegOpenKeyEx(hKeyParent, child, 0, KEY_ALL_ACCESS, &hKeyChild);
if (result != ERROR_SUCCESS)
return;
// Enumerate all of the decendents of this child
FILETIME time;
char buffer[1024];
DWORD size = 1024;
while (RegEnumKeyEx(hKeyChild, 0, buffer, &size, NULL,
NULL, NULL, &time) == S_OK)
{
// Delete the decendents of this child
RecursiveDeleteKey(hKeyChild, buffer);
size = 256;
}
// Close the child
RegCloseKey(hKeyChild);
// Delete this child
RegDeleteKey(hKeyParent, child);
}
// Create a key and set its value
static void SetKeyAndValue(const char* key, const char* subkey, const char* value)
{
HKEY hKey;
char buffer[1024];
strcpy(buffer, key);
// Add subkey name to buffer.
if (subkey)
{
strcat(buffer, "\\");
strcat(buffer, subkey);
}
// Create and open key and subkey.
long result = RegCreateKeyEx(HKEY_CLASSES_ROOT,
buffer,
0, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL,
&hKey, NULL);
if (result != ERROR_SUCCESS)
return;
// Set the value
if (value)
RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)value, strlen(value)+1);
RegCloseKey(hKey);
}
/*****************************************************************************
5. OLE Initialisation and shutdown processing
*****************************************************************************/
extern "C" void InitOLE(int* pbDoRestart)
{
HRESULT hr;
*pbDoRestart = FALSE;
// Initialize the OLE libraries
hr = OleInitialize(NULL);
if (FAILED(hr))
{
MessageBox(0, "Cannot initialise OLE", "Vim Initialisation", 0);
goto error0;
}
// Create the application object
app = CVim::Create(pbDoRestart);
if (app == NULL)
goto error1;
// Create the class factory
cf = CVimCF::Create();
if (cf == NULL)
goto error1;
// Register the class factory
hr = CoRegisterClassObject(
MYCLSID,
cf,
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE,
&cf_id);
if (FAILED(hr))
{
MessageBox(0, "Cannot register class factory", "Vim Initialisation", 0);
goto error1;
}
// Register the application object as active
hr = RegisterActiveObject(
app,
MYCLSID,
NULL,
&app_id);
if (FAILED(hr))
{
MessageBox(0, "Cannot register application object", "Vim Initialisation", 0);
goto error1;
}
return;
// Errors: tidy up as much as needed and return
error1:
UninitOLE();
error0:
return;
}
extern "C" void UninitOLE()
{
// Unregister the application object
if (app_id)
{
RevokeActiveObject(app_id, NULL);
app_id = 0;
}
// Unregister the class factory
if (cf_id)
{
CoRevokeClassObject(cf_id);
cf_id = 0;
}
// Delete the class factory
if (cf)
{
delete cf;
cf = NULL;
}
// Delete the application object
if (app)
{
delete app;
app = NULL;
}
// Shut down the OLE libraries
OleUninitialize();
}
#endif /* HAVE_OLE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -