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

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

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

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

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

ShIvADeSt



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


Код:
 
{****************************************************}
{                                                    }
{               ColorEdit v1.0                       }
{                                                    }
{     Copyright (c) 2004 by Gon Perez-Jimenez        }
{  http://www.torry.net/authorsmore.php?id=3649      }
{                                                    }
{ Copyright (c) 2009 by ShIvADeSt Moderator Ru-Board }
{                                                    }
{     Copyright (c) 2009 by Stalker SoftWare         }
{                                                    }
{****************************************************}
 
unit ColorEdit;
 
interface
       
uses
  Windows, Messages, Classes, Graphics, StdCtrls, Controls;
 
type
  TWordType = (wtSeparator, wtSpace, wtNumber, wtText);
  TCheckWordEvent = procedure(Sender :TObject; cWord :String; WordType :TWordType; var FontColor, BackgroundColor :TColor; var IsUnderline :Boolean) of object;
 
  TColorEdit = class(TEdit)
  private
    { Private declarations }
    FStartCaretPos      :TSize;
    FLineCaretPos       :TSize;
    FFocusLost          :Boolean;
    FSeparators         :TStrings;
    FOnCheckWord        :TCheckWordEvent;
    FKeepSelOnLostFocus :Boolean;
    FAlignment          :TAlignment;
    FWordWrap           :Boolean;
    FWantReturns        :Boolean;
 
    procedure SetRedraw(Handle :THandle; Flag :Boolean);
    procedure CharToCaret(nCharPos :Integer; var nRow, nColumn :Integer);
 
    function  TextFromLine(nRow:integer):string;
 
    procedure WMKillFocus(var Message :TWMKillFocus); message WM_KILLFOCUS;
    procedure WMSetFocus(var Message :TWMSetFocus); message WM_SETFOCUS;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    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(oCanvas :TCanvas; cLineText :String; nCurLine :Integer; rTxtRect :TRect);
    procedure DrawUnderline(oCanvas :TCanvas; nFromX, nFromY, nToX :Integer);
 
    procedure SetSeparators(const Value :TStrings);
 
    function NextWord(var cStr :String) :String;
 
    function GetTextStart(nRow :Integer) :TSize;
 
    procedure SetAlignment(const Value: TAlignment);
    procedure SetWordWrap(const Value: Boolean);
    procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
 
  protected
    { Protected declarations }
    procedure CreateParams(var Params :TCreateParams); override;
     
  public
    { Public declarations }
    procedure GotoXY(nCol, nLine :Integer);
    function Line() :Integer;
    function Col() :Integer;
    function TopLine() :Integer;
    function VisibleLines() :Integer;
    function IsSeparator(cStr :Char) :Boolean;
    function IsNumber(cStr :String) :Boolean;
 
  published
    { Published declarations }
    constructor Create(AOwner :TComponent); override;
    destructor Destroy(); override;
 
    property Separators         :TStrings        read FSeparators         write SetSeparators;
    property OnCheckWord        :TCheckWordEvent read FOnCheckWord        write FOnCheckWord;
    property KeepSelOnLostFocus :Boolean         read FKeepSelOnLostFocus write FKeepSelOnLostFocus default False;
 
    property WordWrap    :Boolean    read FWordWrap    write SetWordWrap default False;
    property WantReturns :Boolean    read FWantReturns write FWantReturns default False;
    property Alignment   :TAlignment read FAlignment   write SetAlignment default taLeftJustify;
 
  end; { TColorEdit }
 
 procedure Register;
 
implementation
 
constructor TColorEdit.Create(AOwner: TComponent);
begin
 inherited;
 FSeparators := TStringList.Create;
 
 FSeparators.Add('.');
 FSeparators.Add(',');
 FSeparators.Add('|');
 FSeparators.Add(' ');
 FSeparators.Add(';');
 FSeparators.Add(':');
 FSeparators.Add('"');
 FSeparators.Add('''');
 FSeparators.Add('^');
 FSeparators.Add('+');
 FSeparators.Add('-');
 FSeparators.Add('*');
 FSeparators.Add('/');
 FSeparators.Add('\');
 FSeparators.Add('`');
 FSeparators.Add('~');
 FSeparators.Add('[');
 FSeparators.Add(']');
 FSeparators.Add('(');
 FSeparators.Add(')');
 FSeparators.Add('{');
 FSeparators.Add('}');
 FSeparators.Add('?');
 FSeparators.Add('!');
 FSeparators.Add('%');
 FSeparators.Add('=');
 FSeparators.Add('<');
 FSeparators.Add('>');
 
 FFocusLost := False;
 FKeepSelOnLostFocus := False;
 
 FAlignment   := taLeftJustify;
 FWordWrap    := False;
 FWantReturns := False;
 
end; { Create }
 
destructor TColorEdit.Destroy;
begin
 FSeparators.Free;
 inherited;
end; { Destroy }
 
function TColorEdit.TextFromLine(nRow:integer):string;
var
  Text: array[0..4095] of Char;
  L: Integer;
begin
  Word((@Text)^) := SizeOf(Text);
  L := SendMessage(Self.Handle, EM_GETLINE, nRow, Longint(@Text));
  if (Text[L - 2] = #13) and (Text[L - 1] = #10) then Dec(L, 2);
  SetString(Result, Text, L);
end;
 
procedure TColorEdit.SetSeparators(const Value :TStrings);
begin
 FSeparators.Assign(Value);
end; { SetSeparators }
 
procedure TColorEdit.SetAlignment(const Value :TAlignment);
begin
 
 if FAlignment <> Value then begin
   FAlignment := Value;
   RecreateWnd;
 end; { if }
 
end; { SetAlignment }
 
procedure TColorEdit.SetWordWrap(const Value :Boolean);
begin
 
 if Value <> FWordWrap then begin
   FWordWrap := Value;
   RecreateWnd;
 end; { if }
 
end;  { SetWordWrap }
 
procedure TColorEdit.WMGetDlgCode(var Message :TWMGetDlgCode);
begin
 
 inherited;
 
 if not FWantReturns then
   Message.Result := (Message.Result and not DLGC_WANTALLKEYS);
   
end; { WMGetDlgCode }
 
procedure TColorEdit.CreateParams(var Params: TCreateParams);
const
  Alignments: array[TAlignment] of Dword = (ES_LEFT, ES_RIGHT, ES_CENTER);
  WordWraps: array[Boolean] of DWORD = (0, ES_AUTOHSCROLL);
 
begin
 
 inherited CreateParams(Params);
 
 if FWordWrap then
   Params.Style := Params.Style and not WordWraps[FWordWrap] or ES_MULTILINE or
                   Alignments[FAlignment]
 else
   Params.Style := Params.Style or Alignments[FAlignment]
 
end; { CreateParams }
 
function TColorEdit.IsSeparator(cStr :Char) :Boolean;
begin
 Result := (FSeparators.IndexOf(cStr) <> -1);
end; { IsSeparator }
 
function TColorEdit.NextWord(var cStr :String) :String;
begin
 
 Result := '';
 
 if cStr = '' then Exit;
 
 if IsSeparator(cStr[1]) then begin
   Result := Result+cStr[1];
   Delete(cStr, 1, 1);
 end else
   while (cStr <> '') and (not IsSeparator(cStr[1])) do begin
     Result := Result+cStr[1];
     Delete(cStr, 1, 1);
   end; { while }
 
end; { NextWord }
 
function TColorEdit.IsNumber(cStr :String) :Boolean;
var
  i: Integer;
 
begin
 
 Result := False;
 
 for i:= 1 to Length(cStr) do
   case cStr[i] of
     '0'..'9':;
   else
     Exit;
   end; { case }
 
 Result := True;
 
end; { IsNumber }
 
function TColorEdit.VisibleLines() :Integer;
begin
 Result := (Height div (Abs(Font.Height)+2));
end; { VisibleLines }
 
procedure TColorEdit.GotoXY(nCol, nLine :Integer);
begin
 
 Dec(nLine);
 SelStart := 0;
 SelLength := 0;
 SelStart := nCol+Perform(EM_LINEINDEX, nLine, 0);
 SelLength :=0;
 
end; { GotoXY }
 
function TColorEdit.GetTextStart(nRow :Integer) :TSize;
var
  ChrInd :Integer;
  Res    :LResult;
  Caret  : TPoint;
  TxtRect:TRect;
begin
 
 Result.cx := 0;
 Result.cy := 0;
 
 if Text = '' then Exit;
 
 ChrInd := SendMessage(Handle, EM_LINEINDEX, nRow, 0);
 Res    := SendMessage(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-FStartCaretPos.cx;
   Result.cy := HiWord(Res);
 end; { if }
 if NOT WordWrap then begin
    Windows.GetCaretPos(Caret);
    SendMessage(Handle,EM_GETRECT,0,LPARAM(@TxtRect));
    Result.cy:= TxtRect.Top;
   end;
end; { GetTextStart }
 
function TColorEdit.TopLine() :Integer;
begin
 Result := SendMessage(Handle, EM_GETFIRSTVISIBLELINE, 0, 0);
end; { TopLine }
 
function TColorEdit.Line() :Integer;
begin
 Result := SendMessage(Handle, EM_LINEFROMCHAR, SelStart, 0);
end; { Line }
 
function TColorEdit.Col() :Integer;
begin
 Result := SelStart - SendMessage(Handle, EM_LINEINDEX, SendMessage(Handle, EM_LINEFROMCHAR, SelStart, 0), 0);
end; { Col }
 
procedure TColorEdit.SetRedraw(Handle :THandle; Flag :Boolean);
begin
 SendMessage(Handle, WM_SETREDRAW, Ord(Flag), 0);
end; { SetRedraw }
 
procedure TColorEdit.WMVScroll(var Message :TWMVScroll);
begin                  
 inherited;
 RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
end; { WMVScroll }
 
procedure TColorEdit.WMKillFocus(var Message :TWMKillFocus);
 
var
  Locked :Boolean;
 
begin
 
 Locked := False;
 
 try
   Locked := LockWindowUpdate(GetDesktopWindow());
   FFocusLost:=True;
   inherited;
   RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
 finally
   if Locked then LockWindowUpdate(0);
 end; { try }
end; { WMKillFocus }
 
procedure TColorEdit.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; { try }
 
end; { WMSetFocus }
 
procedure TColorEdit.WMHScroll(var Message :TWMHScroll);
begin
 inherited;
 RedrawWindow(Handle, nil, 0,  RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
end; { WMHScroll }
 
procedure TColorEdit.WMSize(var Message :TWMSize);
begin
 inherited;
 RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
end; { WMSize }
 
procedure TColorEdit.WMEraseBKGND(var Message :TWMERASEBKGND);
begin
 // не удалять данную пустую процедуру, иначе будут глюки с изображением
end; { WMEraseBKGND }
 
procedure TColorEdit.WMMove(var Message :TWMMove);
begin
 Invalidate;
 inherited;
end; { WMMove }
 
procedure TColorEdit.CharToCaret(nCharPos :Integer; var nRow, nColumn :Integer);
begin
 nRow := SendMessage(Handle, EM_LINEFROMCHAR, nCharPos, 0)+1;
 nColumn := nCharPos - SendMessage(Handle, EM_LINEINDEX, SendMessage(Handle, EM_LINEFROMCHAR, nCharPos, 0), 0);
end; { CharToCaret }
 
procedure TColorEdit.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; { try }
 
end; { WMLButtonUp }
 
procedure TColorEdit.WMLButtonDown(var Message :TWMLButtonDown);
var
  Locked :Boolean;
 
begin
 
 Locked := False;
 
 if FFocusLost 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; { try }
 
end; { WMLButtonDown }
 
procedure TColorEdit.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; { try }
 
end; { WMLButtonDblClk }
 
procedure TColorEdit.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 FFocusLost then
       Locked := LockWindowUpdate(Handle)
     else
       FFocusLost := False;
 
     inherited;
 
   finally
     if (Locked) and (not FFocusLost) then LockWindowUpdate(0);
   end; { try }
 
  end; { if }
 
end; { WMMouseMove }
 
procedure TColorEdit.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; { try }
 
end; { WMMousewheel }
 
procedure TColorEdit.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; { try }
 
end; { WMCHAR }
 
procedure TColorEdit.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; { try }
 
end; { WMKeyDown }
 
procedure TColorEdit.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; { try }
 
end; { WMKeyUp }
 
procedure TColorEdit.PaintLine(oCanvas :TCanvas; cLineText :String; nCurLine :Integer; rTxtRect :TRect);
const
  HilightFont = clHighlightText;
  HilightBack = clHighlight;
 
type
  TxtAttr = record
    FontColor, BckColor :TColor;
    Underline :Boolean;
  end; { TxtAttr }
 
var
  i, j, px :Integer;
  nLineBeg, nColBeg, nLineEnd, nColEnd :Integer;
  LastFont, LastBck :TColor;
  LastUnderline :Boolean;
  rSize         :TSize;
  t, cCurWord   :String;
  aCharsColor   :array of TxtAttr;
  evFontColor, evBckColor :TColor;
  evUnderline   :Boolean;
 
begin
 
 try
 
   CharToCaret(SelStart, nLineBeg, nColBeg);
   CharToCaret(SelStart+SelLength, nLineEnd, nColEnd);
 
   with oCanvas do begin
 
     px := rTxtRect.Left;
     t  := cLineText+' ';
     SetLength(aCharsColor, Length(cLineText)+1);
 
     for i := 0 to High(aCharsColor) do begin  // Инициализируем массив цветов символов
       aCharsColor[i].FontColor := Self.Font.Color;
       aCharsColor[i].BckColor  := Self.Color;
       aCharsColor[i].Underline := False;
     end; { for }
 
     i := 0;
 
     repeat  // Проходим по всей строке и задаем для каждого символа его цвет и цвет его фона
 
       cCurWord := NextWord(t);
 
       if cCurWord <> '' then begin
 
         if cCurWord = ' ' then begin
 
           evFontColor := Self.Font.Color;
           evBckColor  := Self.Color;
           evUnderline := False;
 
           if Assigned(FOnCheckWord) then
             FOnCheckWord(Self, cCurWord, wtSpace, evFontColor, evBckColor, evUnderline);
 
           aCharsColor[i].FontColor := evFontColor;
           aCharsColor[i].BckColor  := evBckColor;
           aCharsColor[i].Underline := evUnderline;
           Inc(i);
 
         end else
         if IsSeparator(cCurWord[1]) then begin
 
           evFontColor := Self.Font.Color;
           evBckColor  := Self.Color;
           evUnderline := False;
 
           if Assigned(FOnCheckWord) then
             FOnCheckWord(Self, cCurWord, wtSeparator, evFontColor, evBckColor, evUnderline);
 
           aCharsColor[i].FontColor := evFontColor;
           aCharsColor[i].BckColor  := evBckColor;
           aCharsColor[i].Underline := evUnderline;
           Inc(i);
 
         end else
         if IsNumber(cCurWord) then begin
 
           evFontColor := Self.Font.Color;
           evBckColor  := Self.Color;
           evUnderline := False;
 
           if Assigned(FOnCheckWord) then
             FOnCheckWord(Self, cCurWord, wtNumber, evFontColor, evBckColor, evUnderline);
 
           for j := 1 to Length(cCurWord) do begin
             aCharsColor[i+j-1].FontColor := evFontColor;
             aCharsColor[i+j-1].BckColor  := evBckColor;
             aCharsColor[i+j-1].Underline := evUnderline;
           end; { for }
 
           Inc(i, Length(cCurWord));
 
         end else begin      // Задаем цвет остального текста
 
           evFontColor := Self.Font.Color;
           evBckColor  := Self.Color;
           evUnderline := False;
 
           if Assigned(FOnCheckWord) then
             FOnCheckWord(Self, cCurWord, wtText, evFontColor, evBckColor, evUnderline);
 
           for j:=1 to Length(cCurWord) do begin
             aCharsColor[i+j-1].FontColor := evFontColor;
             aCharsColor[i+j-1].BckColor  := evBckColor;
             aCharsColor[i+j-1].Underline := evUnderline;
           end; { for }
 
           Inc(i, Length(cCurWord));
 
         end; { if }
 
       end; { if }
 
     until cCurWord = '';
 
     if (Focused) or (FKeepSelOnLostFocus and not Focused) then begin    // это если надо чтобы при потере фокуса исчезало выделение
 
       if (nCurLine = nLineBeg) and (nColBeg <> nColEnd) and (nLineBeg = nLineEnd) then
         for i := nColBeg+1 to nColEnd do begin
           aCharsColor[i-1].FontColor := HilightFont;
           aCharsColor[i-1].BckColor := HilightBack;
         end; { for }
 
       if (nCurLine > nLineBeg) and (nCurLine < nLineEnd) then
         for i := 1 to Length(cLineText) do begin
           aCharsColor[i-1].FontColor := HilightFont;
           aCharsColor[i-1].BckColor := HilightBack;
         end; { for }
 
       if (nCurLine = nLineBeg) and (nLineBeg < nLineEnd) then
         for i := nColBeg+1 to Length(cLineText) do begin
           aCharsColor[i-1].FontColor := HilightFont;
           aCharsColor[i-1].BckColor := HilightBack;
         end; { for }
 
       if (nCurLine = nLineEnd) and (nLineBeg < nLineEnd) then
         for i := 1 to nColEnd do begin
           aCharsColor[i-1].FontColor := HilightFont;
           aCharsColor[i-1].BckColor := HilightBack;
         end; { for }
 
     end; { if }
 
     cCurWord := cLineText[1];
     LastFont := aCharsColor[0].FontColor;
     LastBck  := aCharsColor[0].BckColor;
     LastUnderline := aCharsColor[0].Underline;
 
     if Length(cLineText) = 1 then begin
 
       rSize := TextExtent(cCurWord);
       SetBkMode(Handle, TRANSPARENT);
 
       if LastBck <> Self.Color then begin
         Brush.Color := LastBck;
         FillRect(Rect(px, rTxtRect.Top, px+rSize.cx, rTxtRect.Top+rSize.cy));
       end; { if }
 
       Font := Self.Font;
       Font.Color := LastFont;
       TextOut(px, rTxtRect.Top, cCurWord);
 
     end; { if }
 
     for i := 2 to Length(cLineText) do begin
 
       t := cLineText[i];
 
       if (LastFont <> aCharsColor[i-1].FontColor) or
          (LastBck <> aCharsColor[i-1].BckColor) or
          (LastUnderline <> aCharsColor[i-1].Underline) then begin
 
         rSize := TextExtent(cCurWord);
         SetBkMode(Handle, TRANSPARENT);
 
         if LastBck <> Self.Color then begin
           Brush.Color := LastBck;
           FillRect(Rect(px, rTxtRect.Top, px+rSize.cx, rTxtRect.Top+rSize.cy))
         end; { if }
 
         Font := Self.Font;
         Font.Color := LastFont;
         TextOut(px, rTxtRect.Top, cCurWord);
 
         if aCharsColor[i-2].Underline then
           DrawUnderline(oCanvas, px, rTxtRect.Top+rSize.cy, px+rSize.cx);
 
         Inc(px, rSize.cx);
 
         cCurWord := '';
         LastFont := aCharsColor[i-1].FontColor;
         LastBck  := aCharsColor[i-1].BckColor;
         LastUnderline := aCharsColor[i-1].Underline;
 
       end; { if }
 
       cCurWord := cCurWord+cLineText[i];
 
       if px > rTxtRect.Right then Break;
 
       if i = Length(cLineText) then begin
 
         rSize := TextExtent(cCurWord);
         SetBkMode(Handle, TRANSPARENT);
 
         if LastBck <> Self.Color then begin
           Brush.Color := LastBck;
           FillRect(Rect(px, rTxtRect.Top, px+rSize.cx, rTxtRect.Top+rSize.cy))
 
         end; { if }
 
         Font := Self.Font;
         Font.Color := LastFont;
         TextOut(px, rTxtRect.Top, cCurWord);
 
         if aCharsColor[i-1].Underline then
           DrawUnderline(oCanvas, px, rTxtRect.Top+rSize.cy, px+rSize.cx);
 
       end; { if }
 
     end; { for }
 
   end; { with }
 
 finally
   SetLength(aCharsColor, 0);
 end; { try }
 
end; { PaintLine }
 
procedure TColorEdit.WMPaint(var Message :TWMPaint);
var
  PS         :TPaintStruct;
  psRect     :TRect;
  DC         :HDC;
  hbmNew     :HBITMAP;
  hbmOld     :HBITMAP;
  oCanvas    :TCanvas;
  i          :Integer;
  rSize      :TSize;
  nMax       :Integer;
  nLineFirst :Integer;
  nLineLast  :Integer;
  cLine      :String;
 
begin
 if (FStartCaretPos.cx = 0) and (Text <> '') and (Alignment = taLeftJustify) then
   FStartCaretPos := 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);
 
 oCanvas := TCanvas.Create;
 try
 
   oCanvas.Handle := DC;
   oCanvas.Font := Self.Font;
 
   with oCanvas do begin
 
     if WordWrap then begin
       nMax := TopLine()+VisibleLines();
       if nMax > SendMessage(Handle, EM_GETLINECOUNT,0,0) then nMax := SendMessage(Handle, EM_GETLINECOUNT,0,0);
      end
     else
       nMax := 0;
 
     Brush.Color := Self.Color;
     FillRect(Self.ClientRect);
 
     rSize := TextExtent(' ');
 
     if GetForegroundWindow() = Self.Parent.Handle then begin
       nLineFirst := TopLine() + (PS.rcPaint.Top div rSize.cy);
       nLineLast  := TopLine() + (PS.rcPaint.Bottom div rSize.cy);
     end else begin
       nLineFirst := TopLine();
       nLineLast  := nMax;
     end; { if }
 
     for i := nLineFirst to nLineLast do begin
 
       FLineCaretPos := GetTextStart(i);
       cLine := TextFromLine(i); //Lines[i];
       if cLine = '' then cLine :=' ';
       rSize := TextExtent(cLine);
 
       if FLineCaretPos.cy+rSize.cy <= psRect.Bottom then
         PaintLine(oCanvas, cLine, i+1, Rect(FLineCaretPos.cx, FLineCaretPos.cy, Self.ClientRect.Right, FLineCaretPos.cy+rSize.cy));
 
     end; { for }
 
   end; { with }
 
 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);
   oCanvas.Free;
 end; { try }
 
end; { WMPaint }
 
procedure TColorEdit.WMPrintClient(var Message :TWMPaint);
var
  PS         :TPaintStruct;
  psRect     :TRect;
  DC         :HDC;
  hbmNew     :HBITMAP;
  hbmOld     :HBITMAP;
  oCanvas    :TCanvas;
  i          :Integer;
  rSize      :TSize;
  nMax       :Integer;
  nLineFirst :Integer;
  nLineLast  :Integer;
  cLine      :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);
 
 oCanvas := TCanvas.Create;
 try
 
   oCanvas.Handle := DC;
   oCanvas.Font   := Self.Font;
 
   with oCanvas do begin
 
     if WordWrap then begin
       nMax := TopLine()+VisibleLines();
       if nMax > SendMessage(Handle, EM_GETLINECOUNT,0,0) then nMax := SendMessage(Handle, EM_GETLINECOUNT,0,0);
      end
     else
       nMax := 0;
 
     Brush.Color := Self.Color;
     FillRect(Self.ClientRect);
     rSize := TextExtent(' ');
 
     if GetForegroundWindow=Self.Parent.Handle then begin
       nLineFirst := TopLine() + (PS.rcPaint.Top div rSize.cy);
       nLineLast  := TopLine() + (PS.rcPaint.Bottom div rSize.cy);
     end else begin
       nLineFirst := TopLine();
       nLineLast  := nMax;
     end; { if }
 
     for i := nLineFirst to nLineLast do begin
 
       FLineCaretPos := GetTextStart(i);
       cLine := TextFromLine(i); //Lines[i];
       if cLine = '' then cLine := ' ';
       rSize := TextExtent(cLine);
 
       if FLineCaretPos.cy+rSize.cy <= psRect.Bottom then
         PaintLine(oCanvas, cLine, i+1, Rect(FLineCaretPos.cx, FLineCaretPos.cy,Self.ClientRect.Right, FLineCaretPos.cy+rSize.cy));
 
     end; { for }
 
   end; { with }
 
 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);
   oCanvas.Free;
 end; { try }
 
end; { WMPrintClient }
 
procedure TColorEdit.DrawUnderline(oCanvas :TCanvas; nFromX, nFromY, nToX: Integer);
var
  X  :Integer;
 
begin
 
 with oCanvas do
   for X := nFromX to nToX do
     oCanvas.Pixels[X, nFromY+Round(Sin(X))] := clRed;
 
end; { DrawUnderline }
 
procedure Register;
begin
 
 RegisterComponents('Samples', [TColorEdit]);
 
end; { Register }
 
end.
 



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

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 04:12 29-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