Software & Finance





Visual C++ - COM Client for Word and Excel - CoCreateInstance, IDispatch - ProgID Word.Application and Excel.Application





I have come up a COM Client Application that can create an instance for Word and Excel Application. I have used CoCreateInstance and I have not used any ATL classes in this sample code. I have used IDispatch interface the invoke the property "Visible". This can be done in two steps IDispatch->GetIDsOfNames(...) and IDispatch->Invoke(...) .

 


Source Code


 

// WordExcelClientDlg.cpp : implementation file

//

 

#include "stdafx.h"

#include "WordExcelClient.h"

#include "WordExcelClientDlg.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

 

 

// CAboutDlg dialog used for App About

 

class CAboutDlg : public CDialog

{

public:

      CAboutDlg();

 

// Dialog Data

      enum { IDD = IDD_ABOUTBOX };

 

      protected:

      virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

 

// Implementation

protected:

      DECLARE_MESSAGE_MAP()

};

 

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

}

 

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

{

      CDialog::DoDataExchange(pDX);

}

 

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

END_MESSAGE_MAP()

 

 

// CWordExcelClientDlg dialog

 

 

 

IDispatch *exceldispatch = NULL;

 

CWordExcelClientDlg::CWordExcelClientDlg(CWnd* pParent /*=NULL*/)

      : CDialog(CWordExcelClientDlg::IDD, pParent)

{

      m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

 

void CWordExcelClientDlg::DoDataExchange(CDataExchange* pDX)

{

      CDialog::DoDataExchange(pDX);

}

 

BEGIN_MESSAGE_MAP(CWordExcelClientDlg, CDialog)

      ON_WM_SYSCOMMAND()

      ON_WM_PAINT()

      ON_WM_QUERYDRAGICON()

      //}}AFX_MSG_MAP

    ON_BN_CLICKED(IDC_BUTTON1, &CWordExcelClientDlg::OnBnClickedButton1)

    ON_BN_CLICKED(IDC_BUTTON2, &CWordExcelClientDlg::OnBnClickedButton2)

    ON_BN_CLICKED(IDOK, &CWordExcelClientDlg::OnBnClickedOk)

    ON_BN_CLICKED(IDCANCEL, &CWordExcelClientDlg::OnBnClickedCancel)

END_MESSAGE_MAP()

 

 

// CWordExcelClientDlg message handlers

 

BOOL CWordExcelClientDlg::OnInitDialog()

{

      CDialog::OnInitDialog();

 

      // Add "About..." menu item to system menu.

 

      // IDM_ABOUTBOX must be in the system command range.

      ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

      ASSERT(IDM_ABOUTBOX < 0xF000);

 

      CMenu* pSysMenu = GetSystemMenu(FALSE);

      if (pSysMenu != NULL)

      {

            CString strAboutMenu;

            strAboutMenu.LoadString(IDS_ABOUTBOX);

            if (!strAboutMenu.IsEmpty())

            {

                  pSysMenu->AppendMenu(MF_SEPARATOR);

                  pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

            }

      }

 

      // Set the icon for this dialog.  The framework does this automatically

      //  when the application's main window is not a dialog

      SetIcon(m_hIcon, TRUE);             // Set big icon

      SetIcon(m_hIcon, FALSE);            // Set small icon

 

      // TODO: Add extra initialization here

 

      return TRUE;  // return TRUE  unless you set the focus to a control

}

 

void CWordExcelClientDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

      if ((nID & 0xFFF0) == IDM_ABOUTBOX)

      {

            CAboutDlg dlgAbout;

            dlgAbout.DoModal();

      }

      else

      {

            CDialog::OnSysCommand(nID, lParam);

      }

}

 

// If you add a minimize button to your dialog, you will need the code below

//  to draw the icon.  For MFC applications using the document/view model,

//  this is automatically done for you by the framework.

 

void CWordExcelClientDlg::OnPaint()

{

      if (IsIconic())

      {

            CPaintDC dc(this); // device context for painting

 

            SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

 

            // Center icon in client rectangle

            int cxIcon = GetSystemMetrics(SM_CXICON);

            int cyIcon = GetSystemMetrics(SM_CYICON);

            CRect rect;

            GetClientRect(&rect);

            int x = (rect.Width() - cxIcon + 1) / 2;

            int y = (rect.Height() - cyIcon + 1) / 2;

 

            // Draw the icon

            dc.DrawIcon(x, y, m_hIcon);

      }

      else

      {

            CDialog::OnPaint();

      }

}

 

// The system calls this function to obtain the cursor to display while the user drags

//  the minimized window.

HCURSOR CWordExcelClientDlg::OnQueryDragIcon()

{

      return static_cast<HCURSOR>(m_hIcon);

}

 

 

void CWordExcelClientDlg::OnBnClickedButton1()

{

    ::CoInitialize(NULL);

    IDispatch *worddispatch = NULL;

 

    if( worddispatch == NULL)

    {

        CLSID clsid;

        CLSIDFromProgID(L"Word.Application", &clsid);

        HRESULT hRes = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER,

                           IID_IDispatch, (void**)&worddispatch);

        if(FAILED(hRes))

        {

            MessageBox("Failed to create MS Word Application Object");

            return;

        }

 

        DISPID dispidVisible;

        OLECHAR *propertyName = L"Visible";

        hRes = worddispatch->GetIDsOfNames(IID_NULL, &propertyName, 1, LOCALE_SYSTEM_DEFAULT, &dispidVisible);

        

        if(FAILED(hRes))

        {

            MessageBox("Failed to access MS Word Application Methods");

            return;

        }

        

        unsigned returnArg;

        VARIANT varTrue;

        DISPID rgDispidNamedArgs[1];

        rgDispidNamedArgs[0] = DISPID_PROPERTYPUT;

        DISPPARAMS params = { &varTrue, rgDispidNamedArgs, 1, 1 };

 

        varTrue.vt = VT_BOOL;

        varTrue.boolVal = 0xFFFF;

        

        hRes = worddispatch->Invoke(dispidVisible, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &params, 0, 0, &returnArg);

        

        if(FAILED(hRes))

        {

            MessageBox("Failed to access MS Word Application Methods");

            return;

        }

       

        worddispatch->Release();

    }

}

 

void CWordExcelClientDlg::OnBnClickedButton2()

{

    ::CoInitialize(NULL);

 

    if( exceldispatch == NULL)

    {

        CLSID clsid;

        CLSIDFromProgID(L"Excel.Application", &clsid);

        HRESULT hRes = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER,

                           IID_IDispatch, (void**)&exceldispatch);

        if(FAILED(hRes))

        {

            MessageBox("Failed to create Excel Application Object");

            return;

        }

 

        DISPID dispidVisible;

        OLECHAR *propertyName = L"Visible";

        hRes = exceldispatch->GetIDsOfNames(IID_NULL, &propertyName, 1, LOCALE_SYSTEM_DEFAULT, &dispidVisible);

        

        if(FAILED(hRes))

        {

            MessageBox("Failed to access Excel Application Methods");

            return;

        }

        

        unsigned returnArg;

        VARIANT varTrue;

        DISPID rgDispidNamedArgs[1];

        rgDispidNamedArgs[0] = DISPID_PROPERTYPUT;

        DISPPARAMS params = { &varTrue, rgDispidNamedArgs, 1, 1 };

 

        varTrue.vt = VT_BOOL;

        varTrue.boolVal = 0xFFFF;

        

        hRes = exceldispatch->Invoke(dispidVisible, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &params, 0, 0, &returnArg);

        

        if(FAILED(hRes))

        {

            MessageBox("Failed to access Excel Application Methods");

            return;

        }

       

        // do not release now otherwise it will close the excel application

        //exceldispatch->Release();

    }

}

 

void CWordExcelClientDlg::OnBnClickedOk()

{

    if(exceldispatch != NULL)

        exceldispatch->Release();

    OnOK();

}

 

void CWordExcelClientDlg::OnBnClickedCancel()

{

    if(exceldispatch != NULL)

        exceldispatch->Release();

    OnCancel();

} 

Click here to download the VS 2005 Project file and executable

 

Output