HOWTO: Use OLE Automation from a C Application Rather Than C++
ID: Q181473
|
The information in this article applies to:
-
Microsoft Visual C++, 32-bit Editions, versions 4.0, 5.0, 6.0
-
Microsoft Excel 97 for Windows
-
Microsoft Excel 2000
SUMMARY
If you need to program in C, rather than C++, OLE Automation can be
difficult because the Component Object Model (COM), the building blocks of
OLE, was designed around the binary layout of a C++ class. The header files
included by WINDOWS.H, however, have built-in support for C compilations;
therefore, you can mimic the behavior of a C++ object and make OLE
Automation calls. This article describes how to build a Win32 console
application, using C, that starts up Microsoft Excel and makes it visible
via OLE Automation.
MORE INFORMATION
Use the following method:
- Create a new "Win32 Console Application" project in Microsoft Visual C++
5.0.
- Add a Main.c (not Main.cpp) text file to your project.
- Add the following code to your Main.c file:
#include <stdio.h>
#include <windows.h>
void main(void) {
IDispatch *pDisp; // Main IDispatch pointer.
unsigned short *ucPtr; // Temporary variable to hold names.
DISPID dispID; // Temporary variable to hold DISPIDs.
CLSID clsid; // Holds CLSID of server after CLSIDFromProgID.
HRESULT hr; // General error/result holder.
char buf[8192]; // Generic buffer for output.
// IDispatch::Invoke() parameters...
DISPPARAMS dispParams = { NULL, NULL, 0, 0 };
VARIANT parm1;
DISPID dispidNamed = DISPID_PROPERTYPUT;
// Initialize OLE Libraries.
OleInitialize(NULL);
{
// Get CLSID for Excel.Application from registry.
hr = CLSIDFromProgID(L"Excel.Application", &clsid);
if(FAILED(hr)) {
MessageBox(NULL, "Excel not registered.", "Error",
MB_SETFOREGROUND);
return;
}
// Start Excel97 or Excel 2000 and get its IDispatch pointer.
hr = CoCreateInstance(&clsid, NULL, CLSCTX_LOCAL_SERVER,
&IID_IDispatch, (void **)&pDisp);
if(FAILED(hr)) {
MessageBox(NULL, "Couldn't start Excel.", "Error",
MB_SETFOREGROUND);
return;
}
// Get the 'visible' property's DISPID.
ucPtr = L"Visible";
pDisp->lpVtbl->GetIDsOfNames(pDisp, &IID_NULL, &ucPtr, 1,
LOCALE_USER_DEFAULT, &dispID);
sprintf(buf, "DISPID for 'Visible' property = 0x%08lx",
dispID);
MessageBox(NULL, buf, "Debug Notice", MB_SETFOREGROUND);
// 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;
// Set 'visible' property to true.
hr = pDisp->lpVtbl->Invoke(pDisp,
dispID, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_PROPERTYPUT | DISPATCH_METHOD,
&dispParams, NULL, NULL, NULL
);
if(FAILED(hr)) {
sprintf(buf, "IDispatch::Invoke() failed with %08lx", hr);
MessageBox(NULL, buf, "Debug Notice", MB_SETFOREGROUND);
}
// All done.
MessageBox(NULL, "done.", "Notice", MB_SETFOREGROUND);
}
// Uninitialize OLE Libraries.
OleUninitialize();
}
- Compile and run.
REFERENCES
For more general information regarding OLE, COM, and Automation, consult
the book "Inside OLE" by Kraig Brockschmidt (Microsoft Press).
For more information about IDispatch, consult the Microsoft Visual C++
online help.
For more information about COM, OLE, and automating Microsoft Excel using
Microsoft Visual C++, see Chapters 23-27 of the book "Inside Visual C++" by
David J. Kruglinski (Microsoft Press).
(c) Microsoft Corporation 1999, All Rights Reserved. Contributions by Joe Crump, Microsoft Corporation.
Additional query words:
Keywords : kbcode kbVC400 kbVC500 kbVC600
Version : WINDOWS:2000,97; winnt:4.0,5.0,6.0
Platform : WINDOWS winnt
Issue type : kbhowto
|