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:

  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:


  4. 
          #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();
    
          } 
  5. 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


Last Reviewed: November 25, 1999
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.