Passing a string to excel from a C app

R

Rob Y

I'm trying to add some simple excel automation to my C app. I found
some C++ code that I was able to modify to do what I want, but that code
won't link to my C app, and I can't convert the app to C++ just for this.

I found an article with a tiny 'OLE Automation from a C App' code sample
that works in my app at:
http://support.microsoft.com/kb/181473
but that sample simply starts Excel and sets 'visible'. I need to do a
little (not much) more, passing in file paths and macro names, etc.

Using the C sample as a template, I'm trying to convert the C++ sample
to C. The C sample has code to pass an integer parameter, but I need to
be able to pass in file paths as strings. The C++ sample does this by
converting them to BSTR's (VB string? OLE string?) and passing them as
VT_BSTR. Will Excel accept string parameters as VT_LPSTR, or do I have
to pass them as BSTR's. If so, can anybody provide a code snippet to
create a BSTR from a normal C string?

Thanks,
Rob
 
J

Joel

I think your answer lies in this statement

DISPPARAMS dispParams = { NULL, NULL, 0, 0 };

these arre the parements that you can pass. I guessing the first two NULLs
are standard c language paraments arg(0) - program name and arg(1) - the
number of parameters. These are probably being added by the library. The
two 0's are C-Language Null terminated strings. C- Language parameter for
Main are all strings. Each string is terminated with a NULL (zero). So
really all you have to do is replace the 0's with ascii striings. The
C-Language parameter list is just consecutive memory with 0's terminating the
parameters. The arg(0) indicates how many NULL terminated string are going
to occur. You just have to make sure enough memory is allocated to pqass all
the parremters.
 
R

Rob Y

Joel said:
I think your answer lies in this statement

DISPPARAMS dispParams = { NULL, NULL, 0, 0 };

these arre the parements that you can pass. I guessing the first two NULLs
are standard c language paraments arg(0) - program name and arg(1) - the
number of parameters. These are probably being added by the library. The
two 0's are C-Language Null terminated strings. C- Language parameter for
Main are all strings.

Nope. It's more complicated than that. If you read on, you can see
where dispParms is set up.

// Initiate parameters to set visible property to true.
VariantInit(&parm1);
parm1.vt = VT_I4;
parm1.lVal = 1; // true

// One argument.
dispParams.cArgs = 1;
dispParams.rgvarg = &parm1;

// Handle special-case for property-puts!
dispParams.cNamedArgs = 1;
dispParams.rgdispidNamedArgs = &dispidNamed;

This code is passing in a parameter as type VT_I4 (4-byte integer?), but
I need to pass in a file path as a string. I have it working in C++,
but need to import the code into a C app (unless somebody can point me
to an easy way to integrate snippets of C++ using various MFC classes
into a C app that I can't afford to rewrite).

The working C++ code sample I'm copying from passes strings as VT_BSTR,
and it uses the SysAllocString method of CString to convert the C
strings into BSTR's for passing. Unfortunately, I can't seem to find a
C equivalent of CString::SysAllocString(). The author of the C++ code
sample mentioned that he got his ideas from a Microsoft 'AutoXL' sample
that's no longer available (Microsofters out there, why is that? - can
it be found if you know where to look?). All I can find is the link I
included in my original posting that shows how to launch Excel, but not
how to get it to do anything. Not terribly useful.

BSTR b;
b = SysAllocString(lpsz);
parm1.vt = VT_BSTR;
parm1.bstrVal = b;

-Rob
 
R

Rob Y

The working C++ code sample I'm copying from passes strings as VT_BSTR,
and it uses the SysAllocString method of CString to convert the C
strings into BSTR's for passing. Unfortunately, I can't seem to find a
C equivalent of CString::SysAllocString().

BSTR b;
b = SysAllocString(lpsz);
parm1.vt = VT_BSTR;
parm1.bstrVal = b;

Got it to work. Turns out SysAllocString does work from C. It's just
that it needs a multi-byte char string as input (I guess the C++ version
has a variant that take and converts a regular char string. So in C,
the conversion has to happen in 2 phases. This code works:

BSTR b;
LPCWSTR ws;
int len;

len = strlen(szStr) + 1;
ws = (LPCWSTR) malloc(len*2);
MultiByteToWideChar(CP_ACP, 0, szStr, len, ws, len*2);
b = SysAllocString(ws);
parm1.vt = VT_BSTR;
parm1.bstrVal = b;
free(ws);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top