aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatthoyts <patthoyts>2005-03-02 16:40:48 +0000
committerpatthoyts <patthoyts>2005-03-02 16:40:48 +0000
commitc4253cf2548af2603141befac83d1a9e7998eafa (patch)
tree0ae34f05d078f59e2086a6010b48e98f9de69af9
parent63cbf1a4669932acdcfdc4cb463f8a7774b72c01 (diff)
downloadjimtcl-c4253cf2548af2603141befac83d1a9e7998eafa.zip
jimtcl-c4253cf2548af2603141befac83d1a9e7998eafa.tar.gz
jimtcl-c4253cf2548af2603141befac83d1a9e7998eafa.tar.bz2
Can now create and relese objects and use ole32.invoke to call propert get on them.
See the sample at the top of the file. NB: ONLY propget so far.
-rw-r--r--Makefile.vc27
-rw-r--r--jim-win32com.c147
-rw-r--r--jim.h2
3 files changed, 148 insertions, 28 deletions
diff --git a/Makefile.vc b/Makefile.vc
index d0195e5..90e53bf 100644
--- a/Makefile.vc
+++ b/Makefile.vc
@@ -1,3 +1,7 @@
+# -*- Makefile -*-
+#
+#
+
SRCDIR =.
!ifdef DEBUG
@@ -17,13 +21,14 @@ OBJS = $(TMPDIR)\jim.obj
CC =cl -nologo
LD =link -nologo
-CFLAGS =$(CFLAGS) -W3 -GX -Fd$(TARGET:.dll=.pdb) -YX -Fp$(TMPDIR)^\
+# -Fd$(TMPDIR)^\
+CFLAGS =$(CFLAGS) -W3 -GX -YX -Fp$(TMPDIR)^\
INC =
DEFS =-DWIN32
LIBS =
-all: jim dll win32 win32com
+all: jim win32 win32com
jim: setup $(OUTDIR)\jim.exe
dll: setup $(OUTDIR)\jim.dll
win32: setup $(OUTDIR)\jim-win32.dll
@@ -31,19 +36,19 @@ win32api: setup $(OUTDIR)\jim-win32api.dll
win32com: setup $(OUTDIR)\jim-win32com.dll
$(OUTDIR)\jim.exe: $(OBJS)
- $(LD) $(LDFLAGS) -out:$@ $** $(LIBS)
+ @$(LD) $(LDFLAGS) -out:$@ $** $(LIBS)
$(OUTDIR)\jim.dll: $(OBJS)
- $(LD) $(LDFLAGS) -dll -out:$@ $** $(LIBS)
+ @$(LD) $(LDFLAGS) -dll -out:$@ $** $(LIBS)
$(OUTDIR)\jim-win32.dll: $(TMPDIR)\jim-win32.obj
- $(LD) $(LDFLAGS) -dll -out:$@ $** $(LIBS)
+ @$(LD) $(LDFLAGS) -dll -out:$@ $** $(LIBS)
$(OUTDIR)\jim-win32api.dll: $(TMPDIR)\jim-win32api.obj
- $(LD) $(LDFLAGS) -dll -out:$@ $** $(LIBS)
+ @$(LD) $(LDFLAGS) -dll -out:$@ $** $(LIBS)
$(OUTDIR)\jim-win32com.dll: $(TMPDIR)\jim-win32com.obj
- $(LD) $(LDFLAGS) -dll -out:$@ $** $(LIBS)
+ @$(LD) $(LDFLAGS) -dll -out:$@ $** $(LIBS)
#-------------------------------------------------------------------------
setup:
@@ -55,22 +60,22 @@ test: jim
$(OUTDIR)\jim.exe test.tcl
clean:
- @if exist $(TMPDIR) rmdir /q /s $(TMPDIR) >NUL
+ @if exist $(TMPDIR)\NUL rmdir /q /s $(TMPDIR) >NUL
realclean: clean
- @if exist $(OUTDIR) rmdir /q /s $(OUTDIR) >NUL
+ @if exist $(OUTDIR)\NUL rmdir /q /s $(OUTDIR) >NUL
#-------------------------------------------------------------------------
.SUFFIXES:.c .cpp
{$(SRCDIR)}.c{$(TMPDIR)}.obj::
- $(CC) $(CFLAGS) $(DEFS) $(INC) -Fa$(TMPDIR)^\ -Fo$(TMPDIR)^\ -c @<<
+ @$(CC) $(CFLAGS) $(DEFS) $(INC) -Fa$(TMPDIR)^\ -Fo$(TMPDIR)^\ -c @<<
$<
<<
{$(SRCDIR)}.cpp{$(TMPDIR)}.obj::
- $(CC) $(CFLAGS) $(DEFS) $(INC) -Fo$(TMPDIR)^\ -c @<<
+ @$(CC) $(CFLAGS) $(DEFS) $(INC) -Fo$(TMPDIR)^\ -c @<<
$<
<<
diff --git a/jim-win32com.c b/jim-win32com.c
index a821d6b..3576b64 100644
--- a/jim-win32com.c
+++ b/jim-win32com.c
@@ -2,7 +2,11 @@
*
* Windows COM extension.
*
- *
+ * Example:
+ * load jim-win32com
+ * set obj [ole32 createobject "SysInfo.SysInfo"]
+ * puts "OS Version: [ole32.invoke $obj OSVersion]"
+ * unset obj
*
* NOTES:
* We could use something ro register a shutdown function so that we can
@@ -107,6 +111,38 @@ Jim_ObjType unicodeObjType = {
JIM_TYPE_REFERENCES,
};
+static LPOLESTR
+A2OLE(LPCSTR sz)
+{
+ DWORD nChars = 0;
+ LPOLESTR wsz = NULL;
+ if (sz != NULL) {
+ nChars = MultiByteToWideChar(CP_ACP, 0, sz, -1, NULL, 0);
+ wsz = (LPOLESTR)Jim_Alloc((nChars + 1) * sizeof(OLECHAR));
+ if (wsz != NULL) {
+ nChars = MultiByteToWideChar(CP_ACP, 0, sz, nChars, wsz, nChars + 1);
+ wsz[nChars] = 0;
+ }
+ }
+ return wsz;
+}
+
+static LPSTR
+OLE2A(LPCOLESTR wsz)
+{
+ DWORD nChars = 0;
+ LPSTR sz = NULL;
+ if (wsz != NULL) {
+ nChars = WideCharToMultiByte(CP_ACP, 0, wsz, -1, NULL, 0, NULL, NULL);
+ sz = (LPSTR)Jim_Alloc((nChars + 1) * sizeof(CHAR));
+ if (sz != NULL) {
+ nChars = WideCharToMultiByte(CP_ACP, 0, wsz, nChars, sz, nChars+1, NULL, NULL);
+ sz[nChars] = 0;
+ }
+ }
+ return sz;
+}
+
void
UnicodeFreeInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
{
@@ -150,18 +186,23 @@ Jim_Obj *
Jim_NewUnicodeObj(Jim_Interp *interp, LPCWSTR wsz, size_t len)
{
Jim_Obj *objPtr = Jim_NewObj(interp);
- if (len < 0)
+ JIM_ASSERT(wsz != NULL);
+ if (wsz != NULL && len == -1)
len = wcslen(wsz);
- if (len == 0) {
+ if (wsz == NULL || len == 0) {
objPtr->bytes = "";
objPtr->length = 0;
} else {
- objPtr->internalRep.binaryValue.data = Jim_Alloc(len + sizeof(WCHAR));
+ objPtr->internalRep.binaryValue.data = Jim_Alloc(sizeof(WCHAR) * (len + 1));
wcsncpy((LPWSTR)objPtr->internalRep.binaryValue.data, wsz, len);
((LPWSTR)objPtr->internalRep.binaryValue.data)[len] = 0;
objPtr->internalRep.binaryValue.len = len;
}
objPtr->typePtr = &unicodeObjType;
+
+ objPtr->bytes = OLE2A(wsz);
+ objPtr->length = strlen(objPtr->bytes);
+
return objPtr;
}
@@ -197,8 +238,6 @@ Ole32FreeInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
{
int r = JIM_OK;
IDispatch *p = (IDispatch *)objPtr->internalRep.ptr;
- r = Jim_DeleteCommand(interp, objPtr->bytes);
- JIM_ASSERT(r == JIM_OK && "Failed to delete ole32 command instance.");
p->lpVtbl->Release(p);
JIM_TRACE("free ole32 object 0x%08x\n", (unsigned long)p);
}
@@ -212,6 +251,47 @@ Ole32DupInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
JIM_TRACE("dup ole32 object 0x%08x\n", (unsigned long)p);
}
+static DISPPARAMS*
+Ole32_GetDispParams(Jim_Interp *interp, int objc, Jim_Obj **objv)
+{
+ DISPPARAMS * dp;
+ int cn;
+
+ dp = (DISPPARAMS*)Jim_Alloc(sizeof(DISPPARAMS));
+ if (dp != NULL) {
+ dp->cArgs = objc;
+ dp->cNamedArgs = 0;
+ dp->rgdispidNamedArgs = NULL;
+ dp->rgvarg = NULL;
+ if (objc > 0)
+ dp->rgvarg = (VARIANT*)Jim_Alloc(sizeof(VARIANT) * dp->cArgs);
+
+ /* Note: this array is filled backwards */
+ for (cn = 0; cn < objc; cn++) {
+ LPOLESTR olestr;
+
+ olestr = A2OLE(Jim_GetString(objv[objc - cn - 1], NULL));
+ VariantInit(&dp->rgvarg[cn]);
+ dp->rgvarg[cn].vt = VT_BSTR;
+ dp->rgvarg[cn].bstrVal = SysAllocString(olestr);
+ Jim_Free(olestr);
+ }
+ }
+ return dp;
+}
+
+static void
+Ole32_FreeDispParams(DISPPARAMS *dp)
+{
+ VARIANT *pv = dp->rgvarg;
+ size_t n;
+ for (n = 0; n < dp->cArgs; n++, pv++) {
+ VariantClear(pv);
+ }
+ Jim_Free(dp->rgvarg);
+ Jim_Free(dp);
+}
+
/* $object method|prop ?args...? */
static int
Ole32_Invoke(Jim_Interp *interp, int objc, Jim_Obj **objv)
@@ -219,24 +299,56 @@ Ole32_Invoke(Jim_Interp *interp, int objc, Jim_Obj **objv)
HRESULT hr = S_OK;
LPWSTR name;
DISPID dispid;
- Jim_Obj *objPtr = (Jim_Obj *)Jim_CmdPrivData(interp);
- IDispatch *pdisp = (IDispatch *)objPtr->internalRep.ptr;
+ LPDISPATCH pdisp;
+ Jim_Obj *resultObj = NULL;
- if (objc < 2) {
- Jim_WrongNumArgs(interp, 1, objv, " method|property ?args ...?");
+ if (objc < 3) {
+ Jim_WrongNumArgs(interp, 1, objv, "object method|property ?args ...?");
return JIM_ERR;
}
-
- name = Jim_GetUnicode(objv[1], NULL);
+
+ if (objv[1]->typePtr != &ole32ObjType) {
+ Jim_SetResultString(interp, "first argument must be a ole32 created object", -1);
+ return JIM_ERR;
+ }
+
+ pdisp = (LPDISPATCH)objv[1]->internalRep.ptr;
+ name = Jim_GetUnicode(objv[2], NULL);
hr = pdisp->lpVtbl->GetIDsOfNames(pdisp, &IID_NULL, &name, 1,
LOCALE_SYSTEM_DEFAULT, &dispid);
- if (SUCCEEDED(hr)) {
- Jim_SetResultString(interp, "ook", -1);
+ {
+ VARIANT v;
+ EXCEPINFO ei;
+ DISPPARAMS *dp = NULL;
+ WORD mode;
+ UINT uierr;
+
+ VariantInit(&v);
+ dp = Ole32_GetDispParams(interp, objc-3, objv+3);
+ mode = INVOKE_PROPERTYGET;
+ hr = pdisp->lpVtbl->Invoke(pdisp, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT, mode, dp, &v, &ei, &uierr);
+ Ole32_FreeDispParams(dp);
+
+ if (SUCCEEDED(hr)) {
+ switch (v.vt) {
+ case VT_I2: resultObj = Jim_NewIntObj(interp, v.iVal); break;
+ case VT_I4: resultObj = Jim_NewIntObj(interp, v.lVal); break;
+ //case VT_R4: resultObj = Jim_NewIntObj(interp, v.lVal); break;
+ //case VT_R8: resultObj = Jim_NewIntObj(interp, v.lVal); break;
+ default: {
+ hr = VariantChangeType(&v, &v, VARIANT_ALPHABOOL, VT_BSTR);
+ if (SUCCEEDED(hr))
+ resultObj = Jim_NewUnicodeObj(interp, v.bstrVal, -1);
+ }
+ }
+ }
+ VariantClear(&v);
}
if (FAILED(hr))
- Jim_SetResult(interp, Win32ErrorObj(interp, "dispatch", (DWORD)hr));
+ resultObj = Win32ErrorObj(interp, "dispatch", (DWORD)hr);
+ Jim_SetResult(interp, resultObj);
return SUCCEEDED(hr) ? JIM_OK : JIM_ERR;
}
@@ -250,7 +362,9 @@ Jim_NewOle32Obj(Jim_Interp *interp, LPDISPATCH pdispatch)
objPtr->internalRep.ptr = (void *)pdispatch;
pdispatch->lpVtbl->AddRef(pdispatch);
objPtr->typePtr = &ole32ObjType;
- Jim_CreateCommand(interp, objPtr->bytes, Ole32_Invoke, (void *)objPtr);
+
+ //refPtr = Jim_NewReference(interp, objPtr, NULL);
+ //Jim_CreateCommand(interp, Jim_GetString(refPtr, NULL), Ole32_Invoke, (void *)objPtr);
JIM_TRACE("created ole32 object 0x%08x\n", pdispatch);
return objPtr;
}
@@ -309,6 +423,7 @@ Jim_OnLoad(Jim_Interp *interp)
return JIM_ERR;
}
Jim_CreateCommand(interp, "ole32", Ole32_Command, NULL);
+ Jim_CreateCommand(interp, "ole32.invoke", Ole32_Invoke, NULL);
return JIM_OK;
}
diff --git a/jim.h b/jim.h
index 9932bcc..141da9e 100644
--- a/jim.h
+++ b/jim.h
@@ -74,7 +74,7 @@
* ---------------------------------------------------------------------------*/
#ifdef HAVE_LONG_LONG
-# ifdef __MSVCRT__
+# if defined(_MSC_VER) || defined(__MSVCRT__)
# define JIM_WIDE_MODIFIER "I64d"
# else
# define JIM_WIDE_MODIFIER "lld"