📄 msgqueue.c
字号:
{
//RETAILMSG( 1, ( "test2.\r\n" ) );
if( (uFlag & ATQ_ONLYONE) )
{
//RETAILMSG( 1, ( "test3.\r\n" ) );
if( !_CheckThreadQueue( lpgwe, 0, hWnd, msg, msg, FALSE, 0 ) )
{
mst.message = msg;
mst.wParam = wParam;
mst.lParam = lParam;
mst.hwnd = hWnd;
bRetv = _InsertThreadQueue( lpgwe, &mst, uFlag & QS_EVENT_MASK );
}
}
else
{
//RETAILMSG( 1, ( "test4.\r\n" ) );
// LN, 2003-06-23-begin
if( !lpgwe->msgQueue.size )
{ // 第一次, create a queue
//RETAILMSG( 1, ( "test4-1.\r\n" ) );
if( !_InitThreadQueue(lpgwe) )
{
//RETAILMSG( 1, ( "error: in AddToThreadQueue, !_InitThreadQueue(lpgwe).\r\n" ) );
return FALSE;
}
}
// LN, 2003-06-23-end
//RETAILMSG( 1, ( "test5.\r\n" ) );
mst.message = msg;
mst.wParam = wParam;
mst.lParam = lParam;
mst.hwnd = hWnd;
bRetv = _InsertThreadQueue( lpgwe, &mst, uFlag & QS_EVENT_MASK );
}
}
else
{
RETAILMSG( 1, ( "error: AddToThreadQueue, no lpgwe!.\r\n" ) );
}
}
return bRetv;
}
// **************************************************
// 声明:BOOL ClearThreadQueue( DWORD dwThreadId, HWND hWnd, UINT msgStart, UINT msgEnd )
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 从线程队列清除窗口消息
// 引用:
//
// ************************************************
BOOL ClearThreadQueue( DWORD dwThreadID, HWND hWnd, UINT msgStart, UINT msgEnd )
{ // if 0xffffffff, all msg about the window
_MSGQUEUE * lpmq;
LPGWEDATA lpgwe;
BOOL bRetv = TRUE;
ASSERT( msgStart <= msgEnd );
if( dwThreadID == 0 )
{
if( hWnd )
dwThreadID = _GetHWNDPtr(hWnd)->dwThreadID;
else
dwThreadID = GetCurrentThreadId();
}
lpgwe = GetGWEPtr( dwThreadID );
if( lpgwe && lpgwe->msgQueue.size )
{
int count;
int nHead;
int nTail;
int nSize;
_LPMSGDATA lpMsgData;
lpmq = &lpgwe->msgQueue;
EnterCriticalSection( &lpmq->csThreadQueue );
if( (count = lpmq->count) == 0 )
{
goto CLEAR_LEAVE;
}
nHead = lpmq->nQueueHead;
nTail = lpmq->nQueueTail;
nSize = lpmq->size;
lpMsgData = (lpmq->lpMsgData+lpmq->nQueueHead);
while( count > 0 )
{
if( hWnd == NULL ||
lpMsgData->msg.hwnd == hWnd )
{
if( msgStart == 0 &&
msgEnd == 0 )
lpMsgData->msg.hwnd = INVALID_HANDLE_VALUE;
else if( msgStart <= lpMsgData->msg.message &&
msgEnd >= lpMsgData->msg.message )
lpMsgData->msg.hwnd = INVALID_HANDLE_VALUE;
}
lpMsgData++;
if( ++nHead >= nSize )
{
nHead = 0;
lpMsgData = lpmq->lpMsgData;
}
count--;
}
CLEAR_LEAVE:
LeaveCriticalSection( &lpmq->csThreadQueue );
}
return bRetv;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
static int _CheckThreadQueue( LPGWEDATA lpgwe, _LPMSGDATA lpMsgRec, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, BOOL fRemove, BOOL fCheckChild )
{
int retv = FALSE;
BOOL bFilterWindow = (BOOL)hWnd;
BOOL bFilterMsg = wMsgFilterMax | wMsgFilterMin;
if( lpgwe == NULL )
{
return 0;
}
if( !lpgwe->msgQueue.size )
{ // create a queue
if( !_InitThreadQueue(lpgwe) )
return 0;
}
{
_MSGQUEUE * lpmq = &lpgwe->msgQueue;
EnterCriticalSection( &lpmq->csThreadQueue );
if( lpmq->count > 0 )
{
int nHead = lpmq->nQueueHead;
int nSize = lpmq->size;
int nCount = lpmq->count;
BOOL bClearInvalidMsg = FALSE;
_LPMSGDATA lpMsgData = lpmq->lpMsgData+lpmq->nQueueHead;
while( nCount )
{
HWND hwndMsg = lpMsgData->msg.hwnd;
UINT message = lpMsgData->msg.message;
if( hwndMsg == INVALID_HANDLE_VALUE ||
(hwndMsg && !Win_IsWindow(hwndMsg)) )
{
if( bFilterWindow || bFilterMsg )
{
bClearInvalidMsg = TRUE;
lpMsgData->msg.hwnd = INVALID_HANDLE_VALUE;
goto _L_NEXT;
}
else
{ // remove the message
if( ++(lpmq->nQueueHead) >= lpmq->size )
lpmq->nQueueHead = 0;
lpmq->count--;
goto _L_NEXT;
}
}
if( bFilterWindow )
{
if( hwndMsg != hWnd )
{
if( !( fCheckChild && hwndMsg && Win_IsChild( hWnd, hwndMsg ) ) )
goto _L_NEXT;
}
}
if( bFilterMsg &&
(message < wMsgFilterMin || message > wMsgFilterMax ) )
{
goto _L_NEXT;
}
// a valid message
if( lpMsgRec )
*lpMsgRec = *lpMsgData;
if( fRemove && message != WM_PAINT )
{
if( bFilterWindow || bFilterMsg )
{
lpMsgData->msg.hwnd = INVALID_HANDLE_VALUE;
bClearInvalidMsg = TRUE;
}
else
{
if( ++(lpmq->nQueueHead) >= lpmq->size )
lpmq->nQueueHead = 0;
lpmq->count--;
}
}
retv = TRUE;
break;
_L_NEXT:
if( ++nHead >= nSize )
{
nHead = 0;
lpMsgData = lpmq->lpMsgData;
}
else
lpMsgData++;
nCount--;
}
// clear invalid message if possible
if( bClearInvalidMsg )
{
int nSave, nSaveCount;
_LPMSGDATA lpSaveMsg;
nSave = nHead = lpmq->nQueueHead;
nCount = lpmq->count;
lpSaveMsg = lpMsgData = lpmq->lpMsgData+lpmq->nQueueHead;
nSaveCount = 0;
while( nCount )
{
if( lpMsgData->msg.hwnd != INVALID_HANDLE_VALUE )
{
nSaveCount++;
if( lpSaveMsg != lpMsgData )
*lpSaveMsg = *lpMsgData;
if( ++nSave >= nSize )
{
nSave = 0;
lpSaveMsg = lpmq->lpMsgData;
}
else
lpSaveMsg++;
}
if( ++nHead >= nSize )
{
nHead = 0;
lpMsgData = lpmq->lpMsgData;
}
else
lpMsgData++;
nCount--;
}
lpmq->count = nSaveCount;
lpmq->nQueueTail = nSave;
}
}
LeaveCriticalSection( &lpmq->csThreadQueue );
}
return retv;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
int CheckThreadQueue( _LPMSGDATA lpMsgRec, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, BOOL fRemove, BOOL fCheckChild )
{
LPGWEDATA lpgwe = GetGWEPtr( GetCurrentThreadId() );
if( lpgwe )
{
lpgwe->msgQueue.dwEventMask = 0; // clear
return _CheckThreadQueue( lpgwe, lpMsgRec, hWnd, wMsgFilterMin, wMsgFilterMax, fRemove, fCheckChild );
}
return 0;
}
typedef void (*LPEVENTPROC)(void);
static void _DoMouseEvent(void);
static void _DoKeyEvent(void);
static void _DoTimerEvent(void);
LPEVENTPROC lpEventProc[32] = {
//_DoPostEvent, // ES_POSTMESSAGE
_DoKeyEvent, // ES_KEY
_DoMouseEvent, // ES_MOUSEMOVE
_DoMouseEvent, // ES_MOUSEBUTTON
NULL, // QS_POSTMESSAGE
_DoTimerEvent, // ES_TIMER
// from 4~30
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0, };
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
static void _DoMouseEvent( void )
{
extern HWND _Win_FromPoint( POINT pt, int * lpfDisable );
MSG msg;
HWND hWnd = NULL;
int fDisable;
LPGWEDATA lpgweFore = NULL;
DWORD dwForeThreadID;
dwActiveTimerCount = GetTickCount();
memset( &msg, 0, sizeof( msg ) );
dwForeThreadID = LockForegroundThreadId();
if( dwForeThreadID )
lpgweFore = GetGWEPtr( dwForeThreadID );
UnlockForegroundThreadId();
while( _posEvent.lpPeek( &msg, PM_REMOVE ) )
{
static DWORD dwDownThreadID = 0;
LPGWEDATA lpgwe;
int bPostMsg = FALSE;
DWORD dwWindowThreadID = 0;
hWnd = _Win_FromPoint( msg.pt, &fDisable );
if( hWnd )
dwWindowThreadID = GetWindowThreadProcessId( hWnd, NULL );
if( lpgweFore && lpgweFore->hwndCapture )
{
msg.hwnd = lpgweFore->hwndCapture;
_InsertThreadQueue( lpgweFore, &msg, QS_MOUSE );
bPostMsg = TRUE;
if( dwWindowThreadID == dwForeThreadID )
dwWindowThreadID = 0; // 不要再给dwWindowThreadID发消息
}
if( bPostMsg == FALSE && dwDownThreadID )
{ // when the downwindow's thread is capturing the mouse but
// the downwindow is not foreground thread,
// the handle here
if( dwDownThreadID != dwForeThreadID &&
dwDownThreadID != dwWindowThreadID )
{
lpgwe = GetGWEPtr( dwDownThreadID );
if( lpgwe )
{
if( lpgwe->hwndCapture )
{
_InsertThreadQueue( lpgwe, &msg, QS_MOUSE );
bPostMsg = TRUE;
}
}
else
dwDownThreadID = 0;
}
}
if( dwWindowThreadID )
{
lpgwe = GetGWEPtr( dwWindowThreadID );
if( lpgwe )
{
msg.hwnd = hWnd;
_InsertThreadQueue( lpgwe, &msg, QS_MOUSE );
}
}
if( msg.message == WM_LBUTTONDOWN )
{
dwDownThreadID = dwWindowThreadID;
}
else if( msg.message == WM_LBUTTONUP ) // up
dwDownThreadID = 0;
}
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
static void _DoKeyEvent( void )
{
MSG msg;
DWORD dwID = LockForegroundThreadId();
LPGWEDATA lpgwe = NULL;
if( dwID )
{
lpgwe = GetGWEPtr( dwID );
}
UnlockForegroundThreadId();
dwActiveTimerCount = GetTickCount();
if( dwID )
{
memset( &msg, 0, sizeof( msg ) );
if( lpgwe )
{
msg.hwnd = lpgwe->hwndFocus;
while( _keyEvent.lpPeek( &msg, PM_REMOVE ) )
{
if( msg.hwnd )
_InsertThreadQueue( lpgwe, &msg, QS_KEY );
}
return;
}
}
//clear key event if no any window need
while( _keyEvent.lpPeek( &msg, TRUE ) )
;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
static void _DoTimerEvent( void )
{
MSG msg;
while( _timerEvent.lpPeek( &msg, PM_REMOVE ) )
{
if( msg.hwnd )
{
AddMsgToThreadQueue( msg.hwnd, msg.message, msg.wParam, msg.lParam, ATQ_ONLYONE | QS_TIMER );
}
}
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
void HandleSystemQueue( void )
{
int i = 0;
BOOL bHasEvent = FALSE;
LPEVENTPROC * lpProc = lpEventProc;
DWORD dwState;
EnterCriticalSection( &csMsgQueue );
dwState = _dwSYSQueueState;
_dwSYSQueueState = 0;
LeaveCriticalSection( &csMsgQueue );
for( i = 0; i < 31 && dwState; i++, lpProc++ )
{
if( dwState & 0x1 )
{
if( *lpProc )
(*lpProc)();
bHasEvent = TRUE;
}
dwState >>= 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -