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

Last reviewed: February 19, 1998
Article ID: Q181473
The information in this article applies to:
  • Microsoft Visual C++, 32-bit Editions, versions 4.0, 5.0
  • Microsoft Excel 97 for Windows

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

          #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 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.

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 1998, All Rights Reserved. Contributions by Joe Crump, Microsoft Corporation

Keywords          : kbcode
Technology        : ole com
Version           : WINDOWS:97; WINNT:4.0,5.0
Platform          : WINDOWS winnt
Issue type        : kbhowto


================================================================================


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: February 19, 1998
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.