随笔 - 2146  文章 - 97 评论 - 11767 trackbacks - 253

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

posted on 2008-10-29 14:29  万一  阅读(...)  评论(...编辑  收藏