Commit a66bbe1e authored by Erwan Tulou's avatar Erwan Tulou

skins(Win32): Process events in the winProc (instead of the message loop)

Events like WM_PAINT should be processed in the WinProc, because
some functions directly call the WinProc (e.g UpdateWindow())
parent a38c6d0f
...@@ -45,7 +45,8 @@ ...@@ -45,7 +45,8 @@
#define MY_WM_TRAYACTION (WM_APP + 1) #define MY_WM_TRAYACTION (WM_APP + 1)
LRESULT CALLBACK Win32Proc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) LRESULT CALLBACK Win32Factory::Win32Proc( HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam )
{ {
// Get pointer to thread info: should only work with the parent window // Get pointer to thread info: should only work with the parent window
intf_thread_t *p_intf = (intf_thread_t *)GetWindowLongPtr( hwnd, intf_thread_t *p_intf = (intf_thread_t *)GetWindowLongPtr( hwnd,
...@@ -58,6 +59,7 @@ LRESULT CALLBACK Win32Proc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) ...@@ -58,6 +59,7 @@ LRESULT CALLBACK Win32Proc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
} }
Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( p_intf ); Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( p_intf );
GenericWindow *pWin = pFactory->m_windowMap[hwnd];
if( hwnd == pFactory->getParentWindow() ) if( hwnd == pFactory->getParentWindow() )
{ {
...@@ -92,19 +94,29 @@ LRESULT CALLBACK Win32Proc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) ...@@ -92,19 +94,29 @@ LRESULT CALLBACK Win32Proc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
p_intf->p_sys->p_theme->getWindowManager().raiseAll(); p_intf->p_sys->p_theme->getWindowManager().raiseAll();
CmdDlgHidePopupMenu aCmdPopup( p_intf ); CmdDlgHidePopupMenu aCmdPopup( p_intf );
aCmdPopup.execute(); aCmdPopup.execute();
return 0;
} }
else if( (UINT)lParam == WM_RBUTTONDOWN ) else if( (UINT)lParam == WM_RBUTTONDOWN )
{ {
CmdDlgShowPopupMenu aCmdPopup( p_intf ); CmdDlgShowPopupMenu aCmdPopup( p_intf );
aCmdPopup.execute(); aCmdPopup.execute();
return 0;
} }
else if( (UINT)lParam == WM_LBUTTONDBLCLK ) else if( (UINT)lParam == WM_LBUTTONDBLCLK )
{ {
CmdRestore aCmdRestore( p_intf ); CmdRestore aCmdRestore( p_intf );
aCmdRestore.execute(); aCmdRestore.execute();
return 0;
} }
} }
} }
else if( pWin )
{
Win32Loop* pLoop =
(Win32Loop*) OSFactory::instance( p_intf )->getOSLoop();
if( pLoop )
return pLoop->processEvent( hwnd, uMsg, wParam, lParam );
}
// If hwnd does not match any window or message not processed // If hwnd does not match any window or message not processed
return DefWindowProc( hwnd, uMsg, wParam, lParam ); return DefWindowProc( hwnd, uMsg, wParam, lParam );
...@@ -131,7 +143,7 @@ bool Win32Factory::init() ...@@ -131,7 +143,7 @@ bool Win32Factory::init()
// Create window class // Create window class
WNDCLASS skinWindowClass; WNDCLASS skinWindowClass;
skinWindowClass.style = CS_DBLCLKS; skinWindowClass.style = CS_DBLCLKS;
skinWindowClass.lpfnWndProc = (WNDPROC) Win32Proc; skinWindowClass.lpfnWndProc = (WNDPROC)Win32Factory::Win32Proc;
skinWindowClass.lpszClassName = _T("SkinWindowClass"); skinWindowClass.lpszClassName = _T("SkinWindowClass");
skinWindowClass.lpszMenuName = NULL; skinWindowClass.lpszMenuName = NULL;
skinWindowClass.cbClsExtra = 0; skinWindowClass.cbClsExtra = 0;
...@@ -325,7 +337,6 @@ OSPopup *Win32Factory::createOSPopup() ...@@ -325,7 +337,6 @@ OSPopup *Win32Factory::createOSPopup()
int Win32Factory::getScreenWidth() const int Win32Factory::getScreenWidth() const
{ {
return GetSystemMetrics(SM_CXSCREEN); return GetSystemMetrics(SM_CXSCREEN);
} }
......
...@@ -118,6 +118,10 @@ public: ...@@ -118,6 +118,10 @@ public:
HWND getParentWindow() { return m_hParentWindow; } HWND getParentWindow() { return m_hParentWindow; }
/// Callback function (Windows Procedure)
static LRESULT CALLBACK Win32Proc( HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam );
private: private:
/// Handle of the instance /// Handle of the instance
HINSTANCE m_hInst; HINSTANCE m_hInst;
......
...@@ -119,189 +119,190 @@ void Win32Loop::run() ...@@ -119,189 +119,190 @@ void Win32Loop::run()
// Compute windows message list // Compute windows message list
while( GetMessage( &msg, NULL, 0, 0 ) ) while( GetMessage( &msg, NULL, 0, 0 ) )
{ {
Win32Factory *pFactory = TranslateMessage( &msg );
(Win32Factory*)Win32Factory::instance( getIntf() ); DispatchMessage( &msg );
GenericWindow *pWin = pFactory->m_windowMap[msg.hwnd]; }
if( pWin == NULL ) }
LRESULT CALLBACK Win32Loop::processEvent( HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam )
{
Win32Factory *pFactory =
(Win32Factory*)Win32Factory::instance( getIntf() );
GenericWindow *pWin = pFactory->m_windowMap[hwnd];
GenericWindow &win = *pWin;
switch( msg )
{
case WM_PAINT:
{
PAINTSTRUCT Infos;
BeginPaint( hwnd, &Infos );
EvtRefresh evt( getIntf(),
Infos.rcPaint.left,
Infos.rcPaint.top,
Infos.rcPaint.right - Infos.rcPaint.left + 1,
Infos.rcPaint.bottom - Infos.rcPaint.top + 1 );
win.processEvent( evt );
EndPaint( hwnd, &Infos );
return 0;
}
case WM_COMMAND:
{ {
// We are probably getting a message for a tooltip (which has no EvtMenu evt( getIntf(), LOWORD( wParam ) );
// associated GenericWindow), for a timer, or for the parent window win.processEvent( evt );
DispatchMessage( &msg ); return 0;
continue;
} }
case WM_MOUSEMOVE:
{
// Needed to generate WM_MOUSELEAVE events
TRACKMOUSEEVENT TrackEvent;
TrackEvent.cbSize = sizeof( TRACKMOUSEEVENT );
TrackEvent.dwFlags = TME_LEAVE;
TrackEvent.hwndTrack = hwnd;
TrackEvent.dwHoverTime = 1;
TrackMouseEvent( &TrackEvent );
GenericWindow &win = *pWin; // Compute the absolute position of the mouse
switch( msg.message ) int x = GET_X_LPARAM( lParam ) + win.getLeft();
int y = GET_Y_LPARAM( lParam ) + win.getTop();
EvtMotion evt( getIntf(), x, y );
win.processEvent( evt );
return 0;
}
case WM_MOUSELEAVE:
{
EvtLeave evt( getIntf() );
win.processEvent( evt );
return 0;
}
case WM_MOUSEWHEEL:
{ {
case WM_PAINT: int x = GET_X_LPARAM( lParam ) - win.getLeft();
int y = GET_Y_LPARAM( lParam ) - win.getTop();
int mod = getMod( wParam );
if( GET_WHEEL_DELTA_WPARAM( wParam ) > 0 )
{ {
PAINTSTRUCT Infos; EvtScroll evt( getIntf(), x, y, EvtScroll::kUp, mod );
BeginPaint( msg.hwnd, &Infos );
EvtRefresh evt( getIntf(),
Infos.rcPaint.left,
Infos.rcPaint.top,
Infos.rcPaint.right - Infos.rcPaint.left + 1,
Infos.rcPaint.bottom - Infos.rcPaint.top + 1 );
EndPaint( msg.hwnd, &Infos );
win.processEvent( evt ); win.processEvent( evt );
break;
} }
case WM_COMMAND: else
{ {
EvtMenu evt( getIntf(), LOWORD( msg.wParam ) ); EvtScroll evt( getIntf(), x, y, EvtScroll::kDown, mod );
win.processEvent( evt ); win.processEvent( evt );
break;
} }
case WM_MOUSEMOVE: return 0;
{ }
// Needed to generate WM_MOUSELEAVE events case WM_LBUTTONDOWN:
TRACKMOUSEEVENT TrackEvent; {
TrackEvent.cbSize = sizeof( TRACKMOUSEEVENT ); SetCapture( hwnd );
TrackEvent.dwFlags = TME_LEAVE; EvtMouse evt( getIntf(), GET_X_LPARAM( lParam ),
TrackEvent.hwndTrack = msg.hwnd; GET_Y_LPARAM( lParam ), EvtMouse::kLeft,
TrackEvent.dwHoverTime = 1; EvtMouse::kDown, getMod( wParam ) );
TrackMouseEvent( &TrackEvent ); win.processEvent( evt );
return 0;
}
case WM_RBUTTONDOWN:
{
SetCapture( hwnd );
EvtMouse evt( getIntf(), GET_X_LPARAM( lParam ),
GET_Y_LPARAM( lParam ), EvtMouse::kRight,
EvtMouse::kDown, getMod( wParam ) );
win.processEvent( evt );
return 0;
}
case WM_LBUTTONUP:
{
ReleaseCapture();
EvtMouse evt( getIntf(), GET_X_LPARAM( lParam ),
GET_Y_LPARAM( lParam ), EvtMouse::kLeft,
EvtMouse::kUp, getMod( wParam ) );
win.processEvent( evt );
return 0;
}
case WM_RBUTTONUP:
{
ReleaseCapture();
EvtMouse evt( getIntf(), GET_X_LPARAM( lParam ),
GET_Y_LPARAM( lParam ), EvtMouse::kRight,
EvtMouse::kUp, getMod( wParam ) );
win.processEvent( evt );
return 0;
}
case WM_LBUTTONDBLCLK:
{
ReleaseCapture();
EvtMouse evt( getIntf(), GET_X_LPARAM( lParam ),
GET_Y_LPARAM( lParam ), EvtMouse::kLeft,
EvtMouse::kDblClick, getMod( wParam ) );
win.processEvent( evt );
return 0;
}
case WM_RBUTTONDBLCLK:
{
ReleaseCapture();
EvtMouse evt( getIntf(), GET_X_LPARAM( lParam ),
GET_Y_LPARAM( lParam ), EvtMouse::kRight,
EvtMouse::kDblClick, getMod( wParam ) );
win.processEvent( evt );
return 0;
}
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP:
{
// The key events are first processed here and not translated
// into WM_CHAR events because we need to know the status of
// the modifier keys.
// Compute the absolute position of the mouse // Get VLC key code from the virtual key code
int x = GET_X_LPARAM( msg.lParam ) + win.getLeft(); int key = virtKeyToVlcKey[wParam];
int y = GET_Y_LPARAM( msg.lParam ) + win.getTop(); if( !key )
EvtMotion evt( getIntf(), x, y );
win.processEvent( evt );
break;
}
case WM_MOUSELEAVE:
{ {
EvtLeave evt( getIntf() ); // This appears to be a "normal" (ascii) key
win.processEvent( evt ); key = tolower( MapVirtualKey( wParam, 2 ) );
break;
} }
case WM_MOUSEWHEEL:
if( key )
{ {
int x = GET_X_LPARAM( msg.lParam ) - win.getLeft(); // Get the modifier
int y = GET_Y_LPARAM( msg.lParam ) - win.getTop(); int mod = 0;
int mod = getMod( msg.wParam ); if( GetKeyState( VK_CONTROL ) & 0x8000 )
if( GET_WHEEL_DELTA_WPARAM( msg.wParam ) > 0 )
{ {
EvtScroll evt( getIntf(), x, y, EvtScroll::kUp, mod ); mod |= EvtInput::kModCtrl;
win.processEvent( evt );
} }
else if( GetKeyState( VK_SHIFT ) & 0x8000 )
{ {
EvtScroll evt( getIntf(), x, y, EvtScroll::kDown, mod ); mod |= EvtInput::kModShift;
win.processEvent( evt );
} }
break; if( GetKeyState( VK_MENU ) & 0x8000 )
}
case WM_LBUTTONDOWN:
{
SetCapture( msg.hwnd );
EvtMouse evt( getIntf(), GET_X_LPARAM( msg.lParam ),
GET_Y_LPARAM( msg.lParam ), EvtMouse::kLeft,
EvtMouse::kDown, getMod( msg.wParam ) );
win.processEvent( evt );
break;
}
case WM_RBUTTONDOWN:
{
SetCapture( msg.hwnd );
EvtMouse evt( getIntf(), GET_X_LPARAM( msg.lParam ),
GET_Y_LPARAM( msg.lParam ), EvtMouse::kRight,
EvtMouse::kDown, getMod( msg.wParam ) );
win.processEvent( evt );
break;
}
case WM_LBUTTONUP:
{
ReleaseCapture();
EvtMouse evt( getIntf(), GET_X_LPARAM( msg.lParam ),
GET_Y_LPARAM( msg.lParam ), EvtMouse::kLeft,
EvtMouse::kUp, getMod( msg.wParam ) );
win.processEvent( evt );
break;
}
case WM_RBUTTONUP:
{
ReleaseCapture();
EvtMouse evt( getIntf(), GET_X_LPARAM( msg.lParam ),
GET_Y_LPARAM( msg.lParam ), EvtMouse::kRight,
EvtMouse::kUp, getMod( msg.wParam ) );
win.processEvent( evt );
break;
}
case WM_LBUTTONDBLCLK:
{
ReleaseCapture();
EvtMouse evt( getIntf(), GET_X_LPARAM( msg.lParam ),
GET_Y_LPARAM( msg.lParam ), EvtMouse::kLeft,
EvtMouse::kDblClick, getMod( msg.wParam ) );
win.processEvent( evt );
break;
}
case WM_RBUTTONDBLCLK:
{
ReleaseCapture();
EvtMouse evt( getIntf(), GET_X_LPARAM( msg.lParam ),
GET_Y_LPARAM( msg.lParam ), EvtMouse::kRight,
EvtMouse::kDblClick, getMod( msg.wParam ) );
win.processEvent( evt );
break;
}
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP:
{
// The key events are first processed here and not translated
// into WM_CHAR events because we need to know the status of
// the modifier keys.
// Get VLC key code from the virtual key code
int key = virtKeyToVlcKey[msg.wParam];
if( !key )
{ {
// This appears to be a "normal" (ascii) key mod |= EvtInput::kModAlt;
key = tolower( MapVirtualKey( msg.wParam, 2 ) );
} }
if( key ) // Get the state
EvtKey::ActionType_t state;
if( msg == WM_KEYDOWN ||
msg == WM_SYSKEYDOWN )
{ {
// Get the modifier state = EvtKey::kDown;
int mod = 0;
if( GetKeyState( VK_CONTROL ) & 0x8000 )
{
mod |= EvtInput::kModCtrl;
}
if( GetKeyState( VK_SHIFT ) & 0x8000 )
{
mod |= EvtInput::kModShift;
}
if( GetKeyState( VK_MENU ) & 0x8000 )
{
mod |= EvtInput::kModAlt;
}
// Get the state
EvtKey::ActionType_t state;
if( msg.message == WM_KEYDOWN ||
msg.message == WM_SYSKEYDOWN )
{
state = EvtKey::kDown;
}
else
{
state = EvtKey::kUp;
}
EvtKey evt( getIntf(), key, state, mod );
win.processEvent( evt );
} }
break; else
{
state = EvtKey::kUp;
}
EvtKey evt( getIntf(), key, state, mod );
win.processEvent( evt );
} }
default: return 0;
TranslateMessage( &msg );
DispatchMessage( &msg );
} }
default:
break;
} }
return DefWindowProc( hwnd, msg, wParam, lParam );;
} }
......
...@@ -48,6 +48,10 @@ public: ...@@ -48,6 +48,10 @@ public:
/// Exit the main loop /// Exit the main loop
virtual void exit(); virtual void exit();
/// called by the window procedure callback
virtual LRESULT CALLBACK processEvent( HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam );
private: private:
// Private because it is a singleton // Private because it is a singleton
Win32Loop( intf_thread_t *pIntf ); Win32Loop( intf_thread_t *pIntf );
......
...@@ -69,8 +69,10 @@ Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow, ...@@ -69,8 +69,10 @@ Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow,
m_hWnd = CreateWindowEx( WS_EX_APPWINDOW, "SkinWindowClass", m_hWnd = CreateWindowEx( WS_EX_APPWINDOW, "SkinWindowClass",
"default name", WS_POPUP | WS_CLIPCHILDREN, "default name", WS_POPUP | WS_CLIPCHILDREN,
0, 0, 0, 0, NULL, 0, hInst, NULL ); 0, 0, 0, 0, NULL, 0, hInst, NULL );
}
// Store with it a pointer to the interface thread
SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() );
}
else else
{ {
// top-level window (owned by the root window) // top-level window (owned by the root window)
...@@ -78,6 +80,9 @@ Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow, ...@@ -78,6 +80,9 @@ Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow,
m_hWnd = CreateWindowEx( 0, "SkinWindowClass", m_hWnd = CreateWindowEx( 0, "SkinWindowClass",
"default name", WS_POPUP | WS_CLIPCHILDREN, "default name", WS_POPUP | WS_CLIPCHILDREN,
0, 0, 0, 0, hWnd_owner, 0, hInst, NULL ); 0, 0, 0, 0, hWnd_owner, 0, hInst, NULL );
// Store with it a pointer to the interface thread
SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() );
} }
if( !m_hWnd ) if( !m_hWnd )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment