Click here to Skip to main content
Click here to Skip to main content

ATL Windowless ActiveX Media Container

By , 5 Mar 2009
 

Contents

Silverlight ActiveX Control

Introduction

COM/ActiveX control has been around for more than a decade. In spite of all, it is very difficult to get a complete Windowless container. MFC dialog has its own Windowless container that is truly windowless compared to ATL but if your project can't afford to depend on MFC, you are on your own. The container I am presenting in this article offers complete support to Windowless controls. It is developed especially for ATL/WTL projects and can be used to create composite controls. That means, you can combine multiple Windowless Controls to create your own component.
Imagine being able to encapsulate Adobe Flash, Windows Media Player and Silverlight into your own component. Another advantage you will find with these classes is that the learning curve is quasi zero if you have any previous experiences with ATL. You simply derive your dialog from the new dialog class to get the full power of this container.

Description

Having a full-blown windowless container can be very useful. I hope that you will find some great uses for it. I will describe the process necessary to integrate the container in your own project. Later, in other articles, we'll explore how we can take some of this to a new level.

Think about this, wouldn't it be great if you could integrate Silverlight and Flash contents seamlessly and interact with them within your C++ application?
The more you think about it, this is quite possible after all that's what a web browser does in a large part. But before we go too deep, let's do a quick refresh about ActiveX control container and see how powerful the whole concept was and is, even today. If you are already comfortable with ActiveX and Windowless or don't need a memory refresh, you can jump directly to Using ActiveXContainerImpl Class.

ActiveX Control Container

If you want to be proficient at developing Windowless controls and their container, you have to rely on the OC96 Specification. Basically, you need to know and understand several things.

Apartment-Model Awareness

ActiveX Controls should be developed to conform to apartment-model rules to ensure they behave correctly. That is, you have to think in term of UI thread and make sure that your object is thread safe. If your object uses global variables, it should synchronize access to them.

Windowless

By supporting the windowless control specification, a control can make efficient use of its container's window rather than having a window of its own. This results in using fewer system resources and improves performance through faster activation/deactivation. Providing windowless support not only provides transparency for interesting visual effects, but also further improves the performance of the control.

Hit Detection

Hit detection is provided so that a windowless control can have an irregular shape and to complete the visual benefits of transparency. The container calls IViewObjectEx::QueryHitPoint of the control. In return, the control determines if it has been hit and returns an indication to the container.

Control Persistent Data

A control can use any of IPersistStreamInit, IPersistStorage, IPersistMemory, and IPersistPropertyBag as a Persistent Embedding mechanism. A control may implement more than one of these interfaces if it wants to. The container being presented with this article supports only IPersistStreamInit but IPersistPropertyBag may be added in the future in order to support a wider range of controls.

Interacting with Container

Because the container interface is passed to the control, the entire object model of the container is available and can be manipulated by the control. Consider for example this same scenario with Internet Explorer, a control access the entire DOM tree (IHTMLDocument) and change background color of the document.

CComPtr<IOleContainer> spContainer; 
m_spClientSite->GetContainer(&spContainer); 
CComQIPtr<IHTMLDocument2, &IID_IHTMLDocument2> spDoc(spContainer); 
if (spDoc)
    spDoc->put_bgColor(CComBSTR(_T("blue")));    

What this means is if you develop a custom container or composite control, any control that is hosted into your dialog surface can get access to the methods and properties that your object model supports.
The following diagram shows the main interfaces that come into play.

ActiveX Container Object Model

Basically, to host an ActiveX component, the container must:

  • Call the object SetClientSite to inform the object of its display location, called a "Client Site".
  • Initialize the object properties; It uses IPersistStreamInit, IPersistPropertyBag for this purpose.
  • Call the object SetAdvise method in order to be notified of compound document events.
  • Then, call the object DoVerb method with OLEIVERB_INPLACEACTIVATE to activate the object.

The object then proceeds by:

  • Negotiating its activation by calling CanWindowlessActivate to find out if it can be activated "windowlessly"; if not possible, the control creates its own window.
  • Then, it calls OnInPlaceActivateEx but uses the activate flag to indicate whether it wants windowless activation.
  • Windowless object also calls GetWindowContext to find its position within the container.
  • Finally, the control calls the container ShowObject; This indicates to the container that the control is ready to be shown.

The container is also responsible for managing input focus, mouse capture and associating moniker for the object. The container dispatches mouse and keyboard messages to the windowless control by calling the OnWindowMessage method of the IOleInPlaceObjectWindowless interface. That way, the control may respond to regular inputs when it has focus. This is about all there is to it but the ActiveXContainerImpl class makes this process really transparent. Now, let's see some of it in action.

Using ActiveXContainerImpl Class

ActiveXContainerImpl class supports the following features:

  • Hosting both Windowless and window controls
  • Hosting multiple ActiveX controls in one container
  • Restrict mouse or keyboard input for individual controls (window or windowless)
  • Change control Z-Order (controls can be sent to: back, top, top-most)
  • Supports data moniker (controls are allowed to load data via the http://, file:///, res://)
  • Transparency Support (governed by Z-order position)
  • Rendering Windowless controls to memory DC or printer (not screen)

Hosting ActiveX controls inside of a dialog is basically the same as you did with ATL. You can safely rename your base class from CAxDialogImpl to CAxWindowlessHost. This class inherits from CDialogImplBaseT, thus, will have the same capabilities as any Windows dialog.

class CMainDlg : public CAxWindowlessHost<CMainDlg>
{
public:
    enum { IDD = IDD_MAINDLG };

    BEGIN_MSG_MAP(CMainDlg)
        CHAIN_MSG_MAP(CAxWindowlessHost<CMainDlg>)
        MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
        COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
        COMMAND_ID_HANDLER(IDOK, OnOK)
        COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
    END_MSG_MAP()

    LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, 
		LPARAM /*lParam*/, BOOL& /*bHandled*/);
        LRESULT OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, 
		HWND /*hWndCtl*/, BOOL& /*bHandled*/);
        LRESULT OnOK(WORD /*wNotifyCode*/, WORD wID, 
		HWND /*hWndCtl*/, BOOL& /*bHandled*/);
        LRESULT OnCancel(WORD /*wNotifyCode*/, WORD wID, 
		HWND /*hWndCtl*/, BOOL& /*bHandled*/);
};

Let's get this started with some examples. The examples below assume that the controls are inserted using 'Insert ActiveX Control' from the dialog editor. You still have the flexibility to create everything manually at runtime.

Hosting Microsoft Windows Media Player

Windows Media Player supports windowless activation. Assuming you inserted a media player onto your dialog, the example below shows how you can turn it to windowless mode. Note that in the case of Windows Media Player, a custom property dialog is also available so you can configure your control at design time.

HRESULT hr;
ActiveXSite* pSite;
pSite = CAxWindowlessHost<CMainDlg>::GetControlSite(IDC_WMP11);
if ( pSite != NULL )
{
    pSite->SetAllowResize(false); 	// turn-off resize or media will 
				// resize itself to match its content
    CComQIPtr<IWMPCore> wmp = pSite->ActiveXControl();
    CComQIPtr<IWMPPlayer4> wmp4 = pSite->ActiveXControl();
    if ( wmp4 ) {
        hr = wmp4->put_windowlessVideo( VARIANT_TRUE );
        hr = wmp4->put_uiMode( CComBSTR("Full") );
    }
    hr = wmp->put_URL( CComBSTR("enter resource URL") );
}

Silverlight ActiveX Control

Hosting Adobe Flash Player

You can also host Flash content. Flash animations can be loaded for external file resources or retrieved from the internet. For example, you can add support for YouTube video provided that you correctly specify the URL of the resources. The example below shows how to initialize Adobe Flash player to host an animation or video.

HRESULT hr;
ActiveXSite* pSite;
pSite = CAxWindowlessHost<CMainDlg>::GetControlSite(IDC_SHOCKWAVEFLASH);
if ( pSite != NULL )
{
    CComQIPtr<IShockwaveFlash> spFlash = pSite->ActiveXControl();
    hr = spFlash->put_WMode( CComBSTR("Transparent") );
    hr = spFlash->put_Movie( CComBSTR("enter resource URL") );
}

Setting Transparent mode is necessary to turn Adobe Flash to Windowless mode.

Hosting Microsoft Silverlight

XAML and Silverlight application package (*.xap) can be hosted using Microsoft Silverlight ActiveX control. For security reasons, you can only load data from file:/// or http:// moniker. It would have been nice to support the resource protocol (res://). The example below shows how to configure Silverlight to load external resources.

HRESULT hr;
ActiveXSite* pSite;
pSite = CAxWindowlessHost<CMainDlg>::GetControlSite(IDC_AGCONTROL1);
if ( pSite != NULL )
{
    pSite->SetAllowRClick(false);
    CComBSTR bstrUrl("enter resource URL");
    pSite->SetUrl(bstrUrl);
    CComQIPtr<IXcpControl2> slight = pSite->ActiveXControl();
    hr = slight->put_Source(bstrUrl);
}

In this example, the control is prevented from receiving right clicks so the context menu is never shown.
The demo shows how to use Silverlight in Windowless mode.
A huge number of demos would have to be presented if I had to consider all the ActiveX controls that we have at our disposal. Windows Form ActiveX controls can be hosted by your application as well. A demo is provided here as well.

Conclusion

This article presents a complete and real solution for the ATL windowless ActiveX container issue. I've described the steps necessary to integrate three popular controls in your own dialog. It is quite easy to use other ActiveX controls as well. The container may be used to develop custom composite control. Probably the most interesting part was to show how you can integrate Silverlight Application package (*.xap,*.xaml) within your solution with little effort. I hope you will consider the features that it offers and put them to use in your own program.

References

History

  • 02/19/2009: Initial Release + Windows CE port
  • 03/05/2009: Updated for Silverlight in Windowless and Viewer mode

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0

About the Author

Ernest Laurentin
Software Developer (Senior)
United States United States
Member
Ernest is a multi-discipline software engineer.
Skilled at software design and development for all Windows platforms (starting Windows 3.11),
Windows CE and cross-platform UI development.
-
MCSD (C#, .NET)
Interests: User Interface, GDI/GDI+, Scripting, Windows CE .NET.
Programming Skills: C/C++, C#, Java, VB and ASP.NET.
 
I hope you will enjoy my contributions.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionHow to implement a windowless ActiveX control?membercarlosrt26 Apr '13 - 1:16 
I have an old ActiveX control. It massive, and it was implemented as "windowed".   I want to implement a smaller windoless activeX control. I haven't succeeded in doing so. In terms of documentation available, all I get is "implement the IOleInPlaceObjectWindowless, and/or...
AnswerRe: How to implement a windowless ActiveX control?memberErnest Laurentin26 Apr '13 - 5:03 
Yes, maybe I can help. I have implemented a couple of windowless. Yes, most documentation talk about these two interfaces. It's easier using ATL. I will say: 1) create an ATL control. I believe that the Wizard will let you do that. 2) Now, most of the differences will come from...
QuestionRe: How to implement a windowless ActiveX control?membercarlosrt26 Apr '13 - 5:40 
Wow, I'm impressed. Thank you very much for such quick reply! I will start with no assumptions.   I started by creating a typical ATL Control. Actually, I followed the ubiquitous "Polygon" tutorial. I have inserted/embedded this control in HTML. It deals with the mouse events, no problem....
AnswerRe: How to implement a windowless ActiveX control?memberErnest Laurentin26 Apr '13 - 6:03 
Your OnDraw looks fine (1), (2) - yes correct (3) IE will detect that. You have to implement Safe for scripting interfaces to host in IE.   Compare your class with the class below: // CAxButton class ATL_NO_VTABLE CAxButton : public CComObjectRootEx<CComObjectThreadModel>, ...
GeneralRe: How to implement a windowless ActiveX control?membercarlosrt30 Apr '13 - 0:50 
Brilliant! ... and embarrassing ... the joys of legacy code!   So, this is what I found, and I didn't understand. 1. The wizard does create a windowless control, by default (even if one selects window only). 2. Setting m_bWindowOnly does modify the mode (windowed <--> windowless)....
GeneralRe: How to implement a windowless ActiveX control?memberErnest Laurentin30 Apr '13 - 6:56 
Email me your code (no binary, no .obj, .pdb). I'll try to take a look. In general, you should be able to use OpenGL and DirectX. I have combined Direct3D and standard GDI without problems. Most issues are when you want to implement your own Hit testing, capture mouse and receive keyboard...
AnswerRe: How to implement a windowless ActiveX control?membercarlosrt2 May '13 - 4:32 
Hi Ernest,   I couldn't find a simple way to upload (email you) the code. I managed to sort out the ATL Windowless OpenGL issue.   WINDOWED approach 1. At OnCreate detect the current DC, and client rectangle. Also set the OpenGL context (HGLRC). A slower, proof-of-concept approach...
QuestionControl Cursor Can not be displayedmemberxwanger12 Mar '13 - 21:36 
Silverliht Control Cursor Can not be displayed, Only display the system default cursor, I would like to ask how to do that Please reply thanks
QuestionHow to use WFlashPlayer to play youtube videos where URL is hidden??? [modified]memberramanujamkv22 Sep '11 - 20:37 
Hi Guys,   I need your help.   I am trying to play www.youtube.com videos thorugh WFlashPlayer by specifying the URL of the SWF which is present in the HTML source. WFlashPlayer is failed to play the flash video.   I did a small investigation on these yotube URL's and I...
GeneralRender to texturemembertexel3d6 Mar '11 - 23:24 
Hi, It's very interesting, but i want to render Silverlight files to a texture for a 3D application in order to use it as a GUI (in 3D). Something like Hikari: http://www.ogre3d.org/tikiwiki/Hikari&structure=Libraries   I have tried to modify your code, but i can't succed. I have no...
QuestionCreating Flash Containers at runtime?memberAndrews1326 Nov '10 - 22:44 
Ernest,   What a great article!   You said: "The examples below assume that the controls are inserted using 'Insert ActiveX Control' from the dialog editor. You still have the flexibility to create everything manually at runtime." How can this be achieved, say for a Flash ActiveX...
AnswerRe: Creating Flash Containers at runtime?memberErnest Laurentin6 Dec '10 - 4:57 
Hi, I am only referring to 'Inserting ActiveX control' from the dialog editor. Your ActiveX/OCX controls still have to be registered to be used.
QuestionHow to make the background of the MainDlg tranparent?memberitmagina27 Jul '10 - 19:35 
How to make the background of the MainDlg tranparent? Thank you!
QuestionWhere can I find the sources at ..\Windowless\?memberHomero De la Garza2 Feb '10 - 11:50 
I have been looking for info about this subject and last Saturday I found this very interesting article of yours.   The demos spoke by themselves, but when I tried to load the project it makes reference to several missing files at ..\Windowless\  ...
AnswerRe: Where can I find the sources at ..\Windowless\?memberErnest Laurentin2 Feb '10 - 12:25 
You need to download the source!   Try not to become a man of success but rather to become a man of value. - Albert Einstein Ernest Laurentin
GeneralRe: Where can I find the sources at ..\Windowless\? --- Sorry, my fault :|memberHomero De la Garza2 Feb '10 - 12:46 
First of all, thanks a lot for your fast response.   I did downloaded the ZIP with sources, but as I'm mainly interested in Flash hosting I yesterday copied ONLY the WFlashPlayer folder to where I'm making my tests without checking that in the ZIP file IS the required folder.  ...
Generalwhen MAXIMIZE the View, cause crushmembercrystalicetpmc12 Jan '10 - 1:02 
  While use CAxWindowlessHost with WTL MDI FORM (Dialog-based) View, and then, when MAXIMIZE the View, cause crush.   Why? and How to fixed?   Thanks very much!   CI
GeneralHost multiple ActiveX controlsmembercrystalicetpmc9 Jan '10 - 22:36 
How to Host multiple ActiveX controls in one container with ActiveXContainerImpl?   Thank you!   CI
GeneralRe: Host multiple ActiveX controlsmembercrystalicetpmc10 Jan '10 - 1:52 
Success to Hostting multiple Sliverlight in Dialog.
Thank you very much for your WSilverlightHost Sample!
 
test

Questionport to WinCE ?memberchristophegr31110 Dec '09 - 23:56 
mentionned in the release notes, but not present in the project. Do you plan to publish an updated project for WM5 or WM6.x ? Thanks
AnswerRe: port to WinCE ?memberErnest Laurentin11 Dec '09 - 3:23 
Hi Christopher, Not at the moment but the steps are the same as long you are using ATL/WTL. Cheers   Try not to become a man of success but rather to become a man of value. - Albert Einstein Ernest Laurentin
QuestionWhy the maindlg will not receive WM_CTLCOLORDLG message?memberkcynic26 Nov '09 - 0:02 
I compile WMediaPlayer project, I add WM_CTLCOLORDLG handler for CMainDlg, but it will not be fired.
QuestionCan't compile [modified]membertanya_kuraeva5 Oct '09 - 2:22 
I've got error while include atlapp.h; may be I didn't understand something.. Can you explain how it's work and how can I use it in WinForm application   modified on Monday, October 5, 2009 10:32 AM
AnswerRe: Can't compilememberErnest Laurentin5 Oct '09 - 5:33 
You will need WTL. This is not .NET solution for C++ http://sourceforge.net/project/shownotes.php?release_id=680959[^]   Try not to become a man of success but rather to become a man of value. - Albert Einstein Ernest Laurentin
QuestionWhy exception in WSilverlightPlayer.exe ?membercrystalicetpmc26 Sep '09 - 17:44 
WSilverlightPlayer.exe with 0x511af0b5 exception : 0xC0000005: read position 0x511af0b5 access exception   CI

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 5 Mar 2009
Article Copyright 2009 by Ernest Laurentin
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid