zoukankan      html  css  js  c++  java
  • 终于懂了:Delphi消息的Result完全是生造出来的,不是Windows消息自带的(Delphi对Windows编程体系的改造越大,学习收获就越大)——消息是否继续传递就看这个Result

    Windows中,消息使用统一的结构体(MSG)来存放信息,其中message表明消息的具体的类型,

    而wParam,lParam是其最灵活的两个变量,为不同的消息类型时,存放数据的含义也不一样。

    time表示产生消息的时间,pt表示产生消息时鼠标的位置。

    里面没有Result的选项。然后我用VC2008实测MSG结构的大小:

    #include <afx.h>
    
    void Cxe111Dlg::OnBnClickedButton1()
    {
        CString m_Str;
        int ddd = sizeof(MSG);
        m_Str.Format(_T("%d"), ddd);
        AfxMessageBox(m_Str);
    }

    结果等于28

    void Cxe111Dlg::OnBnClickedButton1()
    {
        CString m_Str;
        int ddd = sizeof(WM_SIZE);
        m_Str.Format(_T("%d"), ddd);
        AfxMessageBox(m_Str);
    }

    结果等于4

    void Cxe111Dlg::OnBnClickedButton1()
    {
        CString m_Str;
        int ddd = sizeof(WM_CHAR);
        m_Str.Format(_T("%d"), ddd);
        AfxMessageBox(m_Str);
    }

    结果等于4

    -------------------------------------------------------------

    再来看Delphi里的定义,它也有原模原样的定义,只不过一般情况下用不到:

      PMsg = ^TMsg;
      tagMSG = packed record
        hwnd: HWND;
        message: UINT;
        wParam: WPARAM;
        lParam: LPARAM;
        time: DWORD;
        pt: TPoint;
      end;
    
      TMsg = tagMSG;
      MSG = tagMSG;

    经过测试,它的大小当然也是28:

    procedure TForm1.Button3Click(Sender: TObject);
    begin
      ShowMessage(IntToStr(sizeof(tagMSG)));
    end;

    再看Delphi真正使用的消息结构,注意它包括了Result:

      PMessage = ^TMessage;
      TMessage = packed record
        Msg: Cardinal;
        case Integer of
          0: (
            WParam: Longint;
            LParam: Longint;
            Result: Longint);
          1: (
            WParamLo: Word;
            WParamHi: Word;
            LParamLo: Word;
            LParamHi: Word;
            ResultLo: Word;
            ResultHi: Word);
      end;

    测试它的大小:

    procedure TForm1.Button3Click(Sender: TObject);
    begin
      ShowMessage(IntToStr(sizeof(TMessage)));
    end;

    结果等于16

    -------------------------------------------------------------

    再测试消息本身的大小:

    procedure TForm1.Button3Click(Sender: TObject);
    begin
      ShowMessage(IntToStr(sizeof(WM_CHAR)));
    end;

    结果等于2

    procedure TForm1.Button3Click(Sender: TObject);
    begin
      ShowMessage(IntToStr(sizeof(WM_SIZE)));
    end;

    结果等于1

    -------------------------------------------------------------

    再来看Delphi定义的消息结构体:

      TWMSize = packed record
        Msg: Cardinal;
        SizeType: Longint; { SIZE_MAXIMIZED, SIZE_MINIMIZED, SIZE_RESTORED,
                             SIZE_MAXHIDE, SIZE_MAXSHOW }
        Width: Word;
        Height: Word;
        Result: Longint;
      end;
    
      TWMKey = packed record
        Msg: Cardinal;
        CharCode: Word;
        Unused: Word;
        KeyData: Longint;
        Result: Longint;
      end;
    
      TWMChar = TWMKey;
    
      TWMPaint = packed record
        Msg: Cardinal;
        DC: HDC;
        Unused: Longint;
        Result: Longint;
      end;
    
      TWMCommand = packed record
        Msg: Cardinal;
        ItemID: Word;
        NotifyCode: Word;
        Ctl: HWND;
        Result: Longint;
      end;
    
      TWMNotify = packed record
        Msg: Cardinal;
        IDCtrl: Longint;
        NMHdr: PNMHdr;
        Result: Longint;
      end;

    测试Delphi消息结构体的大小:

    procedure TForm1.Button3Click(Sender: TObject);
    begin
      ShowMessage(IntToStr(sizeof(TWMSize)));
      ShowMessage(IntToStr(sizeof(TWMChar)));
      ShowMessage(IntToStr(sizeof(TWMPaint)));
      ShowMessage(IntToStr(sizeof(TWMCommand)));
      ShowMessage(IntToStr(sizeof(TWMNotify)));
    end;

    怎么测都是16字节大小。。。

    ------------------------------------------------------------------------

    一个使用例子:

      TWMContextMenu = packed record
        Msg: Cardinal;
        hWnd: HWND;
        case Integer of
          0: (
            XPos: Smallint;
            YPos: Smallint);
          1: (
            Pos: TSmallPoint;
            Result: Longint);
      end;
    
    procedure TControl.WMContextMenu(var Message: TWMContextMenu);
    var
      Pt, Temp: TPoint;
      Handled: Boolean;
      PopupMenu: TPopupMenu;
    begin
      if Message.Result <> 0 then Exit;
      if csDesigning in ComponentState then
      begin
        inherited;
        Exit;
      end;
    
      Pt := SmallPointToPoint(Message.Pos);
      if InvalidPoint(Pt) then
        Temp := Pt
      else
      begin
        Temp := ScreenToClient(Pt);
        if not PtInRect(ClientRect, Temp) then
        begin
          inherited;
          Exit;
        end;
      end;
    
      Handled := False;
      DoContextPopup(Temp, Handled);
      Message.Result := Ord(Handled);
      if Handled then Exit;
    
      PopupMenu := GetPopupMenu;
      if (PopupMenu <> nil) and PopupMenu.AutoPopup then
      begin
        SendCancelMode(nil);
        PopupMenu.PopupComponent := Self;
        if InvalidPoint(Pt) then
          Pt := ClientToScreen(Point(0, 0));
        PopupMenu.Popup(Pt.X, Pt.Y);
        Message.Result := 1;
      end;
    
      if Message.Result = 0 then
        inherited;
    end;
  • 相关阅读:
    1121 Django基本
    1121 爬虫简单面条版
    1118 DOM
    1114 CSS基础
    1116 前端的练习--博客界面
    1112 前端基础之标签
    仿优酷错误
    1107 python自定义实现ORM
    cesm1_2_2在南信大大型机上的移植以及运行简单case的步骤
    ERROR:105: Unable to locate a modulefile for 'xxx'
  • 原文地址:https://www.cnblogs.com/findumars/p/5183689.html
Copyright © 2011-2022 走看看