1 /*****************************************************************************
2 * plugin.cpp: ActiveX control for VLC
3 *****************************************************************************
4 * Copyright (C) 2006 the VideoLAN team
6 * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
25 #include "oleobject.h"
26 #include "olecontrol.h"
27 #include "oleinplaceobject.h"
28 #include "oleinplaceactiveobject.h"
29 #include "persistpropbag.h"
30 #include "persiststreaminit.h"
31 #include "persiststorage.h"
32 #include "provideclassinfo.h"
33 #include "connectioncontainer.h"
34 #include "objectsafety.h"
35 #include "vlccontrol.h"
36 #include "vlccontrol2.h"
37 #include "viewobject.h"
38 #include "dataobject.h"
39 #include "supporterrorinfo.h"
52 ////////////////////////////////////////////////////////////////////////
55 static LRESULT CALLBACK
VLCInPlaceClassWndProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
) {
56 VLCPlugin
*p_instance
= reinterpret_cast<VLCPlugin
*>(GetWindowLongPtr(hWnd
, GWLP_USERDATA
));
66 if( GetUpdateRect(hWnd
, &pr
, FALSE
) )
69 GetClientRect(hWnd
, &bounds
);
70 BeginPaint(hWnd
, &ps
);
71 p_instance
->onPaint(ps
.hdc
, bounds
, pr
);
77 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
81 VLCPluginClass::VLCPluginClass(LONG
*p_class_ref
, HINSTANCE hInstance
, REFCLSID rclsid
) :
82 _p_class_ref(p_class_ref
),
83 _hinstance(hInstance
),
85 _inplace_picture(NULL
)
89 if( ! GetClassInfo(hInstance
, getInPlaceWndClassName(), &wClass
) )
91 wClass
.style
= CS_NOCLOSE
|CS_DBLCLKS
;
92 wClass
.lpfnWndProc
= VLCInPlaceClassWndProc
;
93 wClass
.cbClsExtra
= 0;
94 wClass
.cbWndExtra
= 0;
95 wClass
.hInstance
= hInstance
;
97 wClass
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
98 wClass
.hbrBackground
= NULL
;
99 wClass
.lpszMenuName
= NULL
;
100 wClass
.lpszClassName
= getInPlaceWndClassName();
102 _inplace_wndclass_atom
= RegisterClass(&wClass
);
106 _inplace_wndclass_atom
= 0;
109 HBITMAP hbitmap
= (HBITMAP
)LoadImage(getHInstance(), MAKEINTRESOURCE(2), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
110 if( NULL
!= hbitmap
)
114 pictDesc
.cbSizeofstruct
= sizeof(PICTDESC
);
115 pictDesc
.picType
= PICTYPE_BITMAP
;
116 pictDesc
.bmp
.hbitmap
= hbitmap
;
117 pictDesc
.bmp
.hpal
= NULL
;
119 if( FAILED(OleCreatePictureIndirect(&pictDesc
, IID_IPicture
, TRUE
, reinterpret_cast<LPVOID
*>(&_inplace_picture
))) )
120 _inplace_picture
= NULL
;
125 VLCPluginClass::~VLCPluginClass()
127 if( 0 != _inplace_wndclass_atom
)
128 UnregisterClass(MAKEINTATOM(_inplace_wndclass_atom
), _hinstance
);
130 if( NULL
!= _inplace_picture
)
131 _inplace_picture
->Release();
134 STDMETHODIMP
VLCPluginClass::QueryInterface(REFIID riid
, void **ppv
)
139 if( (IID_IUnknown
== riid
)
140 || (IID_IClassFactory
== riid
) )
143 *ppv
= reinterpret_cast<LPVOID
>(this);
150 return E_NOINTERFACE
;
153 STDMETHODIMP_(ULONG
) VLCPluginClass::AddRef(void)
155 return InterlockedIncrement(_p_class_ref
);
158 STDMETHODIMP_(ULONG
) VLCPluginClass::Release(void)
160 ULONG refcount
= InterlockedDecrement(_p_class_ref
);
169 STDMETHODIMP
VLCPluginClass::CreateInstance(LPUNKNOWN pUnkOuter
, REFIID riid
, void **ppv
)
176 if( (NULL
!= pUnkOuter
) && (IID_IUnknown
!= riid
) ) {
177 return CLASS_E_NOAGGREGATION
;
180 VLCPlugin
*plugin
= new VLCPlugin(this, pUnkOuter
);
183 HRESULT hr
= plugin
->QueryInterface(riid
, ppv
);
184 // the following will destroy the object if QueryInterface() failed
188 return E_OUTOFMEMORY
;
191 STDMETHODIMP
VLCPluginClass::LockServer(BOOL fLock
)
201 ////////////////////////////////////////////////////////////////////////
203 VLCPlugin::VLCPlugin(VLCPluginClass
*p_class
, LPUNKNOWN pUnkOuter
) :
213 vlcOleControl
= new VLCOleControl(this);
214 vlcOleInPlaceObject
= new VLCOleInPlaceObject(this);
215 vlcOleInPlaceActiveObject
= new VLCOleInPlaceActiveObject(this);
216 vlcPersistStorage
= new VLCPersistStorage(this);
217 vlcPersistStreamInit
= new VLCPersistStreamInit(this);
218 vlcPersistPropertyBag
= new VLCPersistPropertyBag(this);
219 vlcProvideClassInfo
= new VLCProvideClassInfo(this);
220 vlcConnectionPointContainer
= new VLCConnectionPointContainer(this);
221 vlcObjectSafety
= new VLCObjectSafety(this);
222 vlcControl
= new VLCControl(this);
223 vlcControl2
= new VLCControl2(this);
224 vlcViewObject
= new VLCViewObject(this);
225 vlcDataObject
= new VLCDataObject(this);
226 vlcOleObject
= new VLCOleObject(this);
227 vlcSupportErrorInfo
= new VLCSupportErrorInfo(this);
229 // configure controlling IUnknown interface for implemented interfaces
230 this->pUnkOuter
= (NULL
!= pUnkOuter
) ? pUnkOuter
: dynamic_cast<LPUNKNOWN
>(this);
233 _p_pict
= p_class
->getInPlacePict();
235 // make sure that persistable properties are initialized
239 VLCPlugin::~VLCPlugin()
242 ** bump refcount to avoid recursive release from
243 ** following interfaces when releasing this interface
247 delete vlcSupportErrorInfo
;
249 delete vlcDataObject
;
250 delete vlcViewObject
;
253 delete vlcConnectionPointContainer
;
254 delete vlcProvideClassInfo
;
255 delete vlcPersistPropertyBag
;
256 delete vlcPersistStreamInit
;
257 delete vlcPersistStorage
;
258 delete vlcOleInPlaceActiveObject
;
259 delete vlcOleInPlaceObject
;
260 delete vlcObjectSafety
;
262 delete vlcOleControl
;
266 SysFreeString(_bstr_mrl
);
267 SysFreeString(_bstr_baseurl
);
272 STDMETHODIMP
VLCPlugin::QueryInterface(REFIID riid
, void **ppv
)
277 if( IID_IUnknown
== riid
)
278 *ppv
= reinterpret_cast<LPVOID
>(this);
279 else if( IID_IOleObject
== riid
)
280 *ppv
= reinterpret_cast<LPVOID
>(vlcOleObject
);
281 else if( IID_IOleControl
== riid
)
282 *ppv
= reinterpret_cast<LPVOID
>(vlcOleControl
);
283 else if( IID_IOleWindow
== riid
)
284 *ppv
= reinterpret_cast<LPVOID
>(vlcOleInPlaceObject
);
285 else if( IID_IOleInPlaceObject
== riid
)
286 *ppv
= reinterpret_cast<LPVOID
>(vlcOleInPlaceObject
);
287 else if( IID_IOleInPlaceActiveObject
== riid
)
288 *ppv
= reinterpret_cast<LPVOID
>(vlcOleInPlaceActiveObject
);
289 else if( IID_IPersist
== riid
)
290 *ppv
= reinterpret_cast<LPVOID
>(vlcPersistStreamInit
);
291 else if( IID_IPersistStreamInit
== riid
)
292 *ppv
= reinterpret_cast<LPVOID
>(vlcPersistStreamInit
);
293 else if( IID_IPersistStorage
== riid
)
294 *ppv
= reinterpret_cast<LPVOID
>(vlcPersistStorage
);
295 else if( IID_IPersistPropertyBag
== riid
)
296 *ppv
= reinterpret_cast<LPVOID
>(vlcPersistPropertyBag
);
297 else if( IID_IProvideClassInfo
== riid
)
298 *ppv
= reinterpret_cast<LPVOID
>(vlcProvideClassInfo
);
299 else if( IID_IProvideClassInfo2
== riid
)
300 *ppv
= reinterpret_cast<LPVOID
>(vlcProvideClassInfo
);
301 else if( IID_IConnectionPointContainer
== riid
)
302 *ppv
= reinterpret_cast<LPVOID
>(vlcConnectionPointContainer
);
303 else if( IID_IObjectSafety
== riid
)
304 *ppv
= reinterpret_cast<LPVOID
>(vlcObjectSafety
);
305 else if( IID_IDispatch
== riid
)
306 *ppv
= (CLSID_VLCPlugin2
== getClassID()) ?
307 reinterpret_cast<LPVOID
>(vlcControl2
) :
308 reinterpret_cast<LPVOID
>(vlcControl
);
309 else if( IID_IVLCControl
== riid
)
310 *ppv
= reinterpret_cast<LPVOID
>(vlcControl
);
311 else if( IID_IVLCControl2
== riid
)
312 *ppv
= reinterpret_cast<LPVOID
>(vlcControl2
);
313 else if( IID_IViewObject
== riid
)
314 *ppv
= reinterpret_cast<LPVOID
>(vlcViewObject
);
315 else if( IID_IViewObject2
== riid
)
316 *ppv
= reinterpret_cast<LPVOID
>(vlcViewObject
);
317 else if( IID_IDataObject
== riid
)
318 *ppv
= reinterpret_cast<LPVOID
>(vlcDataObject
);
319 else if( IID_ISupportErrorInfo
== riid
)
320 *ppv
= reinterpret_cast<LPVOID
>(vlcSupportErrorInfo
);
324 return E_NOINTERFACE
;
326 ((LPUNKNOWN
)*ppv
)->AddRef();
330 STDMETHODIMP_(ULONG
) VLCPlugin::AddRef(void)
332 return InterlockedIncrement((LONG
*)&_i_ref
);
335 STDMETHODIMP_(ULONG
) VLCPlugin::Release(void)
337 if( ! InterlockedDecrement((LONG
*)&_i_ref
) )
345 //////////////////////////////////////
347 HRESULT
VLCPlugin::onInit(void)
349 if( NULL
== _p_libvlc
)
351 // initialize persistable properties
355 _bstr_baseurl
= NULL
;
362 // set default/preferred size (320x240) pixels in HIMETRIC
363 HDC hDC
= CreateDevDC(NULL
);
366 HimetricFromDP(hDC
, (LPPOINT
)&_extent
, 1);
371 return CO_E_ALREADYINITIALIZED
;
374 HRESULT
VLCPlugin::onLoad(void)
376 if( SysStringLen(_bstr_baseurl
) == 0 )
379 ** try to retreive the base URL using the client site moniker, which for Internet Explorer
380 ** is the URL of the page the plugin is embedded into.
382 LPOLECLIENTSITE pClientSite
;
383 if( SUCCEEDED(vlcOleObject
->GetClientSite(&pClientSite
)) && (NULL
!= pClientSite
) )
386 if( SUCCEEDED(CreateBindCtx(0, &pBC
)) )
388 LPMONIKER pContMoniker
= NULL
;
389 if( SUCCEEDED(pClientSite
->GetMoniker(OLEGETMONIKER_ONLYIFTHERE
,
390 OLEWHICHMK_CONTAINER
, &pContMoniker
)) )
393 if( SUCCEEDED(pContMoniker
->GetDisplayName(pBC
, NULL
, &base_url
)) )
396 ** check that the moniker name is a URL
398 if( UrlIsW(base_url
, URLIS_URL
) )
401 _bstr_baseurl
= SysAllocString(base_url
);
403 CoTaskMemFree(base_url
);
413 HRESULT
VLCPlugin::getVLC(libvlc_instance_t
** pp_libvlc
)
415 extern HMODULE
DllGetModule();
420 ** default initialization options
422 const char *ppsz_argv
[32] = { };
425 char p_progpath
[MAX_PATH
];
427 TCHAR w_progpath
[MAX_PATH
];
428 DWORD len
= GetModuleFileName(DllGetModule(), w_progpath
, MAX_PATH
);
431 len
= WideCharToMultiByte(CP_UTF8
, 0, w_progpath
, len
, p_progpath
,
432 sizeof(p_progpath
)-1, NULL
, NULL
);
435 p_progpath
[len
] = '\0';
436 ppsz_argv
[0] = p_progpath
;
441 ppsz_argv
[ppsz_argc
++] = "-vv";
444 char p_pluginpath
[MAX_PATH
];
445 if( RegOpenKeyEx( HKEY_LOCAL_MACHINE
, TEXT("Software\\VideoLAN\\VLC"),
446 0, KEY_READ
, &h_key
) == ERROR_SUCCESS
)
448 DWORD i_type
, i_data
= MAX_PATH
;
449 TCHAR w_pluginpath
[MAX_PATH
];
450 if( RegQueryValueEx( h_key
, TEXT("InstallDir"), 0, &i_type
,
451 (LPBYTE
)w_pluginpath
, &i_data
) == ERROR_SUCCESS
)
453 if( i_type
== REG_SZ
)
455 if( WideCharToMultiByte(CP_UTF8
, 0, w_pluginpath
, -1, p_pluginpath
,
456 sizeof(p_pluginpath
)-sizeof("\\plugins")+1, NULL
, NULL
) )
458 strcat( p_pluginpath
, "\\plugins" );
459 ppsz_argv
[ppsz_argc
++] = "--plugin-path";
460 ppsz_argv
[ppsz_argc
++] = p_pluginpath
;
464 RegCloseKey( h_key
);
467 // make sure plugin isn't affected with VLC single instance mode
468 ppsz_argv
[ppsz_argc
++] = "--no-one-instance";
470 /* common settings */
471 ppsz_argv
[ppsz_argc
++] = "--no-stats";
472 ppsz_argv
[ppsz_argc
++] = "--no-media-library";
473 ppsz_argv
[ppsz_argc
++] = "--ignore-config";
474 ppsz_argv
[ppsz_argc
++] = "--intf=dummy";
476 // loop mode is a configuration option only
478 ppsz_argv
[ppsz_argc
++] = "--loop";
480 libvlc_exception_t ex
;
481 libvlc_exception_init(&ex
);
483 _p_libvlc
= libvlc_new(ppsz_argc
, ppsz_argv
, &ex
);
484 if( libvlc_exception_raised(&ex
) )
487 libvlc_exception_clear(&ex
);
491 // initial volume setting
492 libvlc_audio_set_volume(_p_libvlc
, _i_volume
, NULL
);
495 libvlc_audio_set_mute(_p_libvlc
, TRUE
, NULL
);
498 // initial playlist item
499 if( SysStringLen(_bstr_mrl
) > 0 )
501 char *psz_mrl
= NULL
;
503 if( SysStringLen(_bstr_baseurl
) > 0 )
506 ** if the MRL a relative URL, we should end up with an absolute URL
508 LPWSTR abs_url
= CombineURL(_bstr_baseurl
, _bstr_mrl
);
509 if( NULL
!= abs_url
)
511 psz_mrl
= CStrFromWSTR(CP_UTF8
, abs_url
, wcslen(abs_url
));
512 CoTaskMemFree(abs_url
);
516 psz_mrl
= CStrFromBSTR(CP_UTF8
, _bstr_mrl
);
522 ** baseURL is empty, assume MRL is absolute
524 psz_mrl
= CStrFromBSTR(CP_UTF8
, _bstr_mrl
);
526 if( NULL
!= psz_mrl
)
528 const char *options
[1];
534 snprintf(timeBuffer
, sizeof(timeBuffer
), ":start-time=%d", _i_time
);
535 options
[i_options
++] = timeBuffer
;
537 // add default target to playlist
538 libvlc_playlist_add_extended(_p_libvlc
, psz_mrl
, NULL
, i_options
, options
, NULL
);
539 CoTaskMemFree(psz_mrl
);
543 *pp_libvlc
= _p_libvlc
;
547 void VLCPlugin::setErrorInfo(REFIID riid
, const char *description
)
549 vlcSupportErrorInfo
->setErrorInfo( getClassID() == CLSID_VLCPlugin2
?
550 OLESTR("VideoLAN.VLCPlugin.2") : OLESTR("VideoLAN.VLCPlugin.1"),
554 HRESULT
VLCPlugin::onAmbientChanged(LPUNKNOWN pContainer
, DISPID dispID
)
559 case DISPID_AMBIENT_BACKCOLOR
:
562 if( SUCCEEDED(GetObjectProperty(pContainer
, dispID
, v
)) )
564 setBackColor(V_I4(&v
));
567 case DISPID_AMBIENT_DISPLAYNAME
:
569 case DISPID_AMBIENT_FONT
:
571 case DISPID_AMBIENT_FORECOLOR
:
573 case DISPID_AMBIENT_LOCALEID
:
575 case DISPID_AMBIENT_MESSAGEREFLECT
:
577 case DISPID_AMBIENT_SCALEUNITS
:
579 case DISPID_AMBIENT_TEXTALIGN
:
581 case DISPID_AMBIENT_USERMODE
:
584 if( SUCCEEDED(GetObjectProperty(pContainer
, dispID
, v
)) )
586 setUserMode(V_BOOL(&v
) != VARIANT_FALSE
);
589 case DISPID_AMBIENT_UIDEAD
:
591 case DISPID_AMBIENT_SHOWGRABHANDLES
:
593 case DISPID_AMBIENT_SHOWHATCHING
:
595 case DISPID_AMBIENT_DISPLAYASDEFAULT
:
597 case DISPID_AMBIENT_SUPPORTSMNEMONICS
:
599 case DISPID_AMBIENT_AUTOCLIP
:
601 case DISPID_AMBIENT_APPEARANCE
:
603 case DISPID_AMBIENT_CODEPAGE
:
606 if( SUCCEEDED(GetObjectProperty(pContainer
, dispID
, v
)) )
608 setCodePage(V_I4(&v
));
611 case DISPID_AMBIENT_PALETTE
:
613 case DISPID_AMBIENT_CHARSET
:
615 case DISPID_AMBIENT_RIGHTTOLEFT
:
617 case DISPID_AMBIENT_TOPTOBOTTOM
:
621 ** multiple property change, look up the ones we are interested in
625 if( SUCCEEDED(GetObjectProperty(pContainer
, DISPID_AMBIENT_USERMODE
, v
)) )
627 setUserMode(V_BOOL(&v
) != VARIANT_FALSE
);
631 if( SUCCEEDED(GetObjectProperty(pContainer
, DISPID_AMBIENT_CODEPAGE
, v
)) )
633 setCodePage(V_I4(&v
));
640 HRESULT
VLCPlugin::onClose(DWORD dwSaveOption
)
642 if( isInPlaceActive() )
644 onInPlaceDeactivate();
648 libvlc_instance_t
* p_libvlc
= _p_libvlc
;
651 if( SUCCEEDED(vlcControl2
->get_log(&p_log
)) )
653 // make sure the log is disabled
654 p_log
->put_verbosity(-1);
659 vlcDataObject
->onClose();
662 libvlc_release(p_libvlc
);
667 BOOL
VLCPlugin::isInPlaceActive(void)
669 return (NULL
!= _inplacewnd
);
672 HRESULT
VLCPlugin::onActivateInPlace(LPMSG lpMesg
, HWND hwndParent
, LPCRECT lprcPosRect
, LPCRECT lprcClipRect
)
674 RECT clipRect
= *lprcClipRect
;
677 ** record keeping of control geometry within container
679 _posRect
= *lprcPosRect
;
682 ** Create a window for in place activated control.
683 ** the window geometry matches the control viewport
684 ** within container so that embedded video is always
685 ** properly displayed.
687 _inplacewnd
= CreateWindow(_p_class
->getInPlaceWndClassName(),
688 TEXT("VLC Plugin In-Place Window"),
689 WS_CHILD
|WS_CLIPCHILDREN
|WS_CLIPSIBLINGS
,
692 lprcPosRect
->right
-lprcPosRect
->left
,
693 lprcPosRect
->bottom
-lprcPosRect
->top
,
696 _p_class
->getHInstance(),
700 if( NULL
== _inplacewnd
)
703 SetWindowLongPtr(_inplacewnd
, GWLP_USERDATA
, reinterpret_cast<LONG_PTR
>(this));
705 /* change cliprect coordinates system relative to window bounding rect */
706 OffsetRect(&clipRect
, -lprcPosRect
->left
, -lprcPosRect
->top
);
708 HRGN clipRgn
= CreateRectRgnIndirect(&clipRect
);
709 SetWindowRgn(_inplacewnd
, clipRgn
, TRUE
);
713 /* will run vlc if not done already */
714 libvlc_instance_t
* p_libvlc
;
715 HRESULT result
= getVLC(&p_libvlc
);
719 /* set internal video width and height */
720 libvlc_video_set_size(p_libvlc
,
721 lprcPosRect
->right
-lprcPosRect
->left
,
722 lprcPosRect
->bottom
-lprcPosRect
->top
,
725 /* set internal video parent window */
726 libvlc_video_set_parent(p_libvlc
,
727 reinterpret_cast<libvlc_drawable_t
>(_inplacewnd
), NULL
);
729 if( _b_autoplay
& (libvlc_playlist_items_count(p_libvlc
, NULL
) > 0) )
731 libvlc_playlist_play(p_libvlc
, 0, 0, NULL
, NULL
);
737 ShowWindow(_inplacewnd
, SW_SHOW
);
742 HRESULT
VLCPlugin::onInPlaceDeactivate(void)
746 libvlc_playlist_stop(_p_libvlc
, NULL
);
750 DestroyWindow(_inplacewnd
);
756 void VLCPlugin::setVisible(BOOL fVisible
)
758 if( fVisible
!= _b_visible
)
760 _b_visible
= fVisible
;
761 if( isInPlaceActive() )
763 ShowWindow(_inplacewnd
, fVisible
? SW_SHOW
: SW_HIDE
);
765 InvalidateRect(_inplacewnd
, NULL
, TRUE
);
768 firePropChangedEvent(DISPID_Visible
);
772 void VLCPlugin::setVolume(int volume
)
776 else if( volume
> 200 )
779 if( volume
!= _i_volume
)
784 libvlc_audio_set_volume(_p_libvlc
, _i_volume
, NULL
);
790 void VLCPlugin::setBackColor(OLE_COLOR backcolor
)
792 if( _i_backcolor
!= backcolor
)
794 _i_backcolor
= backcolor
;
795 if( isInPlaceActive() )
803 void VLCPlugin::setTime(int seconds
)
808 if( seconds
!= _i_time
)
810 setStartTime(_i_time
);
813 libvlc_media_player_t
*p_md
= libvlc_playlist_get_media_player(_p_libvlc
, NULL
);
816 libvlc_media_player_set_time(p_md
, _i_time
, NULL
);
817 libvlc_media_player_release(p_md
);
823 void VLCPlugin::setFocus(BOOL fFocus
)
826 SetActiveWindow(_inplacewnd
);
829 BOOL
VLCPlugin::hasFocus(void)
831 return GetActiveWindow() == _inplacewnd
;
834 void VLCPlugin::onDraw(DVTARGETDEVICE
* ptd
, HDC hicTargetDev
,
835 HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
)
839 long width
= lprcBounds
->right
-lprcBounds
->left
;
840 long height
= lprcBounds
->bottom
-lprcBounds
->top
;
842 RECT bounds
= { lprcBounds
->left
, lprcBounds
->top
, lprcBounds
->right
, lprcBounds
->bottom
};
846 /* VLC is in user mode, just draw background color */
847 COLORREF colorref
= RGB(0, 0, 0);
848 OleTranslateColor(_i_backcolor
, (HPALETTE
)GetStockObject(DEFAULT_PALETTE
), &colorref
);
849 if( colorref
!= RGB(0, 0, 0) )
851 /* custom background */
852 HBRUSH colorbrush
= CreateSolidBrush(colorref
);
853 FillRect(hdcDraw
, &bounds
, colorbrush
);
854 DeleteObject((HANDLE
)colorbrush
);
858 /* black background */
859 FillRect(hdcDraw
, &bounds
, (HBRUSH
)GetStockObject(BLACK_BRUSH
));
864 /* VLC is in design mode, draw the VLC logo */
865 FillRect(hdcDraw
, &bounds
, (HBRUSH
)GetStockObject(WHITE_BRUSH
));
867 LPPICTURE pict
= getPicture();
870 OLE_XSIZE_HIMETRIC picWidth
;
871 OLE_YSIZE_HIMETRIC picHeight
;
873 pict
->get_Width(&picWidth
);
874 pict
->get_Height(&picHeight
);
876 SIZEL picSize
= { picWidth
, picHeight
};
878 if( NULL
!= hicTargetDev
)
880 DPFromHimetric(hicTargetDev
, (LPPOINT
)&picSize
, 1);
882 else if( NULL
!= (hicTargetDev
= CreateDevDC(ptd
)) )
884 DPFromHimetric(hicTargetDev
, (LPPOINT
)&picSize
, 1);
885 DeleteDC(hicTargetDev
);
888 if( picSize
.cx
> width
-4 )
889 picSize
.cx
= width
-4;
890 if( picSize
.cy
> height
-4 )
891 picSize
.cy
= height
-4;
893 LONG dstX
= lprcBounds
->left
+(width
-picSize
.cx
)/2;
894 LONG dstY
= lprcBounds
->top
+(height
-picSize
.cy
)/2;
896 if( NULL
!= lprcWBounds
)
898 RECT wBounds
= { lprcWBounds
->left
, lprcWBounds
->top
, lprcWBounds
->right
, lprcWBounds
->bottom
};
899 pict
->Render(hdcDraw
, dstX
, dstY
, picSize
.cx
, picSize
.cy
,
900 0L, picHeight
, picWidth
, -picHeight
, &wBounds
);
903 pict
->Render(hdcDraw
, dstX
, dstY
, picSize
.cx
, picSize
.cy
,
904 0L, picHeight
, picWidth
, -picHeight
, NULL
);
909 SelectObject(hdcDraw
, GetStockObject(BLACK_BRUSH
));
911 MoveToEx(hdcDraw
, bounds
.left
, bounds
.top
, NULL
);
912 LineTo(hdcDraw
, bounds
.left
+width
-1, bounds
.top
);
913 LineTo(hdcDraw
, bounds
.left
+width
-1, bounds
.top
+height
-1);
914 LineTo(hdcDraw
, bounds
.left
, bounds
.top
+height
-1);
915 LineTo(hdcDraw
, bounds
.left
, bounds
.top
);
920 void VLCPlugin::onPaint(HDC hdc
, const RECT
&bounds
, const RECT
&clipRect
)
924 /* if VLC is in design mode, draw control logo */
925 HDC hdcDraw
= CreateCompatibleDC(hdc
);
926 if( NULL
!= hdcDraw
)
928 SIZEL size
= getExtent();
929 DPFromHimetric(hdc
, (LPPOINT
)&size
, 1);
930 RECTL posRect
= { 0, 0, size
.cx
, size
.cy
};
932 int width
= bounds
.right
-bounds
.left
;
933 int height
= bounds
.bottom
-bounds
.top
;
935 HBITMAP hBitmap
= CreateCompatibleBitmap(hdc
, width
, height
);
936 if( NULL
!= hBitmap
)
938 HBITMAP oldBmp
= (HBITMAP
)SelectObject(hdcDraw
, hBitmap
);
940 if( (size
.cx
!= width
) || (size
.cy
!= height
) )
942 // needs to scale canvas
943 SetMapMode(hdcDraw
, MM_ANISOTROPIC
);
944 SetWindowExtEx(hdcDraw
, size
.cx
, size
.cy
, NULL
);
945 SetViewportExtEx(hdcDraw
, width
, height
, NULL
);
948 onDraw(NULL
, hdc
, hdcDraw
, &posRect
, NULL
);
950 SetMapMode(hdcDraw
, MM_TEXT
);
951 BitBlt(hdc
, bounds
.left
, bounds
.top
,
956 SelectObject(hdcDraw
, oldBmp
);
957 DeleteObject(hBitmap
);
964 void VLCPlugin::onPositionChange(LPCRECT lprcPosRect
, LPCRECT lprcClipRect
)
966 RECT clipRect
= *lprcClipRect
;
968 //RedrawWindow(GetParent(_inplacewnd), &_posRect, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN);
971 ** record keeping of control geometry within container
973 _posRect
= *lprcPosRect
;
976 ** change in-place window geometry to match clipping region
978 SetWindowPos(_inplacewnd
, NULL
,
981 lprcPosRect
->right
-lprcPosRect
->left
,
982 lprcPosRect
->bottom
-lprcPosRect
->top
,
988 /* change cliprect coordinates system relative to window bounding rect */
989 OffsetRect(&clipRect
, -lprcPosRect
->left
, -lprcPosRect
->top
);
990 HRGN clipRgn
= CreateRectRgnIndirect(&clipRect
);
991 SetWindowRgn(_inplacewnd
, clipRgn
, FALSE
);
993 //RedrawWindow(_videownd, &posRect, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN);
996 libvlc_video_set_size(_p_libvlc
,
997 lprcPosRect
->right
-lprcPosRect
->left
,
998 lprcPosRect
->bottom
-lprcPosRect
->top
,
1003 void VLCPlugin::freezeEvents(BOOL freeze
)
1005 vlcConnectionPointContainer
->freezeEvents(freeze
);
1008 void VLCPlugin::firePropChangedEvent(DISPID dispid
)
1010 vlcConnectionPointContainer
->firePropChangedEvent(dispid
);
1013 void VLCPlugin::fireOnPlayEvent(void)
1015 DISPPARAMS dispparamsNoArgs
= {NULL
, NULL
, 0, 0};
1016 vlcConnectionPointContainer
->fireEvent(DISPID_PlayEvent
, &dispparamsNoArgs
);
1019 void VLCPlugin::fireOnPauseEvent(void)
1021 DISPPARAMS dispparamsNoArgs
= {NULL
, NULL
, 0, 0};
1022 vlcConnectionPointContainer
->fireEvent(DISPID_PauseEvent
, &dispparamsNoArgs
);
1025 void VLCPlugin::fireOnStopEvent(void)
1027 DISPPARAMS dispparamsNoArgs
= {NULL
, NULL
, 0, 0};
1028 vlcConnectionPointContainer
->fireEvent(DISPID_StopEvent
, &dispparamsNoArgs
);