📄 message.c
字号:
/*** $Id: message.c,v 1.19 2003/09/04 03:46:47 weiym Exp $**** message.c: The Messaging module.**** Copyright (C) 2003 Feynman Software.** Copyright (C) 2000 ~ 2002 Wei Yongming.**** Current maintainer: Wei Yongming.**** Create date: 2000/11/05*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*//*** TODO:*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "common.h"#include "minigui.h"#include "gdi.h"#include "window.h"#include "blockheap.h"#include "cliprect.h"#include "gal.h"#include "internals.h"#include "ctrlclass.h"#include "timer.h"/****************************** Message support ******************************/static BLOCKHEAP QMSGHeap;/* QMSG allocation */BOOL InitFreeQMSGList (void){ InitBlockDataHeap (&QMSGHeap, sizeof (QMSG), SIZE_QMSG_HEAP); return TRUE;}void DestroyFreeQMSGList (void){ DestroyBlockDataHeap (&QMSGHeap);}inline static PQMSG QMSGAlloc (void){ return (PQMSG) BlockDataAlloc (&QMSGHeap);}inline static void FreeQMSG (PQMSG pqmsg){ BlockDataFree (&QMSGHeap, pqmsg);}BOOL InitMsgQueue (PMSGQUEUE pMsgQueue, int iBufferLen){ int i; pMsgQueue->dwState = QS_EMPTY;#ifndef _LITE_VERSION pthread_mutex_init (&pMsgQueue->lock, NULL); sem_init (&pMsgQueue->wait, 0, 0);#endif pMsgQueue->pFirstNotifyMsg = NULL; pMsgQueue->pLastNotifyMsg = NULL; pMsgQueue->readpos = 0; pMsgQueue->writepos = 0;#ifndef _LITE_VERSION pMsgQueue->pFirstSyncMsg = NULL; pMsgQueue->pLastSyncMsg = NULL;#endif if (iBufferLen <= 0) iBufferLen = DEF_MSGQUEUE_LEN; pMsgQueue->msg = malloc (sizeof (MSG) * iBufferLen); pMsgQueue->len = iBufferLen;#ifndef _LITE_VERSION pMsgQueue->TimerMask = 0xFF;#else pMsgQueue->TimerMask = 0xFFFF;#endif for (i = 0; i < DEF_NR_TIMERS; i++) { pMsgQueue->TimerOwner [i] = HWND_DESKTOP; pMsgQueue->TimerID [i] = 0; } return pMsgQueue->msg != NULL;}void DestroyMsgQueue (PMSGQUEUE pMsgQueue){ PQMSG head; PQMSG next; head = next = pMsgQueue->pFirstNotifyMsg; while (head) { next = head->next; FreeQMSG (head); head = next; }#ifndef _LITE_VERSION pthread_mutex_destroy (&pMsgQueue->lock); sem_destroy (&pMsgQueue->wait);#endif free (pMsgQueue->msg); pMsgQueue->msg = NULL;}#ifdef _LITE_VERSIONBOOL InitDskMsgQueue (void){ return InitMsgQueue (&__mg_dsk_msgs, 0);}void DestroyDskMsgQueue (void){ DestroyMsgQueue (&__mg_dsk_msgs);}#endifPMAINWIN CheckAndGetMainWindowPtr (HWND hWnd){ PMAINWIN pWin; pWin = (PMAINWIN)hWnd; if(pWin->DataType != TYPE_HWND) return NULL; if (pWin->WinType == TYPE_MAINWIN) return pWin; return NULL; }PMAINWIN GetMainWindowPtrOfControl (HWND hWnd){ PMAINWIN pWin; if (hWnd == HWND_DESKTOP || hWnd == HWND_INVALID) return NULL; pWin = (PMAINWIN)hWnd; if(pWin->DataType != TYPE_HWND) return NULL; if (pWin->WinType == TYPE_MAINWIN) return pWin; return ((PCONTROL)hWnd)->pMainWin;}PMSGQUEUE GetMsgQueue (HWND hWnd){ if (hWnd == HWND_DESKTOP) return &__mg_dsk_msgs; return GetMainWindowPtrOfControl (hWnd)->pMessages;}static inline WNDPROC GetWndProc (HWND hWnd){ PMAINWIN pMainWin = (PMAINWIN)hWnd; if (hWnd == HWND_DESKTOP) return DesktopWinProc; return pMainWin->MainWindowProc;}static HWND msgCheckInvalidRegion (PMAINWIN pWin){ PCONTROL pCtrl = (PCONTROL)pWin; HWND hwnd; if (pCtrl->InvRgn.rgn.head) return (HWND)pCtrl; pCtrl = pCtrl->children; while (pCtrl) { if ((hwnd = msgCheckInvalidRegion ((PMAINWIN) pCtrl))) return hwnd; pCtrl = pCtrl->next; } return 0;}static PMAINWIN msgGetHostingRoot (PMAINWIN pHosted){ PMAINWIN pHosting; pHosting = pHosted->pHosting; if (pHosting) return msgGetHostingRoot (pHosting); return pHosted;}static HWND msgCheckHostedTree (PMAINWIN pHosting){ HWND hNeedPaint; PMAINWIN pHosted; if ( (hNeedPaint = msgCheckInvalidRegion (pHosting)) ) return hNeedPaint; pHosted = pHosting->pFirstHosted; while (pHosted) { if ( (hNeedPaint = msgCheckHostedTree (pHosted)) ) return hNeedPaint; pHosted = pHosted->pNextHosted; } return 0;}static void CheckCapturedMouseMessage (PMSG pMsg){ if (pMsg->message >= MSG_FIRSTMOUSEMSG && pMsg->message <= MSG_LASTMOUSEMSG) {#ifndef _LITE_VERSION if (__mg_capture_wnd && (__mg_capture_wnd != HWND_INVALID) && (GetMsgQueue (__mg_capture_wnd) == GetMsgQueue (pMsg->hwnd))) {#else if (__mg_capture_wnd && (__mg_capture_wnd != HWND_INVALID) && pMsg->hwnd != HWND_DESKTOP) {#endif if (!(pMsg->wParam | KS_CAPTURED)) { int x, y; x = LOSWORD (pMsg->lParam); y = HISWORD (pMsg->lParam); ClientToScreen (pMsg->hwnd, &x, &y); pMsg->lParam = MAKELONG (x, y); pMsg->wParam |= KS_CAPTURED; } pMsg->hwnd = __mg_capture_wnd; } }}BOOL GUIAPI HavePendingMessage (HWND hWnd){ PMSGQUEUE pMsgQueue; if( !(pMsgQueue = GetMsgQueue(hWnd)) ) return FALSE; if (pMsgQueue->dwState & QS_NOTIFYMSG) { if (pMsgQueue->pFirstNotifyMsg) return TRUE; }#ifndef _LITE_VERSION if (pMsgQueue->dwState & QS_SYNCMSG) { if (pMsgQueue->pFirstSyncMsg) return TRUE; }#endif if (pMsgQueue->dwState & QS_POSTMSG) { if (pMsgQueue->readpos != pMsgQueue->writepos) return TRUE; }#ifndef _LITE_VERSION if (pMsgQueue->dwState & (QS_QUIT | QS_PAINT | QS_TIMER))#else if (pMsgQueue->dwState & (QS_QUIT | QS_PAINT | QS_TIMER | QS_DESKTIMER))#endif return TRUE;#ifdef _LITE_VERSION return pMsgQueue->OnIdle (NULL);#else return FALSE;#endif}int GUIAPI BroadcastMessage (int iMsg, WPARAM wParam, LPARAM lParam){ MSG msg; msg.message = iMsg; msg.wParam = wParam; msg.lParam = lParam; return SendMessage (HWND_DESKTOP, MSG_BROADCASTMSG, 0, (LPARAM)(&msg));}#ifdef _MSG_STRING#include "msgstr.h"const char* GUIAPI Message2Str (int message){ if (message >= 0x0000 && message <= 0x006F) return msgstr1 [message]; else if (message >= 0x00A0 && message <= 0x010F) return msgstr2 [message - 0x00A0]; else if (message >= 0x0120 && message <= 0x017F) return msgstr3 [message - 0x0120]; else if (message >= 0xF000) return "Control Messages"; else return "MSG_USER";}void GUIAPI PrintMessage (FILE* fp, HWND hWnd, int iMsg, WPARAM wParam, LPARAM lParam){ fprintf (fp, "Message %s: hWnd: %#x, wP: %x, lP: %lx.\n", Message2Str (iMsg), hWnd, wParam, lParam);}#endif#ifdef _LITE_VERSIONint GUIAPI GetMessage (PMSG pMsg, HWND hWnd){ PMSGQUEUE pMsgQueue; PQMSG phead; int slot; if( !(pMsgQueue = GetMsgQueue(hWnd)) ) return ERR_INV_HWND; memset (pMsg, 0, sizeof(MSG));checkagain: if (pMsgQueue->dwState & QS_QUIT) { pMsg->hwnd = hWnd; pMsg->message = MSG_QUIT; pMsg->wParam = 0; pMsg->lParam = 0; pMsgQueue->dwState &= ~QS_QUIT; return 0; } if (pMsgQueue->dwState & QS_NOTIFYMSG) { if (pMsgQueue->pFirstNotifyMsg) { phead = pMsgQueue->pFirstNotifyMsg; pMsgQueue->pFirstNotifyMsg = phead->next; *pMsg = phead->Msg; FreeQMSG (phead); return 1; } else pMsgQueue->dwState &= ~QS_NOTIFYMSG; } if (pMsgQueue->dwState & QS_POSTMSG) { if (pMsgQueue->readpos != pMsgQueue->writepos) { *pMsg = pMsgQueue->msg[pMsgQueue->readpos]; CheckCapturedMouseMessage (pMsg); pMsgQueue->readpos++; if (pMsgQueue->readpos >= pMsgQueue->len) pMsgQueue->readpos = 0; return 1; } else pMsgQueue->dwState &= ~QS_POSTMSG; } if (pMsgQueue->dwState & QS_PAINT) { PMAINWIN pHostingRoot; HWND hNeedPaint; PMAINWIN pWin; if (hWnd == HWND_DESKTOP) { pMsg->hwnd = hWnd; pMsg->message = MSG_PAINT; pMsg->wParam = 0; pMsg->lParam = 0; pMsgQueue->dwState &= ~QS_PAINT; return 1; } pMsg->message = MSG_PAINT; pMsg->wParam = 0; pMsg->lParam = 0; pWin = GetMainWindowPtrOfControl (hWnd); pHostingRoot = msgGetHostingRoot (pWin); if ( (hNeedPaint = msgCheckHostedTree (pHostingRoot)) ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -