This articles makes heavy use of ActiveX/COM. While you may believe COM is dead, native C++ code writers know differently.
COM, ActiveX, Oh My!
When you want to use a third party ActiveX control in your WTL project, most of the documentation points to #import as the solution. There are some nice options on #import, such as auto_search that enable the compiler to search for dependent components and bring them into your project as necessary. So what's wrong with using #import? Nothing really, if you don't mind dragging in classes such as _variant_t and _bstr_t.
#import, Why use it?
One of my complaints about using
#import is that is causes the compiler to drag in a lot of unnecessary support for ActiveX/COM, like _variant_t and _bstr_t classes, along with a lot of unnecessary COM headers. You are already using ATL classes (this is a WTL project), so why drag in a lot of stuff that duplicates what you already have access to?
If you want to take a few moments, you can generate files using OleView and MIDL that will integrate a lot more smoothly into your WTL project. You'll also have the advantage of utilizing only ATL templates and classes.
Playing with MIDL generated by OleView
- First, you'll need to download the Windows SDK. At the time of this writing, I would suggest you download 7.0 or later.
- Download this if you are using VS 2008: Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1
- Download this if you are using VS 2010: Microsoft Windows SDK for Windows 7 and .NET Framework 4
- Install the SDK and make sure the bin directory has the executable oleview.exe. (If it does not, then download an earlier version and try again.) I am using SDK version 7.0 for this article.
- You should have a menu option that is similar to the graphic:
 Menu for OLE-COM Object Viewer |
Adding msdatgrd.ocx to your WTL project
For the purposes of this example, we will add the MS Datagrid that ships with Visual Studio 6, with service pack 6 installed.
- Open OLE-COM Viewer
- Choose File->View TypeLib...
 How to View a Type Lib |
- Navigate to msdatgrd.ocx and select it in the file open dialog (C:\Windows\System32 on Windows XP)
 Select msdatgrd.ocx to view |
- After you click the OK button on the file dialog, you should see something similar to the following graphic:
 View of msdatgrd typelib IDL |
This is a more or less complete IDL file. We will want to modify this file to change the import directives that bring in the dependency typelibs. (The dependencies are one of the reasons you see so many requests for help when importing the MS Datagrid control. Folks are too inexperienced to understand that the dependencies must be imported before the MS Datagrid IDL will compile.) - Note the code section that includes the importlib directives. This means the IDL probably won't compile unless the libraries are present, or suitable alternatives to the libraries can be found.
- Click the file menu and save the file as msdatgrd.idl. Place the file in the your WTL project directory and include the file in your project.
- When you add the IDL file to your project, exclude it from the build. You'll compile the file manually, after you configure the compilation. You will only use the IDL file and the MIDL compile to generate header and identifiers to include in your WTL project.
 Excluding an MIDL file from project build |
- Here's a typical configuration for the MIDL project. Be careful when changing file names. The IDL file will overwrite existing files in your project. From personal experience, I can tell you this is not a pleasant experience if you wipe out a perfectly good header file that defines a class.
 Change output file names |
- At this point, you can right click on the file in Solution Explorer and select the Compile menu option. But guess what? It won't compile. You'll get a complaint about a type called single. Don't worry, some of the types haven't been defined yet. Just before the first "[" in your IDL file, add the following statements:
#if (__midl >= 501)
midl_pragma warning( disable: 2362 )
#endif
import "oaidl.idl";
import "ocidl.idl";
typedef float single;
What next?
Now that you have a header file and a msdatgrd_i.c, you have to do something with it. The best thing to do is put it in a header file for a dialog or form.
- Add the msdatgrd.h header file and the msdatgrd_i.c file to your project using the solution explorer.
- Include the msdatgrd.h in the header to one of your dialogs.
- Try to compile and you will see quite a few errors. One of the dependency files needs to be included in the process.
- Repeat the previous section using the file msstdfmt.dll The msstdfmt.h file needs to be included before the msdatgrd.h file. You will also need to add the msstdfmt.h and msstdfmt_i.c files to your project.
Here's a sample WTL project that has an MS Data Grid on the main dialog page. The code simply changes the caption to read "Gene was here". Even though this appears to be a lot of work, you'll find you generate a smaller, more agile exe file using this approach.
I hope you enjoy the code!
WTL Learning Application