Active iveX usin sing MFC : Inside ide/Ou /Out
http:// ://www. www.d dotnetheaven.com/Uploadfile ile/ma /mahesh/x sh/x1 10425200505563...
We served 2,120,289 users last month
How to find a suitable job?
Home| Forums| Forums| ASP.NET 2.0 Tutorials| Tutorials| Web Servic Services| es| How Do I...? | Class Class Browser Browser | WPF Quick Starts | Consulting Search :
Login
Submit Submit an Article
Go
Submit Submit a Blog
Advanced Search »
Home » DLL/ActiveX » ActiveX using MFC : Inside/Out
User Id: Password:
ActiveX using MFC : Inside/Out
Remember Me Sign In
Author Rank: Total page views : 13304 Total downloads : 107
By Mahesh Chand October 03, 2000
Register
A tutorial that explains how to create an activeX using ControlWizard and how control wizard works under the hood.
Forgot Password Forgot Username Why Register Jump to
Print
Post a comment
Similar Articles
Email to a friend
Bookmark
Author's other articles
Share
Technology Website
Download Files:
mcfirstx.zip
Sponsored by Sponsored by
Become a Sponsor Resources About Us ASP.NET Hosting Authors Book Chapters Book Reviews C# Books
There are different ways to develop ActiveX controls for VC++ developers. Using MFC Using ATL Using BaseCtl framework This tutorial guides you towards how to create your activeX control using MFC ActiveX ControlWizard. This article also explains how ControlWizard works under the hood.
C# Consulting C# Training Downloads Media Kit News & Events Newsletter
1. Creating and Understand Skeleton
Become a Sponsor
Similar Similar Articles Articles
Most Read Read
Top Rated Rated
Lat
Creating an activeX object at Runtime? Implement PropertyPage in an ActiveX Debuging MFC DLL Tutorial Part I : MFC DLL Basics AviX : An ActiveX for Viewing AVI Files
First step is to create skeleton using MFC ActiveX ControlWizard. Cr eate new project and select MFC ActiveX ControlWizard.
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 f9
4/24/2010 9 17 P
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, 0 x60, 0xb0, 0xee, 0x76, 0x7 } }; const IID BASED_CODE IID_DMcFirstXEvents = { 0x669df27d, 0x985e, 0x11d4, { 0xb2, 0x4b, 0, 0 x60, 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 f9
4/24/2010 9 17 P
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() { COleContr ol::OnResetS tate(); // 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 f9
4/24/2010 9 17 P
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 f9
4/24/2010 9 17 P
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 f9
4/24/2010 9 17 P
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 f9
4/24/2010 9 17 P
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 A viOcx1.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 f9
4/24/2010 9 17 P
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 s ource code to this article About the author
Looking for C# Consulting?
Mahesh Chand Mahesh is a software developer with over 13 years of e xperience building systems for Financial and Banking, Engineering & Architectural, Imaging, Construction, Biological & Pharmaceuticals, Healthcare and Education industries. His expertise is Windows Forms, ASP.NET, Silverlight, WPF, WCF, 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 Ser ver Consultant in Philadelphia area or remote location, drop me a line at MAHESH [AT] C-SHARPCORNER [DOT] COM.
C# Consulting is f ounded in 2002 by the founders of C# Corner. Unlike a traditional consulting company, our consultants are well-known experts in .NET and many of th MVPs, authors, and trainers. We specialize in Microsoft .NET development and utiliz Development and Extreme Programming practices to provide fa st pace quick turnaro results. Our software development model is a mix of Agile Development, traditional and Waterfall models.
Click here to learn more about C# C
Go.NET Build custom interactive diagrams, network, workflow editors, flowcharts, or soft ware design tools. Includes many predefined kinds of nodes, li nks, and basic shapes . Supports lay 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.
8 f9
Print
Post a comment
Similar Articles
Email to a friend
Bookmark
Author's other articles
Share
4/24/2010 9 17 P
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 © 2010 contents copyright of their authors. Rest everything copyright Mindcracker. All rights reserved.
Current Version: 5.2009.6.2
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 f9
4/24/2010 9 17 P