[delphi] windows消息

来源:互联网 发布:kindle编书软件 编辑:程序博客网 时间:2024/05/22 02:23

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方法之前








0 0