DispHelper test:
#define WIN32_LEAN_AND_MEAN
#include "disphelper.h"
#include <stdio.h>
#pragma comment(lib, "user32")
#define HR_TRY(func) if (FAILED(func)) { printf("\n## Fatal error on line %d.\n", __LINE__); goto cleanup; }
int ACadSample1(void)
{
DISPATCH_OBJ(pApp);
dhInitialize(TRUE);
dhToggleExceptions(TRUE);
HR_TRY( dhCreateObject(L"AutoCAD.Application", NULL, &pApp) );
dhPutValue(pApp, L".Visible = %b", TRUE);
HR_TRY( dhCallMethod(pApp, L".Documents.Add") );
DISPATCH_OBJ(pDoc);
HR_TRY( dhGetValue(L"%o", &pDoc, pApp, L".ActiveDocument") );
cleanup:
dhToggleExceptions(FALSE);
SAFE_RELEASE(pApp);
dhUninitialize(TRUE);
return 0;
}
int main(void)
{
ACadSample1();
return 0;
}
Look acadauto.chm for objects.
For old IntelliCAD 6.x engine (progeCAD Smart 2009) AutoWrap example too:#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <ole2.h>
#include <stdio.h>
#pragma lib "user32.lib"
#pragma lib "ole32.lib"
#pragma lib "oleaut32.lib"
#pragma lib "uuid.lib"
HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp,
WCHAR* ptName, int cArgs, ...);
//int main(int argc, char* argv[])
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
// Initialize COM for this thread...
CoInitialize(NULL);
// Get CLSID for our server...
CLSID clsid;
HRESULT hr = CLSIDFromProgID(L"ICad.Application", &clsid);
if(FAILED(hr)) {
MessageBox(NULL, "CLSIDFromProgID() failed", "Error", 0x10010);
return -1;
}
// Start server and get IDispatch...
IDispatch *pApp;
hr = CoCreateInstance(&clsid, NULL, CLSCTX_LOCAL_SERVER, &IID_IDispatch, (void **)&pApp);
if(FAILED(hr)) {
MessageBox(NULL, "ICad not registered properly", "Error", 0x10010);
return -2;
}
// Make it visible (i.e. app.visible = 1)
{
VARIANT x;
x.vt = VT_I4;
x.lVal = 1;
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pApp, L"Visible", 1, x);
}
IDispatch *pLib = NULL;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pApp, L"Library", 0);
pLib = result.pdispVal;
}
IDispatch *pDoc = NULL;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pApp, L"ActiveDocument", 0);
pDoc = result.pdispVal;
}
IDispatch *pModelSpace = NULL;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pDoc, L"ModelSpace", 0);
pModelSpace = result.pdispVal;
}
IDispatch *pPoint1 = NULL;
{
VARIANT result;
VariantInit(&result);
VARIANT parm1, parm2, parm3;
parm1.vt = VT_R8; parm1.dblVal = 0.0; // Z
parm2.vt = VT_R8; parm2.dblVal = 0.0; // Y
parm3.vt = VT_R8; parm3.dblVal = 0.0; // X
AutoWrap(DISPATCH_PROPERTYGET | DISPATCH_METHOD, &result, pLib, L"CreatePoint", 3, parm1, parm2, parm3);
pPoint1 = result.pdispVal;
}
IDispatch *pPoint2 = NULL;
{
VARIANT result;
VariantInit(&result);
VARIANT parm1, parm2, parm3;
parm1.vt = VT_R8; parm1.dblVal = 0.0; // Z
parm2.vt = VT_R8; parm2.dblVal = 100.0; // Y
parm3.vt = VT_R8; parm3.dblVal = 100.0; // X
AutoWrap(DISPATCH_PROPERTYGET | DISPATCH_METHOD, &result, pLib, L"CreatePoint", 3, parm1, parm2, parm3);
pPoint2 = result.pdispVal;
}
IDispatch *pLine1 = NULL;
{
VARIANT result;
VariantInit(&result);
VARIANT parm1, parm2;
parm1.vt = VT_DISPATCH; parm1.pdispVal = pPoint2;
parm2.vt = VT_DISPATCH; parm2.pdispVal = pPoint1;
AutoWrap(DISPATCH_PROPERTYGET | DISPATCH_METHOD, &result, pModelSpace, L"AddLine", 2, parm1, parm2);
pLine1 = result.pdispVal;
}
{
VARIANT x;
x.vt = VT_I4;
x.lVal = 1;
AutoWrap(DISPATCH_PROPERTYPUT | DISPATCH_METHOD, NULL, pDoc, L"Regen", 1, x);
}
// Release references...
if (pModelSpace) pApp->lpVtbl->Release(pModelSpace);
if (pDoc) pApp->lpVtbl->Release(pDoc);
if (pLib) pApp->lpVtbl->Release(pLib);
if (pApp) pApp->lpVtbl->Release(pApp);
// Uninitialize COM for this thread...
CoUninitialize();
return 0;
}
//
// AutoWrap() - Automation helper function...
//
HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp,
WCHAR* ptName, int cArgs, ...)
{
// Begin variable-argument list...
va_list marker;
va_start(marker, cArgs);
if(!pDisp) {
MessageBox(NULL, "NULL IDispatch passed to AutoWrap()",
"Error", 0x10010);
exit(0);
}
// Variables used...
DISPPARAMS dp = { NULL, NULL, 0, 0 };
DISPID dispidNamed = DISPID_PROPERTYPUT;
DISPID dispID;
HRESULT hr;
char buf[200];
char szName[200];
// Convert down to ANSI
WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);
// Get DISPID for name passed...
hr = pDisp->lpVtbl->GetIDsOfNames(pDisp, &IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT,
&dispID);
if(FAILED(hr)) {
sprintf(buf,
"IDispatchGetIDsOfNames(\"%s\") failed w/err0x%08lx",
szName, hr);
MessageBox(NULL, buf, "AutoWrap()", 0x10010);
return hr;
}
// Allocate memory for arguments...
VARIANT *pArgs = malloc((cArgs+1) * sizeof(VARIANT));
// Extract arguments...
for(int i=0; i<cArgs; i++) {
pArgs[i] = va_arg(marker, VARIANT);
}
// Build DISPPARAMS
dp.cArgs = cArgs;
dp.rgvarg = pArgs;
// Handle special-case for property-puts!
if(autoType & DISPATCH_PROPERTYPUT) {
dp.cNamedArgs = 1;
dp.rgdispidNamedArgs = &dispidNamed;
}
// Make the call!
hr = pDisp->lpVtbl->Invoke(pDisp, dispID, &IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType,
&dp, pvResult, NULL, NULL);
if(FAILED(hr)) {
free(pArgs);
sprintf(buf,
"IDispatchInvoke(\"%s\"=%08lx) failed w/err 0x%08lx",
szName, dispID, hr);
MessageBox(NULL, buf, "AutoWrap()", 0x10010);
return hr;
}
// End variable-argument section...
va_end(marker);
free(pArgs);
return hr;
}