Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.11.05;
Скачать: CL | DM;

Вниз

Как правильно написать свой компонент?   Найти похожие ветки 

 
Alex_C ©   (2006-10-18 11:17) [0]

Суть проблемы: как правильно написать свой компонент, чтобы он наследовал все св-ва своего предшественника и добавлял новые. Вот например - хочу сделать свой компонент TMemo, чтобы добраться до метода Paint.
Делаю так:

 TMyMemo = class(TMemo)
 private
   { Private declarations }
 protected
   { Protected declarations }
   procedure WMPaint(var message: TWMPaint); message WM_PAINT;
 public
   { Public declarations }
 published
   { Published declarations }
 end;

Сам WMPaint для примера - просто вывожу строки, пока даже с ними ничего не делаю, в конце вызываю inherited. Вроде все работает, но вот проблема - в отличии он TMemo мой компонент перестает понимать допустим
SendMessage(Memo1.Handle, EM_SCROLL, SB_LINEDOWN, 0); - при этом дочерний TMemo перемещается на последнюю строчку, а мой нет. Выделение мышкой тоже не так работает. Как этого избежать?


 
Сергей М. ©   (2006-10-18 11:20) [1]


> чтобы он наследовал все св-ва своего предшественника и добавлял
> новые


А где в твоем классе вновь добавленные свойства ? В упор не вижу их ...


 
Alex_C ©   (2006-10-18 13:38) [2]

В том-то и дело, что ничего не добавлено, а как я уже выше писал, не работает, как предшественник. Вопрос: почему? Ведь я только метод WMPaint переопределяю.


 
Сергей М. ©   (2006-10-18 13:50) [3]


> В том-то и дело, что ничего не добавлено


Значит и вопрос твой в корне неверно сформулирован.


> почему? Ведь я только метод WMPaint переопределяю


Значит логика обработки WM_PAINT не верна.


 
Alex_C ©   (2006-10-18 14:00) [4]

Ок, привожу как у меня реализован WMPaint (выделяет определенные слова красным цветом):

procedure THxMemo.WMPaint(var Message: TWMPaint);
var
   i, j, dy, dx: Integer;
   PS: TPaintStruct;
   DC: HDC;
   aCanvas: TCanvas;
   str, StrWord: String;
   IsKeyWord: Boolean;
   BitMap: TBitMap;
begin
   DC:= Message.DC;
   if DC= 0 then
       DC:= BeginPaint(Handle, PS);
   aCanvas:=TCanvas.Create;
   BitMap := TBitMap.Create;
   try
       aCanvas.Handle:= DC;
       aCanvas.Font:= Font;

       BitMap.Height := Height;
       BitMap.Width := Width;
       BitMap.Canvas.FillRect(ClientRect);

       with BitMap.Canvas do
       begin
           dy := 1;
           for i:= 0 to Lines.Count-1 do //Перебираем строки Memo
           begin
               str:= Lines[i];

               StrWord := "";
               dx := 1;
               j := 1;
               While j <= Length(str) do
               begin
                   // Если не пробел и не окончание строки - добавляем в слово
                   While (str[j] <> " ") and (j <= Length(str)) do
                   begin
                       StrWord := StrWord + str[j];
                       Inc(j)
                   end;

                   // Проверка на ключевое слово
                   FOnKeyWord(Self, StrWord, IsKeyWord);
                   if IsKeyWord then
                   begin
                       Font.Color:= clRed
                   else
                       Font.Color:= clBlack;
                   // Выводим слово
                   TextOut(dx, dy, StrWord);
                   // Перемещаемся на следующую позицию
                   dx := dx + TextWidth( StrWord );
                   // Восстанавливаем основной цвет
                   Font.Color:= clBlack;
                   StrWord := "";

                   // Если символ - пробел, выводим его
                   if (str[j] = " ") and (j <= Length(str)) then
                   begin
                       TextOut(dx, dy, " ");
                       dx := dx + TextWidth( " " );
                       Inc(j);
                   end;
               end;
               // Перемещаемся на следующую строку
               dy:= dy + TextHeight("X");
           end;
       end;
       BitBlt( aCanvas.Handle, 0, 0, BitMap.Width, BitMap.Height, BitMap.Canvas.Handle, 0, 0, SRCCOPY );
   finally
       if Message.DC = 0 then EndPaint(Handle, PS);
       aCanvas.Free;
       BitMap.Free;
   end;
   inherited;
end;

Т.е. здесь я всего лишь вывожу текст, выделяя нужные мне слова. Все выделяется, а вот допустим
SendMessage(Memo1.Handle, EM_SCROLL, SB_LINEDOWN, 0);
уже не работает. Почему?


 
Сергей М. ©   (2006-10-18 14:08) [5]


> Т.е. здесь я всего лишь вывожу текст


.. а inherited-метод, будучи вызванный тобой после твоих "хитрых манипуляций" чихает на это (ибо ничего не знает об этом) и выводит текст "по-старинке".

?


 
Alex_C ©   (2006-10-18 14:33) [6]

Нет. Не выводит по старинке. Все работает. Вот если его в начале поставить - то да, не выделяется, а в конце - все работает. Да inherited вообще можно убрать, он тут не влияет.
Да не об этом речь - еще раз спрашиваю: почему
SendMessage(Memo1.Handle, EM_SCROLL, SB_LINEDOWN, 0);
не работает? Ведь в самом TMemo он прекрасно работает?


 
Loginov Dmitry ©   (2006-10-18 15:36) [7]

Alex_C ©   (18.10.06 11:17)
protected
  { Protected declarations }
  procedure WMPaint(var message: TWMPaint); message WM_PAINT;


Интересно, кто такому учит - обработчики сообщений пихать в секцию protected? Далеко не первый раз с подобным явлением сталкиваюсь.


 
Игорь Шевченко ©   (2006-10-18 15:43) [8]

Loginov Dmitry ©   (18.10.06 15:36) [7]

А что, есть принципиальная разница ?


 
Сергей М. ©   (2006-10-18 15:44) [9]


> inherited вообще можно убрать, он тут не влияет


ты с дуба упал ?)


 
Loginov Dmitry ©   (2006-10-18 17:36) [10]

Игорь Шевченко ©   (18.10.06 15:43) [8]
А что, есть принципиальная разница ?


Есть. Причем принципиальная.

Секция protected задумана для того, чтобы методы, объявленные в ней, могли использоваться только в этом же классе или в его потомках (ну или в пределах одного модуля).

procedure WMPaint(var message: TWMPaint); message WM_PAINT;

- это процедура-обработчик сообщения, которая никогда (по крайней мере мне это еще не приходилось видеть) не вызывается из потомков (это, имхо, просто бессмысленно).

Потом. Покажите хоть одно место в VCL, где подобные процедуры объявляются в секции protected.

А если для вас принципиальной разницы нет, то почему вы не объявляете подобные процедуры в секции public (угадал? :))


 
Игорь Шевченко ©   (2006-10-18 17:43) [11]

Loginov Dmitry ©   (18.10.06 17:36) [10]


> Есть. Причем принципиальная.


И в чем же принцип, если не секрет ? Мне именно принцип интересен, если не затруднит.


> Секция protected задумана для того, чтобы методы, объявленные
> в ней, могли использоваться только в этом же классе или
> в его потомках (ну или в пределах одного модуля).


И чего ?


> - это процедура-обработчик сообщения, которая никогда (по
> крайней мере мне это еще не приходилось видеть) не вызывается
> из потомков (это, имхо, просто бессмысленно).


Процедура-обработчик сообщения не вызывается явно ВООБЩЕ НИОТКУДА. Процедуре-обработчику сообщений ВООБЩЕ ПОФИГ в какой секции быть объявленной, она видна извне отовсюду.


 
Loginov Dmitry ©   (2006-10-18 18:18) [12]

Я о том, что некоторые авторы делают акцент на том, что процедуры-обработчики сообщений "правильнее" располагать именно в секции protected.

Известный мне пример - Краснов. (OpenGL в Delphi).


 
Игорь Шевченко ©   (2006-10-18 18:20) [13]

Loginov Dmitry ©   (18.10.06 18:18) [12]

Чем аргументируют ? Краснова посмотреть не могу, но цитата была бы желательной.


 
Ketmar ©   (2006-10-18 18:55) [14]

-- скажи, Ходжа Насреддин, где мусульманину правильней идти во время похорон? впереди гроба, или же позади?
-- главное -- не в самом гробу.


 
Loginov Dmitry ©   (2006-10-18 19:29) [15]

Игорь Шевченко ©   (18.10.06 18:20) [13]

Чем аргументируют ? Краснова посмотреть не могу, но цитата была бы желательной.


Пожалуйста:

... Описание класса формы я дополнил разделом protected, в который поместил forward-описание соответствующей процедуры:

procedure MesDblClick (var MyMessage : TWMMouse) ; message wm_LButtonDblClk;

Замечание
Как правило, перехватчики сообщений для повышения надежности работы приложения описываются в блоке protected.

Имя процедуры я задал таким, чтобы не появлялось предупреждение компилятора о том, что я перекрываю соответствующее событие формы. Служебное слово message указывает на то, что процедура будет перехватывать сооб-щение, мнемонику которого указывают за этим словом. Тип аргумента процедуры-перехватчика индивидуален для каждого сообщения. Имя аргумента произвольно, но, конечно, нельзя брать в качестве имени служебное СЛОВО message.


 
Игорь Шевченко ©   (2006-10-19 10:43) [16]


> Как правило, перехватчики сообщений для повышения надежности
> работы приложения описываются в блоке protected.


Пусть лучше занимается своим OpenGL и не лезет в дебри неизведанного. Потому как на надежность место объявления обработчиков сообщений влияет столько же, сколько указание в верхнем или в нижнем регистре писать ключевые слова языка.


 
Ketmar ©   (2006-10-19 11:06) [17]

>[15] Loginov Dmitry(c) 18-Oct-2006, 19:29
>wm_LButtonDblClk;
расстрелять без права переписки.

>Как правило, перехватчики сообщений для повышения
>надежности работы приложения описываются в блоке protected.
посмертно вывесить для всеобщего обозрения с табличкой "врать некрасиво".


 
Alex_C ©   (2006-10-19 11:17) [18]

Ребята, вы немного увлеклись дискуссией :) , а на мой вопрос то так ответа и нет :(


 
Плохиш ©   (2006-10-19 11:17) [19]


> Замечание
> Как правило, перехватчики сообщений для повышения надежности
> работы приложения описываются в блоке protected.

Озвучте источник, давно такого бреда не читал :-)


 
Loginov Dmitry ©   (2006-10-20 09:13) [20]

> Озвучте источник, давно такого бреда не читал


Источник был озвучен выше.



Страницы: 1 вся ветка

Текущий архив: 2006.11.05;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.057 c
15-1160931021
atruhin
2006-10-15 20:50
2006.11.05
Компонент меняющий свойство Font у всех компонентов на форме


2-1160984972
gvozdkoff
2006-10-16 11:49
2006.11.05
Paradox на другом компе


15-1160387840
Iamdanil
2006-10-09 13:57
2006.11.05
Задача по математике - помогите!


15-1160844416
Kolan
2006-10-14 20:46
2006.11.05
Использование объектов для простых типов. Стоит ли?


2-1161079352
Dmitry_177
2006-10-17 14:02
2006.11.05
Присвоение одному массиву другого