傳遞消息就是傳遞消息數據, 數據是一組數據, 所以消息是一個結構;
系統標准的消息結構在 Delphi 中被定義為 TMsg
PMsg = ^TMsg;
tagMSG = packed record
hwnd: HWND;
message: UINT;
wParam: WPARAM;
lParam: LPARAM;
time: DWord;
pt: TPoint;
end;
TMsg = tagMSG;
MSG = tagMSG;
但 TMsg 和 VCL 中的更多消息結構如: TWMMouse、TWMKey 並不兼容;
但 TWMMouse、TWMKey 等都可以兼容: TMessage;
TMessage 是 VCL 重新定義的消息結構:
PMessage = ^TMessage;
TMessage = packed record
Msg: Cardinal;
case Integer of
0: (
WParam: WPARAM;
LParam: LPARAM;
Result: LRESULT);
1: (
WParamLo: Word;
WParamHi: Word;
LParamLo: Word;
LParamHi: Word;
ResultLo: Word;
ResultHi: Word);
end;
有多少必要讓 Delphi 不直接使用 TMsg 而非要有個 TMessage 呢?
我現在所能知道的: 1、簡化; 2、增加返回值; 肯定還有其他理由, 望先者告訴我.
但我想不管怎樣, VCL 最終肯定要回歸 TMsg 的結構格式, 才能與系統打交道.
因為面對不同的消息, 消息參數的意義會完全不同;
在不同的消息裡面, 有些參數也毫無意義, 可以省略;
另外, 有些消息參數非常抽象, 需要反復換算才得到我們容易理解的數據, 為什麼不直接使用容易理解的數據呢?
所以 Delphi 定義了更多的消息結構:
TWMNoParams
TWMCancelMode = TWMNoParams;
TWMChildActivate = TWMNoParams;
TWMClear = TWMNoParams;
TWMClose = TWMNoParams;
TWMCopy = TWMNoParams;
TWMCut = TWMNoParams;
TWMDestroy = TWMNoParams;
TWMDestroyClipboard = TWMNoParams;
TWMDrawClipboard = TWMNoParams;
TWMFontChange = TWMNoParams;
TWMGetDlgCode = TWMNoParams;
TWMGetFont = TWMNoParams;
TWMGetHotKey = TWMNoParams;
TWMGetTextLength = TWMNoParams;
TWMMDIGetActive = TWMNoParams;
TWMMDIIconArrange = TWMNoParams;
TWMMDIRefreshMenu = TWMNoParams;
TWMNCDestroy = TWMNoParams;
TWMPaintIcon = TWMNoParams;
TWMPaste = TWMNoParams;
TWMQueryDragIcon = TWMNoParams;
TWMQueryNewPalette = TWMNoParams;
TWMQueryOpen = TWMNoParams;
TWMQueueSync = TWMNoParams;
TWMRenderAllFormats = TWMNoParams;
TWMSysColorChange = TWMNoParams;
TWMTimeChange = TWMNoParams;
TWMQueryUIState = TWMNoParams;
TWMUndo = TWMNoParams;
TWMKey
TWMChar = TWMKey;
TWMKeyDown = TWMKey;
TWMKeyUp = TWMKey;
TWMDeadChar = TWMChar;
TWMSysChar = TWMKey;
TWMSysKeyDown = TWMKey;
TWMSysKeyUp = TWMKey;
TWMMouse
TWMLButtonDblClk = TWMMouse;
TWMLButtonDown = TWMMouse;
TWMLButtonUp = TWMMouse;
TWMMButtonDblClk = TWMMouse;
TWMMButtonDown = TWMMouse;
TWMMButtonUp = TWMMouse;
TWMMouseMove = TWMMouse;
TWMRButtonDblClk = TWMMouse;
TWMRButtonDown = TWMMouse;
TWMRButtonUp = TWMMouse;
TWMMouseWheel
TMSHMouseWheel
TWMWindowPosMsg
TWMWindowPosChanged = TWMWindowPosMsg;
TWMWindowPosChanging = TWMWindowPosMsg;
TWMScroll
TWMHScroll = TWMScroll;
TWMVScroll = TWMScroll;
TWMactivate
TWMactivateApp
TWMAskCBFormatName
TWMChangeCBChain
TWMCharToItem
TWMVKeyToItem = TWMCharToItem;
TWMChooseFont_GetLogFont
TWMCommand
TWMCompacting
TWMCompareItem
TWMCopyData
TWMCreate
TWMCtlColor
TWMCtlColorBtn = TWMCtlColor;
TWMCtlColorDlg = TWMCtlColor;
TWMCtlColorEdit = TWMCtlColor;
TWMCtlColorListbox = TWMCtlColor;
TWMCtlColorMsgbox = TWMCtlColor;
TWMCtlColorScrollbar = TWMCtlColor;
TWMCtlColorStatic = TWMCtlColor;
TWMDDE_Ack
TWMDDE_Advise
TWMDDE_Data
TWMDDE_Execute
TWMDDE_Initiate
TWMDDE_Poke
TWMDDE_Request
TWMDDE_Terminate
TWMDDE_Unadvise
TWMDeleteItem
TWMDevModeChange
TWMDrawItem
TWMDropFiles
TWMEnable
TWMEndSession
TWMEnterIdle
TWMEnterMenuLoop
TWMExitMenuLoop = TWMEnterMenuLoop;
TWMEraseBkgnd
TWMGetIcon
TWMGetMinMaxInfo
TWMGetText
TWMHotKey
TWMHScrollClipboard
TWMIconEraseBkgnd = TWMEraseBkgnd;
TWMInitDialog
TWMInitMenu
TWMInitMenuPopup
TWMKillFocus
TWMMDIActivate
TWMMDICascade
TWMMDICreate
TWMMDIDestroy
TWMMDIMaximize
TWMMDINext
TWMMDIRestore
TWMMDISetMenu
TWMMDITile
TWMMeasureItem
TWMMenuChar
TWMMenuSelect
TWMMouseActivate
TWMMove
TWMMoving
TWMNCActivate
TWMNCCalcSize
TWMNCCreate
TWMNCHitTest
TWMNCHitMessage
TWMNCLButtonDblClk = TWMNCHitMessage;
TWMNCLButtonDown = TWMNCHitMessage;
TWMNCLButtonUp = TWMNCHitMessage;
TWMNCMButtonDblClk = TWMNCHitMessage;
TWMNCMButtonDown = TWMNCHitMessage;
TWMNCMButtonUp = TWMNCHitMessage;
TWMNCMouseMove = TWMNCHitMessage;
TWMNCRButtonDblClk = TWMNCHitMessage;
TWMNCRButtonDown = TWMNCHitMessage;
TWMNCRButtonUp = TWMNCHitMessage;
TWMNCPaint
TWMNextDlgCtl
TWMNotify
TWMNotifyFormat
TWMPaint
TWMPaintClipboard
TWMPaletteChanged
TWMPaletteIsChanging
TWMParentNotify
TWMPower
TWMQueryEndSession
TWMQuit
TWMRenderFormat
TWMSetCursor
TWMSetFocus
TWMSetFont
TWMSetHotKey
TWMSetIcon
TWMSetRedraw
TWMSetText
TWMShowWindow
TWMSize
TWMSizeClipboard
TWMSpoolerStatus
TWMStyleChange
TWMStyleChanged = TWMStyleChange;
TWMStyleChanging = TWMStyleChange;
TWMSysCommand
TWMSysDeadChar
TWMSystemError
TWMTimer
TWMUIState
TWMChangeUIState = TWMUIState;
TWMUpdateUIState = TWMUIState;
TWMVScrollClipboard
TWMWinIniChange
TWMSettingChange
TWMHelp
TWMDisplayChange
TWMContextMenu
TWMPrint
TWMPrintClIEnt = TWMPrint;
這樣做的目的, 無非就是為了理解與簡捷. 但為什麼會有那麼多重命名(說明它們的參數結構相同)呢?
我想 Delphi 這樣做可能是為了和消息一一對應吧, 譬如: WM_LButtonDown 消息對應 TWMLButtonDown 結構. 這樣根據命名規則, 可以方便地通過消息名稱方便地找到對應的消息結構.
TMessage 在 VCL 中是通用的, 它可以代替其中任何一個.
另外, 這會是 Windows 消息的全部嗎?
我想肯定不是, 就像 API 函數一樣, 它們在不斷地增加, 況且還有那麼多的自定義消息, 這應該只是一些常用的, 也夠多了.