Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.11.05;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.038 c
3-1157931407
boss_zbk
2006-09-11 03:36
2006.11.05
Как выдать сообщение


2-1161260781
vitaly27
2006-10-19 16:26
2006.11.05
Помогите пожалста больше немогу


15-1160968833
Slider007
2006-10-16 07:20
2006.11.05
С днем рождения ! 15 октября


2-1161086373
RebroFF
2006-10-17 15:59
2006.11.05
Разделение прав и компоненты Delphi


2-1161183115
Mb
2006-10-18 18:51
2006.11.05
Редактирование БД





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский