• 带标题的编辑框


    unit ExEdit;
     
    interface
     
    uses
      System.Classes, Vcl.Controls, Winapi.Windows, Vcl.Graphics, Vcl.StdCtrls,
      System.SysUtils, Winapi.messages;
     
    type
     
      TBorders = class(TPersistent)
      private
        FRight: Boolean;
        FBottom: Boolean;
        FTop: Boolean;
        FLeft: Boolean;
        FPen: TPen;
      public
        constructor Create;
        destructor Destroy; override;
      published
        property Pen: TPen read FPen write FPen;
        property Left: Boolean read FLeft write FLeft;
        property Right: Boolean read FRight write FRight;
        property Top: Boolean read FTop write FTop;
        property Bottom: Boolean read FBottom write FBottom;
      end;
     
      TAlterMode = (alterNone, alterFont, alterHeight);
     
      TExEdit = class(TWinControl)
      private
        FTitle: TCaption;
        FTitleLength: Integer;
        FLines: string;
        fAlterMode: TAlterMode;
        FBorders: TBorders;
        fMinHeight: Integer;
        fMaxFont: Integer;
        fOldText: string;
        fMinFont: Integer;
        fMaxHeight: Integer;
        procedure WMChar(var Msg: TWMChar); message WM_CHAR;
        procedure WMKeyDown(var Msg: TWMKeyDown); message WM_KEYDOWN;
        procedure WMPaint(var Msg: TWMPaint);message WM_PAINT;
        procedure setLines(const Value: string);
        procedure setTitle(const Value: TCaption);
        procedure Polyline(const Points: array of TPoint);
        function getSelection: TSelection;
        procedure checkMode(isRecursion: Boolean = False);
        procedure checkText;
        procedure setMaxHeight(const Value: Integer);
      protected
        { protected declarations }
        procedure CreateParams(var Params: TCreateParams); override;
        procedure Loaded();override;
      public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
      published
        property Font;
        property AlterMode: TAlterMode read fAlterMode write fAlterMode;
        property Borders: TBorders read FBorders write FBorders stored True;
        property Title: TCaption read FTitle write setTitle;
        property Lines: string read FLines write setLines;
        property MinFont: Integer read fMinFont write fMinFont default 12;
        property MaxHeight: Integer read fMaxHeight write setMaxHeight default 0;
      end;
     
    implementation
     
    { TExEdit }
     
    procedure TExEdit.checkMode(isRecursion: Boolean);
    var
      vhdc: HDC;
      vidx,vpos,tmpH: Integer;
      vsize: TSize;
    begin
     
      FLines := string(Text).Substring(FTitleLength);
     
      vhdc := GetDC(Self.Handle);
      vidx := Length(Text);
      vpos := Perform(EM_POSFROMCHAR,vidx - 1,0);
      SelectObject(vhdc, Font.Handle);
      Winapi.Windows.GetTextExtentPoint32(vhdc, 'A', 1, vsize);
      tmpH := HiWord(vpos)+vsize.cy + 5;
     
      if fAlterMode = alterNone then
      begin
        if (vpos = -1) or (tmpH > Height) then
          Perform(WM_CHAR,VK_BACK,$E0001);
      end;
     
      if fAlterMode = alterFont then
      begin
        if (vpos = -1) or (tmpH > Height) then
        begin
          Font.Size := Font.Size - 1;
          if fMinFont > Font.Size then
          begin
            Font.Size := fMinFont;
            Perform(WM_CHAR,VK_BACK,$E0001);
          end else
            checkMode(True);
        end
        else
        begin
          if not isRecursion and (fMaxFont > Font.Size) then
          begin
            Font.Size := Font.Size + 1;
            checkMode;
          end;
        end;
      end;
      if fAlterMode = alterHeight then
      begin
        if (vpos = -1) or (tmpH > Height) then
        begin
          Height := tmpH;
          if (fMaxHeight > 0) and (fMaxHeight < height) then
          begin
            Height := fMaxHeight;
            Perform(WM_CHAR,VK_BACK,$E0001);
          end else
            checkMode;
        end
        else
        begin
          Height := tmpH;
          if fMinHeight > Height then
            Height := fMinHeight;
        end;
      end;
    end;
     
    procedure TExEdit.checkText;
    begin
      if fOldText <> Text then
      begin
        fOldText := Text;
        checkMode;
      end;
    end;
     
    constructor TExEdit.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      FBorders := TBorders.Create;
      FBorders.Left := True;
      FBorders.Right := True;
      FBorders.Top := True;
      FBorders.Bottom := True;
      fMinFont := 12;
      fMaxHeight := 0;
    end;
     
    procedure TExEdit.CreateParams(var Params: TCreateParams);
    begin
      inherited CreateParams(Params);
      CreateSubClass(Params, 'EDIT');
      with Params do
      begin
        Style := Style or ES_MULTILINE;
        { 完全重画 }
        Style := Style and not WS_CLIPCHILDREN;
        Style := Style and not WS_CLIPSIBLINGS;
        { 增加透明 }
        ExStyle := ExStyle or WS_EX_TRANSPARENT;
      end;
    end;
     
    destructor TExEdit.Destroy;
    begin
      FBorders.Free;
      inherited Destroy;
    end;
     
    function TExEdit.getSelection: TSelection;
    begin
      SendMessage(Handle, EM_GETSEL, NativeInt(@Result.StartPos),
      NativeInt(@Result.EndPos));
    end;
     
    procedure TExEdit.Loaded;
    begin
      inherited;
      fMinHeight := Height;
      fMaxFont := Font.Size;
    end;
     
    type
      PPoints = ^TPoints;
      TPoints = array[0..0] of TPoint;
     
    procedure TExEdit.Polyline(const Points: array of TPoint);
    var
      vhdc: HDC;
    begin
      vhdc := GetDC(Self.Handle);
      SelectObject(vhdc,Borders.Pen.Handle);
      SetROP2(vhdc, R2_COPYPEN);
      Winapi.Windows.Polyline(vhdc, PPoints(@Points)^, High(Points) + 1);
    end;
     
    procedure TExEdit.setLines(const Value: string);
    begin
      FLines := Value;
      Text := Title + Lines;
    end;
     
    procedure TExEdit.setMaxHeight(const Value: Integer);
    begin
      fMaxHeight := Value;
      if (fMaxHeight > 0) and (fMaxHeight < height) then
        fMaxHeight := Height;
    end;
     
    procedure TExEdit.setTitle(const Value: TCaption);
    begin
      FTitle := Value;
      FTitleLength := Length(FTitle);
      Text := Title + Lines;
    end;
     
    procedure TExEdit.WMChar(var Msg: TWMChar);
    var
      canInherited: Boolean;
    begin
      canInherited := False;
      case Msg.CharCode of
        VK_BACK:
          canInherited :=
            (getSelection.StartPos >= FTitleLength)
              and (getSelection.EndPos > FTitleLength)
              and (Msg.KeyData <> 0);
      else
        canInherited := getSelection.StartPos >= FTitleLength;
      end;
      if canInherited then
      begin
        inherited;
        checkText;
      end;
    end;
     
    procedure TExEdit.WMKeyDown(var Msg: TWMKeyDown);
    var
      canInherited: Boolean;
    begin
      canInherited := False;
      case Msg.CharCode of
        VK_DELETE:
          canInherited := getSelection.StartPos >= FTitleLength;
      else
        canInherited := True;
      end;
      if canInherited then
      begin
        inherited;
        checkText;
      end;
    end;
     
    procedure TExEdit.WMPaint(var Msg: TWMPaint);
    begin
      inherited;
      if Borders.Bottom then
        Polyline([Point(0, Height-1), Point(Width - 1, Height-1)]);
      if Borders.Left then
        Polyline([Point(0, 0), Point(0, Height - 1)]);
      if Borders.Right then
        Polyline([Point(Width - 1, 0), Point(Width - 1, Height - 1)]);
      if Borders.Top then
        Polyline([Point(0, 0), Point(Width - 1, 0)]);
    end;
     
    { TBorders }
     
    constructor TBorders.Create;
    begin
      FPen := TPen.Create;
    end;
     
    destructor TBorders.Destroy;
    begin
      FPen.Free;
      inherited Destroy;
    end;
     
    end.
    View Code

  • 相关阅读:
    Perl语言入门笔记 第十六章 进程管理
    Perl语言入门笔记 第十五章 智能匹配与given-when结构
    Perl语言入门笔记 第十四章 字符串与排序
    Perl语言入门笔记 第十三章 目录操作
    Perl语言入门笔记 第十二章 文件测试
    artdialog
    trimend("asdas".tocharArry())
    jQuery.isEmptyObject() 函数详解 转
    ajax返回数据成功 却进入error方法
    为什么有些网站PING不通但又能访问.
  • 原文地址:https://www.cnblogs.com/key-ok/p/3380846.html
Copyright © 2020-2023  润新知