Текущий архив: 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.51 MB
Время: 0.048 c