Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Delphi: Создание простого цветного TMemo или TEdit

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
На первую страницук этому сообщениюк последнему сообщению

Открыть новую тему     Написать ответ в эту тему

ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору


Код:
 
(**
  *  Highlight with TMemo Impossible?  try this...
  *                                                by Gon Perez-Jimenez May'04
  *
  *  This is a sample how to work with highlighting within TMemo component by
  *  using interjected class technique.
  *
  *  Of course, this code is still uncompleted but it works fine for my
  *  purposes, so, hope you can improve it and use it.
  *
  *)
 
unit Unit1;
interface
 
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;
 
type
                 // Interjected Class
    TMemo = class(stdctrls.TMemo)
    private
      LineCaretPos,
      StartCaretPos :TSize;
      FocusLost     :boolean;
      function  HScrollPos:integer;
      procedure CharToCaret(CharPos:integer; var Row,Column:integer);
      procedure WMPaint(var Message: TWMPaint);     message WM_PAINT;
      procedure WMKillFocus(var Message: TWMKillFocus);     message WM_KILLFOCUS;
      procedure WMSetFocus(var Message: TWMSetFocus);     message WM_SETFOCUS;
      procedure WMKeyDown(var Message: TWMKeyDown);     message WM_KEYDOWN;
      procedure WMKeyUp(var Message: TWMKeyUp);     message WM_KEYUP;
      procedure WMCHAR(var Message: TWMCHAR);     message WM_CHAR;
      procedure WMPrintClient(var Message: TWMPaint);     message WM_PRINTCLIENT;
      procedure WMERASEBKGND(var Message: TWMERASEBKGND);     message WM_ERASEBKGND;
      procedure WMSize(var Message: TWMSize);       message WM_SIZE;
      procedure WMMove(var Message: TWMMove);       message WM_MOVE;
      procedure WMMouseMove(var Message: TWMMouseMove);       message WM_MOUSEMOVE;
      procedure WMLButtonUp(var Message: TWMLButtonUp);       message WM_LBUTTONUP;
      procedure WMLButtonDown(var Message: TWMLButtonDown);       message WM_LBUTTONDOWN;
      procedure WMLButtonDblClk(var Message: TWMLButtonDblClk);       message WM_LBUTTONDBLCLK;
      procedure WMVScroll(var Message: TWMVScroll);    message WM_VSCROLL;
      procedure WMHScroll(var Message: TWMHScroll);    message WM_HSCROLL;
      procedure WMMousewheel(var Message: TWMMouseWheel); message WM_MOUSEWHEEL;
      procedure PaintLine(Canvas:TCanvas; LineText:string;CurLine:integer; TxtRect:TRect);
      function  IsKeyWord (S: String ):Boolean;
    protected
      procedure Change; override;
      procedure KeyDown(var Key: Word; Shift: TShiftState); override;
      procedure KeyUp(var Key: Word; Shift: TShiftState); override;
      procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
      procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    public
      PosLabel : TLabel;
      HighlightWords : TStrings;
      procedure Update_label;
      procedure AddHighlightWords(Words:string; Separator:char);
      function  GetTextStart(Row:integer):TSize;
      function  Line : Integer;
      function  Col : Integer;
      function  TopLine : Integer;
      function  VisibleLines: Integer;
      constructor Create(AOwner: TComponent); override;
    end;
 
 
  TForm1 = class(TForm)
    Memo1: TMemo;
    Label1: TLabel;
    Label2: TLabel;
    Label6: TLabel;
    Button1: TButton;
    Memo2: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure Memo1KeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Memo1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
implementation
 
{$R *.DFM}
 
procedure SetRedraw(Handle:THandle; Flag: boolean);
begin
    SendMessage(Handle,WM_SETREDRAW, Ord(Flag), 0);
end;
 
