传递消息就是传递消息数据, 数据是一组数据, 所以消息是一个结构;
系统标准的消息结构在 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 函数一样, 它们在不断地增加, 况且还有那么多的自定义消息, 这应该只是一些常用的, 也够多了.