就是实现好像photoshop那样的插入文本功能,文本插入以后,通过鼠标的选择能够移动位置,进行编辑等~~~~~~我现在用brush 只能做到在特定位置插入栅格化了的文字,根本就不能再编辑~~~~~请高手帮帮忙

解决方案 »

  1.   

    photoshop使用了层的概念
    换用DELPHI的说法就是它操作的是两个Tcanvas
      

  2.   

    那尽管]多了一个Tcanvas层也不能达到随意编辑的功能阿~~~~你怎么是那个canvas在运行后随意移动呢?怎么编辑上面的栅格化的文本呢?
      

  3.   

    做个label+edit的功能就成.
    移动可以postmessage(...)具体查下panel的鼠标移动.
    点击时显示edit,移开或双击显示label.移动时可以移动label.然后输出的时候再Copy一下窗体就成:P有点取巧的方法了,不过很简单,想想就明白,标签和edit都要程序来创建哦
      

  4.   

    postmessage(...)不是消息传递吗?我糊涂了~~~~~~~能不能讲的具体一点呢?我还是看不懂~~~~不好意思啊,新手~~~~
      

  5.   

    你看看Windows的画图小程序,它的输入文字的功能,其实就是一个Edit,输入完毕后,再把这些文字画到画布上面的
    你也完全可以这样实现之,这里有一个类,参考一下:
    unit UFontEdit;interface
      uses Messages,Windows,Classes,StdCtrls,Controls,Graphics,Dialogs,Forms;
    type
      TFontEdit=class(TCustomMemo)
      private
        FFontHeight:integer;
        canMove:Boolean;
        MoveSize:integer;
        procedure ManipulateControl(WinControl: TWinControl; Shift: TShiftState;
        X, Y: integer);
        procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
      protected
        procedure CreateWnd; override;
       //鼠标事件处理
        procedure FontEditMouseMove(Sender: TObject; Shift: TShiftState; X,
          Y: Integer);
        procedure FontEditMouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FontEditChange(Sender: TObject);
        procedure FontEditResize(Sender:TObject);
        function isInClient(X,Y:integer):Boolean;
        function GetTextHeight(Font:TFont):Integer;
      public
        Constructor Create(AOwner:TComponent;Font:TFont);
        property Color;
        property Enabled;
        property Font;
        property Lines;
        property ShowHint;
        property Visible;
        property OnClick;
        property OnDblClick;
        property OnEnter;
        property OnExit;
      end;implementation{ TFontEdit }
    //移动和拉动编辑框的方法
    procedure TFontEdit.ManipulateControl(WinControl: TWinControl; Shift: TShiftState;
      X, Y: integer);
    var SC_MANIPULATE: Word; isCan:Boolean;
    begin
      WinControl.Cursor := crDefault;
       SC_MANIPULATE:=0;
      isCan:=False;
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      //光标在控件的最左侧**********************************************************
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      if (X<=MoveSize) and (Y>MoveSize) and (Y<WinControl.Height-MoveSize)
      then begin
             SC_MANIPULATE  := $F001;
             WinControl.Cursor := crSizeWE;
             isCan:=True;
           end
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      //光标在控件的最右侧**********************************************************
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      else if (X>=WinControl.Width-MoveSize) and (Y>MoveSize) and (Y<WinControl.Height-MoveSize)
      then begin
             SC_MANIPULATE  := $F002;
             WinControl.Cursor := crSizeWE;
             isCan:=True;
           end
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      //光标在控件的最上侧**********************************************************
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      else if (X>MoveSize) and (X<WinControl.Width-MoveSize) and (Y<=MoveSize)
      then begin
             SC_MANIPULATE  := $F003;
             WinControl.Cursor := crSizeNS;
             isCan:=True;
           end
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      //光标在控件的左上角**********************************************************
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      else if (X<=MoveSize) and (Y<=MoveSize)
      then begin
             SC_MANIPULATE  := $F009;
             WinControl.Cursor := crSizeAll;
             isCan:=True;
           end
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      //光标在控件的右上角**********************************************************
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      else if (X>=WinControl.Width-MoveSize) and (Y<=MoveSize)
      then begin
             SC_MANIPULATE  := $F005;
             WinControl.Cursor := crSizeNESW;
             isCan:=True;
           end
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      //光标在控件的最下侧**********************************************************
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      else if (X>MoveSize) and (X<WinControl.Width-MoveSize) and (Y>=WinControl.Height-MoveSize)
      then begin
             SC_MANIPULATE  := $F006;
             WinControl.Cursor := crSizeNS;
             isCan:=True;
           end
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      //光标在控件的左下角**********************************************************
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      else if (X<=MoveSize) and (Y>=WinControl.Height-MoveSize)
      then begin
             SC_MANIPULATE  := $F007;
             WinControl.Cursor := crSizeNESW;
             isCan:=True;
           end
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      //光标在控件的右下角**********************************************************
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      else if (X>=WinControl.Width-MoveSize) and (Y>=WinControl.Height-MoveSize)
      then begin
             SC_MANIPULATE  := $F008;
             WinControl.Cursor := crSizeNWSE;
             isCan:=True;
           end;
      if (Shift=[ssLeft])and(isCan=True)and(CanMove=true)then
      begin
        ReleaseCapture;
        WinControl.Perform(WM_SYSCOMMAND, SC_MANIPULATE, 0);
      end;
    end;
    //初始化参数
    constructor TFontEdit.Create(AOwner: TComponent;Font:TFont);
    begin
      inherited Create(AOwner);
      self.OnMouseMove:=FontEditMouseMove;
      self.OnMouseDown:=FontEditMouseDown;
      self.OnChange:=FontEditChange;
      self.OnResize:=FontEditResize;
      FFontHeight:=GetTextHeight(Font);
      self.Height:=FFontHeight+2;
      self.Width:=60;
      MoveSize:=3;
    end;
    //设置编辑框的风格
    procedure TFontEdit.CreateWnd;
    begin
      inherited;
      self.Ctl3D:=false;
      self.Constraints.MinHeight:=FFontHeight*(self.Lines.Count+1)+2;
      self.Constraints.MinWidth:=60;
    end;
    //鼠标移动消息
    procedure TFontEdit.FontEditMouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: Integer);
    begin
      ManipulateControl(self,Shift,X,Y);
    end;
    //判断鼠标是否在可移动范围内
    procedure TFontEdit.FontEditMouseDown(Sender: TObject;
      Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    begin
      if isInClient(X,Y) then
        canMove:=false
      else
        canMove:=true;
    end;
    //判断鼠标是否在客户区内
    function TFontEdit.isInClient(X,Y:Integer): Boolean;
    begin
      result:=false;
      if (X>MoveSize)and(X<self.Width-MoveSize)
      and(Y>MoveSize)and (Y<self.Height-MoveSize) then
        result:=true;
    end;
    //取得一行文本的高度
    function TFontEdit.GetTextHeight(Font:TFont): Integer;
    var C:TCanvas; size:Tsize;
    begin
      result:=0;
      C:=TCanvas.Create;
      C.Handle:=GetDC(Application.Handle);
      try
        C.Font:=Font;
        if GetTextExtentPoint32(C.Handle,'H',1,size)then
          result:=size.cy;
      finally
        C.Free;
      end;
    end;
    //文本改变时调整最小高度
    procedure TFontEdit.FontEditChange(Sender: TObject);
    begin
      self.Constraints.MinHeight:=FFontHeight*(self.Lines.Count+1)+2;
    end;
    //当字体被改变时调用
    procedure TFontEdit.CMFontChanged(var Message: TMessage);
    begin
      inherited;
      FFontHeight:=GetTextHeight(self.Font);
      self.Constraints.MinHeight:=FFontHeight*(self.Lines.Count+1)+2;
    end;
    //当改变大小时,调整最小高度
    procedure TFontEdit.FontEditResize(Sender: TObject);
    begin
      self.Constraints.MinHeight:=FFontHeight*(self.Lines.Count+1)+2;
    end;end.
      

  6.   

    、、、、、、、、、、、、、、、、、、、、
    测试单元:
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Buttons, TFlatMemoUnit,UEdtFont,uFontEdit;type
      TForm1 = class(TForm)
          procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
          Y: Integer);
        procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FormCreate(Sender: TObject);
        procedure BitBtn1Click(Sender: TObject);
      private
        { Private declarations }
        EdtFont:TFontEdit;
       // C:TCanvas;
      public
        { Public declarations }
        isDown:Boolean;
        hasMove:Boolean;
        OrgP,prevP,offSetP:TPoint;
        hasDone:Boolean;
        c:TCanvas;
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      if Button=mbLeft then
      begin
        isDown:=true;
        hasMove:=false;
        orgP:=Point(X,Y);
        offsetP:=Point(X,Y);
        self.Canvas.Rectangle(Rect(orgP,offsetP));
      end;
      if hasDone and assigned(EdtFont) then
      begin
        FreeAndNil(EdtFont);
        hasDone:=false;
      end;
    end;procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      if isDown then
      begin
         hasMove:=True;
         self.Canvas.Rectangle(Rect(orgP,offsetP));
         offsetP:=Point(X,Y);
         self.Canvas.Rectangle(Rect(orgP,offsetP));
      end;
    end;procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
       self.Canvas.Rectangle(Rect(orgP,offsetP));
       isDown:=false;
       hasDone:=true;
       if hasMove then
       begin
         EdtFont:=TFontEdit.Create(self,self.Font);
         EdtFont.Visible:=false;
         EdtFont.Parent:=self;
         EdtFont.Font:=Font;
         EdtFont.Left:=OrgP.X;
         EdtFont.Top:=OrgP.Y;
         EdtFont.Width:=offsetP.X-OrgP.X;
         EdtFont.Height:=offsetP.Y-OrgP.Y;
         EdtFont.Visible:=true;
       end
       else
       begin
         EdtFont:=TFontEdit.Create(self,self.Font);
         EdtFont.Visible:=false;
         EdtFont.Parent:=self;
         EdtFont.Font:=Font;
         EdtFont.Left:=OrgP.X;
         EdtFont.Top:=OrgP.Y;
         EdtFont.Visible:=true;
       end;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      self.Canvas.Pen.Style:=psDash;
      self.Canvas.Pen.Mode:=pmNot;
      self.Canvas.Brush.Style:=bsClear;
      self.DoubleBuffered:=true;
    end;end.
    把上面的代码拷到程序上,再仔细看看吧。
      

  7.   

    非常谢谢楼上的帮助~~~~~不过你的程序有一个小毛病:hasMove在设为True以后就一直没有改变了。anyway~~~~thx~~