Sunteți pe pagina 1din 9

ActiveX using MFC : Inside/Out http://www.dotnetheaven.com/Uploadfile/mahesh/x10425200505563...

We served 2,120,289 users last month How to find a suitable job?

Home | Forums | ASP.NET 2.0 Tutorials | Web Services | How Do I...? | Class Browser | WPF Quick Starts | Consulting Submit an Article Submit a Blog

Search : Go Advanced Search »


Login

User Id: Home » DLL/ActiveX » ActiveX using MFC : Inside/Out

Password:

Remember Me
ActiveX using MFC : Inside/Out Author Rank:
Total page views : 13304
By Mahesh Chand October 03, 2000 Total downloads : 107
Sign In Register
A tutorial that explains how to create an activeX using ControlWizard and how control wizard works under
Forgot Password
the hood.
Forgot Username
Why Register
Print Post a comment Similar Articles Share
Jump to Email to a friend Bookmark Author's other articles
Technology
Website Download Files: mcfirstx.zip

Sponsored by
Sponsored by
Become a Sponsor
There are different ways to develop ActiveX controls for VC++ developers. Become a Sponsor
Resources
Using MFC Similar Articles Most Read Top Rated Latest
About Us
ASP.NET Hosting
Using ATL
Creating an activeX object at Runtime?
Using BaseCtl framework
Authors
Implement PropertyPage in an ActiveX
Book Chapters This tutorial guides you towards how to create your activeX control using MFC ActiveX ControlWizard.
Debuging MFC
Book Reviews This
C# Books article also explains how ControlWizard works under the hood. DLL Tutorial Part I : MFC DLL Basics
C# Consulting AviX : An ActiveX for Viewing AVI Files
C# Training 1. Creating and Understand Skeleton
Downloads
Media Kit
First step is to create skeleton using MFC ActiveX ControlWizard. Create new project and select MFC
ActiveX
News & Events
ControlWizard.
Newsletter
Product Reviews
Testing3334
Tips
Tools
User Groups

Our Network

.NET Heaven
C# Corner
Interview Corner
Longhorn Corner
Mindcracker
VB.NET Heaven

Leave default settings on second page of the wizard. Click Next and Finish.

Now if you go to ClassView of your project, It looks like this:

1 of 9 4/24/2010 9:17 PM
ActiveX using MFC : Inside/Out http://www.dotnetheaven.com/Uploadfile/mahesh/x10425200505563...

Few clicks and skeleton of your control is ready. Great. But do you know how much work ControlWizard did for you?

Under the hood

Now let's see what ControlWizard does under the hood. Let's see classes one by one.

CMFCFirstXApp is the application class. This class is derived from COleControlModule which is derived from
CWinApp. COleControlModule class provides member functions for initializing your control module. Each OLE
control module that uses MFC can only contain one object derived from COleControlModule. This class has two
member functions InitInstance and ExitInstance. InitInstance calls COleControlModule::InitInstance() and
ExitInstance calls COleControlModule::ExitInstance(). See WinApp's InitInstance and ExitInstance for more
details.

// CMcFirstXApp::InitInstance - DLL initialization


BOOL CMcFirstXApp::InitInstance()
{
BOOL bInit = COleControlModule::InitInstance();
if (bInit)
{
// TODO: Add your own module initialization code here.
}
return bInit;
}
// CMcFirstXApp::ExitInstance - DLL termination
int CMcFirstXApp::ExitInstance()
{
// TODO: Add your own module termination code here.
return COleControlModule::ExitInstance();
}

CMFCFirstXCtrl is the control class. This class is derived from COleControl which is derived from CWnd. So we
do anything similar to CWnd. This class is responsible for creating a window and an ellipse on it. This class will
have implementation for your control including all functions implementing methods, properties and events.

When you see this cpp class, it starts with IMPLEMENT_DYNACREATE. After that it has three maps, a message
map, dispatch map and event map. CMFCFirstXCtrl's message map is similar to MFC's message map, the
dispatch map contains entries for all the properties and methods you implement, and the event map contains
entries for all the events you fire.

Now, here are some macros for adding property page.

