HOWTO: Create an Automation Client Project Using ATL

ID: Q196135

The information in this article applies to:

SUMMARY

This article demonstrates how to build a simple Automation client application using ATL.

MORE INFORMATION

The following section illustrates how you can create an ATL client EXE project that automates Microsoft Excel. You can use the first 10 steps for any project, and modify step 11 when you work with another application.

Create an Automation Project

1. With Microsoft Developer Studio 6.0, start a new "ATL COM AppWizard"

   project named "AtlClientApp."

2. In step 1 of the ATL AppWizard, choose "Executable (EXE)" for the Server
   Type and then click Finish. The New Project Information dialog box
   appears and shows the classes to be created. Click OK to create the
   project.

3. From the Insert menu, select "New ATL Object" to bring up the ATL
   Object Wizard. For the type of Object to insert, select Miscellaneous
   and pick Dialog to a add a Dialog Object to the project. Click Next
   to continue.

4. Provide a short name of "ClientDlg" for your new dialog. Accept the
   defaults for all other names and click OK.

5. In the project workspace, click the "Resource View" tab. Double-click
   "AtlClientApp Resources" to expand the resource tree. Double-click
   Dialog in the Resource tree and double-click to select the dialog
   box resource "IDD_CLIENTDLG."

6. Change the caption of the OK button to "Run" and the cancel button to
   "Quit." Leave the button IDs at their default settings and close the
   dialog box design form.

7. In the project workspace, click the "Class View" tab. Double-click the
   "Globals" folder to see the "_tWinMain" entry point, then double-click
   "_tWinMain" to jump to the code location.

8. Replace all the code in the function with the following:

      extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
         HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/)
      {

         HRESULT hRes = CoInitialize(NULL);
         _ASSERTE(SUCCEEDED(hRes));
         _Module.Init(NULL, hInstance);
         _Module.dwThreadID = GetCurrentThreadId();

         int nRet = 0;

         CClientDlg*  pDlg = NULL;

         pDlg = new CClientDlg;
         if(NULL != pDlg)
         {
            pDlg->Create(NULL);
            pDlg->ShowWindow(SW_NORMAL);

            MSG msg;
            while (GetMessage(&msg, 0, 0, 0))
            {
               TranslateMessage(&msg);
               DispatchMessage(&msg);
            }
            nRet = msg.wParam;
            delete pDlg;
         }

         CoUninitialize();
         return nRet;
      }

9. At the top of the file, add the following include statement after the
   others:

      #include "ClientDlg.h"

10. From the "Class View" tab, expand the "CClientDlg" class to reveal its
   class members. Find the "OnCancel" method and double-click it to jump
   to the code. Replace the code in the function with the following:

      LRESULT CClientDlg::OnCancel(WORD wNotifyCode, WORD wID,
         HWND hWndCtl, BOOL& bHandled)
      {
         DestroyWindow();
         PostQuitMessage(0);
         return 0;
      }

11. Replace the code in the "OnOK" method with the following:

      LRESULT CClientDlg::OnOK(WORD wNotifyCode, WORD wID,
         HWND hWndCtl, BOOL& bHandled)
      {
         IDispatch*  pDisp;   // Main IDispatch pointer.
         CLSID       clsid;   // Holds CLSID of server
         DISPID      dispID;  // Temporary variable to hold DISPIDs.
         HRESULT     hr;      // General error/result holder.

         hr = CLSIDFromProgID(L"Excel.Application", &clsid);
         if(FAILED(hr)){
            MessageBox("Excel is not installed.");
            return 0;}

         hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER,
            IID_IDispatch, (void **)&pDisp);
         if(FAILED(hr)){
            MessageBox("Couldn't start Excel.");
            return 0;}

         OLECHAR    *szVisible = L"Visible";
         DISPPARAMS dispParams = { NULL, NULL, 0, 0 };
         DISPID dispidNamed = DISPID_PROPERTYPUT;
         CComVariant vrTrue = VARIANT_TRUE;

         pDisp->GetIDsOfNames(IID_NULL, &szVisible, 1,
            LOCALE_USER_DEFAULT, &dispID);

         dispParams.cArgs = 1;
         dispParams.rgvarg = &vrTrue;
         dispParams.cNamedArgs = 1;
         dispParams.rgdispidNamedArgs = &dispidNamed;

         // Set 'Visible' property to true.
         pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT,
            DISPATCH_PROPERTYPUT | DISPATCH_METHOD, &dispParams,
            NULL, NULL, NULL);

         MessageBox("We're done.", "Finish", MB_SETFOREGROUND);

         // Release the IDispatch pointer before exit
         pDisp->Release();
         return 0;
      }

12. Because you are building a client application, you do not need to
   perform COM registration when you compile the EXE. To remove this step,
   select "Settings" from the Project menu, go to the "Custom Build" tab,
   and remove the all the commands that appear in the "Build Commands"
   window. Do the same for the "Outputs" window, and click OK when done.

13. Compile your project by selecting "Rebuild All" from the Build menu.
   Run your project by pressing the F5 key.

REFERENCES

For additional information on the Automation of Office from Visual C++, please see the Microsoft Knowledge Base articles found at this Web site:

   http://support.microsoft.com/support/visualc/atlmfc/oleatmfc.asp

(c) Microsoft Corporation 1998, All Rights Reserved. Contributions by Richard R. Taylor, Microsoft Corporation.

Additional query words: OLE

Keywords          : kbATL kbAutomation kbExcel kbOLEApp kbVC500 kbVC600 
Version           : WINNT:5.0,6.0
Platform          : winnt
Issue type        : kbhowto

Last Reviewed: January 7, 1999