[vlc-devel] [PATCH 07/13] common/win32_fullscreen: controls moved from VLCFullScreenWnd to VLCControlsWnd class
Sergey Radionov
rsatom at gmail.com
Fri Jan 13 04:54:31 CET 2012
---
common/win32_fullscreen.cpp | 1267 +++++++++++++++++++++++--------------------
common/win32_fullscreen.h | 141 ++++--
2 files changed, 776 insertions(+), 632 deletions(-)
diff --git a/common/win32_fullscreen.cpp b/common/win32_fullscreen.cpp
index 37ee793..41b5745 100644
--- a/common/win32_fullscreen.cpp
+++ b/common/win32_fullscreen.cpp
@@ -30,437 +30,206 @@
#include "win32_fullscreen.h"
-/////////////////////////////////
-//VLCHolderWnd static members
-HINSTANCE VLCHolderWnd::_hinstance = 0;
-ATOM VLCHolderWnd::_holder_wndclass_atom = 0;
-
-enum{
- WM_TRY_SET_MOUSE_HOOK = WM_USER+1,
- WM_MOUSE_EVENT_NOTIFY = WM_APP+1,
- WM_MOUSE_EVENT_NOTIFY_SUCCESS = 0xFF
-};
-
-void VLCHolderWnd::RegisterWndClassName(HINSTANCE hInstance)
+////////////////////////////////////////////////////////////////////////////////
+//VLCControlsWnd members
+////////////////////////////////////////////////////////////////////////////////
+VLCControlsWnd*
+VLCControlsWnd::CreateControlsWindow(HINSTANCE hInstance,
+ VLCWindowsManager* wm, HWND hWndParent)
{
- //save hInstance for future use
- _hinstance = hInstance;
-
- WNDCLASS wClass;
-
- if( ! GetClassInfo(_hinstance, getClassName(), &wClass) )
- {
- wClass.style = CS_DBLCLKS;
- wClass.lpfnWndProc = VLCHolderClassWndProc;
- wClass.cbClsExtra = 0;
- wClass.cbWndExtra = 0;
- wClass.hInstance = _hinstance;
- wClass.hIcon = NULL;
- wClass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- wClass.lpszMenuName = NULL;
- wClass.lpszClassName = getClassName();
-
- _holder_wndclass_atom = RegisterClass(&wClass);
- }
- else
- {
- _holder_wndclass_atom = 0;
- }
-}
-
-void VLCHolderWnd::UnRegisterWndClassName()
-{
- if(0 != _holder_wndclass_atom){
- UnregisterClass(MAKEINTATOM(_holder_wndclass_atom), _hinstance);
- _holder_wndclass_atom = 0;
+ VLCControlsWnd* wnd = new VLCControlsWnd(hInstance, wm);
+ if( wnd && wnd->Create(hWndParent) ) {
+ return wnd;
}
-}
-
-VLCHolderWnd* VLCHolderWnd::CreateHolderWindow(HWND hParentWnd, VLCWindowsManager* WM)
-{
- HWND hWnd = CreateWindow(getClassName(),
- TEXT("Holder Window"),
- WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_VISIBLE,
- 0, 0, 0, 0,
- hParentWnd,
- 0,
- VLCHolderWnd::_hinstance,
- (LPVOID)WM
- );
-
- if(hWnd)
- return reinterpret_cast<VLCHolderWnd*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
-
+ delete wnd;
return 0;
}
-LRESULT CALLBACK VLCHolderWnd::VLCHolderClassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+VLCControlsWnd::VLCControlsWnd(HINSTANCE hInstance, VLCWindowsManager* wm)
+ :VLCWnd(hInstance), _wm(wm),
+ hToolTipWnd(0), hFSButton(0), hPlayPauseButton(0),
+ hVideoPosScroll(0), hMuteButton(0), hVolumeSlider(0)
{
- VLCHolderWnd* h_data = reinterpret_cast<VLCHolderWnd*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
-
- switch( uMsg )
- {
- case WM_CREATE:{
- CREATESTRUCT* CreateStruct = (CREATESTRUCT*)(lParam);
- VLCWindowsManager* WM = (VLCWindowsManager*)CreateStruct->lpCreateParams;
-
- h_data = new VLCHolderWnd(hWnd, WM);
- SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(h_data));
-
- RECT ParentClientRect;
- GetClientRect(CreateStruct->hwndParent, &ParentClientRect);
- MoveWindow(hWnd, 0, 0,
- (ParentClientRect.right-ParentClientRect.left),
- (ParentClientRect.bottom-ParentClientRect.top), FALSE);
- break;
- }
- case WM_PAINT:{
- PAINTSTRUCT PaintStruct;
- HDC hDC = BeginPaint(hWnd, &PaintStruct);
- RECT rect;
- GetClientRect(hWnd, &rect);
- int IconX = ((rect.right - rect.left) - GetSystemMetrics(SM_CXICON))/2;
- int IconY = ((rect.bottom - rect.top) - GetSystemMetrics(SM_CYICON))/2;
- DrawIcon(hDC, IconX, IconY, h_data->RC().hBackgroundIcon);
- EndPaint(hWnd, &PaintStruct);
- break;
- }
- case WM_NCDESTROY:
- delete h_data;
- SetWindowLongPtr(hWnd, GWLP_USERDATA, 0);
- break;
- case WM_TRY_SET_MOUSE_HOOK:{
- h_data->MouseHook(true);
- break;
- }
- case WM_MOUSEMOVE:
- case WM_LBUTTONDBLCLK:
- h_data->_WindowsManager->OnMouseEvent(uMsg);
- break;
- case WM_MOUSE_EVENT_NOTIFY:{
- h_data->_WindowsManager->OnMouseEvent(wParam);
- return WM_MOUSE_EVENT_NOTIFY_SUCCESS;
- }
- default:
- return DefWindowProc(hWnd, uMsg, wParam, lParam);
- }
- return 0;
-};
-
-void VLCHolderWnd::DestroyWindow()
-{
- LibVlcDetach();
- if(_hWnd)
- ::DestroyWindow(_hWnd);
-};
-
-LRESULT CALLBACK VLCHolderWnd::MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
-{
- bool AllowReceiveMessage = true;
- if(nCode >= 0){
- switch(wParam){
- case WM_MOUSEMOVE:
- case WM_LBUTTONDBLCLK:{
- MOUSEHOOKSTRUCT* mhs = reinterpret_cast<MOUSEHOOKSTRUCT*>(lParam);
-
- //try to find HolderWnd and notify it
- HWND hNotifyWnd = mhs->hwnd;
- LRESULT SMRes = ::SendMessage(hNotifyWnd, WM_MOUSE_EVENT_NOTIFY, wParam, 0);
- while( hNotifyWnd && WM_MOUSE_EVENT_NOTIFY_SUCCESS != SMRes){
- hNotifyWnd = GetParent(hNotifyWnd);
- SMRes = ::SendMessage(hNotifyWnd, WM_MOUSE_EVENT_NOTIFY, wParam, 0);
- }
-
- AllowReceiveMessage = WM_MOUSEMOVE==wParam || (WM_MOUSE_EVENT_NOTIFY_SUCCESS != SMRes);
- break;
- }
- }
- }
-
- LRESULT NHRes = CallNextHookEx(NULL, nCode, wParam, lParam);
- if(AllowReceiveMessage)
- return NHRes;
- else
- return 1;
}
-void VLCHolderWnd::MouseHook(bool SetHook)
+VLCControlsWnd::~VLCControlsWnd()
{
- if(SetHook){
- const HWND hChildWnd = GetWindow(getHWND(), GW_CHILD);
- const DWORD WndThreadID = (hChildWnd) ? GetWindowThreadProcessId(hChildWnd, NULL) : 0;
- if( _hMouseHook &&( !hChildWnd || WndThreadID != _MouseHookThreadId) ){
- //unhook if something changed
- MouseHook(false);
- }
-
- if(!_hMouseHook && hChildWnd && WndThreadID){
- _MouseHookThreadId = WndThreadID;
- _hMouseHook =
- SetWindowsHookEx(WH_MOUSE, VLCHolderWnd::MouseHookProc,
- NULL, WndThreadID);
- }
- }
- else{
- if(_hMouseHook){
- UnhookWindowsHookEx(_hMouseHook);
- _MouseHookThreadId=0;
- _hMouseHook = 0;
- }
+ if(hToolTipWnd){
+ ::DestroyWindow(hToolTipWnd);
+ hToolTipWnd = 0;
}
}
-//libvlc events arrives from separate thread
-void VLCHolderWnd::OnLibVlcEvent(const libvlc_event_t* event)
+bool VLCControlsWnd::Create(HWND hWndParent)
{
- //We need set hook to catch doubleclicking (to switch to fullscreen and vice versa).
- //But libvlc media window may not exist yet,
- //and we don't know when it will be created, nor ThreadId of it.
- //So we try catch events,
- //(suppose wnd will be ever created),
- //and then try set mouse hook.
- const HWND hChildWnd = GetWindow(getHWND(), GW_CHILD);
- const DWORD WndThreadID = (hChildWnd) ? GetWindowThreadProcessId(hChildWnd, NULL) : 0;
- //if no hook, or window thread has changed
- if(!_hMouseHook || (hChildWnd && WndThreadID != _MouseHookThreadId)){
- //libvlc events arrives from separate thread,
- //so we need post message to main thread, to notify it.
- PostMessage(getHWND(), WM_TRY_SET_MOUSE_HOOK, 0, 0);
- }
+ return VLCWnd::CreateEx(WS_EX_TOPMOST, TEXT("VLC Controls Window"),
+ WS_CHILD|WS_CLIPSIBLINGS,
+ 0, 0, 0, 0, hWndParent, 0);
}
-void VLCHolderWnd::LibVlcAttach()
+void VLCControlsWnd::PreRegisterWindowClass(WNDCLASS* wc)
{
- libvlc_media_player_set_hwnd(getMD(), getHWND());
-}
+ wc->lpszClassName = TEXT("VLC Controls Class");
+ wc->hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
+};
-void VLCHolderWnd::LibVlcDetach()
+void VLCControlsWnd::CreateToolTip()
{
- libvlc_media_player_t* p_md = getMD();
- if(p_md)
- libvlc_media_player_set_hwnd(p_md, 0);
-
- MouseHook(false);
-}
-
-/////////////////////////////////
-//VLCFullScreenWnd static members
-HINSTANCE VLCFullScreenWnd::_hinstance = 0;
-ATOM VLCFullScreenWnd::_fullscreen_wndclass_atom = 0;
-ATOM VLCFullScreenWnd::_fullscreen_controls_wndclass_atom = 0;
+ hToolTipWnd = CreateWindowEx(WS_EX_TOPMOST,
+ TOOLTIPS_CLASS,
+ NULL,
+ WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ hWnd(),
+ NULL,
+ hInstance(),
+ NULL);
-void VLCFullScreenWnd::RegisterWndClassName(HINSTANCE hInstance)
-{
- //save hInstance for future use
- _hinstance = hInstance;
+ SetWindowPos(hToolTipWnd,
+ HWND_TOPMOST,
+ 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
- WNDCLASS wClass;
- memset(&wClass, 0 , sizeof(wClass));
- if( ! GetClassInfo(_hinstance, getClassName(), &wClass) )
- {
- wClass.style = CS_NOCLOSE|CS_DBLCLKS;
- wClass.lpfnWndProc = FSWndWindowProc;
- wClass.cbClsExtra = 0;
- wClass.cbWndExtra = 0;
- wClass.hInstance = _hinstance;
- wClass.hIcon = NULL;
- wClass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wClass.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
- wClass.lpszMenuName = NULL;
- wClass.lpszClassName = getClassName();
+ TOOLINFO ti;
+ ti.cbSize = sizeof(TOOLINFO);
+ ti.uFlags = TTF_SUBCLASS|TTF_IDISHWND;
+ ti.hwnd = hWnd();
+ ti.hinst = hInstance();
- _fullscreen_wndclass_atom = RegisterClass(&wClass);
- }
- else
- {
- _fullscreen_wndclass_atom = 0;
- }
+ TCHAR HintText[100];
+ RECT ActivateTTRect;
- memset(&wClass, 0 , sizeof(wClass));
- if( ! GetClassInfo(_hinstance, getControlsClassName(), &wClass) )
- {
- wClass.style = CS_NOCLOSE;
- wClass.lpfnWndProc = FSControlsWndWindowProc;
- wClass.cbClsExtra = 0;
- wClass.cbWndExtra = 0;
- wClass.hInstance = _hinstance;
- wClass.hIcon = NULL;
- wClass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wClass.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
- wClass.lpszMenuName = NULL;
- wClass.lpszClassName = getControlsClassName();
+ //end fullscreen button tooltip
+ GetWindowRect(hFSButton, &ActivateTTRect);
+ GetWindowText(hFSButton, HintText, sizeof(HintText));
+ ti.uId = (UINT_PTR)hFSButton;
+ ti.rect = ActivateTTRect;
+ ti.lpszText = HintText;
+ SendMessage(hToolTipWnd, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
- _fullscreen_controls_wndclass_atom = RegisterClass(&wClass);
- }
- else
- {
- _fullscreen_controls_wndclass_atom = 0;
- }
-}
-void VLCFullScreenWnd::UnRegisterWndClassName()
-{
- if(0 != _fullscreen_wndclass_atom){
- UnregisterClass(MAKEINTATOM(_fullscreen_wndclass_atom), _hinstance);
- _fullscreen_wndclass_atom = 0;
- }
+ //play/pause button tooltip
+ GetWindowRect(hPlayPauseButton, &ActivateTTRect);
+ GetWindowText(hPlayPauseButton, HintText, sizeof(HintText));
+ ti.uId = (UINT_PTR)hPlayPauseButton;
+ ti.rect = ActivateTTRect;
+ ti.lpszText = HintText;
+ SendMessage(hToolTipWnd, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
- if(0 != _fullscreen_controls_wndclass_atom){
- UnregisterClass(MAKEINTATOM(_fullscreen_controls_wndclass_atom), _hinstance);
- _fullscreen_controls_wndclass_atom = 0;
- }
+ //mute button tooltip
+ GetWindowRect(hMuteButton, &ActivateTTRect);
+ GetWindowText(hMuteButton, HintText, sizeof(HintText));
+ ti.uId = (UINT_PTR)hMuteButton;
+ ti.rect = ActivateTTRect;
+ ti.lpszText = HintText;
+ SendMessage(hToolTipWnd, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
}
-LRESULT CALLBACK VLCFullScreenWnd::FSWndWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+LRESULT VLCControlsWnd::WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
- VLCFullScreenWnd* fs_data = reinterpret_cast<VLCFullScreenWnd *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
-
- switch( uMsg )
- {
+ switch(uMsg){
case WM_CREATE:{
- CREATESTRUCT* CreateStruct = (CREATESTRUCT*)(lParam);
- VLCWindowsManager* WM = (VLCWindowsManager*)CreateStruct->lpCreateParams;
-
- fs_data = new VLCFullScreenWnd(hWnd, WM);
- SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(fs_data));
-
- fs_data->hControlsWnd =
- CreateWindow(fs_data->getControlsClassName(),
- TEXT("VLC ActiveX Full Screen Controls Window"),
- WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS,
- 0,
- 0,
- 0, 0,
- hWnd,
- 0,
- VLCFullScreenWnd::_hinstance,
- (LPVOID) fs_data);
-
- break;
- }
- case WM_NCDESTROY:
- delete fs_data;
- SetWindowLongPtr(hWnd, GWLP_USERDATA, 0);
- break;
- case WM_SHOWWINDOW:{
- if(FALSE==wParam){ //hiding
- break;
- }
-
- fs_data->NeedShowControls();
-
- //simulate lParam for WM_SIZE
- RECT ClientRect;
- GetClientRect(hWnd, &ClientRect);
- lParam = MAKELPARAM(ClientRect.right, ClientRect.bottom);
- }
- case WM_SIZE:{
- if(fs_data->_WindowsManager->IsFullScreen()){
- int new_client_width = LOWORD(lParam);
- int new_client_height = HIWORD(lParam);
- VLCHolderWnd* HolderWnd = fs_data->_WindowsManager->getHolderWnd();
- SetWindowPos(HolderWnd->getHWND(), HWND_BOTTOM, 0, 0, new_client_width, new_client_height, SWP_NOACTIVATE|SWP_NOOWNERZORDER);
- }
- break;
- }
- default:
- return DefWindowProc(hWnd, uMsg, wParam, lParam);
- }
- return 0L;
-};
-
-#define ID_FS_SWITCH_FS 1
-#define ID_FS_PLAY_PAUSE 2
-#define ID_FS_VIDEO_POS_SCROLL 3
-#define ID_FS_MUTE 4
-#define ID_FS_VOLUME 5
-
-LRESULT CALLBACK VLCFullScreenWnd::FSControlsWndWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- VLCFullScreenWnd* fs_data = reinterpret_cast<VLCFullScreenWnd *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
-
- switch( uMsg )
- {
- case WM_CREATE:{
- CREATESTRUCT* CreateStruct = (CREATESTRUCT*)(lParam);
- fs_data = (VLCFullScreenWnd*)CreateStruct->lpCreateParams;
- const VLCViewResources& rc = fs_data->RC();
-
- SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(fs_data));
-
- const int ControlsHeight = 21+2;
+ const int ControlsHeight = 21+3;
const int ButtonsWidth = ControlsHeight;
- const int ControlsSpace = 5;
const int ScrollVOffset = (ControlsHeight-GetSystemMetrics(SM_CXHSCROLL))/2;
- int HorizontalOffset = ControlsSpace;
+ int HorizontalOffset = xControlsSpace;
int ControlWidth = ButtonsWidth;
- fs_data->hFSButton =
- CreateWindow(TEXT("BUTTON"), TEXT("End Full Screen"), WS_CHILD|WS_VISIBLE|BS_BITMAP|BS_FLAT,
- HorizontalOffset, ControlsSpace, ControlWidth, ControlsHeight, hWnd, (HMENU)ID_FS_SWITCH_FS, 0, 0);
- SendMessage(fs_data->hFSButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)rc.hDeFullscreenBitmap);
- HorizontalOffset+=ControlWidth+ControlsSpace;
-
- ControlWidth = ButtonsWidth;
- fs_data->hPlayPauseButton =
- CreateWindow(TEXT("BUTTON"), TEXT("Play/Pause"), WS_CHILD|WS_VISIBLE|BS_BITMAP|BS_FLAT,
- HorizontalOffset, ControlsSpace, ControlWidth, ControlsHeight, hWnd, (HMENU)ID_FS_PLAY_PAUSE, 0, 0);
- SendMessage(fs_data->hPlayPauseButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)rc.hPauseBitmap);
- HorizontalOffset+=ControlWidth+ControlsSpace;
+ hPlayPauseButton =
+ CreateWindow(TEXT("BUTTON"), TEXT("Play/Pause"),
+ WS_CHILD|WS_VISIBLE|BS_BITMAP|BS_FLAT,
+ HorizontalOffset, xControlsSpace,
+ ControlWidth, ControlsHeight, hWnd(),
+ (HMENU)ID_FS_PLAY_PAUSE, 0, 0);
+ SendMessage(hPlayPauseButton, BM_SETIMAGE,
+ (WPARAM)IMAGE_BITMAP, (LPARAM)RC().hPauseBitmap);
+ HorizontalOffset+=ControlWidth+xControlsSpace;
ControlWidth = 200;
- int VideoPosControlHeight = 12;
- fs_data->hVideoPosScroll =
- CreateWindow(PROGRESS_CLASS, TEXT("Video Position"), WS_CHILD|WS_DISABLED|WS_VISIBLE|SBS_HORZ|SBS_TOPALIGN|PBS_SMOOTH,
- HorizontalOffset, ControlsSpace+(ControlsHeight-VideoPosControlHeight)/2, ControlWidth, VideoPosControlHeight, hWnd, (HMENU)ID_FS_VIDEO_POS_SCROLL, 0, 0);
+ int VideoPosControlHeight = 10;
+ hVideoPosScroll =
+ CreateWindow(PROGRESS_CLASS, TEXT("Video Position"),
+ WS_CHILD|WS_DISABLED|WS_VISIBLE|SBS_HORZ|SBS_TOPALIGN|PBS_SMOOTH,
+ HorizontalOffset, xControlsSpace+(ControlsHeight-VideoPosControlHeight)/2,
+ ControlWidth, VideoPosControlHeight, hWnd(),
+ (HMENU)ID_FS_VIDEO_POS_SCROLL, 0, 0);
HMODULE hThModule = LoadLibrary(TEXT("UxTheme.dll"));
if(hThModule){
FARPROC proc = GetProcAddress(hThModule, "SetWindowTheme");
typedef HRESULT (WINAPI* SetWindowThemeProc)(HWND, LPCWSTR, LPCWSTR);
if(proc){
- //SetWindowTheme(fs_data->hVideoPosScroll, L"", L"");
- ((SetWindowThemeProc)proc)(fs_data->hVideoPosScroll, L"", L"");
+ ((SetWindowThemeProc)proc)(hVideoPosScroll, L"", L"");
}
FreeLibrary(hThModule);
}
- HorizontalOffset+=ControlWidth+ControlsSpace;
+ HorizontalOffset+=ControlWidth+xControlsSpace;
ControlWidth = ButtonsWidth;
- fs_data->hMuteButton =
- CreateWindow(TEXT("BUTTON"), TEXT("Mute"), WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX|BS_PUSHLIKE|BS_BITMAP, //BS_FLAT
- HorizontalOffset, ControlsSpace, ControlWidth, ControlsHeight, hWnd, (HMENU)ID_FS_MUTE, 0, 0);
- SendMessage(fs_data->hMuteButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)rc.hVolumeBitmap);
- HorizontalOffset+=ControlWidth+ControlsSpace;
+ hMuteButton =
+ CreateWindow(TEXT("BUTTON"), TEXT("Mute"),
+ WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX|BS_PUSHLIKE|BS_BITMAP, //BS_FLAT
+ HorizontalOffset, xControlsSpace,
+ ControlWidth, ControlsHeight,
+ hWnd(), (HMENU)ID_FS_MUTE, 0, 0);
+ SendMessage(hMuteButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP,
+ (LPARAM)RC().hVolumeBitmap);
+ HorizontalOffset+=ControlWidth+xControlsSpace;
ControlWidth = 100;
- fs_data->hVolumeSlider =
- CreateWindow(TRACKBAR_CLASS, TEXT("Volume"), WS_CHILD|WS_VISIBLE|TBS_HORZ|TBS_BOTTOM|TBS_AUTOTICKS,
- HorizontalOffset, ControlsSpace, ControlWidth, 21, hWnd, (HMENU)ID_FS_VOLUME, 0, 0);
- HorizontalOffset+=ControlWidth+ControlsSpace;
- SendMessage(fs_data->hVolumeSlider, TBM_SETRANGE, FALSE, (LPARAM) MAKELONG (0, 100));
- SendMessage(fs_data->hVolumeSlider, TBM_SETTICFREQ, (WPARAM) 10, 0);
- SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOOWNERZORDER);
+ hVolumeSlider =
+ CreateWindow(TRACKBAR_CLASS, TEXT("Volume"),
+ WS_CHILD|WS_VISIBLE|TBS_HORZ|TBS_BOTTOM|TBS_AUTOTICKS,
+ HorizontalOffset, xControlsSpace,
+ ControlWidth, ControlsHeight - 4, hWnd(),
+ (HMENU)ID_FS_VOLUME, 0, 0);
+ HorizontalOffset+=ControlWidth+xControlsSpace;
+ SendMessage(hVolumeSlider, TBM_SETRANGE, FALSE, (LPARAM) MAKELONG (0, 100));
+ SendMessage(hVolumeSlider, TBM_SETTICFREQ, (WPARAM) 10, 0);
+
+ ControlWidth = ButtonsWidth;
+ hFSButton =
+ CreateWindow(TEXT("BUTTON"), TEXT("Toggle fullscreen"),
+ WS_CHILD|WS_VISIBLE|BS_BITMAP|BS_FLAT,
+ HorizontalOffset, xControlsSpace,
+ ControlWidth, ControlsHeight, hWnd(),
+ (HMENU)ID_FS_SWITCH_FS, 0, 0);
+ SendMessage(hFSButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP,
+ (LPARAM)RC().hDeFullscreenBitmap);
+ HorizontalOffset+=ControlWidth+xControlsSpace;
+
+ RECT rect;
+ GetClientRect(GetParent(hWnd()), &rect);
int ControlWndWidth = HorizontalOffset;
- int ControlWndHeight = ControlsSpace+ControlsHeight+ControlsSpace;
- SetWindowPos(hWnd, HWND_TOPMOST, (GetSystemMetrics(SM_CXSCREEN)-ControlWndWidth)/2, 0,
- ControlWndWidth, ControlWndHeight, SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_NOACTIVATE);
+ int ControlWndHeight = xControlsSpace+ControlsHeight+xControlsSpace;
+ SetWindowPos(hWnd(), 0,
+ 0, (rect.bottom - rect.top) - ControlWndWidth,
+ rect.right-rect.left, ControlWndHeight,
+ SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_NOACTIVATE);
//new message blinking timer
- SetTimer(hWnd, 2, 500, NULL);
+ SetTimer(hWnd(), 2, 500, NULL);
- fs_data->CreateToolTip();
+ CreateToolTip();
break;
}
+ case WM_SHOWWINDOW:{
+ if(FALSE!=wParam){ //showing
+ UpdateButtons();
+ }
+ break;
+ }
case WM_LBUTTONUP:{
POINT BtnUpPoint = {LOWORD(lParam), HIWORD(lParam)};
RECT VideoPosRect;
- GetWindowRect(fs_data->hVideoPosScroll, &VideoPosRect);
- ClientToScreen(hWnd, &BtnUpPoint);
+ GetWindowRect(hVideoPosScroll, &VideoPosRect);
+ ClientToScreen(hWnd(), &BtnUpPoint);
if(PtInRect(&VideoPosRect, BtnUpPoint)){
- fs_data->SetVideoPos(float(BtnUpPoint.x-VideoPosRect.left)/(VideoPosRect.right-VideoPosRect.left));
+ SetVideoPos(float(BtnUpPoint.x-VideoPosRect.left)/(VideoPosRect.right-VideoPosRect.left));
}
break;
}
@@ -470,30 +239,18 @@ LRESULT CALLBACK VLCFullScreenWnd::FSControlsWndWindowProc(HWND hWnd, UINT uMsg,
POINT MousePoint;
GetCursorPos(&MousePoint);
RECT ControlWndRect;
- GetWindowRect(fs_data->hControlsWnd, &ControlWndRect);
- if(PtInRect(&ControlWndRect, MousePoint)||GetCapture()==fs_data->hVolumeSlider){
+ GetWindowRect(hWnd(), &ControlWndRect);
+ if(PtInRect(&ControlWndRect, MousePoint)||GetCapture()==hVolumeSlider){
//do not allow control window to close while mouse is within
- fs_data->NeedShowControls();
+ NeedShowControls();
}
else{
- fs_data->NeedHideControls();
+ NeedHideControls();
}
break;
}
case 2:{
- const VLCViewResources& rc = fs_data->RC();
- LRESULT lResult = SendMessage(fs_data->hFSButton, BM_GETIMAGE, (WPARAM)IMAGE_BITMAP, 0);
- if((HANDLE)lResult == rc.hDeFullscreenBitmap){
- if(fs_data->_WindowsManager->getNewMessageFlag()){
- SendMessage(fs_data->hFSButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)rc.hNewMessageBitmap);
- //do not allow control window to close while there are new messages
- fs_data->NeedShowControls();
- }
- }
- else{
- SendMessage(fs_data->hFSButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)rc.hDeFullscreenBitmap);
- }
-
+ UpdateButtons();
break;
}
}
@@ -501,7 +258,7 @@ LRESULT CALLBACK VLCFullScreenWnd::FSControlsWndWindowProc(HWND hWnd, UINT uMsg,
}
case WM_SETCURSOR:{
RECT VideoPosRect;
- GetWindowRect(fs_data->hVideoPosScroll, &VideoPosRect);
+ GetWindowRect(hVideoPosScroll, &VideoPosRect);
DWORD dwMsgPos = GetMessagePos();
POINT MsgPosPoint = {LOWORD(dwMsgPos), HIWORD(dwMsgPos)};
if(PtInRect(&VideoPosRect, MsgPosPoint)){
@@ -509,7 +266,7 @@ LRESULT CALLBACK VLCFullScreenWnd::FSControlsWndWindowProc(HWND hWnd, UINT uMsg,
return TRUE;
}
else{
- return DefWindowProc(hWnd, uMsg, wParam, lParam);
+ return VLCWnd::WindowProc(uMsg, wParam, lParam);
}
break;
}
@@ -522,21 +279,23 @@ LRESULT CALLBACK VLCFullScreenWnd::FSControlsWndWindowProc(HWND hWnd, UINT uMsg,
case BN_CLICKED:{
switch(Control){
case ID_FS_SWITCH_FS:
- fs_data->_WindowsManager->ToggleFullScreen();
+ WM().ToggleFullScreen();
break;
case ID_FS_PLAY_PAUSE:{
- libvlc_media_player_t* p_md = fs_data->getMD();
- if( p_md ){
- if(fs_data->IsPlaying()) libvlc_media_player_pause(p_md);
- else libvlc_media_player_play(p_md);
+ libvlc_media_player_t* mp = MP();
+ if( mp ){
+ if( IsPlaying() )
+ libvlc_media_player_pause(mp);
+ else
+ libvlc_media_player_play(mp);
}
break;
}
case ID_FS_MUTE:{
- libvlc_media_player_t* p_md = fs_data->getMD();
- if( p_md ){
- libvlc_audio_set_mute(p_md, IsDlgButtonChecked(hWnd, ID_FS_MUTE));
- fs_data->SyncVolumeSliderWithVLCVolume();
+ libvlc_media_player_t* mp = MP();
+ if( mp ){
+ libvlc_audio_set_mute(mp, IsDlgButtonChecked(hWnd(), ID_FS_MUTE));
+ SyncVolumeSliderWithVLCVolume();
}
break;
}
@@ -546,252 +305,589 @@ LRESULT CALLBACK VLCFullScreenWnd::FSControlsWndWindowProc(HWND hWnd, UINT uMsg,
}
break;
}
+ case WM_SIZE:{
+ const int new_client_width = LOWORD(lParam);
+ const int new_client_height = HIWORD(lParam);
+
+ HDWP hDwp = BeginDeferWindowPos(4);
+
+ int VideoScrollWidth = new_client_width;
+
+ POINT pt = {0, 0};
+ RECT rect;
+ GetWindowRect(hPlayPauseButton, &rect);
+ pt.x = rect.right;
+ ScreenToClient(hWnd(), &pt);
+ VideoScrollWidth -= pt.x;
+ VideoScrollWidth -= xControlsSpace;
+
+ RECT VideoSrcollRect;
+ GetWindowRect(hVideoPosScroll, &VideoSrcollRect);
+
+ RECT MuteRect;
+ GetWindowRect(hMuteButton, &MuteRect);
+ VideoScrollWidth -= xControlsSpace;
+ VideoScrollWidth -= (MuteRect.right - MuteRect.left);
+
+ RECT VolumeRect;
+ GetWindowRect(hVolumeSlider, &VolumeRect);
+ VideoScrollWidth -= xControlsSpace;
+ VideoScrollWidth -= (VolumeRect.right - VolumeRect.left);
+
+ RECT FSRect;
+ GetWindowRect(hFSButton, &FSRect);
+ VideoScrollWidth -= xControlsSpace;
+ VideoScrollWidth -= (FSRect.right - FSRect.left);
+ VideoScrollWidth -= xControlsSpace;
+
+ pt.x = VideoSrcollRect.left;
+ pt.y = VideoSrcollRect.top;
+ ScreenToClient(hWnd(), &pt);
+ hDwp = DeferWindowPos(hDwp, hVideoPosScroll, 0, pt.x, pt.y,
+ VideoScrollWidth,
+ VideoSrcollRect.bottom - VideoSrcollRect.top,
+ SWP_NOACTIVATE|SWP_NOOWNERZORDER);
+
+ int HorizontalOffset =
+ pt.x + VideoScrollWidth + xControlsSpace;
+ pt.x = 0;
+ pt.y = MuteRect.top;
+ ScreenToClient(hWnd(), &pt);
+ hDwp = DeferWindowPos(hDwp, hMuteButton, 0,
+ HorizontalOffset, pt.y, 0, 0,
+ SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOOWNERZORDER);
+ HorizontalOffset +=
+ MuteRect.right - MuteRect.left + xControlsSpace;
+
+ pt.x = 0;
+ pt.y = VolumeRect.top;
+ ScreenToClient(hWnd(), &pt);
+ hDwp = DeferWindowPos(hDwp, hVolumeSlider, 0,
+ HorizontalOffset, pt.y, 0, 0,
+ SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOOWNERZORDER);
+ HorizontalOffset +=
+ VolumeRect.right - VolumeRect.left + xControlsSpace;
+
+ pt.x = 0;
+ pt.y = FSRect.top;
+ ScreenToClient(hWnd(), &pt);
+ hDwp = DeferWindowPos(hDwp, hFSButton, 0,
+ HorizontalOffset, pt.y, 0, 0,
+ SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOOWNERZORDER);
+
+ EndDeferWindowPos(hDwp);
+ break;
+ }
case WM_HSCROLL:
case WM_VSCROLL: {
- libvlc_media_player_t* p_md = fs_data->getMD();
- if( p_md ){
- if(fs_data->hVolumeSlider==(HWND)lParam){
- LRESULT SliderPos = SendMessage(fs_data->hVolumeSlider, (UINT) TBM_GETPOS, 0, 0);
- fs_data->SetVLCVolumeBySliderPos(SliderPos);
+ libvlc_media_player_t* mp = MP();
+ if( mp ){
+ if(hVolumeSlider==(HWND)lParam){
+ LRESULT SliderPos = SendMessage(hVolumeSlider, (UINT) TBM_GETPOS, 0, 0);
+ SetVLCVolumeBySliderPos(SliderPos);
}
}
break;
}
default:
- return DefWindowProc(hWnd, uMsg, wParam, lParam);
+ return VLCWnd::WindowProc(uMsg, wParam, lParam);
}
return 0L;
+}
+
+void VLCControlsWnd::UpdateButtons()
+{
+ if(hVideoPosScroll){
+ SetVideoPosScrollRangeByVideoLen();
+ SyncVideoPosScrollPosWithVideoPos();
+ }
+
+ if(hVolumeSlider){
+ SyncVolumeSliderWithVLCVolume();
+ }
+
+ if(hFSButton) {
+ HANDLE hFSBitmap =
+ WM().IsFullScreen() ? RC().hDeFullscreenBitmap :
+ RC().hFullscreenBitmap;
+
+ HANDLE hBitmap =
+ (HANDLE)SendMessage(hFSButton, BM_GETIMAGE, (WPARAM)IMAGE_BITMAP, 0);
+
+ if( WM().getNewMessageFlag() &&
+ (hBitmap == RC().hDeFullscreenBitmap ||
+ hBitmap == RC().hFullscreenBitmap) )
+ {
+ SendMessage(hFSButton, BM_SETIMAGE,
+ (WPARAM)IMAGE_BITMAP,
+ (LPARAM)RC().hNewMessageBitmap);
+ //do not allow control window to close while there are new messages
+ NeedShowControls();
+ }
+ else{
+ if(hBitmap != hFSBitmap)
+ SendMessage(hFSButton, BM_SETIMAGE,
+ (WPARAM)IMAGE_BITMAP,
+ (LPARAM)hFSBitmap);
+ }
+ }
+
+ if(hPlayPauseButton){
+ HANDLE hBmp = IsPlaying() ? RC().hPauseBitmap : RC().hPlayBitmap;
+ SendMessage(hPlayPauseButton, BM_SETIMAGE,
+ (WPARAM)IMAGE_BITMAP, (LPARAM)hBmp);
+ }
+
+}
+
+void VLCControlsWnd::NeedShowControls()
+{
+ if( !IsWindowVisible( hWnd() ) ){
+ ShowWindow( hWnd(), SW_SHOW );
+ }
+ //hide controls after 2 seconds
+ SetTimer(hWnd(), 1, 2*1000, NULL);
+}
+
+void VLCControlsWnd::NeedHideControls()
+{
+ KillTimer( hWnd(), 1 );
+ ShowWindow( hWnd(), SW_HIDE );
+}
+
+void VLCControlsWnd::SyncVideoPosScrollPosWithVideoPos()
+{
+ libvlc_media_player_t* mp = MP();
+ if( mp ){
+ libvlc_time_t pos = libvlc_media_player_get_time(mp);
+ SetVideoPosScrollPosByVideoPos(pos);
+ }
+}
+
+void VLCControlsWnd::SetVideoPosScrollRangeByVideoLen()
+{
+ libvlc_media_player_t* mp = MP();
+ if( mp ){
+ libvlc_time_t MaxLen = libvlc_media_player_get_length(mp);
+ VideoPosShiftBits = 0;
+ while(MaxLen>0xffff){
+ MaxLen >>= 1;
+ ++VideoPosShiftBits;
+ };
+ SendMessage(hVideoPosScroll, (UINT)PBM_SETRANGE, 0, MAKELPARAM(0, MaxLen));
+ }
+}
+
+void VLCControlsWnd::SetVideoPosScrollPosByVideoPos(libvlc_time_t CurScrollPos)
+{
+ SendMessage(hVideoPosScroll, (UINT)PBM_SETPOS, (WPARAM) (CurScrollPos >> VideoPosShiftBits), 0);
+}
+
+void VLCControlsWnd::SetVideoPos(float Pos) //0-start, 1-end
+{
+ libvlc_media_player_t* mp = MP();
+ if( mp ){
+ libvlc_media_player_set_time(mp, static_cast<libvlc_time_t>(libvlc_media_player_get_length(mp)*Pos));
+ SyncVideoPosScrollPosWithVideoPos();
+ }
+}
+
+void VLCControlsWnd::SyncVolumeSliderWithVLCVolume()
+{
+ libvlc_media_player_t* mp = MP();
+ if( mp ){
+ int vol = libvlc_audio_get_volume(mp);
+ const LRESULT SliderPos = SendMessage(hVolumeSlider, (UINT) TBM_GETPOS, 0, 0);
+ if(SliderPos!=vol)
+ SendMessage(hVolumeSlider, (UINT) TBM_SETPOS, (WPARAM) TRUE, (LPARAM) vol);
+
+ bool muted = libvlc_audio_get_mute(mp)!=0;
+ int MuteButtonState = SendMessage(hMuteButton, (UINT) BM_GETCHECK, 0, 0);
+ if((muted&&(BST_UNCHECKED==MuteButtonState))||(!muted&&(BST_CHECKED==MuteButtonState))){
+ SendMessage(hMuteButton, BM_SETCHECK, (WPARAM)(muted?BST_CHECKED:BST_UNCHECKED), 0);
+ }
+ LRESULT lResult = SendMessage(hMuteButton, BM_GETIMAGE, (WPARAM)IMAGE_BITMAP, 0);
+ if( (muted && ((HANDLE)lResult == RC().hVolumeBitmap)) ||
+ (!muted&&((HANDLE)lResult == RC().hVolumeMutedBitmap)) )
+ {
+ HANDLE hBmp = muted ? RC().hVolumeMutedBitmap : RC().hVolumeBitmap ;
+ SendMessage(hMuteButton, BM_SETIMAGE,
+ (WPARAM)IMAGE_BITMAP, (LPARAM)hBmp);
+ }
+ }
+}
+
+void VLCControlsWnd::SetVLCVolumeBySliderPos(int CurPos)
+{
+ libvlc_media_player_t* mp = MP();
+ if( mp ){
+ libvlc_audio_set_volume(mp, CurPos);
+ if(0==CurPos){
+ libvlc_audio_set_mute(mp, IsDlgButtonChecked( hWnd(), ID_FS_MUTE) );
+ }
+ SyncVolumeSliderWithVLCVolume();
+ }
+}
+
+
+/////////////////////////////////////
+//VLCControlsWnd event handlers
+
+void VLCControlsWnd::handle_position_changed_event(const libvlc_event_t* event)
+{
+ SyncVideoPosScrollPosWithVideoPos();
+}
+
+void VLCControlsWnd::handle_input_state_event(const libvlc_event_t* event)
+{
+ switch( event->type )
+ {
+ case libvlc_MediaPlayerPlaying:
+ SendMessage(hPlayPauseButton, BM_SETIMAGE,
+ (WPARAM)IMAGE_BITMAP, (LPARAM)RC().hPauseBitmap);
+ break;
+ case libvlc_MediaPlayerPaused:
+ SendMessage(hPlayPauseButton, BM_SETIMAGE,
+ (WPARAM)IMAGE_BITMAP, (LPARAM)RC().hPlayBitmap);
+ break;
+ case libvlc_MediaPlayerStopped:
+ SendMessage(hPlayPauseButton, BM_SETIMAGE,
+ (WPARAM)IMAGE_BITMAP, (LPARAM)RC().hPlayBitmap);
+ break;
+ }
+}
+
+//libvlc events arrives from separate thread
+void VLCControlsWnd::OnLibVlcEvent(const libvlc_event_t* event)
+{
+ switch(event->type){
+ case libvlc_MediaPlayerPlaying:
+ case libvlc_MediaPlayerPaused:
+ case libvlc_MediaPlayerStopped:
+ handle_input_state_event(event);
+ break;
+ case libvlc_MediaPlayerPositionChanged:
+ handle_position_changed_event(event);
+ break;
+ }
+}
+
+/////////////////////////////////
+//VLCHolderWnd static members
+HINSTANCE VLCHolderWnd::_hinstance = 0;
+ATOM VLCHolderWnd::_holder_wndclass_atom = 0;
+
+enum{
+ WM_TRY_SET_MOUSE_HOOK = WM_USER+1,
+ WM_MOUSE_EVENT_NOTIFY = WM_APP+1,
+ WM_MOUSE_EVENT_NOTIFY_SUCCESS = 0xFF
};
-VLCFullScreenWnd* VLCFullScreenWnd::CreateFSWindow(VLCWindowsManager* WM)
+void VLCHolderWnd::RegisterWndClassName(HINSTANCE hInstance)
+{
+ //save hInstance for future use
+ _hinstance = hInstance;
+
+ WNDCLASS wClass;
+
+ if( ! GetClassInfo(_hinstance, getClassName(), &wClass) )
+ {
+ wClass.style = CS_DBLCLKS;
+ wClass.lpfnWndProc = VLCHolderClassWndProc;
+ wClass.cbClsExtra = 0;
+ wClass.cbWndExtra = 0;
+ wClass.hInstance = _hinstance;
+ wClass.hIcon = NULL;
+ wClass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
+ wClass.lpszMenuName = NULL;
+ wClass.lpszClassName = getClassName();
+
+ _holder_wndclass_atom = RegisterClass(&wClass);
+ }
+ else
+ {
+ _holder_wndclass_atom = 0;
+ }
+}
+
+void VLCHolderWnd::UnRegisterWndClassName()
+{
+ if(0 != _holder_wndclass_atom){
+ UnregisterClass(MAKEINTATOM(_holder_wndclass_atom), _hinstance);
+ _holder_wndclass_atom = 0;
+ }
+}
+
+VLCHolderWnd* VLCHolderWnd::CreateHolderWindow(HWND hParentWnd, VLCWindowsManager* WM)
{
HWND hWnd = CreateWindow(getClassName(),
- TEXT("VLC ActiveX Full Screen Window"),
- WS_POPUP|WS_CLIPCHILDREN,
- 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
- 0,
- 0,
- VLCFullScreenWnd::_hinstance,
- (LPVOID)WM
- );
+ TEXT("Holder Window"),
+ WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_VISIBLE,
+ 0, 0, 0, 0,
+ hParentWnd,
+ 0,
+ VLCHolderWnd::_hinstance,
+ (LPVOID)WM
+ );
+
if(hWnd)
- return reinterpret_cast<VLCFullScreenWnd*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
+ return reinterpret_cast<VLCHolderWnd*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
return 0;
}
-/////////////////////////////////////
-//VLCFullScreenWnd members
-VLCFullScreenWnd::~VLCFullScreenWnd()
+LRESULT CALLBACK VLCHolderWnd::VLCHolderClassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ VLCHolderWnd* h_data = reinterpret_cast<VLCHolderWnd*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
+
+ switch( uMsg )
+ {
+ case WM_CREATE:{
+ CREATESTRUCT* CreateStruct = (CREATESTRUCT*)(lParam);
+ VLCWindowsManager* WM = (VLCWindowsManager*)CreateStruct->lpCreateParams;
+
+ h_data = new VLCHolderWnd(hWnd, WM);
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(h_data));
+
+ RECT ParentClientRect;
+ GetClientRect(CreateStruct->hwndParent, &ParentClientRect);
+ MoveWindow(hWnd, 0, 0,
+ (ParentClientRect.right-ParentClientRect.left),
+ (ParentClientRect.bottom-ParentClientRect.top), FALSE);
+ break;
+ }
+ case WM_PAINT:{
+ PAINTSTRUCT PaintStruct;
+ HDC hDC = BeginPaint(hWnd, &PaintStruct);
+ RECT rect;
+ GetClientRect(hWnd, &rect);
+ int IconX = ((rect.right - rect.left) - GetSystemMetrics(SM_CXICON))/2;
+ int IconY = ((rect.bottom - rect.top) - GetSystemMetrics(SM_CYICON))/2;
+ DrawIcon(hDC, IconX, IconY, h_data->RC().hBackgroundIcon);
+ EndPaint(hWnd, &PaintStruct);
+ break;
+ }
+ case WM_NCDESTROY:
+ delete h_data;
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, 0);
+ break;
+ case WM_TRY_SET_MOUSE_HOOK:{
+ h_data->MouseHook(true);
+ break;
+ }
+ case WM_MOUSEMOVE:
+ case WM_LBUTTONDBLCLK:
+ h_data->_WindowsManager->OnMouseEvent(uMsg);
+ break;
+ case WM_MOUSE_EVENT_NOTIFY:{
+ h_data->_WindowsManager->OnMouseEvent(wParam);
+ return WM_MOUSE_EVENT_NOTIFY_SUCCESS;
+ }
+ default:
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+ }
+ return 0;
+};
+
+void VLCHolderWnd::DestroyWindow()
+{
+ LibVlcDetach();
+ if(_hWnd)
+ ::DestroyWindow(_hWnd);
+};
+
+LRESULT CALLBACK VLCHolderWnd::MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
- if(hToolTipWnd){
- ::DestroyWindow(hToolTipWnd);
- hToolTipWnd = 0;
- }
-}
+ bool AllowReceiveMessage = true;
+ if(nCode >= 0){
+ switch(wParam){
+ case WM_MOUSEMOVE:
+ case WM_LBUTTONDBLCLK:{
+ MOUSEHOOKSTRUCT* mhs = reinterpret_cast<MOUSEHOOKSTRUCT*>(lParam);
-void VLCFullScreenWnd::NeedShowControls()
-{
- if(!IsWindowVisible(hControlsWnd)){
- libvlc_media_player_t* p_md = getMD();
- if( p_md ){
- if(hVideoPosScroll){
- SetVideoPosScrollRangeByVideoLen();
- SyncVideoPosScrollPosWithVideoPos();
- }
- if(hVolumeSlider){
- SyncVolumeSliderWithVLCVolume();
- }
- if(hPlayPauseButton){
- HANDLE hBmp = IsPlaying() ? RC().hPauseBitmap : RC().hPlayBitmap;
- SendMessage(hPlayPauseButton, BM_SETIMAGE,
- (WPARAM)IMAGE_BITMAP, (LPARAM)hBmp);
+ //try to find HolderWnd and notify it
+ HWND hNotifyWnd = mhs->hwnd;
+ LRESULT SMRes = ::SendMessage(hNotifyWnd, WM_MOUSE_EVENT_NOTIFY, wParam, 0);
+ while( hNotifyWnd && WM_MOUSE_EVENT_NOTIFY_SUCCESS != SMRes){
+ hNotifyWnd = GetParent(hNotifyWnd);
+ SMRes = ::SendMessage(hNotifyWnd, WM_MOUSE_EVENT_NOTIFY, wParam, 0);
+ }
+
+ AllowReceiveMessage = WM_MOUSEMOVE==wParam || (WM_MOUSE_EVENT_NOTIFY_SUCCESS != SMRes);
+ break;
}
}
- ShowWindow(hControlsWnd, SW_SHOW);
}
- //hide controls after 2 seconds
- SetTimer(hControlsWnd, 1, 2*1000, NULL);
-}
-void VLCFullScreenWnd::NeedHideControls()
-{
- KillTimer(hControlsWnd, 1);
- ShowWindow(hControlsWnd, SW_HIDE);
+ LRESULT NHRes = CallNextHookEx(NULL, nCode, wParam, lParam);
+ if(AllowReceiveMessage)
+ return NHRes;
+ else
+ return 1;
}
-void VLCFullScreenWnd::SyncVideoPosScrollPosWithVideoPos()
+void VLCHolderWnd::MouseHook(bool SetHook)
{
- libvlc_media_player_t* p_md = getMD();
- if( p_md ){
- libvlc_time_t pos = libvlc_media_player_get_time(p_md);
- SetVideoPosScrollPosByVideoPos(pos);
- }
-}
+ if(SetHook){
+ const HWND hChildWnd = GetWindow(getHWND(), GW_CHILD);
+ const DWORD WndThreadID = (hChildWnd) ? GetWindowThreadProcessId(hChildWnd, NULL) : 0;
+ if( _hMouseHook &&( !hChildWnd || WndThreadID != _MouseHookThreadId) ){
+ //unhook if something changed
+ MouseHook(false);
+ }
-void VLCFullScreenWnd::SetVideoPosScrollRangeByVideoLen()
-{
- libvlc_media_player_t* p_md = getMD();
- if( p_md ){
- libvlc_time_t MaxLen = libvlc_media_player_get_length(p_md);
- VideoPosShiftBits = 0;
- while(MaxLen>0xffff){
- MaxLen >>= 1;
- ++VideoPosShiftBits;
- };
- SendMessage(hVideoPosScroll, (UINT)PBM_SETRANGE, 0, MAKELPARAM(0, MaxLen));
+ if(!_hMouseHook && hChildWnd && WndThreadID){
+ _MouseHookThreadId = WndThreadID;
+ _hMouseHook =
+ SetWindowsHookEx(WH_MOUSE, VLCHolderWnd::MouseHookProc,
+ NULL, WndThreadID);
+ }
+ }
+ else{
+ if(_hMouseHook){
+ UnhookWindowsHookEx(_hMouseHook);
+ _MouseHookThreadId=0;
+ _hMouseHook = 0;
+ }
}
}
-void VLCFullScreenWnd::SetVideoPosScrollPosByVideoPos(libvlc_time_t CurScrollPos)
+//libvlc events arrives from separate thread
+void VLCHolderWnd::OnLibVlcEvent(const libvlc_event_t* event)
{
- SendMessage(hVideoPosScroll, (UINT)PBM_SETPOS, (WPARAM) (CurScrollPos >> VideoPosShiftBits), 0);
+ //We need set hook to catch doubleclicking (to switch to fullscreen and vice versa).
+ //But libvlc media window may not exist yet,
+ //and we don't know when it will be created, nor ThreadId of it.
+ //So we try catch events,
+ //(suppose wnd will be ever created),
+ //and then try set mouse hook.
+ const HWND hChildWnd = GetWindow(getHWND(), GW_CHILD);
+ const DWORD WndThreadID = (hChildWnd) ? GetWindowThreadProcessId(hChildWnd, NULL) : 0;
+ //if no hook, or window thread has changed
+ if(!_hMouseHook || (hChildWnd && WndThreadID != _MouseHookThreadId)){
+ //libvlc events arrives from separate thread,
+ //so we need post message to main thread, to notify it.
+ PostMessage(getHWND(), WM_TRY_SET_MOUSE_HOOK, 0, 0);
+ }
}
-void VLCFullScreenWnd::SetVideoPos(float Pos) //0-start, 1-end
+void VLCHolderWnd::LibVlcAttach()
{
- libvlc_media_player_t* p_md = getMD();
- if( p_md ){
- libvlc_media_player_set_time(p_md, libvlc_media_player_get_length(p_md)*Pos);
- SyncVideoPosScrollPosWithVideoPos();
- }
+ libvlc_media_player_set_hwnd(getMD(), getHWND());
}
-void VLCFullScreenWnd::SyncVolumeSliderWithVLCVolume()
+void VLCHolderWnd::LibVlcDetach()
{
libvlc_media_player_t* p_md = getMD();
- if( p_md ){
- int vol = libvlc_audio_get_volume(p_md);
- const LRESULT SliderPos = SendMessage(hVolumeSlider, (UINT) TBM_GETPOS, 0, 0);
- if(SliderPos!=vol)
- SendMessage(hVolumeSlider, (UINT) TBM_SETPOS, (WPARAM) TRUE, (LPARAM) vol);
+ if(p_md)
+ libvlc_media_player_set_hwnd(p_md, 0);
- bool muted = libvlc_audio_get_mute(p_md);
- int MuteButtonState = SendMessage(hMuteButton, (UINT) BM_GETCHECK, 0, 0);
- if((muted&&(BST_UNCHECKED==MuteButtonState))||(!muted&&(BST_CHECKED==MuteButtonState))){
- SendMessage(hMuteButton, BM_SETCHECK, (WPARAM)(muted?BST_CHECKED:BST_UNCHECKED), 0);
- }
- LRESULT lResult = SendMessage(hMuteButton, BM_GETIMAGE, (WPARAM)IMAGE_BITMAP, 0);
- if( (muted && ((HANDLE)lResult == RC().hVolumeBitmap)) ||
- (!muted&&((HANDLE)lResult == RC().hVolumeMutedBitmap)) )
- {
- HANDLE hBmp = muted ? RC().hVolumeMutedBitmap : RC().hVolumeBitmap ;
- SendMessage(hMuteButton, BM_SETIMAGE,
- (WPARAM)IMAGE_BITMAP, (LPARAM)hBmp);
- }
- }
+ MouseHook(false);
}
-void VLCFullScreenWnd::SetVLCVolumeBySliderPos(int CurPos)
-{
- libvlc_media_player_t* p_md = getMD();
- if( p_md ){
- libvlc_audio_set_volume(p_md, CurPos);
- if(0==CurPos){
- libvlc_audio_set_mute(p_md, IsDlgButtonChecked(getHWND(), ID_FS_MUTE));
- }
- SyncVolumeSliderWithVLCVolume();
- }
-}
+////////////////////////////////////////////////////////////////////////////////
+//VLCFullScreenWnd members
+////////////////////////////////////////////////////////////////////////////////
+HINSTANCE VLCFullScreenWnd::_hinstance = 0;
+ATOM VLCFullScreenWnd::_fullscreen_wndclass_atom = 0;
-void VLCFullScreenWnd::CreateToolTip()
+void VLCFullScreenWnd::RegisterWndClassName(HINSTANCE hInstance)
{
- hToolTipWnd = CreateWindowEx(WS_EX_TOPMOST,
- TOOLTIPS_CLASS,
- NULL,
- WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- this->getHWND(),
- NULL,
- _hinstance,
- NULL);
-
- SetWindowPos(hToolTipWnd,
- HWND_TOPMOST,
- 0, 0, 0, 0,
- SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
-
-
- TOOLINFO ti;
- ti.cbSize = sizeof(TOOLINFO);
- ti.uFlags = TTF_SUBCLASS|TTF_IDISHWND;
- ti.hwnd = this->getHWND();
- ti.hinst = _hinstance;
+ //save hInstance for future use
+ _hinstance = hInstance;
- TCHAR HintText[100];
- RECT ActivateTTRect;
+ WNDCLASS wClass;
- //end fullscreen button tooltip
- GetWindowRect(this->hFSButton, &ActivateTTRect);
- GetWindowText(this->hFSButton, HintText, sizeof(HintText));
- ti.uId = (UINT_PTR)this->hFSButton;
- ti.rect = ActivateTTRect;
- ti.lpszText = HintText;
- SendMessage(hToolTipWnd, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+ memset(&wClass, 0 , sizeof(wClass));
+ if( ! GetClassInfo(_hinstance, getClassName(), &wClass) )
+ {
+ wClass.style = CS_NOCLOSE|CS_DBLCLKS;
+ wClass.lpfnWndProc = FSWndWindowProc;
+ wClass.cbClsExtra = 0;
+ wClass.cbWndExtra = 0;
+ wClass.hInstance = _hinstance;
+ wClass.hIcon = NULL;
+ wClass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wClass.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
+ wClass.lpszMenuName = NULL;
+ wClass.lpszClassName = getClassName();
- //play/pause button tooltip
- GetWindowRect(this->hPlayPauseButton, &ActivateTTRect);
- GetWindowText(this->hPlayPauseButton, HintText, sizeof(HintText));
- ti.uId = (UINT_PTR)this->hPlayPauseButton;
- ti.rect = ActivateTTRect;
- ti.lpszText = HintText;
- SendMessage(hToolTipWnd, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+ _fullscreen_wndclass_atom = RegisterClass(&wClass);
+ }
+ else
+ {
+ _fullscreen_wndclass_atom = 0;
+ }
- //mute button tooltip
- GetWindowRect(this->hMuteButton, &ActivateTTRect);
- GetWindowText(this->hMuteButton, HintText, sizeof(HintText));
- ti.uId = (UINT_PTR)this->hMuteButton;
- ti.rect = ActivateTTRect;
- ti.lpszText = HintText;
- SendMessage(hToolTipWnd, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
}
-
-/////////////////////////////////////
-//VLCFullScreenWnd event handlers
-void VLCFullScreenWnd::handle_position_changed_event(const libvlc_event_t* event)
+void VLCFullScreenWnd::UnRegisterWndClassName()
{
- SyncVideoPosScrollPosWithVideoPos();
+ if(0 != _fullscreen_wndclass_atom){
+ UnregisterClass(MAKEINTATOM(_fullscreen_wndclass_atom), _hinstance);
+ _fullscreen_wndclass_atom = 0;
+ }
}
-void VLCFullScreenWnd::handle_input_state_event(const libvlc_event_t* event)
+LRESULT CALLBACK VLCFullScreenWnd::FSWndWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
- const VLCViewResources& rc = RC();
- switch( event->type )
+ VLCFullScreenWnd* fs_data = reinterpret_cast<VLCFullScreenWnd *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
+
+ switch( uMsg )
{
- case libvlc_MediaPlayerPlaying:
- SendMessage(hPlayPauseButton, BM_SETIMAGE,
- (WPARAM)IMAGE_BITMAP, (LPARAM)rc.hPauseBitmap);
+ case WM_CREATE:{
+ CREATESTRUCT* CreateStruct = (CREATESTRUCT*)(lParam);
+ VLCWindowsManager* WM = (VLCWindowsManager*)CreateStruct->lpCreateParams;
+
+ fs_data = new VLCFullScreenWnd(hWnd, WM);
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(fs_data));
+
break;
- case libvlc_MediaPlayerPaused:
- SendMessage(hPlayPauseButton, BM_SETIMAGE,
- (WPARAM)IMAGE_BITMAP, (LPARAM)rc.hPlayBitmap);
+ }
+ case WM_NCDESTROY:
+ delete fs_data;
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, 0);
break;
- case libvlc_MediaPlayerStopped:
- SendMessage(hPlayPauseButton, BM_SETIMAGE,
- (WPARAM)IMAGE_BITMAP, (LPARAM)rc.hPlayBitmap);
+ case WM_SHOWWINDOW:{
+ if(FALSE==wParam){ //hiding
+ break;
+ }
+
+ //simulate lParam for WM_SIZE
+ RECT ClientRect;
+ GetClientRect(hWnd, &ClientRect);
+ lParam = MAKELPARAM(ClientRect.right, ClientRect.bottom);
+ }
+ case WM_SIZE:{
+ if(fs_data->_WindowsManager->IsFullScreen()){
+ int new_client_width = LOWORD(lParam);
+ int new_client_height = HIWORD(lParam);
+ VLCHolderWnd* HolderWnd = fs_data->_WindowsManager->getHolderWnd();
+ SetWindowPos(HolderWnd->getHWND(), HWND_BOTTOM, 0, 0, new_client_width, new_client_height, SWP_NOACTIVATE|SWP_NOOWNERZORDER);
+ }
break;
+ }
+ default:
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
-}
+ return 0L;
+};
-//libvlc events arrives from separate thread
-void VLCFullScreenWnd::OnLibVlcEvent(const libvlc_event_t* event)
+VLCFullScreenWnd* VLCFullScreenWnd::CreateFSWindow(VLCWindowsManager* WM)
{
- if( !_WindowsManager->IsFullScreen() )
- return;
+ HWND hWnd = CreateWindow(getClassName(),
+ TEXT("VLC ActiveX Full Screen Window"),
+ WS_POPUP|WS_CLIPCHILDREN,
+ 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
+ 0,
+ 0,
+ VLCFullScreenWnd::_hinstance,
+ (LPVOID)WM
+ );
+ if(hWnd)
+ return reinterpret_cast<VLCFullScreenWnd*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
- switch(event->type){
- case libvlc_MediaPlayerPlaying:
- case libvlc_MediaPlayerPaused:
- case libvlc_MediaPlayerStopped:
- handle_input_state_event(event);
- break;
- case libvlc_MediaPlayerPositionChanged:
- handle_position_changed_event(event);
- break;
- }
+ return 0;
}
///////////////////////
@@ -944,7 +1040,6 @@ void VLCWindowsManager::OnMouseEvent(UINT uMouseMsg)
DWORD MsgPos = GetMessagePos();
if(Last_WM_MOUSEMOVE_Pos != MsgPos){
Last_WM_MOUSEMOVE_Pos = MsgPos;
- if(IsFullScreen()) _FSWnd->NeedShowControls();
}
break;
}
diff --git a/common/win32_fullscreen.h b/common/win32_fullscreen.h
index 2a37a76..fba8e3a 100644
--- a/common/win32_fullscreen.h
+++ b/common/win32_fullscreen.h
@@ -28,6 +28,8 @@
#include <vlc/vlc.h>
+#include "win32_vlcwnd.h"
+
struct VLCViewResources
{
VLCViewResources()
@@ -46,6 +48,86 @@ struct VLCViewResources
HICON hBackgroundIcon;
};
+////////////////////////////////////////////////////////////////////////////////
+//class VLCControlsWnd
+////////////////////////////////////////////////////////////////////////////////
+class VLCWindowsManager;
+class VLCControlsWnd: public VLCWnd
+{
+ enum{
+ xControlsSpace = 5
+ };
+
+ enum{
+ ID_FS_SWITCH_FS = 1,
+ ID_FS_PLAY_PAUSE = 2,
+ ID_FS_VIDEO_POS_SCROLL = 3,
+ ID_FS_MUTE = 4,
+ ID_FS_VOLUME = 5,
+ };
+
+protected:
+ VLCControlsWnd(HINSTANCE hInstance, VLCWindowsManager* WM);
+ bool Create(HWND hWndParent);
+
+public:
+ static VLCControlsWnd*
+ CreateControlsWindow(HINSTANCE hInstance,
+ VLCWindowsManager* wm, HWND hWndParent);
+ ~VLCControlsWnd();
+
+ void NeedShowControls();
+
+ //libvlc events arrives from separate thread
+ void OnLibVlcEvent(const libvlc_event_t* event);
+
+protected:
+ virtual void PreRegisterWindowClass(WNDCLASS* wc);
+ virtual LRESULT WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+private:
+ void SetVideoPosScrollRangeByVideoLen();
+ void SyncVideoPosScrollPosWithVideoPos();
+ void SetVideoPos(float Pos); //0-start, 1-end
+
+ void SyncVolumeSliderWithVLCVolume();
+ void SetVLCVolumeBySliderPos(int CurScrollPos);
+ void SetVideoPosScrollPosByVideoPos(libvlc_time_t CurScrollPos);
+ void UpdateButtons();
+
+ void NeedHideControls();
+
+ void handle_position_changed_event(const libvlc_event_t* event);
+ void handle_input_state_event(const libvlc_event_t* event);
+
+ bool IsPlaying()
+ {
+ libvlc_media_player_t* mp = MP();
+ if( mp )
+ return libvlc_media_player_is_playing(mp) != 0;
+ return false;
+ }
+
+private:
+ VLCWindowsManager* _wm;
+
+ VLCWindowsManager& WM() {return *_wm;}
+ inline const VLCViewResources& RC();
+ inline libvlc_media_player_t* MP() const;
+
+ void CreateToolTip();
+
+private:
+ HWND hToolTipWnd;
+ HWND hFSButton;
+ HWND hPlayPauseButton;
+ HWND hVideoPosScroll;
+ HWND hMuteButton;
+ HWND hVolumeSlider;
+
+ int VideoPosShiftBits;
+};
+
class VLCWindowsManager;
///////////////////////
//VLCHolderWnd
@@ -111,21 +193,15 @@ private:
static LPCTSTR getClassName(void) { return TEXT("VLC ActiveX Fullscreen Class"); };
static LRESULT CALLBACK FSWndWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- static LPCTSTR getControlsClassName(void) { return TEXT("VLC ActiveX Fullscreen Controls Class"); };
- static LRESULT CALLBACK FSControlsWndWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
-
private:
static HINSTANCE _hinstance;
static ATOM _fullscreen_wndclass_atom;
- static ATOM _fullscreen_controls_wndclass_atom;
private:
VLCFullScreenWnd(HWND hWnd, VLCWindowsManager* WM)
- :_WindowsManager(WM), hControlsWnd(0), hToolTipWnd(0),
- hFSButton(0), hPlayPauseButton(0), hVideoPosScroll(0),
- hMuteButton(0), hVolumeSlider(0), _hWnd(hWnd) {};
+ :_WindowsManager(WM), _hWnd(hWnd) {};
- ~VLCFullScreenWnd();
+ ~VLCFullScreenWnd(){};
private:
VLCWindowsManager& WM()
@@ -133,28 +209,9 @@ private:
inline libvlc_media_player_t* getMD() const;
inline const VLCViewResources& RC() const;
- bool IsPlaying()
- {
- libvlc_media_player_t* p_md = getMD();
- int is_playing = 0;
- if( p_md ){
- is_playing = libvlc_media_player_is_playing(p_md);
- }
- return is_playing!=0;
- }
-
-private:
- void SetVideoPosScrollRangeByVideoLen();
- void SyncVideoPosScrollPosWithVideoPos();
- void SetVideoPos(float Pos); //0-start, 1-end
-
- void SyncVolumeSliderWithVLCVolume();
- void SetVLCVolumeBySliderPos(int CurScrollPos);
-
public:
- void NeedShowControls();
//libvlc events arrives from separate thread
- void OnLibVlcEvent(const libvlc_event_t* event);
+ void OnLibVlcEvent(const libvlc_event_t* event) {};
private:
void NeedHideControls();
@@ -165,24 +222,6 @@ private:
private:
VLCWindowsManager* _WindowsManager;
-private:
- HWND hControlsWnd;
- HWND hToolTipWnd;
-
- HWND hFSButton;
-
- HWND hPlayPauseButton;
-
- HWND hVideoPosScroll;
-
- HWND hMuteButton;
- HWND hVolumeSlider;
-
-private:
- void SetVideoPosScrollPosByVideoPos(libvlc_time_t CurPos);
- void handle_position_changed_event(const libvlc_event_t* event);
- void handle_input_state_event(const libvlc_event_t* event);
-
public:
HWND getHWND() const {return _hWnd;}
@@ -251,6 +290,16 @@ private:
////////////////////////////
//inlines
////////////////////////////
+inline libvlc_media_player_t* VLCControlsWnd::MP() const
+{
+ return _wm->getMD();
+}
+
+inline const VLCViewResources& VLCControlsWnd::RC()
+{
+ return _wm->RC();
+}
+
inline libvlc_media_player_t* VLCHolderWnd::getMD() const
{
return _WindowsManager->getMD();
--
1.7.7.1.msysgit.0
More information about the vlc-devel
mailing list