// TODO: Add more property pages as needed. Remember to increase the count!
BEGIN_PROPPAGEIDS(CMcFirstXCtrl, 1)
PROPPAGEID(CMcFirstXPropPage::guid)
END_PROPPAGEIDS(CMcFirstXCtrl)

Next lines are for class factory, type library and interface ids.

// Initialize class factory and guid


IMPLEMENT_OLECREATE_EX(CMcFirstXCtrl, "MCFIRSTX.McFirstXCtrl.1",
0x669df27e, 0x985e, 0x11d4, 0xb2, 0x4b, 0, 0x60, 0xb0, 0xee, 0x76, 0x7)
// Type library ID and version
IMPLEMENT_OLETYPELIB(CMcFirstXCtrl, _tlid, _wVerMajor, _wVerMinor)
// Interface IDs
const IID BASED_CODE IID_DMcFirstX =
{ 0x669df27c, 0x985e, 0x11d4, { 0xb2, 0x4b, 0, 0x60, 0xb0, 0xee, 0x76, 0x7 } };
const IID BASED_CODE IID_DMcFirstXEvents =
{ 0x669df27d, 0x985e, 0x11d4, { 0xb2, 0x4b, 0, 0x60, 0xb0, 0xee, 0x76, 0x7 } };
// Control type information
static const DWORD BASED_CODE _dwMcFirstXOleMisc =
OLEMISC_ACTIVATEWHENVISIBLE | OLEMISC_SETCLIENTSITEFIRST | OLEMISC_INSIDEOUT |
OLEMISC_CANTLINKINSIDE | OLEMISC_RECOMPOSEONRESIZE;
IMPLEMENT_OLECTLTYPE(CMcFirstXCtrl, IDS_MCFIRSTX, _dwMcFirstXOleMisc)

_dwMcFirstXOleMisc tells what kind of control is it. This variable is passed to AfxOLERegisterControlClass as
a parameter. BOOL CMcFirstXCtrl::CMcFirstXCtrlFactory::UpdateRegistry(BOOL bRegister), registers and
unregisters the control's OLE class. Next code lines are two constructors. Calling COleControl's InitializeIIDs
&IID_DMcFirstX, &IID_DMcFirstXEvents); function informs that the base class of the interface IDs your control

2 of 9 4/24/2010 9:17 PM
ActiveX using MFC : Inside/Out http://www.dotnetheaven.com/Uploadfile/mahesh/x10425200505563...

will be using.

// CMcFirstXCtrl::CMcFirstXCtrl - Constructor
CMcFirstXCtrl::CMcFirstXCtrl()
{
InitializeIIDs(&IID_DMcFirstX, &IID_DMcFirstXEvents);
// TODO: Initialize your control's instance data here.
}
// CMcFirstXCtrl::~CMcFirstXCtrl - Destructor
CMcFirstXCtrl::~CMcFirstXCtrl()
{
// TODO: Cleanup your control's instance data here.
}

Next function is Overridden OnDraw which just draws an ellipse on the window. Similar to CWnd's OnDraw.
void CMcFirstXCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
// TODO: Replace the following code with your own drawing code.
pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
pdc->Ellipse(rcBounds);
}

Next DoPropExchange is used when saving the control's properties to the container or loading them from the
container.

void CMcFirstXCtrl::DoPropExchange(CPropExchange* pPX)


{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
// TODO: Call PX_ functions for each persistent custom property.
}

OnResetState is called when the control should reset its state to the default initial state.

void CMcFirstXCtrl::OnResetState()
{
COleControl::OnResetState(); // Resets defaults found in DoPropExchange
// TODO: Reset any other control state here.
}

Last, and perhaps least, is OnAbout, which displays your control's About box.

void CMcFirstXCtrl::AboutBox()
{
CDialog dlgAbout(IDD_ABOUTBOX_MCFIRSTX);
dlgAbout.DoModal();
}

CMFCFirstXPropPage is the your control's property page class. This class is derived from COlePropertyPage.
This class will have implementation for your control's property page. It has the message map and
DoDataExchange function that all MFC dialog boxes use. In addition to that, it's declared for dynamic and OLE
creation via the IMPLEMENT_DYNCREATE and IMPLEMENT_OLECREATE_EX macros (and their corresponding
DECLARE_ variants in the header file). There is one more function BOOL
McFirstXPropPage::CMcFirstXPropPageFactory::UpdateRegistry( BOOL bRegister), which registers and
unregisters the property page with OLE. This function will be called by MFC when the control is being initialized
and destroyed.

Global Members There are four global members. DllRegisterServer, DllUnregisterServer, the interface ID
IID_DMcFirstX, and CMcFirstXApp global instance theApp.

Let's see DllRegisterServer and DllUnregisterServer functions:

// DllRegisterServer - Adds entries to the system registry


STDAPI DllRegisterServer(void)
{
AFX_MANAGE_STATE(_afxModuleAddrThis);
if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
return ResultFromScode(SELFREG_E_TYPELIB);
if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
return ResultFromScode(SELFREG_E_CLASS);
return NOERROR;
}
// DllUnregisterServer - Removes entries from the system registry
STDAPI DllUnregisterServer(void)
{
AFX_MANAGE_STATE(_afxModuleAddrThis);
if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
return ResultFromScode(SELFREG_E_TYPELIB);
if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
return ResultFromScode(SELFREG_E_CLASS);
return NOERROR;
}

Other Files

Let's see what ActiveX ControlWizard writes under the hood.

3 of 9 4/24/2010 9:17 PM
ActiveX using MFC : Inside/Out http://www.dotnetheaven.com/Uploadfile/mahesh/x10425200505563...

It has generated a .rc resource file, an .ODL file, a .DEF file, and a .CPP and .H file for each class we have
discussed earlier and stdafx.h and cpp files. The mcfirst.rc and mcfirst.def files are the standard resource and
linker definition files. The mcfirst.odl file contains type information for OLE.

2. ActiveX Control and Its Components

ActiveX has are four basic components. Before adding any functionality to our control, let's see its components.

Methods
Properties
PropertyPages
Events

Methods

Methods are functions implemented inside an activeX. They are accessible via control's wrapper class from a
client program. There are two types of methods, stock and custom. MFC provides two stock methods, DoClick
and Refresh.

Adding an Method

You don't have to write any code for stock methods. Right click on your interface and select Add Method from
Menu will display this dialog box.

If you add DoClick method, ControlWizard writes a single line of code in your dispatch map section and your odl
file's method's section looks like this:

methods:

// NOTE - ClassWizard will maintain method information here.


// Use extreme caution when editing this section.
//{{AFX_ODL_METHOD(CMcFirstXCtrl)
[id(DISPID_DOCLICK)] void DoClick();
//}}AFX_ODL_METHOD

and dispatch map looks like this:

And here is dispatch map. Bold line is added after adding the method.

// Dispatch map
BEGIN_DISPATCH_MAP(CMcFirstXCtrl, COleControl)
//{{AFX_DISPATCH_MAP(CMcFirstXCtrl)
DISP_STOCKFUNC_DOCLICK()
//}}AFX_DISPATCH_MAP
DISP_FUNCTION_ID(CMcFirstXCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()

4 of 9 4/24/2010 9:17 PM
ActiveX using MFC : Inside/Out http://www.dotnetheaven.com/Uploadfile/mahesh/x10425200505563...

Custom methods are the functions added by you. Here is how I add TestMessage method.

After adding TestMessage, odl file and massage map looks like this:

methods:

// NOTE - ClassWizard will maintain method information here.


// Use extreme caution when editing this section.
//{{AFX_ODL_METHOD(CMcFirstXCtrl)
[id(DISPID_DOCLICK)] void DoClick();
[id(1)] void TestMessage();
//}}AFX_ODL_METHOD

And here is dispatch map. Bold line is added after adding the method.

// Dispatch map
BEGIN_DISPATCH_MAP(CMcFirstXCtrl, COleControl)
//{{AFX_DISPATCH_MAP(CMcFirstXCtrl)
DISP_FUNCTION(CMcFirstXCtrl, "TestMessage", TestMessage, VT_EMPTY, VTS_NONE)
DISP_STOCKFUNC_DOCLICK()
//}}AFX_DISPATCH_MAP
DISP_FUNCTION_ID(CMcFirstXCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()

Here VT_EMPTY means that the return type of the Next method is void, and VTS_NONE means that the
TestMessage method takes no parameters. If the method had a return value, its return type constant
(VT_xxx) would replace VT_EMPTY. If it took parameters, the types of the parameters would be represented
by a comma-separated list of parameter type constants (VTS_xxx) instead of VTS_NONE. The list of
constants is in the MFC documentation for DISP_FUNCTION. Besides these two changes, ControlWizard adds
TestMessage function to your CMcFirstXCtrl class. Here is how it it looks like now:

Properties

An activeX control exposes its variables through it properties. There are two types of control properties: Stock
and Custom. Custom properties are implemented by you. ClassWizard offers two ways to implement a custom
property: as a pair of Get/Set methods, or as a member variable. Stock Properties is a set of properties
implemented by MFC. To use them, just add them to your control with ClassWizard—the code is already there to
implement the properties. You can add these properties using ControlWizard. Select Add Property from your
interface's right click, you will get this dialog:

Here you can add your property or add an existing one. If you select Stock option, wizard write code for you. If
your property is a custom then you have two choices i.e., either member variable or get/set method. First
option adds one variable to your code. This variable is accessible from clients. Clients can sent its value.

Other option is to use Get/Set pair. This option adds two functions to your control class. Say if you add a
property Color by using Get/Set method then Wizard will add GetColor and SetColor functions to your control
class. How to add these we will see in our next step.

5 of 9 4/24/2010 9:17 PM
ActiveX using MFC : Inside/Out http://www.dotnetheaven.com/Uploadfile/mahesh/x10425200505563...

ProperyPages

We have already seen that ControlWizards adds a COlePropertyPage derived class to every activex. This class
COlePropertyPage is derived from CDialog. So you can use your property page class as a dialog. Property pages
are used to allow visual implementation of control's properties. By using these pages, you can set control's
properties.

Events

Events are the notifications your control sends to its container when something has happened. Controls have
two types of events, custom and stock. MFC provides about a dozen stock events, mainly having to do with
mouse clicks and key presses.

Adding an Event

You can add an event by right clicking on your control's event interface. Its _DMcFirstXEvents in this picture.

Now let's add Click event by selecting Add Event on Right mouse click.

This action updates odl file's CMcFirstXCtrl interface section. See bold line here.

// Event dispatch interface for CMcFirstXCtrl


[ uuid(669DF27D-985E-11D4-B24B-0060B0EE7607), helpstring("Event interface for McFirstX Control") ]
dispinterface _DMcFirstXEvents
{
properties:
// Event interface has no properties methods:
// NOTE - ClassWizard will maintain event information here.

6 of 9 4/24/2010 9:17 PM
ActiveX using MFC : Inside/Out http://www.dotnetheaven.com/Uploadfile/mahesh/x10425200505563...

// Use extreme caution when editing this section.


//{{AFX_ODL_EVENT(CMcFirstXCtrl)
[id(DISPID_CLICK)] void Click();
//}}AFX_ODL_EVENT
};

as well as event map. Bold line is added after adding the event.

// Event map
BEGIN_EVENT_MAP(CMcFirstXCtrl, COleControl)
//{{AFX_EVENT_MAP(CMcFirstXCtrl)
EVENT_STOCK_CLICK()
//}}AFX_EVENT_MAP
END_EVENT_MAP()

You can add your custom events too. You can pass your parameters to provide more information about the
situation. We don't have any custom event in our sample example.

3. Implementation

Ok, now let's see actual implementation of an ActiveX Control. This activeX will display AVI files. Add one
method to this activeX called ViewAVI. This function takes avi file name as an input parameter.

Go to your project's setting's Link option and link with vfw32.lib and winmm.lib files #include "vfw.h".

Now add this below code to ViewAvi finction of your control class:

void CMcFirstXCtrl::ViewAVi(LPCTSTR szFileName)


{
HWND mciHWnd;
if(m_mciHWnd)
{
MCIWndDestroy(m_mciHWnd);
m_mciHWnd = NULL;
Invalidate();
}
mciHWnd = MCIWndCreateA((HWND)this->m_hWnd,AfxGetInstanceHandle(), MCIWNDF_NOTIFYPOS|MCIWNDF_NOTIFYALL|MCIWNDF_NOMENU
,FileName);
if ( mciHWnd )
{
MCI_SET_PARMS setParam;
setParam.dwCallback = (DWORD)this->m_hWnd;
setParam.dwTimeFormat = MCI_SET_TIME_FORMAT|MCI_FORMAT_FRAMES;
setParam.dwAudio = MCI_SET_OFF;
mciSendCommand(MCIWndGetDeviceID(mciHWnd), MCI_SET, MCI_NOTIFY, (DWORD) (LPMCI_SET_PARMS)setParam);
m_mciHWnd = mciHWnd;

Build your project. Your ocx is ready to use now. Now you can insert this control in a dialog based application
and call its ViewAvi method to view avi files.
}

How to Use the ActiveX?

Create a dialog based application.

Insert the ActiveX

Insert your AviOcx1.ocx ActiveX by using Project->Add To Project->Components and Controls menu item.
This action adds one control to your controls list and one wrapper class to your project. Say my class is

7 of 9 4/24/2010 9:17 PM
ActiveX using MFC : Inside/Out http://www.dotnetheaven.com/Uploadfile/mahesh/x10425200505563...

CAviOcx1. Now drag the ActiveX on your dialog.

Add a Variable corresponding to the control by using ClassWizard.

Now call ViewDoc of activeX on OnInitDialog with an AVI file name as a parameter.

m_ctrl.ViewAVi("C:\\Winnt\\clock.avi");

Here is the result.

Login to add your contents and source code to this article

About the author Looking for C# Consulting?

C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional


Mahesh Chand consulting company, our consultants are well-known experts in .NET and many of them
Mahesh is a software developer with over 13 years of experience building MVPs, authors, and trainers. We specialize in Microsoft .NET development and utilize
systems for Financial and Banking, Engineering & Architectural, Imaging, Development and Extreme Programming practices to provide fast pace quick turnaround
Construction, Biological & Pharmaceuticals, Healthcare and Education results. Our software development model is a mix of Agile Development, traditional S
industries. His expertise is Windows Forms, ASP.NET, Silverlight, WPF, WCF, and Waterfall models.
Visual Studio 2010, SQL Server, and Oracle. If you are looking for a
Windows Forms, ASP.NET, WPF, Silverlight, C#, VB.NET, Oracle, and
SQL Server Consultant in Philadelphia area or remote location, drop me
a line at MAHESH [AT] C-SHARPCORNER [DOT] COM. Click here to learn more about C# Consulting.

Go.NET
Build custom interactive diagrams, network, workflow editors, flowcharts, or software design tools. Includes many predefined kinds of nodes, links, and basic shapes. Supports layers,
scrolling, zooming, selection, drag-and-drop, clipboard, in-place editing, tooltips, grids, printing, overview window, palette. 100% implemented in C# as a managed .NET Control.
Document/View/Tool architecture with many properties&events. Optional automatic layout.

Print Post a comment Similar Articles Share


Email to a friend Bookmark Author's other articles

8 of 9 4/24/2010 9:17 PM
ActiveX using MFC : Inside/Out http://www.dotnetheaven.com/Uploadfile/mahesh/x10425200505563...

Download Files: mcfirstx.zip

Post a Feedback, Comment, or Question about this article


Subject:
Comment:

Submit

Sponsored by
Become a Sponsor

Comments

m_mciHWnd declaration! by khalfi On January 2, 2010


m_mciHWnd
i don't know where to declare this variable

Reply | Email | Delete |

Hosted by MaximumASP | Found a broken link? | Contact Us | Terms & conditions | Privacy Policy | Site Map | Suggest an Idea | Media Kit Current Version: 5.2009.6.2
© 2010 contents copyright of their authors. Rest everything copyright Mindcracker. All rights reserved.

Channels: Jobs | Interviews | Consulting | Training | Photos | Authors | Tips | Forums | E-Books | Blogs
Programming: C# | Visual Basic | ASP.NET & Web Development | C++ | Other .NET Languages | Windows Vista | XAML | Tutorials
Sponsors: ASP.NET 4 Hosting | Clickatell | Dundas Software | DynamicPDF | Nevron | RedGate Software

9 of 9 4/24/2010 9:17 PM

S-ar putea să vă placă și