]> git.sesse.net Git - vlc/blob - activex/plugin.cpp
Avoid \r\n problems between platforms
[vlc] / activex / plugin.cpp
1 /*****************************************************************************
2  * plugin.cpp: ActiveX control for VLC
3  *****************************************************************************
4  * Copyright (C) 2005 VideoLAN
5  *
6  * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
7  *
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.
12  *
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.
17  *
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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21  *****************************************************************************/
22
23 #include "plugin.h"
24
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
37 #include "utils.h"
38
39 #include <string.h>
40 #include <winreg.h>
41
42 using namespace std;
43
44 ////////////////////////////////////////////////////////////////////////
45 //class factory
46
47 // {E23FE9C6-778E-49d4-B537-38FCDE4887D8}
48 //const GUID CLSID_VLCPlugin = 
49 //    { 0xe23fe9c6, 0x778e, 0x49d4, { 0xb5, 0x37, 0x38, 0xfc, 0xde, 0x48, 0x87, 0xd8 } };
50
51 static LRESULT CALLBACK VLCInPlaceClassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
52     switch( uMsg )
53     {
54         case WM_ERASEBKGND:
55             return 1L;
56
57         case WM_PAINT:
58             PAINTSTRUCT ps;
59             if( GetUpdateRect(hWnd, NULL, FALSE) )
60             {
61                 BeginPaint(hWnd, &ps);
62                 EndPaint(hWnd, &ps);
63             }
64             return 0L;
65
66         default:
67             return DefWindowProc(hWnd, uMsg, wParam, lParam);
68     }
69 };
70
71 static LRESULT CALLBACK VLCVideoClassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
72     VLCPlugin *p_instance = reinterpret_cast<VLCPlugin *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
73
74     switch( uMsg )
75     {
76         case WM_ERASEBKGND:
77             return 1L;
78
79         case WM_PAINT:
80             PAINTSTRUCT ps;
81             RECT pr;
82             if( GetUpdateRect(hWnd, &pr, FALSE) )
83             {
84                 BeginPaint(hWnd, &ps);
85                 p_instance->onPaint(ps, pr);
86                 EndPaint(hWnd, &ps);
87             }
88             return 0L;
89
90         default:
91             return DefWindowProc(hWnd, uMsg, wParam, lParam);
92     }
93 };
94
95 VLCPluginClass::VLCPluginClass(LONG *p_class_ref, HINSTANCE hInstance) :
96     _p_class_ref(p_class_ref),
97     _hinstance(hInstance)
98 {
99     WNDCLASS wClass;
100
101     if( ! GetClassInfo(hInstance, getInPlaceWndClassName(), &wClass) )
102     {
103         wClass.style          = CS_NOCLOSE|CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
104         wClass.lpfnWndProc    = VLCInPlaceClassWndProc;
105         wClass.cbClsExtra     = 0;
106         wClass.cbWndExtra     = 0;
107         wClass.hInstance      = hInstance;
108         wClass.hIcon          = NULL;
109         wClass.hCursor        = LoadCursor(NULL, IDC_ARROW);
110         wClass.hbrBackground  = NULL;
111         wClass.lpszMenuName   = NULL;
112         wClass.lpszClassName  = getInPlaceWndClassName();
113        
114         _inplace_wndclass_atom = RegisterClass(&wClass);
115     }
116     else
117     {
118         _inplace_wndclass_atom = 0;
119     }
120
121     if( ! GetClassInfo(hInstance, getVideoWndClassName(), &wClass) )
122     {
123         wClass.style          = CS_NOCLOSE|CS_HREDRAW|CS_VREDRAW;
124         wClass.lpfnWndProc    = VLCVideoClassWndProc;
125         wClass.cbClsExtra     = 0;
126         wClass.cbWndExtra     = 0;
127         wClass.hInstance      = hInstance;
128         wClass.hIcon          = NULL;
129         wClass.hCursor        = LoadCursor(NULL, IDC_ARROW);
130         wClass.hbrBackground  = NULL;
131         wClass.lpszMenuName   = NULL;
132         wClass.lpszClassName  = getVideoWndClassName();
133        
134         _video_wndclass_atom = RegisterClass(&wClass);
135     }
136     else
137     {
138         _video_wndclass_atom = 0;
139     }
140
141     _inplace_hbitmap = (HBITMAP)LoadImage(getHInstance(), TEXT("INPLACE-PICT"), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
142
143     AddRef();
144 };
145
146 VLCPluginClass::~VLCPluginClass()
147 {
148     if( 0 != _inplace_wndclass_atom )
149         UnregisterClass(MAKEINTATOM(_inplace_wndclass_atom), _hinstance);
150
151     if( 0 != _video_wndclass_atom )
152         UnregisterClass(MAKEINTATOM(_video_wndclass_atom), _hinstance);
153
154     if( NULL != _inplace_hbitmap )
155         DeleteObject(_inplace_hbitmap);
156 };
157
158 STDMETHODIMP VLCPluginClass::QueryInterface(REFIID riid, void **ppv)
159 {
160     if( NULL == ppv )
161         return E_INVALIDARG;
162
163     if( (IID_IUnknown == riid) || (IID_IClassFactory == riid) )
164     {
165         AddRef();
166         *ppv = reinterpret_cast<LPVOID>(this);
167
168         return NOERROR;
169     }
170
171     *ppv = NULL;
172
173     return E_NOINTERFACE;
174 };
175
176 STDMETHODIMP_(ULONG) VLCPluginClass::AddRef(void)
177 {
178     return InterlockedIncrement(_p_class_ref);
179 };
180
181 STDMETHODIMP_(ULONG) VLCPluginClass::Release(void)
182 {
183     ULONG refcount = InterlockedDecrement(_p_class_ref);
184     if( 0 == refcount )
185     {
186         delete this;
187         return 0;
188     }
189     return refcount;
190 };
191
192 STDMETHODIMP VLCPluginClass::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv)
193 {
194     if( NULL == ppv )
195         return E_POINTER;
196
197     *ppv = NULL;
198
199     if( NULL != pUnkOuter )
200         return CLASS_E_NOAGGREGATION;
201
202     VLCPlugin *plugin = new VLCPlugin(this);
203     if( NULL != plugin )
204     {
205         HRESULT hr = plugin->QueryInterface(riid, ppv);
206         plugin->Release();
207         return hr;
208     }
209     return E_OUTOFMEMORY;
210 };
211
212 STDMETHODIMP VLCPluginClass::LockServer(BOOL fLock)
213 {
214     if( fLock )
215         AddRef();
216     else 
217         Release();
218
219     return S_OK;
220 };
221
222 ////////////////////////////////////////////////////////////////////////
223
224 VLCPlugin::VLCPlugin(VLCPluginClass *p_class) :
225     _inplacewnd(NULL),
226     _p_class(p_class),
227     _i_ref(1UL),
228     _codepage(CP_ACP),
229     _psz_src(NULL),
230     _b_autostart(TRUE),
231     _b_loopmode(FALSE),
232     _b_visible(TRUE),
233     _b_sendevents(TRUE),
234     _i_vlc(0)
235 {
236     p_class->AddRef();
237
238     vlcOleObject = new VLCOleObject(this);
239     vlcOleControl = new VLCOleControl(this);
240     vlcOleInPlaceObject = new VLCOleInPlaceObject(this);
241     vlcOleInPlaceActiveObject = new VLCOleInPlaceActiveObject(this);
242     vlcPersistStorage = new VLCPersistStorage(this);
243     vlcPersistStreamInit = new VLCPersistStreamInit(this);
244     vlcPersistPropertyBag = new VLCPersistPropertyBag(this);
245     vlcProvideClassInfo = new VLCProvideClassInfo(this);
246     vlcConnectionPointContainer = new VLCConnectionPointContainer(this);
247     vlcObjectSafety = new VLCObjectSafety(this);
248     vlcControl = new VLCControl(this);
249 };
250
251 VLCPlugin::~VLCPlugin()
252 {
253     vlcOleInPlaceObject->UIDeactivate();
254     vlcOleInPlaceObject->InPlaceDeactivate();
255
256     delete vlcControl;
257     delete vlcObjectSafety;
258     delete vlcConnectionPointContainer;
259     delete vlcProvideClassInfo;
260     delete vlcPersistPropertyBag;
261     delete vlcPersistStreamInit;
262     delete vlcPersistStorage;
263     delete vlcOleInPlaceActiveObject;
264     delete vlcOleInPlaceObject;
265     delete vlcOleControl;
266     delete vlcOleObject;
267
268     if( _psz_src )
269         free(_psz_src);
270
271     _p_class->Release();
272 };
273
274 STDMETHODIMP VLCPlugin::QueryInterface(REFIID riid, void **ppv)
275 {
276     if( NULL == ppv )
277         return E_INVALIDARG;
278
279     if( IID_IUnknown == riid )
280     {
281         AddRef();
282         *ppv = reinterpret_cast<LPVOID>(this);
283         return NOERROR;
284     }
285     else if( IID_IOleObject == riid )
286     {
287         AddRef();
288         *ppv = reinterpret_cast<LPVOID>(vlcOleObject);
289         return NOERROR;
290     }
291     else if( IID_IOleControl == riid )
292     {
293         AddRef();
294         *ppv = reinterpret_cast<LPVOID>(vlcOleControl);
295         return NOERROR;
296     }
297     else if( IID_IOleWindow == riid )
298     {
299         AddRef();
300         *ppv = reinterpret_cast<LPVOID>(vlcOleInPlaceObject);
301         return NOERROR;
302     }
303     else if( IID_IOleInPlaceObject == riid )
304     {
305         AddRef();
306         *ppv = reinterpret_cast<LPVOID>(vlcOleInPlaceObject);
307         return NOERROR;
308     }
309     else if( IID_IOleInPlaceActiveObject == riid )
310     {
311         AddRef();
312         *ppv = reinterpret_cast<LPVOID>(vlcOleInPlaceActiveObject);
313         return NOERROR;
314     }
315     else if( IID_IPersist == riid )
316     {
317         AddRef();
318         *ppv = reinterpret_cast<LPVOID>(vlcPersistPropertyBag);
319         return NOERROR;
320     }
321     else if( IID_IPersistStreamInit == riid )
322     {
323         AddRef();
324         *ppv = reinterpret_cast<LPVOID>(vlcPersistStreamInit);
325         return NOERROR;
326     }
327     else if( IID_IPersistStorage == riid )
328     {
329         AddRef();
330         *ppv = reinterpret_cast<LPVOID>(vlcPersistStorage);
331         return NOERROR;
332     }
333     else if( IID_IPersistPropertyBag == riid )
334     {
335         AddRef();
336         *ppv = reinterpret_cast<LPVOID>(vlcPersistPropertyBag);
337         return NOERROR;
338     }
339     else if( IID_IProvideClassInfo == riid )
340     {
341         AddRef();
342         *ppv = reinterpret_cast<LPVOID>(vlcProvideClassInfo);
343         return NOERROR;
344     }
345     else if( IID_IProvideClassInfo2 == riid )
346     {
347         AddRef();
348         *ppv = reinterpret_cast<LPVOID>(vlcProvideClassInfo);
349         return NOERROR;
350     }
351     else if( IID_IConnectionPointContainer == riid )
352     {
353         AddRef();
354         *ppv = reinterpret_cast<LPVOID>(vlcConnectionPointContainer);
355         return NOERROR;
356     }
357     else if( IID_IObjectSafety == riid )
358     {
359         AddRef();
360         *ppv = reinterpret_cast<LPVOID>(vlcObjectSafety);
361         return NOERROR;
362     }
363     else if( IID_IDispatch == riid )
364     {
365         AddRef();
366         *ppv = reinterpret_cast<LPVOID>(vlcControl);
367         return NOERROR;
368     }
369     else if( IID_IVLCControl == riid )
370     {
371         AddRef();
372         *ppv = reinterpret_cast<LPVOID>(vlcControl);
373         return NOERROR;
374     }
375
376     *ppv = NULL;
377
378     return E_NOINTERFACE;
379 };
380
381 STDMETHODIMP_(ULONG) VLCPlugin::AddRef(void)
382 {
383     return InterlockedIncrement((LONG *)&_i_ref);
384 };
385
386 STDMETHODIMP_(ULONG) VLCPlugin::Release(void)
387 {
388     if( ! InterlockedDecrement((LONG *)&_i_ref) )
389     {
390         delete this;
391         return 0;
392     }
393     return _i_ref;
394 };
395
396 //////////////////////////////////////
397
398 /*
399 ** we use an in-place child window to represent plugin viewport,
400 ** whose size is limited by the clipping rectangle
401 ** all drawing within this window must follow 
402 ** cartesian coordinate system represented by _bounds.
403 */
404
405 void VLCPlugin::calcPositionChange(LPRECT lprPosRect, LPCRECT lprcClipRect)
406 {
407     _bounds.right  = lprPosRect->right-lprPosRect->left;
408
409     if( lprcClipRect->left <= lprPosRect->left )
410     {
411         // left side is not clipped out
412         _bounds.left = 0;
413
414         if( lprcClipRect->right >= lprPosRect->right )
415         {
416             // right side is not clipped out, no change
417         }
418         else if( lprcClipRect->right >= lprPosRect->left )
419         {
420             // right side is clipped out
421             lprPosRect->right = lprcClipRect->right;
422         }
423         else
424         {
425             // outside of clipping rectange, not visible
426             lprPosRect->right = lprPosRect->left;
427         }
428     }
429     else
430     {
431         // left side is clipped out
432         _bounds.left = lprPosRect->left-lprcClipRect->left;
433         _bounds.right += _bounds.left;
434
435         lprPosRect->left = lprcClipRect->left;
436         if( lprcClipRect->right >= lprPosRect->right )
437         {
438             // right side is not clipped out
439         }
440         else
441         {
442             // right side is clipped out
443             lprPosRect->right = lprcClipRect->right;
444         }
445     }
446
447     _bounds.bottom = lprPosRect->bottom-lprPosRect->top;
448
449     if( lprcClipRect->top <= lprPosRect->top )
450     {
451         // top side is not clipped out
452         _bounds.top = 0;
453
454         if( lprcClipRect->bottom >= lprPosRect->bottom )
455         {
456             // bottom side is not clipped out, no change
457         }
458         else if( lprcClipRect->bottom >= lprPosRect->top )
459         {
460             // bottom side is clipped out
461             lprPosRect->bottom = lprcClipRect->bottom;
462         }
463         else
464         {
465             // outside of clipping rectange, not visible
466             lprPosRect->right = lprPosRect->left;
467         }
468     }
469     else
470     {
471         _bounds.top = lprPosRect->top-lprcClipRect->top;
472         _bounds.bottom += _bounds.top;
473
474         lprPosRect->top = lprcClipRect->top;
475         if( lprcClipRect->bottom >= lprPosRect->bottom )
476         {
477             // bottom side is not clipped out
478         }
479         else
480         {
481             // bottom side is clipped out
482             lprPosRect->bottom = lprcClipRect->bottom;
483         }
484     }
485 };
486
487 HRESULT VLCPlugin::onInitNew(void)
488 {
489     if( 0 == _i_vlc )
490     {
491         char *ppsz_argv[] = { "vlc", "-vv" };
492         HKEY h_key;
493         DWORD i_type, i_data = MAX_PATH + 1;
494         char p_data[MAX_PATH + 1];
495         if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\VideoLAN\\VLC",
496                           0, KEY_READ, &h_key ) == ERROR_SUCCESS )
497         {
498              if( RegQueryValueEx( h_key, "InstallDir", 0, &i_type,
499                                   (LPBYTE)p_data, &i_data ) == ERROR_SUCCESS )
500              {
501                  if( i_type == REG_SZ )
502                  {
503                      strcat( p_data, "\\vlc" );
504                      ppsz_argv[0] = p_data;
505                  }
506              }
507              RegCloseKey( h_key );
508         }
509
510 #if 0
511         ppsz_argv[0] = "C:\\cygwin\\home\\Damien_Fouilleul\\dev\\videolan\\vlc-trunk\\vlc";
512 #endif
513
514         _i_vlc = VLC_Create();
515         
516         if( VLC_Init(_i_vlc, sizeof(ppsz_argv)/sizeof(char*), ppsz_argv) )
517         {
518             VLC_Destroy(_i_vlc);
519             _i_vlc = 0;
520             return E_FAIL;
521         }
522         return S_OK;
523     }
524     return E_UNEXPECTED;
525 };
526     
527 HRESULT VLCPlugin::onClose(DWORD dwSaveOption)
528 {
529     if( _i_vlc )
530     {
531         if( isInPlaceActive() )
532         {
533             onInPlaceDeactivate();
534         }
535
536         VLC_CleanUp(_i_vlc);
537         VLC_Destroy(_i_vlc);
538         _i_vlc = 0;
539     }
540     return S_OK;
541 };
542
543 BOOL VLCPlugin::isInPlaceActive(void)
544 {
545     return (NULL != _inplacewnd);
546 };
547
548 HRESULT VLCPlugin::onActivateInPlace(LPMSG lpMesg, HWND hwndParent, LPCRECT lprcPosRect, LPCRECT lprcClipRect)
549 {
550     RECT posRect = *lprcPosRect;
551
552     calcPositionChange(&posRect, lprcClipRect);
553
554     _inplacewnd = CreateWindow(_p_class->getInPlaceWndClassName(),
555             "VLC Plugin In-Place Window",
556             WS_CHILD|WS_CLIPCHILDREN|WS_TABSTOP,
557             posRect.left,
558             posRect.top,
559             posRect.right-posRect.left,
560             posRect.bottom-posRect.top,
561             hwndParent,
562             0,
563             _p_class->getHInstance(),
564             NULL
565            );
566
567     if( NULL == _inplacewnd )
568         return E_FAIL;
569
570     SetWindowLongPtr(_inplacewnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
571
572     _videownd = CreateWindow(_p_class->getVideoWndClassName(),
573             "VLC Plugin Video Window",
574             WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE,
575             _bounds.left,
576             _bounds.top,
577             _bounds.right-_bounds.left,
578             _bounds.bottom-_bounds.top,
579             _inplacewnd,
580             0,
581             _p_class->getHInstance(),
582             NULL
583            );
584
585     if( NULL == _videownd )
586     {
587         DestroyWindow(_inplacewnd);
588         return E_FAIL;
589     }
590
591     SetWindowLongPtr(_videownd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
592
593     if( getVisible() )
594         ShowWindow(_inplacewnd, SW_SHOWNORMAL);
595
596     /* horrible cast there */
597     vlc_value_t val;
598     val.i_int = reinterpret_cast<int>(_videownd);
599     VLC_VariableSet(_i_vlc, "drawable", val);
600
601     if( NULL != _psz_src )
602     {
603         // add target to playlist
604         char *cOptions[1];
605         int  cOptionsCount = 0;
606
607         if( _b_loopmode )
608         {
609             cOptions[cOptionsCount++] = "loop";
610         }
611         VLC_AddTarget(_i_vlc, _psz_src, (const char **)&cOptions, cOptionsCount, PLAYLIST_APPEND, PLAYLIST_END);
612
613         if( _b_autostart )
614         {
615             VLC_Play(_i_vlc);
616             fireOnPlayEvent();
617         }
618     }
619     return S_OK;
620 };
621
622 HRESULT VLCPlugin::onInPlaceDeactivate(void)
623 {
624     VLC_Stop(_i_vlc);
625     fireOnStopEvent();
626
627     DestroyWindow(_videownd);
628     _videownd = NULL;
629     DestroyWindow(_inplacewnd);
630     _inplacewnd = NULL;
631  
632     return S_OK;
633 };
634
635 void VLCPlugin::setVisible(BOOL fVisible)
636 {
637     _b_visible = fVisible;
638     if( isInPlaceActive() )
639         ShowWindow(_inplacewnd, fVisible ? SW_SHOWNORMAL : SW_HIDE);
640     firePropChangedEvent(DISPID_Visible);
641 };
642
643 void VLCPlugin::setFocus(BOOL fFocus)
644 {
645     if( fFocus )
646         SetActiveWindow(_inplacewnd);
647 };
648
649 BOOL VLCPlugin::hasFocus(void)
650 {
651     return GetActiveWindow() == _inplacewnd;
652 };
653
654 void VLCPlugin::onPaint(PAINTSTRUCT &ps, RECT &pr)
655 {
656     /*
657     ** if VLC is playing, it may not display any VIDEO content 
658     ** hence, draw control logo
659     */ 
660     int width = _bounds.right-_bounds.left;
661     int height = _bounds.bottom-_bounds.top;
662
663     HBITMAP pict = _p_class->getInPlacePict();
664     if( NULL != pict )
665     {
666         HDC hdcPict = CreateCompatibleDC(ps.hdc);
667         if( NULL != hdcPict )
668         {
669             BITMAP bm;
670             if( GetObject(pict, sizeof(BITMAPINFO), &bm) )
671             {
672                 int dstWidth = bm.bmWidth;
673                 if( dstWidth > width-4 )
674                     dstWidth = width-4;
675
676                 int dstHeight = bm.bmHeight;
677                 if( dstHeight > height-4 )
678                     dstHeight = height-4;
679
680                 int dstX = (width-dstWidth)/2;
681                 int dstY = (height-dstHeight)/2;
682
683                 SelectObject(hdcPict, pict);
684                 StretchBlt(ps.hdc, dstX, dstY, dstWidth, dstHeight,
685                         hdcPict, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
686                 DeleteDC(hdcPict);
687                 ExcludeClipRect(ps.hdc, dstX, dstY, dstWidth+dstX, dstHeight+dstY);
688             }
689         }
690     }
691
692     FillRect(ps.hdc, &pr, (HBRUSH)GetStockObject(WHITE_BRUSH));
693     SelectObject(ps.hdc, GetStockObject(BLACK_BRUSH));
694
695     MoveToEx(ps.hdc, 0, 0, NULL);
696     LineTo(ps.hdc, width-1, 0);
697     LineTo(ps.hdc, width-1, height-1);
698     LineTo(ps.hdc, 0, height-1);
699     LineTo(ps.hdc, 0, 0);
700 };
701
702 void VLCPlugin::onPositionChange(LPCRECT lprcPosRect, LPCRECT lprcClipRect)
703 {
704     RECT posRect = *lprcPosRect;
705
706     calcPositionChange(&posRect, lprcClipRect);
707
708     /*
709     ** change in-place window geometry to match clipping region
710     */
711     MoveWindow(_inplacewnd,
712             posRect.left,
713             posRect.top,
714             posRect.right-posRect.left,
715             posRect.bottom-posRect.top,
716             FALSE);
717
718     /*
719     ** change video window geometry to match object bounds within clipping region
720     */
721     MoveWindow(_videownd,
722             _bounds.left,
723             _bounds.top,
724             _bounds.right-_bounds.left,
725             _bounds.bottom-_bounds.top,
726             FALSE);
727
728     RECT updateRect;
729
730     updateRect.left = -_bounds.left;
731     updateRect.top = -_bounds.top;
732     updateRect.right = _bounds.right-_bounds.left;
733     updateRect.bottom = _bounds.bottom-_bounds.top;
734
735     ValidateRect(_videownd, NULL);
736     InvalidateRect(_videownd, &updateRect, FALSE);
737     UpdateWindow(_videownd);
738 };
739
740 void VLCPlugin::firePropChangedEvent(DISPID dispid)
741 {
742     if( _b_sendevents )
743     {
744         vlcConnectionPointContainer->firePropChangedEvent(dispid); 
745     }
746 };
747
748 void VLCPlugin::fireOnPlayEvent(void)
749 {
750     if( _b_sendevents )
751     {
752         DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
753         vlcConnectionPointContainer->fireEvent(DISPID_PlayEvent, &dispparamsNoArgs); 
754     }
755 };
756
757 void VLCPlugin::fireOnPauseEvent(void)
758 {
759     if( _b_sendevents )
760     {
761         DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
762         vlcConnectionPointContainer->fireEvent(DISPID_PauseEvent, &dispparamsNoArgs); 
763     }
764 };
765
766 void VLCPlugin::fireOnStopEvent(void)
767 {
768     if( _b_sendevents )
769     {
770         DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
771         vlcConnectionPointContainer->fireEvent(DISPID_StopEvent, &dispparamsNoArgs); 
772     }
773 };
774