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(), TEXT("INPLACE-PICT"), 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()
241 delete vlcSupportErrorInfo
;
243 delete vlcDataObject
;
244 delete vlcViewObject
;
247 delete vlcConnectionPointContainer
;
248 delete vlcProvideClassInfo
;
249 delete vlcPersistPropertyBag
;
250 delete vlcPersistStreamInit
;
251 delete vlcPersistStorage
;
252 delete vlcOleInPlaceActiveObject
;
253 delete vlcOleInPlaceObject
;
254 delete vlcObjectSafety
;
256 delete vlcOleControl
;
260 SysFreeString(_bstr_mrl
);
261 SysFreeString(_bstr_baseurl
);
266 STDMETHODIMP
VLCPlugin::QueryInterface(REFIID riid
, void **ppv
)
271 if( IID_IUnknown
== riid
)
272 *ppv
= reinterpret_cast<LPVOID
>(this);
273 else if( IID_IOleObject
== riid
)
274 *ppv
= reinterpret_cast<LPVOID
>(vlcOleObject
);
275 else if( IID_IOleControl
== riid
)
276 *ppv
= reinterpret_cast<LPVOID
>(vlcOleControl
);
277 else if( IID_IOleWindow
== riid
)
278 *ppv
= reinterpret_cast<LPVOID
>(vlcOleInPlaceObject
);
279 else if( IID_IOleInPlaceObject
== riid
)
280 *ppv
= reinterpret_cast<LPVOID
>(vlcOleInPlaceObject
);
281 else if( IID_IOleInPlaceActiveObject
== riid
)
282 *ppv
= reinterpret_cast<LPVOID
>(vlcOleInPlaceActiveObject
);
283 else if( IID_IPersist
== riid
)
284 *ppv
= reinterpret_cast<LPVOID
>(vlcPersistStreamInit
);
285 else if( IID_IPersistStreamInit
== riid
)
286 *ppv
= reinterpret_cast<LPVOID
>(vlcPersistStreamInit
);
287 else if( IID_IPersistStorage
== riid
)
288 *ppv
= reinterpret_cast<LPVOID
>(vlcPersistStorage
);
289 else if( IID_IPersistPropertyBag
== riid
)
290 *ppv
= reinterpret_cast<LPVOID
>(vlcPersistPropertyBag
);
291 else if( IID_IProvideClassInfo
== riid
)
292 *ppv
= reinterpret_cast<LPVOID
>(vlcProvideClassInfo
);
293 else if( IID_IProvideClassInfo2
== riid
)
294 *ppv
= reinterpret_cast<LPVOID
>(vlcProvideClassInfo
);
295 else if( IID_IConnectionPointContainer
== riid
)
296 *ppv
= reinterpret_cast<LPVOID
>(vlcConnectionPointContainer
);
297 else if( IID_IObjectSafety
== riid
)
298 *ppv
= reinterpret_cast<LPVOID
>(vlcObjectSafety
);
299 else if( IID_IDispatch
== riid
)
300 *ppv
= (CLSID_VLCPlugin2
== getClassID()) ?
301 reinterpret_cast<LPVOID
>(vlcControl2
) :
302 reinterpret_cast<LPVOID
>(vlcControl
);
303 else if( IID_IVLCControl
== riid
)
304 *ppv
= reinterpret_cast<LPVOID
>(vlcControl
);
305 else if( IID_IVLCControl2
== riid
)
306 *ppv
= reinterpret_cast<LPVOID
>(vlcControl2
);
307 else if( IID_IViewObject
== riid
)
308 *ppv
= reinterpret_cast<LPVOID
>(vlcViewObject
);
309 else if( IID_IViewObject2
== riid
)
310 *ppv
= reinterpret_cast<LPVOID
>(vlcViewObject
);
311 else if( IID_IDataObject
== riid
)
312 *ppv
= reinterpret_cast<LPVOID
>(vlcDataObject
);
313 else if( IID_ISupportErrorInfo
== riid
)
314 *ppv
= reinterpret_cast<LPVOID
>(vlcSupportErrorInfo
);
318 return E_NOINTERFACE
;
320 ((LPUNKNOWN
)*ppv
)->AddRef();
324 STDMETHODIMP_(ULONG
) VLCPlugin::AddRef(void)
326 return InterlockedIncrement((LONG
*)&_i_ref
);
329 STDMETHODIMP_(ULONG
) VLCPlugin::Release(void)
331 if( ! InterlockedDecrement((LONG
*)&_i_ref
) )
339 //////////////////////////////////////
341 HRESULT
VLCPlugin::onInit(void)
343 if( NULL
== _p_libvlc
)
345 // initialize persistable properties
348 _bstr_baseurl
= NULL
;
355 // set default/preferred size (320x240) pixels in HIMETRIC
356 HDC hDC
= CreateDevDC(NULL
);
359 HimetricFromDP(hDC
, (LPPOINT
)&_extent
, 1);
364 return CO_E_ALREADYINITIALIZED
;
367 HRESULT
VLCPlugin::onLoad(void)
369 if( SysStringLen(_bstr_baseurl
) == 0 )
372 ** try to retreive the base URL using the client site moniker, which for Internet Explorer
373 ** is the URL of the page the plugin is embedded into.
375 LPOLECLIENTSITE pClientSite
;
376 if( SUCCEEDED(vlcOleObject
->GetClientSite(&pClientSite
)) && (NULL
!= pClientSite
) )
379 if( SUCCEEDED(CreateBindCtx(0, &pBC
)) )
381 LPMONIKER pContMoniker
= NULL
;
382 if( SUCCEEDED(pClientSite
->GetMoniker(OLEGETMONIKER_ONLYIFTHERE
,
383 OLEWHICHMK_CONTAINER
, &pContMoniker
)) )
386 if( SUCCEEDED(pContMoniker
->GetDisplayName(pBC
, NULL
, &base_url
)) )
389 ** check that the moniker name is a URL
391 if( UrlIsW(base_url
, URLIS_URL
) )
394 _bstr_baseurl
= SysAllocString(base_url
);
396 CoTaskMemFree(base_url
);
406 HRESULT
VLCPlugin::getVLCObject(int* i_vlc
)
408 libvlc_instance_t
*p_libvlc
;
409 HRESULT result
= getVLC(&p_libvlc
);
410 if( SUCCEEDED(result
) )
412 *i_vlc
= libvlc_get_vlc_id(p_libvlc
);
421 HRESULT
VLCPlugin::getVLC(libvlc_instance_t
** pp_libvlc
)
423 extern HMODULE
DllGetModule();
428 ** default initialization options
430 char *ppsz_argv
[32] = { "vlc" };
433 char p_progpath
[MAX_PATH
];
435 TCHAR w_progpath
[MAX_PATH
];
436 DWORD len
= GetModuleFileName(DllGetModule(), w_progpath
, MAX_PATH
);
439 len
= WideCharToMultiByte(CP_UTF8
, 0, w_progpath
, len
, p_progpath
,
440 sizeof(p_progpath
)-1, NULL
, NULL
);
443 p_progpath
[len
] = '\0';
444 ppsz_argv
[0] = p_progpath
;
449 ppsz_argv
[ppsz_argc
++] = "-vv";
452 char p_pluginpath
[MAX_PATH
];
453 if( RegOpenKeyEx( HKEY_LOCAL_MACHINE
, TEXT("Software\\VideoLAN\\VLC"),
454 0, KEY_READ
, &h_key
) == ERROR_SUCCESS
)
456 DWORD i_type
, i_data
= MAX_PATH
;
457 TCHAR w_pluginpath
[MAX_PATH
];
458 if( RegQueryValueEx( h_key
, TEXT("InstallDir"), 0, &i_type
,
459 (LPBYTE
)w_pluginpath
, &i_data
) == ERROR_SUCCESS
)
461 if( i_type
== REG_SZ
)
463 if( WideCharToMultiByte(CP_UTF8
, 0, w_pluginpath
, -1, p_pluginpath
,
464 sizeof(p_pluginpath
)-sizeof("\\plugins")+1, NULL
, NULL
) )
466 strcat( p_pluginpath
, "\\plugins" );
467 ppsz_argv
[ppsz_argc
++] = "--plugin-path";
468 ppsz_argv
[ppsz_argc
++] = p_pluginpath
;
472 RegCloseKey( h_key
);
475 // make sure plugin isn't affected with VLC single instance mode
476 ppsz_argv
[ppsz_argc
++] = "--no-one-instance";
478 /* common settings */
479 ppsz_argv
[ppsz_argc
++] = "--no-stats";
480 ppsz_argv
[ppsz_argc
++] = "--no-media-library";
481 ppsz_argv
[ppsz_argc
++] = "--intf=dummy";
483 // loop mode is a configuration option only
485 ppsz_argv
[ppsz_argc
++] = "--loop";
487 _p_libvlc
= libvlc_new(ppsz_argc
, ppsz_argv
, NULL
);
488 if( NULL
== _p_libvlc
)
494 // initial volume setting
495 libvlc_audio_set_volume(_p_libvlc
, _i_volume
, NULL
);
498 libvlc_audio_set_mute(_p_libvlc
, TRUE
, NULL
);
501 // initial playlist item
502 if( SysStringLen(_bstr_mrl
) > 0 )
504 char *psz_mrl
= NULL
;
506 if( SysStringLen(_bstr_baseurl
) > 0 )
509 ** if the MRL a relative URL, we should end up with an absolute URL
511 LPWSTR abs_url
= CombineURL(_bstr_baseurl
, _bstr_mrl
);
512 if( NULL
!= abs_url
)
514 psz_mrl
= CStrFromWSTR(CP_UTF8
, abs_url
, wcslen(abs_url
));
515 CoTaskMemFree(abs_url
);
519 psz_mrl
= CStrFromBSTR(CP_UTF8
, _bstr_mrl
);
525 ** baseURL is empty, assume MRL is absolute
527 psz_mrl
= CStrFromBSTR(CP_UTF8
, _bstr_mrl
);
529 if( NULL
!= psz_mrl
)
531 const char *options
[1];
537 snprintf(timeBuffer
, sizeof(timeBuffer
), ":start-time=%d", _i_time
);
538 options
[i_options
++] = timeBuffer
;
540 // add default target to playlist
541 libvlc_playlist_add_extended(_p_libvlc
, psz_mrl
, NULL
, i_options
, options
, NULL
);
542 CoTaskMemFree(psz_mrl
);
546 *pp_libvlc
= _p_libvlc
;
550 void VLCPlugin::setErrorInfo(REFIID riid
, const char *description
)
552 vlcSupportErrorInfo
->setErrorInfo( getClassID() == CLSID_VLCPlugin2
?
553 OLESTR("VideoLAN.VLCPlugin.2") : OLESTR("VideoLAN.VLCPlugin.1"),
557 HRESULT
VLCPlugin::onAmbientChanged(LPUNKNOWN pContainer
, DISPID dispID
)
562 case DISPID_AMBIENT_BACKCOLOR
:
565 if( SUCCEEDED(GetObjectProperty(pContainer
, dispID
, v
)) )
567 setBackColor(V_I4(&v
));
570 case DISPID_AMBIENT_DISPLAYNAME
:
572 case DISPID_AMBIENT_FONT
:
574 case DISPID_AMBIENT_FORECOLOR
:
576 case DISPID_AMBIENT_LOCALEID
:
578 case DISPID_AMBIENT_MESSAGEREFLECT
:
580 case DISPID_AMBIENT_SCALEUNITS
:
582 case DISPID_AMBIENT_TEXTALIGN
:
584 case DISPID_AMBIENT_USERMODE
:
587 if( SUCCEEDED(GetObjectProperty(pContainer
, dispID
, v
)) )
589 setUserMode(V_BOOL(&v
) != VARIANT_FALSE
);
592 case DISPID_AMBIENT_UIDEAD
:
594 case DISPID_AMBIENT_SHOWGRABHANDLES
:
596 case DISPID_AMBIENT_SHOWHATCHING
:
598 case DISPID_AMBIENT_DISPLAYASDEFAULT
:
600 case DISPID_AMBIENT_SUPPORTSMNEMONICS
:
602 case DISPID_AMBIENT_AUTOCLIP
:
604 case DISPID_AMBIENT_APPEARANCE
:
606 case DISPID_AMBIENT_CODEPAGE
:
609 if( SUCCEEDED(GetObjectProperty(pContainer
, dispID
, v
)) )
611 setCodePage(V_I4(&v
));
614 case DISPID_AMBIENT_PALETTE
:
616 case DISPID_AMBIENT_CHARSET
:
618 case DISPID_AMBIENT_RIGHTTOLEFT
:
620 case DISPID_AMBIENT_TOPTOBOTTOM
:
624 ** multiple property change, look up the ones we are interested in
628 if( SUCCEEDED(GetObjectProperty(pContainer
, DISPID_AMBIENT_USERMODE
, v
)) )
630 setUserMode(V_BOOL(&v
) != VARIANT_FALSE
);
634 if( SUCCEEDED(GetObjectProperty(pContainer
, DISPID_AMBIENT_CODEPAGE
, v
)) )
636 setCodePage(V_I4(&v
));
643 HRESULT
VLCPlugin::onClose(DWORD dwSaveOption
)
645 if( isInPlaceActive() )
647 onInPlaceDeactivate();
651 libvlc_instance_t
* p_libvlc
= _p_libvlc
;
654 if( SUCCEEDED(vlcControl2
->get_log(&p_log
)) )
656 // make sure the log is disabled
657 p_log
->put_verbosity(-1);
662 vlcDataObject
->onClose();
664 libvlc_destroy(p_libvlc
, NULL
);
669 BOOL
VLCPlugin::isInPlaceActive(void)
671 return (NULL
!= _inplacewnd
);
674 HRESULT
VLCPlugin::onActivateInPlace(LPMSG lpMesg
, HWND hwndParent
, LPCRECT lprcPosRect
, LPCRECT lprcClipRect
)
676 RECT clipRect
= *lprcClipRect
;
679 ** record keeping of control geometry within container
681 _posRect
= *lprcPosRect
;
684 ** Create a window for in place activated control.
685 ** the window geometry matches the control viewport
686 ** within container so that embedded video is always
687 ** properly displayed.
689 _inplacewnd
= CreateWindow(_p_class
->getInPlaceWndClassName(),
690 TEXT("VLC Plugin In-Place Window"),
691 WS_CHILD
|WS_CLIPCHILDREN
|WS_CLIPSIBLINGS
,
694 lprcPosRect
->right
-lprcPosRect
->left
,
695 lprcPosRect
->bottom
-lprcPosRect
->top
,
698 _p_class
->getHInstance(),
702 if( NULL
== _inplacewnd
)
705 SetWindowLongPtr(_inplacewnd
, GWLP_USERDATA
, reinterpret_cast<LONG_PTR
>(this));
707 /* change cliprect coordinates system relative to window bounding rect */
708 OffsetRect(&clipRect
, -lprcPosRect
->left
, -lprcPosRect
->top
);
710 HRGN clipRgn
= CreateRectRgnIndirect(&clipRect
);
711 SetWindowRgn(_inplacewnd
, clipRgn
, TRUE
);
715 /* will run vlc if not done already */
716 libvlc_instance_t
* p_libvlc
;
717 HRESULT result
= getVLC(&p_libvlc
);
721 /* set internal video width and height */
722 libvlc_video_set_size(p_libvlc
,
723 lprcPosRect
->right
-lprcPosRect
->left
,
724 lprcPosRect
->bottom
-lprcPosRect
->top
,
727 /* set internal video parent window */
728 libvlc_video_set_parent(p_libvlc
,
729 reinterpret_cast<libvlc_drawable_t
>(_inplacewnd
), NULL
);
731 if( _b_autoplay
& (libvlc_playlist_items_count(p_libvlc
, NULL
) > 0) )
733 libvlc_playlist_play(p_libvlc
, 0, 0, NULL
, NULL
);
739 ShowWindow(_inplacewnd
, SW_SHOW
);
744 HRESULT
VLCPlugin::onInPlaceDeactivate(void)
748 libvlc_playlist_stop(_p_libvlc
, NULL
);
752 DestroyWindow(_inplacewnd
);
758 void VLCPlugin::setVisible(BOOL fVisible
)
760 if( fVisible
!= _b_visible
)
762 _b_visible
= fVisible
;
763 if( isInPlaceActive() )
765 ShowWindow(_inplacewnd
, fVisible
? SW_SHOW
: SW_HIDE
);
767 InvalidateRect(_inplacewnd
, NULL
, TRUE
);
770 firePropChangedEvent(DISPID_Visible
);
774 void VLCPlugin::setVolume(int volume
)
778 else if( volume
> 200 )
781 if( volume
!= _i_volume
)
786 libvlc_audio_set_volume(_p_libvlc
, _i_volume
, NULL
);
792 void VLCPlugin::setBackColor(OLE_COLOR backcolor
)
794 if( _i_backcolor
!= backcolor
)
796 _i_backcolor
= backcolor
;
797 if( isInPlaceActive() )
805 void VLCPlugin::setTime(int seconds
)
810 if( seconds
!= _i_time
)
812 setStartTime(_i_time
);
815 libvlc_media_instance_t
*p_md
= libvlc_playlist_get_media_instance(_p_libvlc
, NULL
);
818 libvlc_media_instance_set_time(p_md
, _i_time
, NULL
);
819 libvlc_media_instance_release(p_md
);
825 void VLCPlugin::setFocus(BOOL fFocus
)
828 SetActiveWindow(_inplacewnd
);
831 BOOL
VLCPlugin::hasFocus(void)
833 return GetActiveWindow() == _inplacewnd
;
836 void VLCPlugin::onDraw(DVTARGETDEVICE
* ptd
, HDC hicTargetDev
,
837 HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
)
841 long width
= lprcBounds
->right
-lprcBounds
->left
;
842 long height
= lprcBounds
->bottom
-lprcBounds
->top
;
844 RECT bounds
= { lprcBounds
->left
, lprcBounds
->top
, lprcBounds
->right
, lprcBounds
->bottom
};
848 /* VLC is in user mode, just draw background color */
849 COLORREF colorref
= RGB(0, 0, 0);
850 OleTranslateColor(_i_backcolor
, (HPALETTE
)GetStockObject(DEFAULT_PALETTE
), &colorref
);
851 if( colorref
!= RGB(0, 0, 0) )
853 /* custom background */
854 HBRUSH colorbrush
= CreateSolidBrush(colorref
);
855 FillRect(hdcDraw
, &bounds
, colorbrush
);
856 DeleteObject((HANDLE
)colorbrush
);
860 /* black background */
861 FillRect(hdcDraw
, &bounds
, (HBRUSH
)GetStockObject(BLACK_BRUSH
));
866 /* VLC is in design mode, draw the VLC logo */
867 FillRect(hdcDraw
, &bounds
, (HBRUSH
)GetStockObject(WHITE_BRUSH
));
869 LPPICTURE pict
= getPicture();
872 OLE_XSIZE_HIMETRIC picWidth
;
873 OLE_YSIZE_HIMETRIC picHeight
;
875 pict
->get_Width(&picWidth
);
876 pict
->get_Height(&picHeight
);
878 SIZEL picSize
= { picWidth
, picHeight
};
880 if( NULL
!= hicTargetDev
)
882 DPFromHimetric(hicTargetDev
, (LPPOINT
)&picSize
, 1);
884 else if( NULL
!= (hicTargetDev
= CreateDevDC(ptd
)) )
886 DPFromHimetric(hicTargetDev
, (LPPOINT
)&picSize
, 1);
887 DeleteDC(hicTargetDev
);
890 if( picSize
.cx
> width
-4 )
891 picSize
.cx
= width
-4;
892 if( picSize
.cy
> height
-4 )
893 picSize
.cy
= height
-4;
895 LONG dstX
= lprcBounds
->left
+(width
-picSize
.cx
)/2;
896 LONG dstY
= lprcBounds
->top
+(height
-picSize
.cy
)/2;
898 if( NULL
!= lprcWBounds
)
900 RECT wBounds
= { lprcWBounds
->left
, lprcWBounds
->top
, lprcWBounds
->right
, lprcWBounds
->bottom
};
901 pict
->Render(hdcDraw
, dstX
, dstY
, picSize
.cx
, picSize
.cy
,
902 0L, picHeight
, picWidth
, -picHeight
, &wBounds
);
905 pict
->Render(hdcDraw
, dstX
, dstY
, picSize
.cx
, picSize
.cy
,
906 0L, picHeight
, picWidth
, -picHeight
, NULL
);
911 SelectObject(hdcDraw
, GetStockObject(BLACK_BRUSH
));
913 MoveToEx(hdcDraw
, bounds
.left
, bounds
.top
, NULL
);
914 LineTo(hdcDraw
, bounds
.left
+width
-1, bounds
.top
);
915 LineTo(hdcDraw
, bounds
.left
+width
-1, bounds
.top
+height
-1);
916 LineTo(hdcDraw
, bounds
.left
, bounds
.top
+height
-1);
917 LineTo(hdcDraw
, bounds
.left
, bounds
.top
);
922 void VLCPlugin::onPaint(HDC hdc
, const RECT
&bounds
, const RECT
&clipRect
)
926 /* if VLC is in design mode, draw control logo */
927 HDC hdcDraw
= CreateCompatibleDC(hdc
);
928 if( NULL
!= hdcDraw
)
930 SIZEL size
= getExtent();
931 DPFromHimetric(hdc
, (LPPOINT
)&size
, 1);
932 RECTL posRect
= { 0, 0, size
.cx
, size
.cy
};
934 int width
= bounds
.right
-bounds
.left
;
935 int height
= bounds
.bottom
-bounds
.top
;
937 HBITMAP hBitmap
= CreateCompatibleBitmap(hdc
, width
, height
);
938 if( NULL
!= hBitmap
)
940 HBITMAP oldBmp
= (HBITMAP
)SelectObject(hdcDraw
, hBitmap
);
942 if( (size
.cx
!= width
) || (size
.cy
!= height
) )
944 // needs to scale canvas
945 SetMapMode(hdcDraw
, MM_ANISOTROPIC
);
946 SetWindowExtEx(hdcDraw
, size
.cx
, size
.cy
, NULL
);
947 SetViewportExtEx(hdcDraw
, width
, height
, NULL
);
950 onDraw(NULL
, hdc
, hdcDraw
, &posRect
, NULL
);
952 SetMapMode(hdcDraw
, MM_TEXT
);
953 BitBlt(hdc
, bounds
.left
, bounds
.top
,
958 SelectObject(hdcDraw
, oldBmp
);
959 DeleteObject(hBitmap
);
966 void VLCPlugin::onPositionChange(LPCRECT lprcPosRect
, LPCRECT lprcClipRect
)
968 RECT clipRect
= *lprcClipRect
;
970 //RedrawWindow(GetParent(_inplacewnd), &_posRect, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN);
973 ** record keeping of control geometry within container
975 _posRect
= *lprcPosRect
;
978 ** change in-place window geometry to match clipping region
980 SetWindowPos(_inplacewnd
, NULL
,
983 lprcPosRect
->right
-lprcPosRect
->left
,
984 lprcPosRect
->bottom
-lprcPosRect
->top
,
990 /* change cliprect coordinates system relative to window bounding rect */
991 OffsetRect(&clipRect
, -lprcPosRect
->left
, -lprcPosRect
->top
);
992 HRGN clipRgn
= CreateRectRgnIndirect(&clipRect
);
993 SetWindowRgn(_inplacewnd
, clipRgn
, FALSE
);
995 //RedrawWindow(_videownd, &posRect, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN);
998 libvlc_video_set_size(_p_libvlc
,
999 lprcPosRect
->right
-lprcPosRect
->left
,
1000 lprcPosRect
->bottom
-lprcPosRect
->top
,
1005 void VLCPlugin::freezeEvents(BOOL freeze
)
1007 vlcConnectionPointContainer
->freezeEvents(freeze
);
1010 void VLCPlugin::firePropChangedEvent(DISPID dispid
)
1012 vlcConnectionPointContainer
->firePropChangedEvent(dispid
);
1015 void VLCPlugin::fireOnPlayEvent(void)
1017 DISPPARAMS dispparamsNoArgs
= {NULL
, NULL
, 0, 0};
1018 vlcConnectionPointContainer
->fireEvent(DISPID_PlayEvent
, &dispparamsNoArgs
);
1021 void VLCPlugin::fireOnPauseEvent(void)
1023 DISPPARAMS dispparamsNoArgs
= {NULL
, NULL
, 0, 0};
1024 vlcConnectionPointContainer
->fireEvent(DISPID_PauseEvent
, &dispparamsNoArgs
);
1027 void VLCPlugin::fireOnStopEvent(void)
1029 DISPPARAMS dispparamsNoArgs
= {NULL
, NULL
, 0, 0};
1030 vlcConnectionPointContainer
->fireEvent(DISPID_StopEvent
, &dispparamsNoArgs
);