Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

HOWTO: Use OLE Automation from a C Application Rather Than C++


View products that this article applies to.

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.

↑ Back to the top


More information

Use the following method:
  1. Create a new "Win32 Console Application" project in Microsoft Visual C++ 5.0.
  2. Add a Main.c (not Main.cpp) text file to your project.
  3. 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, Excel 2000, or Excel 2002 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();
    
          }
    					
  4. Compile and run.

↑ Back to the top


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.

↑ Back to the top


Keywords: KB181473, kbhowto

↑ Back to the top

Article Info
Article ID : 181473
Revision : 7
Created on : 2/12/2007
Published on : 2/12/2007
Exists online : False
Views : 606