2016-04-22 13:06:22 -05:00
// 6 april 2015
# include "uipriv_windows.hpp"
2017-08-20 20:31:41 -05:00
std : : map < UINT_PTR , TimerHandler > timerHandlers ;
2016-04-22 13:36:21 -05:00
static HHOOK filter ;
static LRESULT CALLBACK filterProc ( int code , WPARAM wParam , LPARAM lParam )
{
MSG * msg = ( MSG * ) lParam ;
if ( code < 0 )
goto callNext ;
2016-04-22 13:56:09 -05:00
if ( areaFilter ( msg ) ) // don't continue to our IsDialogMessage() hack if the area handled it
goto discard ;
2016-04-22 13:36:21 -05:00
2016-04-22 13:56:09 -05:00
// TODO IsDialogMessage() hack here
// otherwise keep going
goto callNext ;
2016-04-22 13:36:21 -05:00
2016-04-22 13:56:09 -05:00
discard :
2016-04-22 13:36:21 -05:00
// we handled it; discard the message so the dialog manager doesn't see it
return 1 ;
callNext :
2016-04-23 21:29:54 -05:00
return CallNextHookEx ( filter , code , wParam , lParam ) ;
2016-04-22 13:36:21 -05:00
}
int registerMessageFilter ( void )
{
filter = SetWindowsHookExW ( WH_MSGFILTER ,
filterProc ,
hInstance ,
GetCurrentThreadId ( ) ) ;
return filter ! = NULL ;
}
void unregisterMessageFilter ( void )
{
2016-04-23 21:29:54 -05:00
if ( UnhookWindowsHookEx ( filter ) = = 0 )
2016-04-22 13:36:21 -05:00
logLastError ( L " error unregistering libui message filter " ) ;
}
2016-05-24 21:14:05 -05:00
// LONGTERM http://blogs.msdn.com/b/oldnewthing/archive/2005/04/08/406509.aspx when adding accelerators, TranslateAccelerators() before IsDialogMessage()
static void processMessage ( MSG * msg )
{
2016-05-29 18:55:53 -05:00
HWND correctParent ;
if ( msg - > hwnd ! = NULL )
correctParent = parentToplevel ( msg - > hwnd ) ;
else // just to be safe
correctParent = GetActiveWindow ( ) ;
if ( correctParent ! = NULL )
// this calls our mesage filter above for us
if ( IsDialogMessage ( correctParent , msg ) ! = 0 )
2016-05-24 21:14:05 -05:00
return ;
TranslateMessage ( msg ) ;
DispatchMessageW ( msg ) ;
}
static int waitMessage ( MSG * msg )
{
int res ;
res = GetMessageW ( msg , NULL , 0 , 0 ) ;
if ( res < 0 ) {
logLastError ( L " error calling GetMessage() " ) ;
return 0 ; // bail out on error
}
return res ! = 0 ; // returns false on WM_QUIT
}
2016-04-22 13:06:22 -05:00
void uiMain ( void )
2016-05-24 21:14:05 -05:00
{
while ( uiMainStep ( 1 ) )
;
}
2016-06-17 08:22:31 -05:00
void uiMainSteps ( void )
2016-06-16 13:12:47 -05:00
{
2016-06-17 08:22:31 -05:00
// don't need to do anything here
2016-06-16 13:12:47 -05:00
}
2016-05-24 21:14:05 -05:00
static int peekMessage ( MSG * msg )
{
BOOL res ;
res = PeekMessageW ( msg , NULL , 0 , 0 , PM_REMOVE ) ;
if ( res = = 0 )
return 2 ; // no message available
if ( msg - > message ! = WM_QUIT )
return 1 ; // a message
return 0 ; // WM_QUIT
}
int uiMainStep ( int wait )
2016-04-22 13:06:22 -05:00
{
MSG msg ;
2016-05-24 21:14:05 -05:00
if ( wait ) {
if ( ! waitMessage ( & msg ) )
return 0 ;
processMessage ( & msg ) ;
return 1 ;
}
// don't wait for a message
switch ( peekMessage ( & msg ) ) {
case 0 : // quit
// TODO PostQuitMessage() again?
return 0 ;
case 1 : // process a message
processMessage ( & msg ) ;
// fall out to the case for no message
2016-04-22 13:06:22 -05:00
}
2016-05-24 21:14:05 -05:00
return 1 ; // no message
2016-04-22 13:06:22 -05:00
}
void uiQuit ( void )
{
PostQuitMessage ( 0 ) ;
}
void uiQueueMain ( void ( * f ) ( void * data ) , void * data )
{
if ( PostMessageW ( utilWindow , msgQueued , ( WPARAM ) f , ( LPARAM ) data ) = = 0 )
2016-05-29 18:55:53 -05:00
// LONGTERM this is likely not safe to call across threads (allocates memory)
2016-04-22 13:06:22 -05:00
logLastError ( L " error queueing function to run on main thread " ) ;
}
2017-08-19 17:32:52 -05:00
void uiTimer ( int milliseconds , int ( * f ) ( void * data ) , void * data )
{
2017-08-20 20:31:41 -05:00
UINT_PTR id = timerHandlers . size ( ) + 1 ;
if ( SetTimer ( utilWindow , id , milliseconds , NULL ) = = 0 )
logLastError ( L " SetTimer() " ) ;
timerHandlers [ id ] = TimerHandler ( f , data ) ;
2017-08-19 17:32:52 -05:00
}