ComponentOne VSView 8.0
Dual Interfaces in MFC

The wrapper classes created by the MFCwizard are very helpful, and for a while they were the best you could get. With Visual Studio6, however, the compiler has built-in COMsupport, including a different way to create wrapper classes for ActiveXobjects through the new #import compiler directive. These "native" wrapper classes are faster and more flexible than the ones generated by MFC:

Taking advantage of dual interfaces in existing MFCprojects is easy. All you have to do is include the appropriate #import statement in your StdAfx.h file, then create a pointer and assign it to the existing control. For example, assuming you have an MFC-based m_Printer control, all the extra code you would need would be this:

Example Title
Copy Code
// include this statement in the StdAfx.h file

#import "c:\windows\system\vsprint8.ocx" no_namespace

Then, instead of using the control in the usual way, declare a variable of type IVSPrinterPtr, initialize it by setting it to m_Printer.GetControlUnknown(), and use it instead of m_Printer. The two routines listed below illustrate the difference between the two approaches (both routines create a table with 10,000 rows and report how long it took to do it):

Example Title
Copy Code
// Using the MFC-generated wrapper class

void CMyDlg::BenchDispatchClick()

{

  // keep track of the start time

  DWORD tStart = GetTickCount();

 

  // generate the document

  COleVariant vNone(0L, VT_ERROR);

  m_Printer.StartDoc();

  m_Printer.StartTable();

  m_Printer.AddTable("1000|2000|2000", "Col1|Col2|Col3", "",

                     vNone, vNone, vNone);

  m_Printer.SetTableCell(1 /*tcRows*/, vNone, vNone,

                         vNone, vNone, COleVariant(1000L));

  for (long r = 1; r <= 10000; r++) {

    for (long c = 1; c <= 3; c++) {

      CString str;

      str.Format("R%d C%d", r, c);

      m_Printer.SetTableCell(18 /*tcText*/,

                             COleVariant(r), COleVariant(c),

                             vNone, vNone, COleVariant(str));

    }

  }

  m_Printer.EndTable();

  m_Printer.EndDoc();

 

  // report how long it took

  DWORD tElapsed = GetTickCount() - tStart;

  CString str;

  str.Format("Done in %d seconds using dual interface.",

            (int)(tElapsed / 1000));

  MessageBox(str);

}

// Using the native wrapper class (#import-based)

void CMyDlg::BenchDualClick()

{

  // keep track of the start time

  DWORD tStart = GetTickCount();

 

  // get VTBL (dual) interface

  IVSPrinterPtr spPrinter = m_Printer.GetControlUnknown();

 

  // generate the document

  spPrinter->StartDoc();

  spPrinter->StartTable();

  spPrinter->AddTable("1000|2000|2000", "Col1|Col2|Col3", "");

  spPrinter->PutTableCell(tcRows, vtMissing, vtMissing,

                          vtMissing, vtMissing, 1000L);

  for (long r = 1; r <= 10000; r++) {

    for (long c = 1; c <= 3; c++) {

      CString str;

      str.Format("R%d C%d", r, c);

      spPrinter->PutTableCell(tcText, r, c, vtMissing, vtMissing,

                             (LPCTSTR)str);

    }

  }

  spPrinter->EndTable();

  spPrinter->EndDoc();

 

  // report how long it took

  DWORD tElapsed = GetTickCount() - tStart;

  CString str;

  str.Format("Done in %d seconds using dual interface.",

            (int)(tElapsed / 1000));

  MessageBox(str);

}

The code looks very similar, except for the dot notation used with the m_Printer variable and the arrow used with the spPrinter variable. The difference is in execution speed. The MFC/Dispatch version takes 8 seconds to create the table, while the native/dual version takes only 6 seconds. The dual version is 25% faster than the traditional MFC/Dispatch version.

In functions that only set a few properties, it probably doesn't matter much which type of wrapper class you choose. But in functions with lengthy for statements, that access properties or methods several hundred times, you should definitely consider using the #import statement and the dual interface.

 

 


Copyright (c) GrapeCity, inc. All rights reserved.

Product Support Forum  |  Documentation Feedback