• Winodws消息


    procedure WMGetDlgCode(var Msg: TWMGetDlgCode); message WM_GETDLGCODE;
    {说明:
    可以拦截处理方向键,但是有更灵活的方法,介绍如下:
    想要你的组件能够处理方向键,你必须要拦截 CM_WANTSPECIALKEY 组件讯息。 CM_WANTSP
    ECIALKEY 组件讯息提供你比拦截 WM_GETDLGCODE 窗口讯息更容易且灵活的判断方法来决定
    是否需要某些特殊键的讯息。当控件收到任何一个特殊键时就会送出CM_WANTSPECIALKEY 组
    件讯息给控件。

    CM_WANTSPECIALKEY 组件讯息比 WM_GETDLGCODE 讯息更具有弹性的地方在这儿。我们甚至
    可以根据是按下的是哪个特殊键才决定是否处理这个键。例如,你的控件有三张影像,你可
    以让使用者利用左右方向键来回检视它们,如果翻到最后一张影像再按向右键时,焦点就让
    它离开组件,剩下的全部都让 Delphi 来处理。

    举例:
    procedure TCustomGrid.WMGetDlgCode(var Msg: TWMGetDlgCode);
    begin
    Msg.Result := DLGC_WANTARROWS; //在这说明要处理方向键
    if goRowSelect in Options then Exit;
    if goTabs in Options then Msg.Result := Msg.Result or DLGC_WANTTAB; //这里同样可以处理Tab键
    if goEditing in Options then Msg.Result := Msg.Result or DLGC_WANTCHARS;
    end;

    相关:
    VCL内部消息 CM_WANTSPECIALKEY
    }
    procedure WMMeasureItem(var Message: TWMMeasureItem); message WM_MEASUREITEM;
    procedure WMDrawItem(var Message: TWMDrawItem); message WM_DRAWITEM;
    {说明:
    procedure WMMeasureItem(var Message: TWMMeasureItem); message WM_MEASUREITEM;
    procedure WMDrawItem(var Message: TWMDrawItem); message WM_DRAWITEM;
    这两个消息息息相关,一起做说明--

    系统会在控件需要绘制的时候先发送一个WM_MEASUREITEM消息给当此控件的父窗体(注意这里要
    注意,这是由于标准Win32开发方式决定的,由于原来大多数的控件都是在接收到主窗体的W
    M_CREATE消息时候创建的,一个窗口过程是当时程序员可以编写代码唯一的机会,所有的消
    息都发送到主线程的消息循环中,所以控件的消息自然发到这里来了!可没有这么频繁使用
    子类化或者超类化的方式)来确定控件的绘制范围,然后接着发送WM_DRAWITEM给此控件的父
    窗体,而我们要做一个独立的组件,它怎么知道什么时候该绘制呢?代码本来应该写在窗体
    中才对啊!好在delphi在库中意见考虑到这个需求,只要你的控件是在delphi中使用的,那
    么TForm窗体会将所有接收的消息发送给相应的窗口过程处理,TWinControl.WMDrawItem相关
    代码如下(经过处理):

    举例:
    procedure TWinControl.WMDrawItem(var Message: TWMDrawItem);
    begin
    if not DoControlMsg(Message.DrawItemStruct^.CtlID, Message) then iherited;
    end;
    而DoControlMsg的实现很简单:
    function DoControlMsg(ControlHandle: HWnd; var Message): Boolean;
    var Control: TWinControl;
    begin
    DoControlMsg := False;
    Control := FindControl(ControlHandle);
    if Control <> nil then
    with TMessage(Message) do
    begin
    Result := Control.Perform(Msg + CN_BASE, WParam, LParam);
    DoControlMsg := True;
    end;
    end;

    相关:
    上述消息在主窗体中被处理,Delphi中主窗体接受到此消息后,就查找要接受该消息的子窗体。
    找到控件后将该消息的标识加上CN_BASE发送给相应窗口就是了(CN_DRAWITEM=CN_BASE+WM_
    DRAWITEM),所以这里是第二个注意点:在组件中截获WM_DRAWITEM消息是没有效果的,事实
    上根本没有这个消息传送到组件的窗口过程,而应该截获的是CN_DRAWITEM,WM_MEASUREITE
    M的消息处理过程是一样的,组件中应该截取CN_MEASUREITEM消息。两个Delphi自定义消息
    声明如下:

    procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
    procedure CNMeasureItem(var Message: TWMMeasureItem); message CN_MEASUREITEM;
    }

  • 相关阅读:
    C#应用NPOI实现导出EXcel表格中插入饼状图(可实现动态数据生成)
    Asp.Net开发学习知识点整理
    Javascript,闭包
    sublime 自定义快捷生成代码块
    $.extend()使用
    ztree 数据格式及其配置
    ztree 数据格式 及 基本用法
    表单中两个submit如何判断点击的是哪个submit
    myChart.on('finished')
    jQuery数组排序
  • 原文地址:https://www.cnblogs.com/spiritofcloud/p/3978323.html
Copyright © 2020-2023  润新知