Statement
#define Msg_error-1#define msg_succeed0#define msg_true1#define msg_false0#define pm_noremove 0x00#define PM_REMOVE 0 X01typedef unsigned long wparam;typedef unsigned long lparam;typedef unsigned intuint;typedef intmsg_bool;//This return value is two, don't squirt me. ... typedef struct{uint message;//message type UINT idthread;//thread idwparamwparam; Lparamlparam;} Msg;typedef msg* lpmsg;typedef struct node{msgdata;struct node* next;} Msg_node;void setupmessage ();//Start message queue void Terminalmessage ();//Terminate Message Queue Msg_bool PeekMessage (lpmsg lpmsg,uint hwnd,uint Wmsgfiltermin,uint wmsgfiltermax,uint wremovemsg); Msg_bool postthreadmessage (UINT idthread,uint msg, WPARAM WPARAM, LPARAM LPARAM);
Realize
#include "msg.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <pthread.h>static msg_node * g_message_queue = null;static msg_node* msg_create () {msg_node* phead = calloc (sizeof (MSG_ NODE), 1); return phead;} Static void msg_destroy (msg_node* phead) {msg_node* pnode = null;if (pHead) {PNode = phead->next;while (Pnode) {phead->next = pnode->next;printf ("Free Node:%p\n ", Pnode); free (pnode);p Node = phead->next;} Free (phead);p rintf ("free head node:%p\n", Phead);}} Navigate to the Message list trailing Static msg_node* msg_tail (msg_node* phead) {msg_node* ptail = null;if ( !phead) return null;ptail = phead;while (ptail->next) pTail = pTail-> Next;return ptail;} The tail inserts a message node Static int msg_push_back (msg_node* phead, msg_node* pnode) {msg_node* ptail = null;if ( !phead | | !pnode) return msg_error;ptail = msg_tail (phead); if (ptail) {pTail->next = pnode;pnode->next = null;return msg_succeed;} Return msg_error;} Start Void setupmessage () {if (!g_message_queue) {g_message_queue = msg_create (); Assert (G_message_ queue);}} Terminating Void terminalmessage () {Msg_destroy (g_message_queue); g_message_queue = null;} Msg_bool postthreadmessage (uint idthread,uint msg, wparam wparam, lparam LParam) {msg_node* pnode = null;if ( !g_message_queue && (msg < 0) ) return msg_false;pnode = calloc (sizeof (Msg_node), 1);if (PNode) { pnode->data.message = msg;pnode->data.idthread = (!idThread)? Pthread_self (): IdThread ;//If the ID is 0 default, the current thread PNODE->DATA.WPARAM&NBSP;=&NBSP;WPARAM;PNode->data.lparam = lparam;pnode->next = null;return (Msg_push_back (G_message_ Queue,pnode) == msg_succeed)? Msg_true:msg_false;} Return msg_false;} The second parameter is completed in order to function "like" Win32 API is useless, Linux does not have a window handle that says msg_bool peekmessage (Lpmsg lpmsg, UINT&NBSP;HWND,UINT&NBSP;WMSGFILTERMIN,UINT&NBSP;WMSGFILTERMAX,UINT&NBSP;WREMOVEMSG) {MSG_NODE*pNode= NULL ; msg_node*pprenode = null;//Save the previous node if ( !g_message_queue && lpmsg) return msg_false;pprenode = g_message_queue;pnode = g_message_queue->next;/** Don't squirt me With so many goto just for don't write a bunch of duplicate code */while (pnode) {if (pnode->data.idthread != (UINT) pthread_self () ) {Goto next;} if (Wmsgfiltermin|wmsgfiltermax) {if ( pNode->data.message >= wMsgFilterMin && pnode->data.message <= wmsgfiltermax ) {goto get_msg;}} Else{goto get_msg;} Next:pprenode = pnode;pnode = pnode->next;continue; get_msg:memcpy (lpmsg,&pnode->data,sizeof (MSG) ); if (wremovemsg == pm_remove)//Delete message link table Node { pprenode->next = pnode->next;//precursor node associated successor node prevent list truncation free (pnode);//Release current message link table node}return msg_ TRUE;} Return msg_true;}
Test Cases
#include <stdio.h> #include <string.h> #include "msg.h" int main (int argc,char** argv) {int i=0; MSG msg; Setupmessage (); for (i=0;i<10;i++) {postthreadmessage (0,1000+i, 100+i, 200+i);} while (1) {PeekMessage (&msg,0,0,0,pm_remove);p rintf ("id:%u,wparam:%lu,lparam:%lu\n", Msg.message,msg.wparam, Msg.lparam); if (!msg.message) Break;memset (&msg,0,sizeof (msg)); Sleep (2);} Terminalmessage (); return 0;}
Test cases are just tests that do some simple basics and are not perfect.
In addition to thread-related system calls, all are implemented using standard libraries.