上一篇:MiniGUI源码分析--hellowworld(2):主窗口诞生的秘密
这本篇中,将重点介绍MiniGUI的消息。
在MiniGUI中,有以下几种消息:
1. 同步消息,由SendMessage、SendSyncMessage发送的同步消息,消息将被立即处理,消息的返回值将通过函数的返回值返回;
2. Notify消息,通过SendNotifyMessage发送 。这是一个异步的消息,但是一定能够被处理
3. Post消息,通过PostMessage发送,这也是一个异步消息,可能会丢失
4. 特殊的消息,包括MSG_PAINT和MSG_TIMER,MSG_QUIT,这三个消息是系统消息,在消息队列中,实际上以标志位的方式存在。MSG_PAINT消息可以由InvalidateRect和 UpdateRect两个函数引起。而MSG_TIMER消息,则必须由系统产生。MSG_QUIT只能通过PostQuitMessage产生
消息的优先级是这样定义的:MSG_QUIT > 同步消息 > Notify消息 > Post消息 > MSG_PAINT > MSG_TIMER消息。
在上一篇中,在创建一个窗口时,我们使用了函数 InitMsgQueueThisThread(3.0版本的为mg_InitMsgQueueThisThread)和GetMsgQueueThisThread,前者为当前线程创建一个消息队列(仅限线程版,进程版和standalone版都只有一个消息队列),后者是获取当前线程的消息队列。
InitMsgQueueThisThread函数本身很简单。它主要是创建和初始化MSGQUEUE结构体。(_LITE_VERSION代表的是进程版和standalone版。在3.0中,这个宏已经被规范为_MGRM_PROCESSES 和_MGRM_STANDALONE。)
struct _MSGQUEUE
{
DWORD dwState; // message queue states
#ifndef _LITE_VERSION
pthread_mutex_t lock; // lock
sem_t wait; // the semaphore for wait message
sem_t sync_msg; // the semaphore for sync message
#endif
PQMSG pFirstNotifyMsg; // head of the notify message queue
PQMSG pLastNotifyMsg; // tail of the notify message queue
#ifndef _LITE_VERSION
PSYNCMSG pFirstSyncMsg; // head of the sync message queue
PSYNCMSG pLastSyncMsg; // tail of the sync message queue
#else
IDLEHANDLER OnIdle; // Idle handler
#endif
#ifndef _LITE_VERSION
PMAINWIN pRootMainWin; // The root main window of this message queue.
#endif
MSG* msg; /* post message buffer */
int len; /* buffer len */
int readpos, writepos; /* positions for reading and writing */
int FirstTimerSlot; /* the first timer slot to be checked */
DWORD TimerMask; /* timer slots mask */
int loop_depth; /* message loop depth, for dialog boxes. */
};
#define QS_NOTIFYMSG 0x10000000
#ifndef _LITE_VERSION
#define QS_SYNCMSG 0x20000000
#else
#define QS_DESKTIMER 0x20000000
#endif
#define QS_POSTMSG 0x40000000
#define QS_QUIT 0x80000000
#define QS_INPUT 0x01000000
#define QS_PAINT 0x02000000
#define QS_TIMER 0x0000FFFF
#define QS_EMPTY 0x00000000
QS_NOTIFYMSG 标志表示消息队列中有待处理的notify消息。同理,QS_SYNCMSG表示有待处理的同步消息;QS_POSTMSG表示有待处理的post消息。
QS_QUIT、QS_PAINT和QS_TIMER分别对应MSG_QUIT, MSG_PAINT和MSG_TIMER。
同步消息在线程版,分成两种情况来实现:1)如果消息发送者和消息接受者在同一个线程,则直接调用窗口的窗口过程;2)如果不在同一个线程,则使用同步消息,来传递。