Skip to content

Instantly share code, notes, and snippets.

@kaimingguo
Created December 6, 2023 11:04
Show Gist options
  • Save kaimingguo/d2ebabbc6920f8e58ba48f1f0098e069 to your computer and use it in GitHub Desktop.
Save kaimingguo/d2ebabbc6920f8e58ba48f1f0098e069 to your computer and use it in GitHub Desktop.
Automation OLE Display PowerPoint Version
#include <assert.h>
#include <ole2.h>
#include <iostream>
#include <memory>
#include <sstream>
#include <vector>
template <class T>
void SafeRelease(T **ppT) {
if (*ppT) {
(*ppT)->Release();
*ppT = nullptr;
}
}
HRESULT AutoWrap(int, VARIANT *, IDispatch *, LPOLESTR, int...);
int main(int argc, char *argv[]) {
HRESULT hr;
CLSID clsid;
IDispatch *app = nullptr;
std::wostringstream wss;
hr = CoInitialize(NULL);
if (FAILED(hr)) {
std::cerr << "Failed to initialize COM" << std::endl;
return EXIT_FAILURE;
}
hr = CLSIDFromProgID(_T("PowerPoint.Application"), &clsid);
if (FAILED(hr)) {
std::cerr << "CLSIDFromProgID() failed" << std::endl;
goto exit;
}
hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch,
reinterpret_cast<void **>(&app));
if (FAILED(hr)) {
std::cerr << "PowerPoint not registered property" << std::endl;
goto exit;
}
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, app, _T("Version"), 0);
std::wstring ws(result.bstrVal, SysStringLen(result.bstrVal));
wss << _T("Microsoft PowerPoint v") << ws.c_str() << _T(" ");
VariantClear(&result);
}
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, app, _T("Build"), 0);
std::wstring ws(result.bstrVal, SysStringLen(result.bstrVal));
wss << _T("Build ") << ws.c_str() << _T(" ");
VariantClear(&result);
}
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, app, _T("OperatingSystem"), 0);
std::wstring ws(result.bstrVal, SysStringLen(result.bstrVal));
wss << _T("on ") << ws.c_str() << std::endl;
VariantClear(&result);
}
std::wcout << wss.str() << std::endl;
// Tell Excel to quit
AutoWrap(DISPATCH_METHOD, nullptr, app, _T("Quit"), 0);
exit:
SafeRelease(&app);
CoUninitialize();
return 0;
}
HRESULT AutoWrap(int auto_type, VARIANT *result, IDispatch *disp, LPOLESTR name,
int args...) {
if (!disp) {
return E_INVALIDARG;
}
HRESULT hr;
DISPPARAMS dp = {0};
DISPID dispid_named = DISPID_PROPERTYPUT;
DISPID dispid;
std::shared_ptr<EXCEPINFO> excep;
std::vector<VARIANT> arg_vec(args + 1);
va_list marker;
va_start(marker, args);
for (auto i = 0; i < args; i++) {
arg_vec[i] = va_arg(marker, VARIANT);
}
va_end(marker);
hr = disp->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid);
if (FAILED(hr)) {
_tprintf(_T("IDispatch::GetIDsOfName(\"%s\") failed w/err 0x%08lx"), name, hr);
return hr;
}
dp.cArgs = args;
dp.rgvarg = arg_vec.data();
if (auto_type & DISPATCH_PROPERTYPUT) {
dp.cNamedArgs = 1;
dp.rgdispidNamedArgs = &dispid_named;
}
hr = disp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, auto_type, &dp,
result, excep.get(), nullptr);
if (FAILED(hr)) {
if (hr == DISP_E_EXCEPTION) {
_tprintf(_T("IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx"), name, dispid, excep->scode);
} else {
_tprintf(_T("IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx"), name, dispid, hr);
}
return hr;
}
arg_vec.clear();
return S_OK;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment