TEdit的Ctl3D属性指定为False后,Edit的边框变为黑色,这是在哪里实现的

解决方案 »

  1.   

    看了下源码:
    Ctl3D属性应该是从TCustomEdit这来的
    当修改Ctl3D的属性的时候就会触发CM_CTL3DCHANGED这个消息
    然后再procedure TCustomEdit.CMCtl3DChanged(var Message: TMessage);
    响应过程中处理,主要就是UpdateHeight和RecreateWnd这两个过程
    具体的可以看看不得闲大牛的博客:
    http://www.cnblogs.com/DxSoft/archive/2010/04/30/1724809.html
      

  2.   

    我之前就跟过UpdateHeight和RecreateWnd,但还是没找到!
      

  3.   


    StdCtrls.pas
    procedure TCustomEdit.CMCtl3DChanged(var Message: TMessage);
    begin
      if NewStyleControls and (FBorderStyle = bsSingle) then
      begin
        UpdateHeight;
        RecreateWnd;
      end;
      inherited;
    end;procedure TCustomEdit.UpdateHeight;
    begin
      if FAutoSize and (BorderStyle = bsSingle) then
      begin
        ControlStyle := ControlStyle + [csFixedHeight];
        AdjustHeight;
      end else
        ControlStyle := ControlStyle - [csFixedHeight];
    end;Controls.pas
    procedure TWinControl.RecreateWnd;
    begin
      if WindowHandle <> 0 then Perform(CM_RECREATEWND, 0, 0);
    end;
      

  4.   

    LZ跟得没仔细而已。不得闲大牛在博客中也阐述得很明了:“...在设置新样式的时候,调用了一个RecreateWnd的方法...”,而这个方法又会引起使用StdCtrls单元的TCustomEdit.CreateParams方法来重建Tedit的Style,在CreateParams方法中:
    procedure TCustomEdit.CreateParams(var Params: TCreateParams);
    const
      Passwords: array[Boolean] of DWORD = (0, ES_PASSWORD);
      ReadOnlys: array[Boolean] of DWORD = (0, ES_READONLY);
      CharCases: array[TEditCharCase] of DWORD = (0, ES_UPPERCASE, ES_LOWERCASE);
      HideSelections: array[Boolean] of DWORD = (ES_NOHIDESEL, 0);
      OEMConverts: array[Boolean] of DWORD = (0, ES_OEMCONVERT);
    begin
      inherited CreateParams(Params);
      CreateSubClass(Params, 'EDIT');
      with Params do
      begin
        Style := Style or (ES_AUTOHSCROLL or ES_AUTOVSCROLL) or
          BorderStyles[FBorderStyle] or Passwords[FPasswordChar <> #0] or
          ReadOnlys[FReadOnly] or CharCases[FCharCase] or
          HideSelections[FHideSelection] or OEMConverts[FOEMConvert];//设置它的风格
        if NewStyleControls and Ctl3D and (FBorderStyle = bsSingle) then
        begin//如果是Ctl3D才会执行
          Style := Style and not WS_BORDER;
          ExStyle := ExStyle or WS_EX_CLIENTEDGE;
        end;
      end;
    end;
    这恐怕正是你想找的地方了吧?
      

  5.   

    如果这样注释了它:
    //  if NewStyleControls and Ctl3D and (FBorderStyle = bsSingle) then
    把 StdCtrls.dcu 改个名字,让系统自己重新编译过它以后,那么,你就再无法令“TEdit的Ctl3D属性指定为False后,Edit的边框变为黑色”了。所以,说明StdCtrls单元的TCustomEdit.CreateParams 里面,正是“实现的地方”。
      

  6.   

    补充一下,上述指的当然是运行时的,如果设计时在对象浏览器里改变Ctl3D属性,是将透过Controls单元的SetCtl3D方法,直接给它发送消息来改变(反相)的。