📄 msgqueue.c
字号:
/******************************************************
Copyright(c) 版权所有,1998-2005微逻辑。保留所有权利。
******************************************************/
/*****************************************************
文件说明:消息,事件队列管理器
版本号:3.0.0
开发时期:1999
作者:李林
修改记录:
2003-10-07: 增加HWND 为NULL的处理
2003-06-23: AddToThreadQueue , 增加对队列的初始化代码
2003-06-03: 增加对 dwForegroundThreadID 的互斥
******************************************************/
#include <eframe.h>
#include <eassert.h>
#include <eobjtype.h>
#include <eapisrv.h>
#include <epwin.h>
#include <eevent.h>
#include <winsrv.h>
#include <gdisrv.h>
#include <bheap.h>
#include <gwmeobj.h>
extern _EVENTDRV _posEvent;
extern _EVENTDRV _timerEvent;
extern _EVENTDRV _keyEvent;
static BOOL _InsertThreadQueue( LPGWEDATA lpgwe, LPMSG lpMsg, DWORD dwEventType );
static int _CheckThreadQueue( LPGWEDATA lpgwe, _LPMSGDATA lpMsgRec, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, BOOL fRemove, BOOL fCheckChild );
static BOOL _InitThreadQueue( LPGWEDATA lpgwe );
void HandleSystemQueue( void );
static DWORD _dwSYSQueueState = 0;
static CRITICAL_SECTION csMsgQueue;
extern DWORD dwActiveTimerCount;
#ifdef EML_DOS
#include <dos.h>
#include <bios.h>
#endif
// declare post driver
static int _PostInstall(void);
static int _PostRelease(void);
static int _PostWho(void);
static int _PostPeek( LPMSG, UINT );
static int _PostPut( LPMSG );
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
LPGWEDATA GetGWEPtr( DWORD dwThreadId )
{
LPGWEDATA lpgwe = NULL;
if( dwThreadId )
{
lpgwe = (LPGWEDATA)GetThreadGWEPtr( dwThreadId );//TlsGetThreadValue( dwThreadId, TLS_MSGQUEUE );
if( lpgwe == NULL )
{
EnterCriticalSection( &csMsgQueue );
// lpgwe of thread may be change here, so i get it and check it again
lpgwe = (LPGWEDATA)GetThreadGWEPtr( dwThreadId );
if( lpgwe == NULL )
{
lpgwe = BlockHeap_Alloc( hgwmeBlockHeap, 0, sizeof(GWEDATA) );
if( lpgwe )
{
memset( lpgwe, 0, sizeof( GWEDATA ) );
_InitThreadQueue( lpgwe );
SetThreadGWEPtr( dwThreadId, lpgwe );
}
else
{
RETAILMSG( 1, ( "error : GetGWEPtr:no enough memory.\r\n" ) );
}
}
LeaveCriticalSection( &csMsgQueue );
}
}
else
{
RETAILMSG( 1, ( "GetGWEPtr error: invalid dwThreadId == 0.\r\n" ) );
}
return lpgwe;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
DWORD GetSYSQueueState( void )
{
return _dwSYSQueueState;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
DWORD SetSYSQueueState( DWORD dwStateBit, BOOL bSetBit )
{
DWORD dwOld = _dwSYSQueueState;
EnterCriticalSection( &csMsgQueue );
if( bSetBit )
{
extern HANDLE hgwmeEvent;
_dwSYSQueueState |= dwStateBit;
ASSERT( hgwmeEvent );
LeaveCriticalSection( &csMsgQueue );
if( hgwmeEvent )
SetEvent(hgwmeEvent);
}
else
{
_dwSYSQueueState &= ~dwStateBit;
LeaveCriticalSection( &csMsgQueue );
}
return dwOld;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
BOOL _InitSysQueue( void )
{
InitializeCriticalSection( &csMsgQueue );
_posEvent.lpInstall();
_timerEvent.lpInstall();
_keyEvent.lpInstall();
return TRUE;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
static BOOL _InitQueue( _MSGQUEUE * lpmq, int nInitSize )
{
void * p;
int size = nInitSize * sizeof(_MSGDATA);
ASSERT( lpmq->size == 0 );
memset( lpmq, 0, sizeof( _MSGQUEUE ) );
InitializeCriticalSection( &lpmq->csThreadQueue );
lpmq->csThreadQueue.lpcsName = "CS-QUE";
lpmq->hWaitEvent = CreateEvent( NULL, FALSE, 0, NULL );
p = malloc( size );
if( p )
{
memset( p, 0, size );
lpmq->size = nInitSize;
lpmq->nQueueTail = lpmq->nQueueHead = 0;
lpmq->lpMsgData = (_LPMSGDATA)p;
}
return p != NULL;
}
/// free the message queue with the thread
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
BOOL FASTCALL MQ_FreeThreadQueue( void )
{
LPGWEDATA lpgwe = TlsGetValue( TLS_MSGQUEUE );
if( lpgwe )
{
TlsSetValue( TLS_MSGQUEUE, 0 );
if( lpgwe->msgQueue.csThreadQueue.hSemaphore )
{
EnterCriticalSection( &lpgwe->msgQueue.csThreadQueue );
LeaveCriticalSection( &lpgwe->msgQueue.csThreadQueue );
DeleteCriticalSection( &lpgwe->msgQueue.csThreadQueue );
}
if( lpgwe->msgQueue.hWaitEvent )
CloseHandle( lpgwe->msgQueue.hWaitEvent );
if( lpgwe->msgQueue.lpMsgData )
{
free( lpgwe->msgQueue.lpMsgData );
lpgwe->msgQueue.lpMsgData = NULL;
}
BlockHeap_Free( hgwmeBlockHeap, 0, lpgwe, sizeof(GWEDATA) );
}
return TRUE;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
static BOOL _InsertQueue(_MSGQUEUE * lpQueue, LPMSG lpMsg, UINT eventType )
{
BOOL bRetv = FALSE;
ASSERT( lpMsg->hwnd != INVALID_HANDLE_VALUE );
EnterCriticalSection( &lpQueue->csThreadQueue );
_I_REPEAT:
if( lpQueue->count < lpQueue->size )
{
lpQueue->lpMsgData[lpQueue->nQueueTail].msg = *lpMsg;
lpQueue->lpMsgData[lpQueue->nQueueTail].eventType = (WORD)eventType;
if( ++(lpQueue->nQueueTail) >= lpQueue->size)
lpQueue->nQueueTail = 0;
lpQueue->count++;
bRetv = TRUE;
}
else
{ //queue is full
_LPMSGDATA p;
p = (_LPMSGDATA)realloc( lpQueue->lpMsgData, (lpQueue->size+8) * sizeof(_MSGDATA) );
if( p )
{
int i;
lpQueue->nQueueTail = lpQueue->size;
lpQueue->size += 8;
lpQueue->lpMsgData = p;
for ( i = 0; i < lpQueue->nQueueHead; i++ )
{
lpQueue->lpMsgData[lpQueue->nQueueTail] = lpQueue->lpMsgData[i];
if( ++(lpQueue->nQueueTail) >= lpQueue->size )
lpQueue->nQueueTail = 0;
}
goto _I_REPEAT;
}
else
{
RETAILMSG( 1, ( "error: in _InsertQueue, no enough memory!.\r\n" ) );
}
}
LeaveCriticalSection( &lpQueue->csThreadQueue );
return bRetv;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
static BOOL _RemoveQueue(_MSGQUEUE *lpQueue)
{
BOOL bRetv = TRUE;
EnterCriticalSection( &lpQueue->csThreadQueue );
if( lpQueue->count > 0 )
{
if( ++(lpQueue->nQueueHead) >= lpQueue->size )
lpQueue->nQueueHead = 0;
lpQueue->count--;
}
else
bRetv = FALSE;
LeaveCriticalSection( &lpQueue->csThreadQueue );
return bRetv;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
static BOOL _InitThreadQueue( LPGWEDATA lpgwe )
{
{
{
_InitQueue( &lpgwe->msgQueue, 8 );
return TRUE;
}
}
ASSERT( 0 );
return 0;
}
// **************************************************
// 声明:DWORD WINAPI _WinSys_WaitMessage( DWORD dwTimeOut )
// 参数:
// dwTimeOut - 超时等待时间
// 返回值:
// 假入成功,返回WAIT_OBJET_0;否则,返回WAIT_FAILED
// 功能描述:
//
// 引用:
//
// ************************************************
DWORD WINAPI _WinSys_WaitMessage( DWORD dwTimeOut )
{
#ifdef SINGLE_THREAD
return WAIT_OBJECT_0;
#else
LPGWEDATA lpgwe = GetGWEPtr( GetCurrentThreadId() );
if( lpgwe )
return WaitForSingleObject( lpgwe->msgQueue.hWaitEvent, dwTimeOut );
else
return WAIT_FAILED;
#endif
}
// **************************************************
// 声明:VOID WINAPI _WinSys_SetMessageEvent( void )
// 参数:
// 无
// 返回值:
// 无
// 功能描述:
// 设置消息事件
// 引用:
//
// ************************************************
VOID WINAPI _WinSys_SetMessageEvent( DWORD dwThreadId )
{
LPGWEDATA lpgwe = GetGWEPtr( dwThreadId );
if( lpgwe )
{
SetEvent( lpgwe->msgQueue.hWaitEvent );
}
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
BOOL WINAPI _WinSys_PostThreadMessage( DWORD dwThreadID, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
LPGWEDATA lpgwe = GetThreadGWEPtr( dwThreadID );
if( lpgwe )
{
//put message to queue
MSG msg;
memset( &msg, 0, sizeof( msg ) );
msg.hwnd = NULL;
msg.lParam = lParam;
msg.message = uMsg;
msg.wParam = wParam;
_InsertThreadQueue( lpgwe, &msg, QS_POSTMESSAGE );
return TRUE;
}
return FALSE;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
static BOOL _InsertThreadQueue( LPGWEDATA lpgwe, LPMSG lpMsg, DWORD dwEventType )
{
if( lpgwe->msgQueue.size )
{
_InsertQueue( &lpgwe->msgQueue, lpMsg, dwEventType );
lpgwe->msgQueue.dwEventMask |= dwEventType;
SetEvent( lpgwe->msgQueue.hWaitEvent );
return TRUE;
}
else
{
RETAILMSG( 1, ( "error: in _InsertThreadQueue, lpgwe->msgQueue.size == 0!.\r\n" ) );
}
return FALSE;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
BOOL AddMsgToThreadQueue( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT uFlag )
{
MSG mst;
DWORD dwID;
LPGWEDATA lpgwe;
BOOL bRetv = FALSE;
if( hWnd )
{
dwID = Win_GetThreadProcessId( hWnd, NULL );
if( dwID == 0 )
dwID = Win_GetThreadProcessId( hWnd, NULL );
lpgwe = GetGWEPtr( dwID );
//RETAILMSG( 1, ( "test1.\r\n" ) );
if( lpgwe )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -