| Tenouk C & C++ | MFC Home | Automation 11 | Automation 13 | Download | Site Index |


 

 

 

 

 

Automation 12

 

 

 

 

 

 

Program examples compiled using Visual C++ 6.0 compiler on Windows XP Pro machine with Service Pack 2. The Excel version is Excel 2003/Office 11. Topics and sub topics for this tutorial are listed below. Don’t forget to read Tenouk’s small disclaimer.  The supplementary notes for this tutorial are automation, variant and COlevariant class.

  1. The MYMFC29E Automation Client Example

  2. The MYMFC29E Steps From Scratch

  3. The Coding Part

 

The MYMFC29E Automation Client Example

 

This program uses the new #import directive to generate smart pointers. It behaves just like MYMFC29D except that it doesn't run Excel. The #import statements are in the StdAfx.h file to minimize the number of times the compiler has to generate the driver classes.

 

The MYMFC29E Steps From Scratch

 

As usual start with AppWizard, just follow the shown steps and option settings. These monotonous steps provide a very good practice for you!

 

Figure 1: MYMFC29E – Visual C++ new project dialog.

 

Figure 1: MYMFC29E – Visual C++ new project dialog.

 

 

Figure 2: MYMFC29E – AppWizard step 1 of 6, an SDI application.

 

Figure 2: MYMFC29E – AppWizard step 1 of 6, an SDI application.

 

Figure 3: MYMFC29E – AppWizard step 2 of 6.

 

Figure 3: MYMFC29E – AppWizard step 2 of 6.

 

Figure 4: MYMFC29E – AppWizard step 3 of 6.

 

Figure 4: MYMFC29E – AppWizard step 3 of 6.

 

Figure 5: MYMFC29E – AppWizard step 4 of 6, deselecting the printing services.

 

Figure 5: MYMFC29E – AppWizard step 4 of 6, deselecting the printing services.

 

Figure 6: MYMFC29E – AppWizard step 5 of 6.

 

Figure 6: MYMFC29E – AppWizard step 5 of 6.

 

Figure 7: MYMFC29E – AppWizard step 6 of 6.

 

Figure 7: MYMFC29E – AppWizard step 6 of 6.

 

Figure 8: MYMFC29E project summary.

 

Figure 8: MYMFC29E project summary.

 

Add a new dialog. Insert new dialog and use the following information for the dialog, static text and edit controls. Leave the static texts IDs to the default.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ID

Item

IDD_ALARMDLG

Dialog with ‘29E Alarm Dialog’ caption

IDC_HOURS

Hours edit box

IDC_MINUTES

Minutes edit box

IDC_SECONDS

Seconds edit box

 

Table 1.

 

Figure 9: Adding new dialog and editing its property.

 

Figure 9: Adding new dialog and editing its property.

 

Next, use ClassWizard to create CAlarmDialog, a new class for the dialog.

 

Figure 10: Adding new class, CAlarmDialog for the dialog.

 

Figure 10: Adding new class, CAlarmDialog for the dialog.

 

Fill in the CAlarmDialog class information.

 

Figure 11: Entering the CAlarmDialog class information.

 

Figure 11: Entering the CAlarmDialog class information.

 

Add member variables and initialize them. Click the Member Variables tab and use the following information for the variables.

 

ID

Type

Member name

Min/Max value

IDC_HOURS

int

m_nHours

0/23

IDC_MINUTES

int

m_nMinutes

0/59

IDC_SECONDS

int

m_nSeconds

0/59

 

Table 2.

 

Figure 12: Adding member variables to controls in dialog.

 

Figure 12: Adding member variables to controls in dialog.

 

Add menu items for Bank Comp.

 

ID

Menu

Prompt

ID_BANKOLE_LOAD

Load

Load the bank component, MYMFC29A.EXE

ID_BANKOLE_TEST

Test

Test the bank component

ID_BANKOLE_UNLOAD

Unload

Unload the bank component

 

Table 3.

 

Figure 13: Adding Bank Comp menu and its’ items.

 

Figure 13: Adding Bank Comp menu and its’ items.

 

Add menu items for DLL Comp.

 

ID

Menu

Prompt

ID_DLLOLE_LOAD

Load

Load the DLL component, MYMFC29B.DLL

ID_DLLOLE_GETDATA

Get Data

Get data from the DLL component

ID_DLLOLE_UNLOAD

Unload

Unload the DLL component

 

Table 4.

 

Figure 14: Adding DLL Comp menu and its’ items.

 

Figure 14: Adding DLL Comp menu and its’ items.

 

Add menu items for Clock Comp.

 

ID

Menu

Prompt

ID_CLOCKOLE_LOAD

Load

Load the clock component, MYMFC29C.EXE

ID_CLOCKOLE_CREATEALARM

Create Alarm

Create an alarm

ID_CLOCKOLE_REFRESHTIME

Refresh Time

Refresh the time from the system clock

ID_CLOCKOLE_UNLOAD

Unload

Unload the clock component

 

Table 5.

 

Figure 15: Adding Clock Comp menu and its’ items.

 

Figure 15: Adding Clock Comp menu and its’ items.

 

Next, Using ClassWizard, add the menu commands and update command UI events in the CMymfc29EView class for all the menu items created previously.

 

 

ID

ID_BANKOLE_LOAD

ID_BANKOLE_TEST

ID_BANKOLE_UNLOAD

ID_DLLOLE_LOAD

ID_DLLOLE_GETDATA

ID_DLLOLE_UNLOAD

ID_CLOCKOLE_LOAD

ID_CLOCKOLE_CREATEALARM

ID_CLOCKOLE_REFRESHTIME

ID_CLOCKOLE_UNLOAD

ID_EXCELOLE_LOAD

 

Table 6.

 

 

Figure 16: Adding menu Commands and Update Commands to CMymfc29EView class.

 

Figure 16: Adding menu Commands and Update Commands to CMymfc29EView class.

 

The Coding Part

 

Add the automation support manually. Add the following code in StdAfx.h.

 

#include <afxdisp.h>

 

C++ and MFC programming - Automation C++ code snippet

 

Listing 1.

 

Then add this call at the beginning of the application's InitInstance() function in mymfc29D.cpp.

 

AfxOleInit();

 

C++ and MFC programming - Automation C++ code snippet

 

Listing 2.

 

Back to StdAfx.h and add the following #import directives. you should change the path accordingly to suit your project directory. For Tenouk, all Visual C++ project is under F:\mfcproject directory.

 

#import "..\mymfc29A\debug\mymfc29A.tlb" rename_namespace("BankDriv")

using namespace BankDriv;

 

#import "..\mymfc29B\debug\mymfc29B.tlb" rename_namespace("Mymfc29BDriv")

using namespace Mymfc29BDriv;

 

#import "..\mymfc29C\debug\mymfc29C.tlb" rename_namespace("ClockDriv")

using namespace ClockDriv;

 

C++ and MFC programming - Automation C++ code snippet

 

Listing 3.

 

Add the following embedded smart pointers in the CMymfc29EView class header, mymfc29EView.h.

 

public:

IMymfc29BAutoPtr m_auto;

IBankPtr         m_bank;

IMymfc29CPtr     m_clock;

IAlarmPtr        m_alarm;

 

C++ and MFC programming - Automation C++ code snippet

 

Listing 4.

 

Add the #include directive for AlarmDialog.h in the CMymfc29EView class implementation, mymfc29EView.cpp. If you rebuild your ClassWizard database, this step is unnecessary.

 

#include "AlarmDialog.h"

 

C++ and MFC programming - Automation C++ code snippet

 

Listing 5.

 

Add code for CMymfc29DView::OnDraw() member function in mymfc29EView.cpp.

 

void CMymfc29EView::OnDraw(CDC* pDC)

{

    CMymfc29EDoc* pDoc = GetDocument();

    ASSERT_VALID(pDoc);

    pDC->TextOut(100, 0, "--COleDispatchDriver usage, mymfc29E--");

    pDC->TextOut(10, 25, "Run this program from the debugger to see test output.");

    pDC->TextOut(10, 50, "The MYMFC29A, MYMFC29B and MYMFC29C components...");

    pDC->TextOut(10, 75, "...must be built and registered prior to loading this crap...");

    pDC->TextOut(10, 100, "Originally for VC++ 6 + Excel 97 but here VC++ 6 + Excel 2003...");

}

 

C++ and MFC programming - Automation C++ code snippet

 

Listing 6.

 

Finally, add codes for the commands and update command UI events of the CMymfc29EView class.

 

void CMymfc29EView::OnBankoleLoad()

{

    if(m_bank.CreateInstance(__uuidof(Bank)) != S_OK)

    {

        AfxMessageBox("Bank component not found");

        return;

    }

      else

      { AfxMessageBox("OK, Bank component found lor!"); }

}

 

void CMymfc29EView::OnUpdateBankoleLoad(CCmdUI* pCmdUI)

{ pCmdUI->Enable(m_bank.GetInterfacePtr() == NULL); }

 

void CMymfc29EView::OnBankoleTest()

{

    try {

        m_bank->Deposit(20.0);

        m_bank->Withdrawal(15.0);

        TRACE("new balance = %f\n", m_bank->GetBalance());

    }

    catch(_com_error& e)

    { AfxMessageBox(e.ErrorMessage()); }

}

 

C++ and MFC programming - Automation C++ code snippet

 

Listing 7.

 

void CMymfc29EView::OnUpdateBankoleTest(CCmdUI* pCmdUI)

{ pCmdUI->Enable(m_bank.GetInterfacePtr() != NULL); }

 

void CMymfc29EView::OnBankoleUnload()

{ m_bank.Release(); }

 

void CMymfc29EView::OnUpdateBankoleUnload(CCmdUI* pCmdUI)

{ pCmdUI->Enable(m_bank.GetInterfacePtr() != NULL); }

 

void CMymfc29EView::OnClockoleCreatealarm()

{

    CAlarmDialog dlg;

    try

    {

        if (dlg.DoModal() == IDOK)

        {

            COleDateTime dt(2004, 12, 23, dlg.m_nHours, dlg.m_nMinutes, dlg.m_nSeconds);

            LPDISPATCH pAlarm = m_clock->CreateAlarm(dt);

            m_alarm.Attach((IAlarm*) pAlarm);  // releases prior object!

            m_clock->RefreshWin();

        }

    }

    catch(_com_error& e)

    { AfxMessageBox(e.ErrorMessage()); }

}

 

C++ and MFC programming - Automation C++ code snippet

 

Listing 8.

 

void CMymfc29EView::OnUpdateClockoleCreatealarm(CCmdUI* pCmdUI)

{ pCmdUI->Enable(m_clock.GetInterfacePtr() != NULL); }

 

void CMymfc29EView::OnClockoleLoad()

{

    if(m_clock.CreateInstance(__uuidof(Document)) != S_OK)

    {

        AfxMessageBox("Clock component not found");

        return;

    }

    try

    {

        m_clock->PutFigure(0, COleVariant("XII"));

        m_clock->PutFigure(1, COleVariant("III"));

        m_clock->PutFigure(2, COleVariant("VI"));

        m_clock->PutFigure(3, COleVariant("IX"));

        OnClockoleRefreshtime();

        m_clock->ShowWin();

    }

    catch(_com_error& e)

    { AfxMessageBox(e.ErrorMessage()); }

}

 

void CMymfc29EView::OnUpdateClockoleLoad(CCmdUI* pCmdUI)

{ pCmdUI->Enable(m_clock.GetInterfacePtr() == NULL); }

 

C++ and MFC programming - Automation C++ code snippet

 

Listing 9.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

void CMymfc29EView::OnClockoleRefreshtime()

{

    COleDateTime now = COleDateTime::GetCurrentTime();

    try

    {

        m_clock->PutTime(now);

        m_clock->RefreshWin();

    }

    catch(_com_error& e)

    { AfxMessageBox(e.ErrorMessage()); }

}

 

void CMymfc29EView::OnUpdateClockoleRefreshtime(CCmdUI* pCmdUI)

{ pCmdUI->Enable(m_clock.GetInterfacePtr() != NULL); }

 

void CMymfc29EView::OnClockoleUnload()

{ m_clock.Release(); }

 

void CMymfc29EView::OnUpdateClockoleUnload(CCmdUI* pCmdUI)

{ pCmdUI->Enable(m_clock.GetInterfacePtr() != NULL); }

 

C++ and MFC programming - Automation C++ code snippet

 

Listing 10.

 

void CMymfc29EView::OnDlloleGetdata()

{

    try {

        m_auto->DisplayDialog();

        COleVariant vaData = m_auto->GetTextData();

        ASSERT(vaData.vt == VT_BSTR);

        CString strTextData = vaData.bstrVal;

        long lData = m_auto->GetLongData();

        TRACE("CMymfc29DView::OnDlloleGetdata-long = %ld, text = %s\n", lData, strTextData);

    }

    catch(_com_error& e)

    { AfxMessageBox(e.ErrorMessage()); }

}

 

void CMymfc29EView::OnUpdateDlloleGetdata(CCmdUI* pCmdUI)

{ pCmdUI->Enable(m_auto.GetInterfacePtr() != NULL); }

 

C++ and MFC programming - Automation C++ code snippet

 

Listing 11.

 

void CMymfc29EView::OnDlloleLoad()

{

    if(m_auto.CreateInstance(__uuidof(Auto)) != S_OK)

    {

        AfxMessageBox("Mymfc29BAuto component not found");

        return;

    }

      else

      { AfxMessageBox("Mymfc29BAuto component found lol!"); }

 

}

 

void CMymfc29EView::OnUpdateDlloleLoad(CCmdUI* pCmdUI)

{ pCmdUI->Enable(m_auto.GetInterfacePtr() == NULL); }

 

void CMymfc29EView::OnDlloleUnload()

{ m_auto.Release(); }

 

void CMymfc29EView::OnUpdateDlloleUnload(CCmdUI* pCmdUI)

{ pCmdUI->Enable(m_auto.GetInterfacePtr() != NULL); }

 

C++ and MFC programming - Automation C++ code snippet

 

Listing 12.

 

Check your ClassView for the added classes and the member functions.

 

Figure 17: The added classes seen through ClassView.

 

Figure 17: The added classes seen through ClassView.

 

 

 

 

 

 

 

 

 

 

 

 

 

Further reading and digging:

  1. DCOM at MSDN.

  2. COM+ at MSDN.

  3. COM at MSDN.

  4. Win32 process, thread and synchronization story can be found starting from Module R.

  5. MSDN MFC 7.0 class library online documentation.

  6. MSDN MFC 9.0 class library online documentation - latest version.

  7. MSDN Library

  8. Windows data type.

  9. Win32 programming Tutorial.

  10. The best of C/C++, MFC, Windows and other related books.

  11. Unicode and Multibyte character set: Story and program examples.

 

 


 

| Tenouk C & C++ | MFC Home | Automation 11 | Automation 13 | Download | Site Index |