////////////////////////////////////////////////////////////////////////////////
// functions for managing keywords and numbers of each line of TMemo ///////////
////////////////////////////////////////////////////////////////////////////////
function IsSeparator(Symbol:char):Boolean;
begin
 Case Symbol of
 '.', ';', ',', ':', 'Ў', '!', '·', '"', '''', '^', '+', '-', '*', '/', '\', 'Ё',' ',
 '`', '[', ']', '(', ')', 'є', 'Є', '{', '}', '?', 'ї', '%','=', '<','>': result := true;
 else
     result := false;
 end;
end;
////////////////////////////////////////////////////////////////////////////////
function NextWord ( var s: String): String;
begin
 result := '';
 if s='' then Exit;
 if IsSeparator(s[1]) then begin
     result := result+s[1];
     delete(s,1,1);
 end else
 while(s<>'') and not IsSeparator(s[1]) do begin
     result := result+s[1];
     delete(s,1,1);
 end;
end;
////////////////////////////////////////////////////////////////////////////////
function TMemo.IsKeyWord ( s: String ):Boolean;
begin
 result := False;
 if s='' then Exit;
 result := HighlightWords.IndexOf( lowercase(s) ) <> -1;
end;
////////////////////////////////////////////////////////////////////////////////
function IsNumber ( s: String ):Boolean;
var i: Integer;
begin
 result := False;
 for i:=1 to length(s) do
     Case s[i] of
     '0'..'9':;
     else Exit;
     end;
 result := True;
end;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// New or overrided methods and properties for TMemo using Interjected Class ///
// Technique ///////////////////////////////////////////////////////////////////
function TMemo.VisibleLines: Integer;
begin
 result := Height div ( Abs(Self.Font.Height)+2);
end;
////////////////////////////////////////////////////////////////////////////////
function TMemo.GetTextStart(Row:integer):TSize;
var
 ChrInd   : integer;
 Res      : LResult;
begin
 Result.cx := 0;
 Result.cy := 0;
 if Self.Lines.Count <= 0 then Exit;
 case Self.ScrollBars of
  ssBoth, ssHorizontal:
       if HScrollPos=0 then begin
         ChrInd:=SendMessage(Handle, EM_LINEINDEX, Row, 0);
         Res := SendMessage(Self.Handle,EM_POSFROMCHAR, ChrInd,0);
         if Res>0 then begin
           Result.cx:=LoWord(Res);
           Result.cy:=HiWord(Res);
          end
      end
      else begin
         ChrInd:=SendMessage(Handle, EM_LINEINDEX, Row, 0);
         Res := SendMessage(Self.Handle,EM_POSFROMCHAR, ChrInd,0);
         if Res>0 then begin
           Result.cx:=StartCaretPos.cx-HScrollPos;
           Result.cy:=HiWord(Res);
         end;
      end;
   ssVertical, ssNone:
      begin
         ChrInd:=SendMessage(Handle, EM_LINEINDEX, Row, 0);
         Res := SendMessage(Self.Handle,EM_POSFROMCHAR, ChrInd,0);
         if Res>0 then begin
           Result.cx:=LoWord(Res);
           if Result.cx>Self.ClientRect.Right then Result.cx:=Result.cx-65535;
           Result.cy:=HiWord(Res);
          end
      end;
  end;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.AddHighlightWords(Words:string;Separator:char);
var
     CurWord            :string;
begin
     While Words[1]=Separator do Delete(Words,1,1);
     While Words[Length(Words)]=Separator do Delete(Words,Length(Words),1);
     if (Words[Length(Words)]<>Separator) and (Length(Words)>0) then Words:=Words+Separator;
     repeat
       CurWord:=Copy(Words,1,Pos(Separator,Words)-1);
       HighlightWords.Add(CurWord);
       Delete(Words,1,Pos(Separator,Words));
     until Words='';
end;
////////////////////////////////////////////////////////////////////////////////
constructor TMemo.Create(AOwner: TComponent);
begin
     HighlightWords:=TStringList.Create;
     HighlightWords.Clear;
     AddHighlightWords('and#array#as#asm#begin#case#class#const#constructor#destructor#dispinterface'+
                       '#div#do#downto#else#end#except#exports#file#finalization#finally#for#function#'+
                       'goto#if#implementation#in#inherited#initialization#inline#interface#is#label#'+
                       'library#mod#nil#not#object#of#or#out#overload#override#packed#private#procedure'+
                       '#program#property#protected#public#raise#record#reintroduce#repeat#resourcestring'+
                       '#set#shl#shr#string#then#threadvar#to#try#type#unit#until#uses#var#while#with#xor','#');
     inherited;
     FocusLost:=False;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.Update_label;
begin
 if PosLabel=nil then Exit;
 PosLabel.Caption := '('+IntToStr(Line+1)+','+IntToStr(Col)+')';
end;
////////////////////////////////////////////////////////////////////////////////
function TMemo.TopLine : Integer;
begin
 Result := SendMessage(Self.Handle, EM_GETFIRSTVISIBLELINE, 0, 0);
end;
////////////////////////////////////////////////////////////////////////////////
function TMemo.Line : Integer;
begin
  Result := SendMessage(Self.Handle, EM_LINEFROMCHAR, Self.SelStart, 0);
end;  
////////////////////////////////////////////////////////////////////////////////
function TMemo.Col : Integer;
begin
  Result := Self.SelStart - SendMessage(Self.Handle, EM_LINEINDEX, SendMessage(Self.Handle,
    EM_LINEFROMCHAR, Self.SelStart, 0), 0);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.WMVScroll(var Message: TWMVScroll);
{var
    Locked      : boolean;}
begin
//   Locked:=LockWindowUpdate(Handle);
   inherited;
   RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
//   if Locked then LockWindowUpdate(0);
end;
////////////////////////////////////////////////////////////////////////////////
function TMemo.HScrollPos:integer;
var
    ScrollInfo  : TScrollInfo;
begin
   FillChar(ScrollInfo,SizeOf(TScrollInfo),0);
   ScrollInfo.cbSize:=SizeOf(TScrollInfo);
   ScrollInfo.fMask:=SIF_POS;
   GetScrollInfo(Handle,SB_HORZ, ScrollInfo);
   Result:=ScrollInfo.nPos;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.WMHScroll(var Message: TWMHScroll);
begin
   inherited;
   RedrawWindow(Handle, nil, 0,  RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.WMSize(var Message: TWMSize);
begin
   Update_label;
//   Locked:=LockWindowUpdate(Handle);
   inherited;
   RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
//   if Locked then LockWindowUpdate(0);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.WMEraseBKGND(var Message: TWMERASEBKGND);
begin
 // не удалять данную пустую процедуру, иначе будут глюки с изображением
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.WMMove(var Message: TWMMove);
begin
 Invalidate;
 inherited;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.CharToCaret(CharPos:integer; var Row,Column:integer);
begin
  Row := SendMessage(Self.Handle, EM_LINEFROMCHAR, CharPos, 0)+1;
  Column := CharPos - SendMessage(Self.Handle, EM_LINEINDEX, SendMessage(Self.Handle,
    EM_LINEFROMCHAR, CharPos, 0), 0);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.WMLButtonUp(var Message: TWMLButtonUp);
var
    Locked : boolean;
begin
    Locked:=False;
    try
     Locked:=LockWindowUpdate(Handle);
     inherited;
     RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
    finally
     if Locked then LockWindowUpdate(0);
   end;
end;
////////////////////////////////////////////////////////////////////////////////
procedure Tmemo.WMKillFocus(var Message: TWMKillFocus);
begin
    try
     SetRedraw(Handle,False);
     FocusLost:=True;
     inherited;
     RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
    finally
     SetRedraw(Handle,True);
   end;
end;
////////////////////////////////////////////////////////////////////////////////
procedure Tmemo.WMSetFocus(var Message: TWMSetFocus);
var
    Locked:boolean;
begin
    Locked:=False;
    try
     Locked:=LockWindowUpdate(GetDesktopWindow);
     inherited;
     RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
    finally
     if Locked then LockWindowUpdate(0);
   end;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.WMLButtonDown(var Message: TWMLButtonDown);
var
    Locked : boolean;
begin
    Locked:=False;
    if FocusLost then begin
       SetRedraw(Handle,False);
       inherited;
       RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
       SetRedraw(Handle,True);
      end
     else
    try
     Locked:=LockWindowUpdate(Handle);
     inherited;
     RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
    finally
     if Locked then LockWindowUpdate(0);
   end;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.WMLButtonDblClk(var Message: TWMLButtonDblClk);
var
    Locked : boolean;
begin
    Locked:=False;
    try
     Locked:=LockWindowUpdate(Handle);
     inherited;
     RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
    finally
     if Locked then LockWindowUpdate(0);
   end;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.WMMouseMove(var Message: TWMMouseMove);
var
    Locked              : boolean;
begin
   Locked:=False;
   if (Message.Keys and MK_LBUTTON)=0 then inherited else begin
    try
     RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
     if NOT FocusLost then
        Locked:=LockWindowUpdate(Handle)
     else
        FocusLost:=False;
     inherited;
    finally
     if Locked and NOT FocusLost then LockWindowUpdate(0);
   end;
  end;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.WMMousewheel(var Message: TWMMouseWheel);
var
    Locked : boolean;
begin
    Locked:=False;
    try
     Locked:=LockWindowUpdate(Handle);
     inherited;
     RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
    finally
     if Locked then LockWindowUpdate(0);
   end;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.Change;
begin
 Update_label;
 inherited Change;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.WMCHAR(var Message: TWMCHAR);
var
    Locked : boolean;
begin
    Locked:=False;
    try
     Locked:=LockWindowUpdate(Handle);
     inherited;
     RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
    finally
     if Locked then LockWindowUpdate(0);
   end;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.WMKeyDown(var Message: TWMKeyDown);
var
    Locked : boolean;
begin
    Locked:=False;
    try
     Locked:=LockWindowUpdate(Handle);
     inherited;
     RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
    finally
     if Locked then LockWindowUpdate(0);
   end;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.WMKeyUp(var Message: TWMKeyUp);
var
    Locked : boolean;
begin
    Locked:=False;
    try
     Locked:=LockWindowUpdate(Handle);
     inherited;
     RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
    finally
     if Locked then LockWindowUpdate(0);
   end;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.KeyDown(var Key: Word; Shift: TShiftState);
begin
 Update_label;
 inherited KeyDown(Key,Shift);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.KeyUp(var Key: Word; Shift: TShiftState);
begin
 Update_label;
 inherited KeyUp(Key,Shift);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 Update_label;
 inherited MouseDown(Button,Shift,X,Y);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 Update_label;
 inherited MouseUp(Button,Shift,X,Y);
// invalidate;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.PaintLine(Canvas:TCanvas; LineText:string; CurLine:integer; TxtRect:TRect);
const
     HilightFont = clNavy;
     HilightBack = clSilver;
type
     TxtAttr = record
       FontColor, BckColor      :TColor;
     end;
var
     i, j, px    :integer;
     LineSt,ColSt,LineEnd,ColEnd  :integer;
     LastFont, LastBck :TColor;
     Size       :TSize;
     t, CurWord :string;
     CharsColor :array of TxtAttr;
begin
     try
     CharToCaret(Self.SelStart,LineSt,ColSt);
     CharToCaret(Self.SelStart+Self.SelLength,LineEnd,ColEnd);
     with Canvas do begin
       px:=TxtRect.Left;
       t:=LineText+' ';
       SetLength(CharsColor,Length(LineText)+1);
       for i:=0 to High(CharsColor) do begin
           CharsColor[i].FontColor:=clBlack;
           CharsColor[i].BckColor:=Self.Color;
       end;
       i:=0;
       repeat
         CurWord:=NextWord(t);
         if CurWord<>'' then
          if CurWord=' ' then begin
             CharsColor[i].FontColor:=clBlack;
             CharsColor[i].BckColor:=Self.Color;
             Inc(i);
            end
          else
          if IsKeyWord(CurWord) then begin
            for j:=1 to Length(CurWord) do begin
              CharsColor[i+j-1].FontColor:=clWhite;
              CharsColor[i+j-1].BckColor:=Self.Color;
             end;
             Inc(i,Length(CurWord));
            end
          else
           if IsSeparator(CurWord[1]) then begin
             CharsColor[i].FontColor:=clYellow;
             CharsColor[i].BckColor:=Self.Color;
             Inc(i);
           end
           else
           if IsNumber(CurWord) then begin
            for j:=1 to Length(CurWord) do begin
              CharsColor[i+j-1].FontColor:=clFuchsia;
              CharsColor[i+j-1].BckColor:=Self.Color;
             end;
             Inc(i,Length(CurWord));
            end
           else begin
            for j:=1 to Length(CurWord) do begin
              CharsColor[i+j-1].FontColor:=clLime;
              CharsColor[i+j-1].BckColor:=Self.Color;
             end;
             Inc(i,Length(CurWord));
           end;
       until CurWord='';
       if Focused or NOT HideSelection then begin  // это если надо чтобы при потере фокуса исчезало выделение
       if (CurLine=LineSt) and (ColSt<>ColEnd) and (LineSt=LineEnd) then
          for i:=ColSt+1 to ColEnd do begin
              CharsColor[i-1].FontColor:=HilightFont;
              CharsColor[i-1].BckColor:=HilightBack;
            end;
       if (CurLine>LineSt) and (CurLine<LineEnd) then
          for i:=1 to Length(LineText) do begin
              CharsColor[i-1].FontColor:=HilightFont;
              CharsColor[i-1].BckColor:=HilightBack;
            end;
       if (CurLine=LineSt) and (LineSt<LineEnd) then
          for i:=ColSt+1 to Length(LineText) do begin
              CharsColor[i-1].FontColor:=HilightFont;
              CharsColor[i-1].BckColor:=HilightBack;
            end;
       if (CurLine=LineEnd) and (LineSt<LineEnd) then
          for i:=1 to ColEnd do begin
              CharsColor[i-1].FontColor:=HilightFont;
              CharsColor[i-1].BckColor:=HilightBack;
            end;
       end;
       CurWord:=LineText[1];
       LastFont:=CharsColor[0].FontColor;
       LastBck:=CharsColor[0].BckColor;
       if Length(LineText)=1 then begin
           Size:=TextExtent(CurWord);
           SetBkMode(Handle, TRANSPARENT);
           if LastBck<>Self.Color then begin
              Brush.Color:=LastBck;
              FillRect(Rect(px,TxtRect.Top,px+Size.cx,TxtRect.Top+Size.cy));
            end;
           Font:=Self.Font;
           Font.Color:=LastFont;
           TextOut(px,TxtRect.Top, CurWord);
         end;
       for i:=2 to Length(LineText) do begin
         t:=LineText[i];
         if (LastFont<>CharsColor[i-1].FontColor) or (LastBck<>CharsColor[i-1].BckColor) then begin
           Size:=TextExtent(CurWord);
           SetBkMode(Handle, TRANSPARENT);
           if LastBck<>Self.Color then begin
              Brush.Color:=LastBck;
              FillRect(Rect(px,TxtRect.Top,px+Size.cx,TxtRect.Top+Size.cy));
            end;
           Font:=Self.Font;
           Font.Color:=LastFont;
           TextOut(px,TxtRect.Top, CurWord);
           Inc(px,Size.cx);
           CurWord:='';
           LastFont:=CharsColor[i-1].FontColor;
           LastBck:=CharsColor[i-1].BckColor;
          end;
         CurWord:=CurWord+LineText[i];
         if px>TxtRect.Right then Break;
         if i=Length(LineText) then begin
           Size:=TextExtent(CurWord);
           SetBkMode(Handle, TRANSPARENT);
           if LastBck<>Self.Color then begin
              Brush.Color:=LastBck;
              FillRect(Rect(px,TxtRect.Top,px+Size.cx,TxtRect.Top+Size.cy));
            end;
           Font:=Self.Font;
           Font.Color:=LastFont;
           TextOut(px,TxtRect.Top, CurWord);
          end;
        end;
     end;
     finally
       SetLength(CharsColor,0);
    end;    
end;
////////////////////////////////////////////////////////////////////////////////
procedure TMemo.WMPaint(var Message: TWMPaint);
var
  PS           :TPaintStruct;
  DC           :HDC;
  hbmNew       :HBITMAP;
  hbmOld       :HBITMAP;
  Canvas       :TCanvas;
  i            :Integer;
  psRect       :TRect;
  Size         :TSize;
  Max, LineFirst,
  LineLast     :Integer;
  s            : String;
begin
{  inherited;
  Exit;}
  if (StartCaretPos.cx=0) and (Self.Lines.Count>0) and (Self.Alignment=taLeftJustify) then
     StartCaretPos:=GetTextStart(0);
  BeginPaint(Handle, PS);
  psRect:=Self.ClientRect;
  DC:=CreateCompatibleDC(ps.hdc);
  hbmNew := CreateCompatibleBitmap(PS.hdc, psRect.Right - psRect.Left, psRect.Bottom - psRect.Top);
  hbmOld := SelectObject(DC, hbmNew);
  Canvas:=TCanvas.Create;
  try
    Canvas.Handle:=DC;
    Canvas.Font:=Self.Font;
    with Canvas do begin
      Max := TopLine+VisibleLines;
      if Max>Pred(Lines.Count)then Max := Pred(Lines.Count);
      Brush.Color := Self.Color;
      FillRect( Self.ClientRect );
      Size:=TextExtent(' ');
      if GetForegroundWindow=Self.Parent.Handle then begin
        LineFirst:= TopLine+(PS.rcPaint.Top div Size.cy);
        LineLast:=TopLine+(PS.rcPaint.Bottom div Size.cy);
       end
      else begin
        LineFirst:= TopLine;
        LineLast:=Max;
       end;
      for i:=LineFirst to LineLast  do begin
        LineCaretPos:=GetTextStart(i);
        s:=Lines[i];
        if s='' then s:=' ';
        Size:=TextExtent(s);
        if LineCaretPos.cy+Size.cy<=psRect.Bottom then PaintLine(Canvas,s,i+1,Rect(LineCaretPos.cx,LineCaretPos.cy,Self.ClientRect.Right,LineCaretPos.cy+Size.cy));
      end;
    end;
  finally
    BitBlt(PS.hdc, psRect.Left, psRect.Top, psRect.Right - psRect.Left, psRect.Bottom - psRect.Top, dc, 0, 0, SRCCOPY);
    SelectObject(DC, hbmOld);
    DeleteObject(hbmNew);
    DeleteDC(DC);
    EndPaint(Handle, PS);
  end;
  Canvas.Free;
end;
 
procedure TMemo.WMPrintClient(var Message: TWMPaint);
var
  PS           :TPaintStruct;
  DC           :HDC;
  hbmNew       :HBITMAP;
  hbmOld       :HBITMAP;
  Canvas       :TCanvas;
  i            :Integer;
  psRect       :TRect;
  Size         :TSize;
  Max, LineFirst,
  LineLast     :Integer;
  s            : String;
begin
  BeginPaint(Handle, PS);
  psRect:=Self.ClientRect;
  DC:=CreateCompatibleDC(ps.hdc);
  hbmNew := CreateCompatibleBitmap(PS.hdc, psRect.Right - psRect.Left, psRect.Bottom - psRect.Top);
  hbmOld := SelectObject(DC, hbmNew);
  Canvas:=TCanvas.Create;
  try
    Canvas.Handle:=DC;
    Canvas.Font:=Self.Font;
    with Canvas do begin
      Max := TopLine+VisibleLines;
      if Max>Pred(Lines.Count)then Max := Pred(Lines.Count);
      Brush.Color := Self.Color;
      FillRect( Self.ClientRect );
      Size:=TextExtent(' ');
      if GetForegroundWindow=Self.Parent.Handle then begin
        LineFirst:= TopLine+(PS.rcPaint.Top div Size.cy);
        LineLast:=TopLine+(PS.rcPaint.Bottom div Size.cy);
       end
      else begin
        LineFirst:= TopLine;
        LineLast:=Max;
       end;
      for i:=LineFirst to LineLast  do begin
        LineCaretPos:=GetTextStart(i);
        s:=Lines[i];
        if s='' then s:=' ';
        Size:=TextExtent(s);
        if LineCaretPos.cy+Size.cy<=psRect.Bottom then PaintLine(Canvas,s,i+1,Rect(LineCaretPos.cx,LineCaretPos.cy,Self.ClientRect.Right,LineCaretPos.cy+Size.cy));
      end;
    end;
  finally
    BitBlt(PS.hdc, psRect.Left, psRect.Top, psRect.Right - psRect.Left, psRect.Bottom - psRect.Top, dc, 0, 0, SRCCOPY);
    SelectObject(DC, hbmOld);
    DeleteObject(hbmNew);
    DeleteDC(DC);
    EndPaint(Handle, PS);
  end;
  Canvas.Free;
end;
 
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
 
////////////////////////////////////////////////////////////////////////////////
// Procedures for Form1 ////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
procedure TForm1.FormCreate(Sender: TObject);
begin
 Memo1.PosLabel := Label1;
 Memo1.Update_label;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TForm1.Memo1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
    Point       : TPoint;
begin
 if Key=VK_F1 then Memo1.Invalidate;
 if Key=VK_F2 then begin
      Windows.GetCaretPos(Point);
      ShowMessage(Format('%d:%d',[Point.x,Point.y]));
 end;
 if Key=VK_F3 then Windows.SetCaretPos(20,2);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 Action := caFree;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TForm1.Memo1Click(Sender: TObject);
begin
     if Memo1.SelLength=0 then Memo1.invalidate;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
      if Memo1.Alignment=taCenter then begin
        Memo1.Alignment:=taRightJustify;
        Exit;
       end;
      if Memo1.Alignment=taRightJustify then begin
        Memo1.LineCaretPos.cx:=0;
        Memo1.Alignment:=taLeftJustify;
        Exit;
       end;
      if Memo1.Alignment=taLeftJustify then begin
        Memo1.Alignment:=taCenter;
        Exit;
       end;
 
end;
 
end.
 



----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 03:20 24-09-2009 | Исправлено: ShIvADeSt, 05:38 24-09-2009
Открыть новую тему     Написать ответ в эту тему

На первую страницук этому сообщениюк последнему сообщению

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Delphi: Создание простого цветного TMemo или TEdit


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru