您的位置:首页 > 编程语言 > Delphi

[delphi] windows消息

2016-12-18 18:11 429 查看
windows消息的结构

  TMsg = packed record

    hwnd: HWND;//窗口句柄

    message: UINT;//消息标识

    wParam: WPARAM;//

    lParam: LPARAM;//

    time: DWORD;//消息创建的时间

    pt: TPoint;//消息创建时鼠标所在位置

  end;

WM_KEYDOWN,WM_KEYUP, WM_KEYPRESS: KEYPress消息不同之处在于只有对应有ascii码的按键才会产生这个消息

windows消息流程

1.系统中产生事件

2.windows把这个事件翻译成消息,并放入消息队列

3.应用程序从消息队列中接收到这个消息,把它放到TMsg记录中

4.应用程序把消息传递给一个适当的窗口的窗口过程

5.窗口过程响应这个消息并处理

步骤3,4就构成了应用程序的消息循环。

delphi把windows的TMsg记录中的信息映射为TMessage记录:

TMessage = record
Msg: Cardinal;
case Integer of
0:( WParam: LongInt;
LParam: LongInt;
Result: LongInt);
1:( WParamLo: Word;
WParamHi: Word;
LParamLo: Word;
LParamHi: Word;
ResultLo: Word;
ReslutHi: Word);
end;


除此之外,delphi为每个windows消息定义了一个特殊的消息记录,方便使用,例如一个鼠标消息:

TWMMoust = record
Msg: Cardinal;
Keys: LongInt;
case: Integer of
0:(XPos, YPos: SamllInt);
1:(Pos: TSmallPoint; Result: LongInt);
end;


MessageBeep(): 穷人的调试器

对消息中的Result赋值:

典型的例子是WM_CTLCOLOR,处理这个消息时,windows期望返回一个画刷的句柄,

所以需要在消息处理之后对result赋值

procedure TFrom1.WMCtlColor(var Msg: TWMCtlColor);
var
BrushHand: hBrush;
begin
inherited;
// todo: 创建一个画刷,放入BrushHand
Msg.Result := BrushHand;
end;
Application.OnMessage
OnMessage相应的是从消息队列中检索到的消息,所以SendMessage发送的消息会绕过消息队列,就不会触发OnMessage事件

子类化

用自己的窗口过程代替Application的窗口过程,当在自己的窗口过程处理完成呢过后,把消息再传递给原窗口。这个过程就叫 子类化

1.使用SetWindowLong()来指定与i个新的窗口过程:

  声明:

function NewWndProc(Handle: hWnd; Msg, WParam, LParam: LongInt): Longint; stdcall;使用
OldWndProc := Pointer(SetWindowLong(Application.Handle, gwl_WndProc, Integer(@NewWndProc)));
来设置。
2.也可以使用Delphi方法来代替上面的NewWndProc

需要使用MakeObjectInstance()来处理一下这个delphi的方法

NewProc := MakeObjectInstance(self.NewWndProc);
OldWProc := Pointer(SetWindowLong(Application.Handle, GWL_WNDPROC, Integer(NewProc)));

3.HookMainWindow()
这个函数能把一个自定义的消息处理过程插入到TApplication的WndProc方法之前
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: