📄 winapi.c
字号:
BOOL WINAPI PostMessage(HWND hWnd,UINT Message,WPARAM WParam,LPARAM LParam){ if(IsWnd(hWnd)) { if(Message == WM_PAINT) { if(!WndGetAttr(hWnd,WS_NEEDPAINT)) { SomeWndNeedPaint=true; WndAddAttr(hWnd,WS_NEEDPAINT); WNDPTR(hWnd)->Family->CanvasChanged=true; } return true; } else if(Message == WM_EXPOSE) { if(!WNDPTR(hWnd)->Family->CanvasChanged) { WNDPTR(hWnd)->Family->CanvasChanged=true; SomeWndNeedPaint=true; } } else { char *newwritepos=g_SysMsgQueue.writepos+g_SysMsgQueue.messagesize; if(newwritepos>=g_SysMsgQueue.endaddress) { newwritepos=g_SysMsgQueue.startaddress; } if(newwritepos!=g_SysMsgQueue.readpos) { extern TWndDateTime g_SysTime; TMSG *msg=(TMSG *)g_SysMsgQueue.writepos; msg->Handle=hWnd; msg->Message=Message; msg->WParam=WParam; msg->LParam=LParam; msg->Time=(DWORD)g_SysTime; g_SysMsgQueue.writepos=newwritepos; #if(BASE_OS_TYPE>1) /*Kernel of EmbedOS available*/ if(g_SysMsgQueue.Waiting) { g_SysMsgQueue.Waiting=false; Semaphore_Release(g_SysMsgQueue.Semaphore); } #endif return true; } } } return false;}/*---------------------------------------------------------------------------FUNCTION PostQuitMessageDESCRIPTION The PostQuitMessage function indicates to Windows that a thread has made a request to terminate (quit). It is typically used in response to a WM_DESTROY message.---------------------------------------------------------------------------*/void WINAPI PostQuitMessage(HWND hWnd){ PostMessage(hWnd, WM_QUIT, 0, 0);}/*---------------------------------------------------------------------------FUNCTION PeekMessageDESCRIPTION 从目标应用程序的消息队列中读取一条消息,如果消息队列为空,直接返回 布尔型参数Remove的值,决定消息读取后是否从窗口消息队列中删除。OUTPUTS 成功读取到一条消息则返回true,否则返回false---------------------------------------------------------------------------*/BOOL WINAPI PeekMessage(PMSG Msg,BOOL Remove){ DO_PEEK_MESSAGE: if(!g_SysMsgQueue.readpos) { Msg->Message=WM_QUIT; return true; } if(g_SysMsgQueue.readpos!=g_SysMsgQueue.writepos) { memcpy(Msg,g_SysMsgQueue.readpos,g_SysMsgQueue.messagesize); if(Remove) { g_SysMsgQueue.readpos+=g_SysMsgQueue.messagesize; if(g_SysMsgQueue.readpos>=g_SysMsgQueue.endaddress) g_SysMsgQueue.readpos=g_SysMsgQueue.startaddress; } return true; } if(SomeWndNeedPaint) { extern BOOL CheckPaintMessage(PMSG); return CheckPaintMessage(Msg); } #if(BASE_OS_TYPE==1) /* On PC-Simulator*/ { extern BOOL PeekSimuMessage(void); if(PeekSimuMessage()) goto DO_PEEK_MESSAGE; } #endif return false; }/*---------------------------------------------------------------------------FUNCTION CM_RemoveMessageDESCRIPTION Remove all messages from msg queue for the target window---------------------------------------------------------------------------*/void CM_RemoveMessage(HWND hWnd){ PMSG readpos=(PMSG)g_SysMsgQueue.readpos; while(readpos!=(PMSG)g_SysMsgQueue.writepos) { if(readpos->Handle==hWnd) { if(readpos==(PMSG)g_SysMsgQueue.readpos) { g_SysMsgQueue.readpos+=g_SysMsgQueue.messagesize; }else readpos->Handle=NULL; } readpos++; }}/*---------------------------------------------------------------------------FUNCTION SendMessageDESCRIPTION The SendMessage function sends the specified message to a window or windows. The function calls the window procedure for the specified window and does not return until the window procedure has processed the message. The PostMessage function, in contrast, posts a message to a thread's message queue and returns immediately.OUTPUTS The return value specifies the result of the message processing and depends on the message sent. ---------------------------------------------------------------------------*/HRESULT WINAPI SendMessage(HWND hWnd,UINT Message,WPARAM WParam,LPARAM LParam){ if(IsWnd(hWnd)) { PWND pWnd= WNDPTR(hWnd); if(pWnd->HookProc && (!pWnd->HookMessage || pWnd->HookMessage==Message)) { BOOL bIntercept=false; HRESULT hresult=pWnd->HookProc((HWND)pWnd,Message,WParam,LParam,&bIntercept); if(bIntercept)return hresult; } /*窗口的默认处理*/ if(pWnd->WinClass && pWnd->WinClass->lpfnWndProc) { /*返回目标窗体的回调处理结果*/ return pWnd->WinClass->lpfnWndProc((HWND)pWnd,Message,WParam,LParam); } } return -1;}/**************************************************************************** FUNCTION* InstallHook* DESCRIPTION* 给指定窗口安装消息钩子* 当目标窗体安装了消息钩子后,发往目标窗体的指定的消息将首先被钩子处理函数截获.* 如果指定参数message为0,则截获所有的消息.* 如果安装成功,则返回目标窗体原来的钩子处理函数* 一个窗体只允许安装一个消息钩子,如果多次安装则后一个覆盖前一个. ****************************************************************************/TWNDHOOK InstallHook(HWND hWnd,UINT hookMsg,TWNDHOOK hookProc){ if(IsWnd(hWnd)) { TWNDHOOK OldHook = WNDPTR(hWnd)->HookProc; WNDPTR(hWnd)->HookProc = hookProc; WNDPTR(hWnd)->HookMessage = hookMsg; return OldHook; } return NULL;}/**************************************************************************** FUNCTION* UninstallHook* DESCRIPTION* 卸载目标窗口的消息钩子****************************************************************************/void UninstallHook(HWND hWnd){ if(IsWnd(hWnd)) { WNDPTR(hWnd)->HookProc = NULL; }}/*---------------------------------------------------------------------------FUNCTION HandleMessageDESCRIPTION HandleMessage interrupts the execution of the application so that Windows can process a single message from the Windows message queue before returning control to the application.---------------------------------------------------------------------------*/BOOL HandleMessage(void){ TMSG msg; if(GetMessage(&msg)) { /*直接从消息队列中取出来的消息(进队消息)要先进行译码然后再派发*/ TranslateMessage(&msg); DispatchMessage(&msg); return true; } return false;}/*---------------------------------------------------------------------------FUNCTION ProcessMessagesDESCRIPTION Call ProcessMessages to permit the application to process messages that are currently in the message queue. ProcessMessages cycles the Windows message loop until it is empty, and then returns control to the application.---------------------------------------------------------------------------*/void ProcessMessages(void){ TMSG msg; while(PeekMessage(&msg,true)) { /*直接从消息队列中取出来的消息(进队消息)要先进行译码然后再派发*/ TranslateMessage(&msg); DispatchMessage(&msg); }}/*---------------------------------------------------------------------------FUNCTION DispatchMessageDESCRIPTION The DispatchMessage function dispatches a message to a window procedure. It is typically used to dispatch a message retrieved by the GetMessage function. OUTPUT The return value specifies the value returned by the window procedure. Although its meaning depends on the message being dispatched, the return value generally is ignored.---------------------------------------------------------------------------*/BOOL WINAPI DispatchMessage(PMSG Msg){ return SendMessage(Msg->Handle,Msg->Message,Msg->WParam,Msg->LParam);}/*---------------------------------------------------------------------------FUNCTION TranslateMessageDESCRIPTION The TranslateMessage function do translates virtual-key messages into character messages. 这里只要对小键盘进行译码---------------------------------------------------------------------------*/#define KEY_DECODE_TIME 1000#define DECODE_VKEY_FISRT VK_NUMPAD0#define DECODE_VKEY_LAST VK_NUMPAD9#define KEYDECODE_NUM (DECODE_VKEY_LAST-DECODE_VKEY_FISRT+1)/** 小键盘是否上档 **/BOOL keypad_shifton=true; /** keypad_shifton==false时, 一对一映射译码表 **/static const char shiftOff_decode[KEYDECODE_NUM]={'0','1','2','3','4','5','6','7','8','9'};/** keypad_shifton==true时, 一对多映射译码表 **/static const char * shifton_decode[KEYDECODE_NUM]={"+-=?!<>(){}[]"," @./:;~_*#$%^&\\|'\",`" , "abcABC" , "defDEF" , "ghiGHI" ,"jklJKL" ,"mnoMNO" , "pqrsPQRS" , "tuvTUV" ,"wxyzWXYZ" };/////////////////////////////////////////////////////////////////////////static int shifton_codelen[KEYDECODE_NUM]={0};static DWORD LastDecodeTime=0; static int KeyOnDecoding=0; //上一次译码时按下的键值static int KeyDecodeDepth=0; //记录译码键译码的深度//---------------------------------------------------------------------------BOOL WINAPI TranslateMessage(PMSG Msg){ if(Msg->Message==WM_KEYDOWN) { char character; if(Msg->WParam >= DECODE_VKEY_FISRT && Msg->WParam <= DECODE_VKEY_LAST) { int index=Msg->WParam - VK_NUMPAD0; if(!keypad_shifton) { character=shiftOff_decode[index]; KeyDecodeDepth=0; } else { int codelen; if(KeyDecodeDepth && (KeyOnDecoding!=(int)Msg->WParam || Msg->Time-LastDecodeTime>KEY_DECODE_TIME) ) { KeyDecodeDepth=0; } KeyOnDecoding=Msg->WParam; LastDecodeTime=Msg->Time; codelen=shifton_codelen[index]; if(!codelen) { codelen=strlen(shifton_decode[index]); shifton_codelen[index]=codelen; } character=shifton_decode[index][KeyDecodeDepth % codelen]; KeyDecodeDepth++; } SendMessage(Msg->Handle, WM_CHAR, character, KeyDecodeDepth); } else { KeyDecodeDepth=0; } return true; } return false;}//---------------------------------------------------------------------------PWND SeekWndForPaint(PWND pWnd){ if(WndGetAttr(pWnd,WS_NEEDPAINT|WS_HIDE)==WS_NEEDPAINT) { return pWnd; } pWnd=pWnd->Children; if(pWnd) { PWND seekwnd=NULL; /*seek the last brother*/ while(pWnd->Next) { pWnd=pWnd->Next; } /*seek the wnd need paint*/ while(pWnd) { seekwnd=SeekWndForPaint(pWnd); if(seekwnd) { return seekwnd; } pWnd=pWnd->Prev; } } return NULL;}BOOL CheckPaintMessage(PMSG Msg){ if( g_RootWnd->Family->CanvasChanged ) { g_RootWnd->Family->CanvasChanged=false; WndSubAttr(g_RootWnd,WS_NEEDPAINT); Msg->Handle=(HWND)g_RootWnd; Msg->Message=WM_EXPOSE; /*PS: for RootWindow there's no WM_PAINT but WM_EXPOSE */ return true; } else { PWND seekwnd=g_RootWnd->Children; PWND mainwnd=NULL; while(seekwnd) { if(seekwnd->Family->CanvasChanged) { mainwnd=seekwnd; } seekwnd=seekwnd->Next; } if(mainwnd) { seekwnd=SeekWndForPaint(mainwnd); if(seekwnd) { WndSubAttr(seekwnd,WS_NEEDPAINT); Msg->Handle=(HWND)seekwnd; Msg->Message=WM_PAINT; } else { mainwnd->Family->CanvasChanged=false; Msg->Handle=(HWND)mainwnd; Msg->Message=WM_EXPOSE; } return true; } } SomeWndNeedPaint=false; return false;}/*---------------------------------------------------------------------------FUNCTION DispatchUserMsgDESCRIPTION 分发键盘/鼠标消息---------------------------------------------------------------------------*/static HWND g_LastClickedWnd=NULL; /*the last clicked window*/void DispatchUserMsg(DWORD msg,DWORD wParam,DWORD lParam){ HWND hWnd; if(msg==WM_KEYDOWN) { hWnd=g_LastClickedWnd=(HWND)g_CurrentFocus; } else if(msg==WM_LBUTTONDOWN) { int x=LOWORD(lParam),y=HIWORD(lParam); PWND node,newfocus=g_RootWnd; while(newfocus && newfocus->Children) { node=newfocus->Children; while(node) { if( WndGetAttr(node,WS_HIDE|WS_DISABLED)==0 ) { if(x>=node->WndRect.left && y>=node->WndRect.top && x<node->WndRect.right && y<node->WndRect.bottom) { newfocus=node; break; } } else if( WndGetAttr(node,WS_HIDE|WS_DISABLED)==WS_DISABLED ) { if(x>=node->WndRect.left && y>=node->WndRect.top && x<node->WndRect.right && y<node->WndRect.bottom) { g_LastClickedWnd=node; return; } } node=node->Next; } if(!node)break; } hWnd=g_LastClickedWnd=(HWND)newfocus; } else { hWnd=g_LastClickedWnd; } PostMessage(hWnd,msg,wParam,lParam);}/*---------------------------------------------------------------------------END --- Thank you! ming.c---------------------------------------------------------------------------*//*unmapcount表示窗口某个瞬间的绘图显示状态,是临时状态或者。WS_HIDE 表示是否为可见窗口,是反映窗口最终要达到显示状态的。*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -