ActiveX Control Property Page Container


First I 'd like to write some reason how I come up with this idea, probably that will help future user of this code understand the power and flexibility which these functions provide.

Everybody understands the benefits of writing component software and COM comes very handy to help in implementation of components. One of great applications of COM component technology is ActiveX controls which allow to implement various kind of powerful controls and use them almost everywhere. If you implemented powerful desktop application COM (OLE2) also comes very helpful when you want to use parts of you objects within other applications or contain peace (or even entire ActiveX document) of other application.

But there is some area that for some reason is missing from component infrastructure invented by Microsoft: it is dialog boxes. Sometimes this appears very useful if for example you want to implement some sort of reporting applications where others, including you, can write separate components to provide new type of query. Usually such components must contain dialog box or property page to allow user enter query specific parameters and engine which retrieves records using parameters entered by user.

When I was faced with such problem I started thinking about ActiveX controls but controls can't contain several child windows and especially navigate focus smoothly between them as it works in dialog box. And then I though why we can't take this control property page and put it inside another dialog box or formview as a container. Actually I did not invent anything new I just used existing technology in different application. All features I used here are very well documented in Visual C++ help files but anyway I did not see any samples of such usage so I have to start from scratch.

The function showed below implements most part of the functionality. There are 2 interfaces involved: IPropertyPage and ISpecifyPropertyPages. Container dialog box implements IPropertyPageSite to host property pages within itself. I heavily use COM smart pointer declared in <comdef.h> and encourage everybody to use them because they simplify life a lot. I understand that this is not "a MFC style" but this is really boring to write all this using plain LPUNKNOWNs. Code provided here uses first page of ActiveX control to display on the container dialog box but page number can be easily changed in CoCreateInstance() call. Besides displaying property page this function can be used to switch pages on fly, provided you add user interface to select different ActiveX controls.

Property page resource in ActiveX control however requires additional style named "Control" located on "More Styles" page otherwise navigation keys like Tab and Shift+Tab will not jump from container controls to inner property page controls. The other limitation is that property page can be 250x110 or 250x62 dialog units otherwise debug version of MFC will present a message box. From my point of view this space is quite enough for most applications, and anyway you need some space limitation if you want to be able to create new pages without rewriting the container. If you ok to live with MFC debug warning message you may use whatever size you want. Happily release version of MFC doesn't produce any warnings.

This sample is some kind symbiosys because ActiveX control is running in regular mode while property page is displayed which suppose to be visible only in design mode. But it works and it appears very helpful for me and I hope for somebody else. Sample contains implementation for classes derived from CDialog but I tried them in CFormView and even dockable control bar - they all work perfectly.

BOOL CPropPageCntrDlg::SetCurrentPage( IUnknown * pUnknown, LPRECT rc )
{
	HRESULT hr = NOERROR;

	try
	{
		// hide previous page and release page pointer
		if( m_pCurrentPage != NULL )
		{
			m_pCurrentPage->Show( SW_HIDE );
			m_pCurrentPage->Deactivate();
			m_pCurrentPage = NULL;

			if( pUnknown == NULL ) return TRUE;
		}
		
		ISpecifyPropertyPagesPtr pSpecifyPropertyPages = pUnknown;

		CAUUID pages;
		hr = pSpecifyPropertyPages->GetPages( &pages );
		if( FAILED( hr ) ) throw _com_error( hr );

		ASSERT( pages.cElems > 0 && pages.pElems != NULL );

		IPropertyPagePtr pPropPage;
		
		// get 0-page GUID and create page object
		hr = CoCreateInstance( pages.pElems[0], NULL, CLSCTX_INPROC, IID_IPropertyPage, (void**)&pPropPage );
		if( FAILED( hr ) ) throw _com_error( hr );

		hr = pPropPage->SetPageSite( (IPropertyPageSite*) GetInterface( &IID_IPropertyPageSite ) );
		if( FAILED( hr ) ) throw _com_error( hr );

		hr = pPropPage->SetObjects( 1, &pUnknown );
		if( FAILED( hr ) ) throw _com_error( hr );

		hr = pPropPage->Activate( GetSafeHwnd(), rc, TRUE );
		if( FAILED( hr ) ) throw _com_error( hr );

		hr = pPropPage->Show( SW_SHOW );
		if( FAILED( hr ) ) throw _com_error( hr );

		m_pCurrentPage = pPropPage;
	}
	catch( _com_error &e )
	{
		hr = e.Error();
		ASSERT( SUCCEEDED( hr ) );
	}

	return SUCCEEDED( hr );
}

The demo project contains sample container and two dummy ActiveX controls that are generated by MFC and ATL wizards. The only option important is to mark these controls as invisible at runtime. MFC property page is more preferable if you want to put other ActiveX control on that page because up to now ATL property page does not support hosting of ActiveX controls. Sample container switches user interface on fly using ActiveX controls property pages. And what is more important container may execute queries without knowing anything about what kind of user interface required to enter query parameters! The ActiveX controls in turn talk back to container using regular fire event mechanism and container displays results of a query also without knowing how they were retrived!

Download demo project - 40 KB



Comments

  • How To Write An ActiveX Control Like SSTab

    Posted by Legacy on 07/25/2002 12:00am

    Originally posted by: Chen.J.D

    In VB,SSTab is useful.I know how to make a control container,but can't find a method to make a control
    like sstab?

    Reply
  • Identifying OK or Cancel at runtime.

    Posted by Legacy on 05/18/2002 12:00am

    Originally posted by: Munda

    If I display the property pages at runtime using the IOLEObject interface, then how do I know that either OK or Cancel has been pressed by the user?

    Reply
  • How to ActiveX Container ?

    Posted by Legacy on 10/08/2001 12:00am

    Originally posted by: Fresh Group

    Beginner-level tutorial to help you write your first ActiveX container (with stock properties and custom properties)

    Reply
  • How do I get "Apply" button enabled with later approach?

    Posted by Legacy on 03/03/2000 12:00am

    Originally posted by: Darwin

    HELP! I've successfully added my own property page as a Shell Extension using "OleCreatePropertyFrame()" but can't seem to get the "Apply" button enabled. I call "SetDirty(TRUE)" but the property page it crashes at this point (in fact, Windows "explorer" crashes and then automatically restarts again, at least on WinNT 4.0).

    I notice that "m_pPageSite" pointer is NULL at the point where "SetDirty" is called which I'm pretty sure is the problem. Somehow for my custom property page shell extension this page site isn't being initialized properly. How do I initialize/set this, and where should it be done.
    I'm using COM/ATL.

    Thanks in advance everyone for you patience and assistance! I'm fairly new and this COM stuff and really don't know enough to even be dangerous. [I'd appreciate a direct reply to my email address as I don't get on this site very often.]

    Darwin
    darwin@sharplabs.com

    Reply
  • Doesn't realy work in VB

    Posted by Legacy on 02/23/2000 12:00am

    Originally posted by: Jerislav Bobić

    Yes, code for MFC is ok, it works well, but ATL code doesn't work in VBasic. VBasic doesn't popup properties for ATL demo.

    Is there a way to override this problem somehow?

    Thanks
    J.

    Reply
  • alternative

    Posted by Legacy on 04/15/1999 12:00am

    Originally posted by: Steve

    This is a nice demo, however an easier way of hosting COM property pages is through OleCreatePropertyFrame() which will automatically implement the site object.

    Steve

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: December 18, 2014 The Internet of Things (IoT) incorporates physical devices into business processes using predictive analytics. While it relies heavily on existing Internet technologies, it differs by including physical devices, specialized protocols, physical analytics, and a unique partner network. To capture the real business value of IoT, the industry must move beyond customized projects to general patterns and platforms. Check out this webcast and join industry experts as …

  • On-demand Event Event Date: October 29, 2014 It's well understood how critical version control is for code. However, its importance to DevOps isn't always recognized. The 2014 DevOps Survey of Practice shows that one of the key predictors of DevOps success is putting all production environment artifacts into version control. In this webcast, Gene Kim discusses these survey findings and shares woeful tales of artifact management gone wrong! Gene also shares examples of how high-performing DevOps …

Most Popular Programming Stories

More for Developers

RSS Feeds