Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.03.2009, 03:46   #1
besserebrenik
 
Регистрация: 23.03.2009
Сообщений: 6
По умолчанию Как реализовать RichMemo c графическими указателями в начале строки?

Попытался максимально в названии темы объяснить проблему.. Не уверен, что получилось

Мне нужно по учебе сделать 1 в 1 форму как Editor Properties в Delfi 7..
В привиденном ниже рисунке розовым обведено то место над которым я замялся. Не знаю как это сделать
besserebrenik вне форума Ответить с цитированием
Старый 23.03.2009, 10:15   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Ну вообще-то тут два контрола - Сам "Мемо" ипанелька слева, на канву которой отрисовывается в нужных координатах рисунок.
Вот и ту так сделай.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 23.03.2009, 11:11   #3
Kotofff
Участник клуба
 
Аватар для Kotofff
 
Регистрация: 11.01.2009
Сообщений: 1,917
По умолчанию

Цитата:
Вот и ту так сделай.
ИМХО
И так будет немного проще чем морочиться с отступом в самом RichEdit и потом отображением картинок там же ...
"Заряженному танку в дуло не смотрят" @Dekmer in WoT
Kotofff вне форума Ответить с цитированием
Старый 23.03.2009, 13:04   #4
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

в принципе, есть удобные компоненты от SynEdit
поддерживает кучу форматов, регулярные выражения
soleil@mmc вне форума Ответить с цитированием
Старый 23.03.2009, 19:41   #5
CahekG
Пользователь
 
Регистрация: 25.02.2009
Сообщений: 28
По умолчанию

Можно свой класс на основе TRichEdit сделать.
В принципе под желаемый еще надо его доделать, но если не лень, то можно всё (с картинки) легко организовать.
Да и глюки с текстом болшим чем окно имеются. (при определении номера строки, она может быть отображена частично, а я использовал полную выстоту строки. время нет доработать)
Для начала я накидал код:
Код:
unit MyRichEdit;

interface

uses
  SysUtils, Classes, Controls, StdCtrls, ComCtrls,Messages,Windows,Graphics;

type
  TMyRichEdit = class(TRichEdit)
  private
    { Private declarations }
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
    constructor Create(AOwner: TComponent);override;
  protected
    { Protected declarations }
    MarkLn:string;
  public
    { Public declarations }
  published
    { Published declarations }
    procedure MarkLine(Line:integer);
    procedure UnMarkLine(Line:integer);
    procedure UnMarkAll;

  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TMyRichEdit]);
end;

constructor TMyRichEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  MarkLn:='';// тут храним маркеры строк которые надо помечать (символом #)
           end;


// процедура вкл. пометки линии
    procedure TMyRichEdit.MarkLine(Line:integer);
    begin
     if Line<0 then exit;
     while Length(markLn)<=(Line+1) do markLn:=markLn+' ';
     markLn[Line+1]:='#';
     Invalidate;
    end;

// процедура откл. пометки линии
    procedure TMyRichEdit.UnMarkLine(Line:integer);
    begin
     if (Line<0) or (Length(markLn)<(Line+1)) then exit;
     markLn[Line+1]:=' ';
     Invalidate;
    end;


    procedure TMyRichEdit.UnMarkAll;
    begin
      markLn:='';
      Invalidate;
    end;

//я на галазок (без констант) взял 24 пиксела 

procedure TMyRichEdit.WMSize(var Message: TWMSize);
var
  R: TRect;
begin
    inherited;
      GetWindowRect(Handle, R);
      OffsetRect(R, -R.Left+1, -R.Top+1);
      r.Left:=r.Left+24;
      Perform(Messages.em_SetRect, 0, Integer(@r));
end;

// дорисовываем что нам надо
procedure TMyRichEdit.WMPaint(var Message: TWMPaint);
var
  DC: HDC;
  R1,R: TRect;
  Brush:Hbrush;
  P:Tpoint;
  i,LineIndex,charIndex:integer;
  t:Tbitmap;
  TM : TTextMetric;
// получаем номер строки (для strings[]) по координатам p
function getLine(p:TPoint):integer;
begin
 getLine:=-1;
 charIndex := Perform(Messages.EM_CHARFROMPOS, 0, Integer(@p));
 if charIndex > 0 then getLine  := Perform(em_LineFromChar, charIndex,0);
end;

begin

    { Get window DC that is clipped to the non-client area }

    inherited;
    DC := GetDCEx(Handle, 0, DCX_WINDOW or DCX_CACHE or DCX_CLIPSIBLINGS);
    try
      GetWindowRect(Handle, R);
      OffsetRect(R, -R.Left+1, -R.Top+1);
     // получаем Rect области с тестом
      with R do
      begin

        // визуально отделяем наш столбец
        MoveToEx(DC,r.Left+22 , r.Top+1,@P);
        LineTo(DC,r.Left+22 , r.Top+1+Height-2);
      // пребираем линии попиксельно 
      i:=r.Top+1;
      WHILE  i<=r.Top+1+Height-2 do
         begin
          p.X:=r.Left+30;p.y:=i;
           LineIndex:=getLine(p);
            if LineIndex>=0 then
             begin
              if Lines.Count>LineIndex then
                if length(MarkLn)>LineIndex+1 then
                 begin
// мы нашли какой строке принадлежит эта координата,
// проверяем на наличие маркера
                  if MarkLn[LineIndex+1]='#' then
                   begin
// перебираем координуту y до следующей строки
                    WHILE  (i<=r.Top+1+Height-2) and (LineIndex=getLine(Point(p.X,i))) do inc(i);
                    r1:=Rect(r.Left+4,p.y,r.Left+18,i);
                    Brush := CreateSolidBrush(ColorToRGB(clRed));
// рисуем что-то похожее на красный маркер
                    FillRect (dc,rect(r1.Left+2,r1.Top,r1.Right-2,r1.Bottom), Brush);
                    FillRect (dc,rect(r1.Left+1,r1.Top+1,r1.Right-1,r1.Bottom-1),Brush);
                    FillRect (dc,rect(r1.Left,r1.Top+2,r1.Right,r1.Bottom-2),Brush);

                    Perform(Messages.em_GetRect, 0, Integer(@r1));
                    GetTextMetrics(DC, TM);

                    t := TBitMap.Create;
                    t.Width :=r1.Right-r1.Left;
                    t.Height:=tm.tmHeight;// это высота строки текста

// инверсией рисуем выделение всей строки
                    FillRect (t.Canvas.Handle,Rect(0,0,r1.Right-r1.Left,tm.tmHeight),Brush);
                    BitBlt(dc,r1.Left,p.Y,r1.Right-r1.Left,tm.tmHeight,t.Canvas.Handle,0,0,PATINVERT);
                      t.Free;
                   end;
                 end;

           end;
          inc(i);
         end;
      end;
    finally
      ReleaseDC(Handle, DC);
    end;


end;
end.

Последний раз редактировалось CahekG; 23.03.2009 в 20:04.
CahekG вне форума Ответить с цитированием
Старый 23.11.2009, 18:04   #6
besserebrenik
 
Регистрация: 23.03.2009
Сообщений: 6
По умолчанию

спасибо за ответы)
besserebrenik вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
в начале месяца произойдет перенос форума на новый сервер Xeon 3.2 Alar О форуме и сайтах клуба 23 17.12.2008 11:02
3D фигуры, как реализовать? Nikiforov Помощь студентам 2 22.02.2008 00:24
Как такое реализовать? AnalogXP Общие вопросы Delphi 9 17.02.2008 00:22
Работа с графическими фигурами Fanat1k Помощь студентам 1 03.05.2007 07:59
Как реализовать ASin Romanus Общие вопросы C/C++ 2 16.04.2007 09:46