-
-
Save T3nb3w/50c15c18bd7cdf327a136767c181c5ac to your computer and use it in GitHub Desktop.
Example Using COM IDispatch Interface
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Example using the COM interface without AutoCOM. The entire | |
* file can be automated with AutoCOM in under 15-lines of code. | |
* | |
* #include "autocom.hpp" | |
* int main(int argc, char *argv[]) | |
* { | |
* com::Bstr text; | |
* com::Dispatch dispatch("VBScript.RegExp"); | |
* dispatch.put("Pattern", L"\\w+"); | |
* for (auto match: dispatch.iter("Execute", L"A(b) c35 d_[x] yyy")) { | |
* match.get("Value", text); | |
* printf("Match is %S\n", text); | |
* } | |
* return 0; | |
* } | |
*/ | |
#include <cassert> | |
#include <cstdio> | |
#include <dispex.h> | |
#include <oaidl.h> | |
#include <wtypes.h> | |
void putPattern(IDispatch *dispatch) | |
{ | |
// initialize parameters | |
DISPPARAMS dp = {nullptr, nullptr, 0, 0}; | |
VARIANT *args = new VARIANT[1]; | |
DISPID named = DISPID_PROPERTYPUT; | |
VariantInit(&args[0]); | |
args[0].vt = VT_BSTR; | |
args[0].bstrVal = SysAllocString(L"\\w+"); | |
dp.rgvarg = args; | |
dp.cArgs = 1; | |
dp.rgdispidNamedArgs = &named; | |
dp.cNamedArgs = 1; | |
// get function ID | |
DISPID id; | |
LPOLESTR string = L"Pattern"; | |
if (FAILED(dispatch->GetIDsOfNames(IID_NULL, &string, DISPATCH_METHOD, LOCALE_USER_DEFAULT, &id))) { | |
assert(false); | |
} | |
// call method | |
VARIANT result; | |
VariantInit(&result); | |
if (FAILED(dispatch->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &dp, &result, nullptr, nullptr))) { | |
assert(false); | |
} | |
// cleanup | |
VariantClear(&args[0]); | |
VariantClear(&result); | |
delete[] args; | |
} | |
IDispatch * callExecute(IDispatch *dispatch) | |
{ | |
// initialize parameters | |
DISPPARAMS dp = {nullptr, nullptr, 0, 0}; | |
VARIANT *args = new VARIANT[1]; | |
VariantInit(&args[0]); | |
args[0].vt = VT_BSTR; | |
args[0].bstrVal = SysAllocString(L"A(b) c35 d_[x] yyy"); | |
dp.rgvarg = args; | |
dp.cArgs = 1; | |
// get function ID | |
DISPID id; | |
LPOLESTR string = L"Execute"; | |
if (FAILED(dispatch->GetIDsOfNames(IID_NULL, &string, DISPATCH_METHOD, LOCALE_USER_DEFAULT, &id))) { | |
assert(false); | |
} | |
// call method | |
VARIANT result; | |
if (FAILED(dispatch->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET | DISPATCH_METHOD, &dp, &result, nullptr, nullptr))) { | |
assert(false); | |
} | |
// cleanup | |
VariantClear(&args[0]); | |
delete[] args; | |
return result.pdispVal; | |
} | |
IEnumVARIANT * requestEnumVariant(IDispatch *dispatch) | |
{ | |
// initialize parameters | |
DISPPARAMS dp = {nullptr, nullptr, 0, 0}; | |
VARIANT result; | |
// call method | |
auto hr = dispatch->Invoke(DISPID_NEWENUM, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET | DISPATCH_METHOD, &dp, &result, nullptr, nullptr); | |
if (FAILED(hr)) { | |
assert(false); | |
} | |
IEnumVARIANT *ev = nullptr; | |
if (result.vt == VT_DISPATCH) { | |
hr = result.pdispVal->QueryInterface(IID_IEnumVARIANT, (void**) &ev); | |
} else if (result.vt == VT_UNKNOWN) { | |
hr = result.punkVal->QueryInterface(IID_IEnumVARIANT, (void**) &ev); | |
} else { | |
hr = E_NOINTERFACE; | |
} | |
VariantClear(&result); | |
if (FAILED(hr)) { | |
assert(false); | |
} | |
return ev; | |
} | |
void printMatch(IDispatch *match) | |
{ | |
// initialize parameters | |
DISPPARAMS dp = {nullptr, nullptr, 0, 0}; | |
VARIANT result; | |
VariantInit(&result); | |
// get function ID | |
DISPID id; | |
LPOLESTR string = L"Value"; | |
if (FAILED(match->GetIDsOfNames(IID_NULL, &string, DISPATCH_METHOD, LOCALE_USER_DEFAULT, &id))) { | |
assert(false); | |
} | |
// call method | |
if (FAILED(match->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET | DISPATCH_METHOD, &dp, &result, nullptr, nullptr))) { | |
assert(false); | |
} | |
// get value | |
printf("Match is %S\n", result.bstrVal); | |
VariantClear(&result); | |
} | |
int main(int argc, char *argv[]) | |
{ | |
CoInitializeEx(nullptr, COINIT_MULTITHREADED); | |
// create our dispatcher | |
GUID guid; | |
IDispatch *dispatch; | |
CLSIDFromProgID(L"VBScript.RegExp", (LPCLSID) &guid); | |
if (FAILED(CoCreateInstance(guid, nullptr, CLSCTX_INPROC_SERVER, IID_IDispatch, (void **) &dispatch))) { | |
assert(false); | |
} | |
// call methods | |
putPattern(dispatch); | |
auto *enumdispatcher = callExecute(dispatch); | |
auto ev = requestEnumVariant(enumdispatcher); | |
// iterate | |
VARIANT result; | |
ULONG fetched; | |
if (SUCCEEDED(ev->Next(1, &result, &fetched))) { | |
IDispatch *match = result.pdispVal; | |
printMatch(match); | |
} | |
// cleanup | |
ev->Release(); | |
enumdispatcher->Release(); | |
dispatch->Release(); | |
CoUninitialize(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment