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

  • Best-in-Class organizations execute on a strategy that supports the multi-channel nature of customer requests. These leading organizations do not just open up their service infrastructures to accommodate new channels, but also empower their teams to deliver an effective and consistent experience regardless of the channel selected by the customer. This document will highlight the key business capabilities that support a Best-in-Class customer engagement strategy.

  • As mobile devices have pushed their way into the enterprise, they have brought cloud apps along with them. This app explosion means account passwords are multiplying, which exposes corporate data and leads to help desk calls from frustrated users. This paper will discover how IT can improve user productivity, gain visibility and control over SaaS and mobile apps, and stop password sprawl. Download this white paper to learn: How you can leverage your existing AD to manage app access. Key capabilities to …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds