Rating:
Igor Makarov (view profile) July 11, 2006 |
Environment: Visual C++ 6.0
This article illustrates the implementation of a simple OLE container that is used to host a transparent or windowed Flash Player Object. The simplest OLE control implementation for an ActiveX object should consist of several interfaces: My implementation of the OLE container is called COleContainerWnd. It is declared as in the following: where TObj is the desired interface of an ActiveX object. Importing the Flash Object into VC++ is done by using the #import command: The named_guids directive is used to generate a CLSID_ShockwaveFlash class ID. If you are running under Windows 2000, change the system folder to "winnt". As a result of the #import command, the compiler will generate the flash.tli and flash.tlh files. They contain your Flash Player interface declarations. This class is based on COleContainer and uses ShockwaveFlashObjects:IShockwaveFlash as the template parameter: It also implements the _IShockwaveFlashEvents interface to receive fscommand() events from the Flash movie. The creation of CFlashWnd object: The first parameter is the class ID of the Flash Player Object. The second parameter is the extended window style; it should be set to WS_EX_LAYERED for transparent Flash control and 0 for non-transparent. The third is the window style, followed by the owner window and application instance. The HWND handle for the OLE container can be retrieved by using the GetHWND() function. First, the window class is registered. Then, the window with your specified styles is created. The OleCreate function creates an instance of an IOleObject object. It passes COleContainer's IOleClientSite and IStorage to the IOleObject object. Then, the OleSetContainedObject is called to inform the object of its embedded state. TheIShockwaveFlash interface is obtained from IOleObject by using QueryInterface. IViewObjectEx is obtained in the same way. If a windowless control is created, the container needs the IOleInPlaceObjectWindowless interface to dispatch messages to the object because the object does not have its own window. In another case, the IOleInPlaceObject interface is required to draw the object. IOleObject::DoVerb() is used to show the object and switch it to its running state. Now, the Flash Player object is fully created. It is not quite trivial to draw semitransparent translucent windows. The algorithm is the following: To render Flash player contents, I use the OleDraw helper function. It internally calls the IViewObject::Draw() method: The DVASPECT_TRANSPARENT drawing aspect tells the object to draw its content using alpha blending. When implementing this, I met a serious bug in Flash Player Control 8. This bug is only in this version. Players 7 and 9 are free of it. The bug is in the way Flash Control fills the alpha channel of a 32-bit device context. If at least 1 of 255 alpha values is applied to a pixel, the colors are mixed correctly, but the resulting alpha channel is set to 255, even if it was initially zero. This makes it impossible to create semitransparent windows. So, I had to develop a solution to fix this bug. The solution is quite simple. These equations are used by the Flash Player Control for alpha blending: If I draw the contents of Flash onto a black surface, I get the following: If I draw the contents of Flash onto a white surface, I get this: Here is the system of equations: where alpha and Rsrc are unknown. After solving it, you will get: So, the solution is found. Now, you can draw the contents of the Flash player twice and then correct the spoiled alpha channel. Flash Control Events are handled by using IDispatch. After the Flash control is created, you retrieve a IConnectionPointContainer and try to find DIID__IShockwaveFlashEvents' connection point: After a successful Advise(), you will receive events in the IDispatch::Invoke method. About the Author DownloadsPart 1. OLE Interfaces
(continued)
template<class TObj> class COleContainerWnd :
virtual public IOleClientSite,
virtual public IOleInPlaceSiteWindowless,
virtual public IOleInPlaceFrame,
virtual public IStorage
Part 2. Flash Object
#import "c:\\windows\\system32\\macromed\\flash\\flash.ocx" named_guids
Part 3. CFlashWnd Derivative Class
class CFlashWnd :
public COleContainerWnd<ShockwaveFlashObjects::IShockwaveFlash>,
public ShockwaveFlashObjects::_IShockwaveFlashEvents
g_flashWnd = new CFlashWnd;
g_flashWnd->Create(ShockwaveFlashObjects::CLSID_ShockwaveFlash,
WS_EX_LAYERED, WS_POPUP | WS_VISIBLE |
WS_CLIPSIBLINGS, g_hWnd, g_hInst);
Part 4. Inside CFlashWnd::Create()
hr = m_lpO->DoVerb(OLEIVERB_SHOW, NULL, (IOleClientSite *)this,
0, NULL, NULL);
Part 5. Transparent Window Drawing
hr = OleDraw(lpV, DVASPECT_TRANSPARENT, hdcDraw, &rTotal);
Part 6. Events
hr = m_lpControl->QueryInterface(IID_IConnectionPointContainer,
(void**)&m_lpConCont);
if (FAILED(hr))
return FALSE;
hr = m_lpConCont->FindConnectionPoint(
ShockwaveFlashObjects::DIID__IShockwaveFlashEvents, &m_lpConPoint);
if (FAILED(hr))
return FALSE;
hr = m_lpConPoint->Advise((ShockwaveFlashObjects::
_IShockwaveFlashEvents *)this,
&m_dwConPointID);
if (FAILED(hr))
return FALSE;
Senior Visual C++ developer.
'ActiveX' 카테고리의 다른 글
팝업 블로커 - 코드프로젝트 참조.... 분석할 점이 많다. 레지스트리 등록 등 (0) | 2008.09.17 |
---|---|
고급 액티브X 컨트롤에 도전하자 (1) | 2008.09.14 |
ActiveX Server Component with ATL/MFC (1) | 2008.09.08 |
IE에서의 액티브X 컨트롤 (1) | 2008.09.07 |
MDSN 액티브X 한글 매뉴얼 (0) | 2008.09.07 |
액티브X 생성에서 배포까지 (5) | 2008.09.06 |
웹페이지 바탕화면 바로가기 만들기 - 간단한 activex 이용 (1) | 2008.08.30 |