Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Delphi |
![]() ![]() |
Топик располагается на нескольких страницах: ←Ctrl назад 1 2 3 [4] 5 вперед Ctrl→ все |
ёёёёё Member Откуда: Сообщений: 2017 |
"Запечатывание" виртуального метода, запрещающее перекрытие в наследнике. Да, в 7-ке не работает. |
||||
18 окт 19, 18:19 [21997685] Ответить | Цитировать Сообщить модератору |
ёёёёё Member Откуда: Сообщений: 2017 |
Может быть, тебе protected члены нужны? http://www.delphibasics.ru/Protected.php protected члены класса доступны в наследниках, но из других объектов - недоступны. Ну, кроме тех, которые в том же модуле (юните) находятся. |
||
18 окт 19, 18:24 [21997688] Ответить | Цитировать Сообщить модератору |
alekcvp Member Откуда: Сообщений: 2736 |
WAT? O_o |
||||||
18 окт 19, 18:39 [21997698] Ответить | Цитировать Сообщить модератору |
Андрей Игоревич Member Откуда: Сообщений: 319 |
Я вот всегда туплю в определении "наследник". TClassB = class (TClassA) ClassD: TClassD; End; Вопрос - наследник/потомок это ClassB от ClassA или ClassD потомок от ClassB? Или тут более хитрая терминология. Просто в интернете и то и то видел как называют потомком. В первом случае protected доступны, во втором нет. |
||||
18 окт 19, 18:55 [21997713] Ответить | Цитировать Сообщить модератору |
ёёёёё Member Откуда: Сообщений: 2017 |
Класс TClassA - родитель класса TClassВ. Класс TClassB - наследник класса TClassА. Класс TClassB связан с классом TClassА отношением "наследование". Объекта класса TClassD агрегирован в класс TClassB. |
||||
18 окт 19, 19:01 [21997715] Ответить | Цитировать Сообщить модератору |
Андрей Игоревич Member Откуда: Сообщений: 319 |
Жуть, первый раз вижу такой термин применительно к Delphi. В общем я писал про доступность из агрегированных классов к процедурам ээ...ээ.. агрегатора? И наоборот. Хотя основной мой вопрос был, почему Inherites проскакивало через несколько наследников(тут всё корректно) сразу к Panel, может ли быть это связано с owner, который я не переприсваивал у потомков (обходясь parent). |
||
18 окт 19, 19:12 [21997723] Ответить | Цитировать Сообщить модератору |
ёёёёё Member Откуда: Сообщений: 2017 |
Не было такого, "мамой клянусь". |
||
18 окт 19, 19:23 [21997733] Ответить | Цитировать Сообщить модератору |
white_nigger Member Откуда: Тула Сообщений: 2471 |
В общем случае мне больше нравятся термины: "унаследован от", "предок", "наследник" |
19 окт 19, 22:27 [21998107] Ответить | Цитировать Сообщить модератору |
white_nigger Member Откуда: Тула Сообщений: 2471 |
|
||
19 окт 19, 22:37 [21998109] Ответить | Цитировать Сообщить модератору |
alekcvp Member Откуда: Сообщений: 2736 |
Единственное, что мне приходит в голову - это то, что где-то в этой цепочке у переопределения методов было пропущено слово override (при этом должно быть предупреждение от компилятора), в результате inherites обращался к последнему переопределённому методу, а не к этим. |
||
20 окт 19, 13:18 [21998248] Ответить | Цитировать Сообщить модератору |
Андрей Игоревич Member Откуда: Сообщений: 319 |
В свете перехода мной с Delphi 7 на 10 начинают возникать куча мелких непонятных проблем в уже, казалось бы сделанных вещах. Вкратце. "Главная" панель - перехватываю paint - рисую нужную мне картинку (через буферный BitMap). На "главной" панели размещены другие панели с дополнительной информацией, в них рисую так же. Часть функционала - перетаскивание, редактирование содержания и масштабирование информационных панелей напрямую. С большим трудом в 7ке сделал, чтоб всё работало плавно и удобно. Перешел на 10ку (ибо приложение надо 64битное) и при срабатывании события Paint (которое Override) панель в самом начале кода события(до выполнения чего бы то ни было) закрашивается в базовый (выбранный цвет), из-за чего происходит раздражающее мерцание. На гифке это не так заметно, пропускает кадры - в жизни прям дико мигает. Масштабирую через perform, который, периодически и вызывает то самое событие paint, но через раз, иногда может просто закрасить в серый не вызвав событие (потому пока дополнительно вызываю repaint);
С "главной" панелью (которая тоже мерцала) часть проблем решил через override Repaint с кодом InvalidateRect( Handle, NIL, FALSE ) ; и вызов обновления картинки только через Repaint; Так же главная панель так же окрашивалась в серый - если один из дочерних компонентов менял родителя (у меня при каждой отрисовке сбрасывались родители, а потом назначались в зависимости от того, что рисуется). Решил убрав такое присвоение, но логики всё равно не понял, почему перед Pаint именно в этом случае панель закрашивалась в серый, а без присвоения наследников - не окрашивалась, а нормально перерисовывалась. Главный вопрос: Почему панель закрашивается в серый до Override paint, как это отключить? (И почему на 7ке его не было, и, кстати, если использовать res 7ки, но компилировав в 10 - не мерцает).
Сообщение было отредактировано: 24 янв 20, 13:19 |
|||
24 янв 20, 13:10 [22065952] Ответить | Цитировать Сообщить модератору |
Kazantsev Alexey Member Откуда: Сообщений: 4993 |
Андрей Игоревич, Мерцание панели может быть связано со свойством ParentBackground. Установи его в False. Если не поможет, попробуй обрабатывать сообщение WM_ERASEBKGND, устанавливая результат обработки AMessage.Result := 1; |
24 янв 20, 13:25 [22065968] Ответить | Цитировать Сообщить модератору |
s62 Member Откуда: Жуковский Сообщений: 1269 |
Андрей Игоревич,А вообще я малость замучился рисовать всё через Paint - так как там тотальное перекрёстное вызывание этих событий у всех дочерних и родительских компонентов. Меняешь что-то на "дочерней" панели, она вызывает Paint основной, та вызывает Paint всех дочерних, в том числе и той, которая вызвала обновление, а если там что-то завязано на текущее состояние... Любая неосторожная строчка кода сразу вызывает СтакОверфлоу или зацикленное мигание. ... Так ведь вам предлагали не использовать множество панелей, а рисовать всё на одном канвасе, например PaintBox'а. Я так понимаю, что у вас было уже что-то готовое на панелях, потому вы не стали радикально переделывать. Но ваш вариант содержит в себе просто море ненужного обременения - все эти окна (TPanel это ведь наследник от TWinControl) ну и вообще весь ненужный в вашем случае код элементов управления. Уже писали, в том числе люди с наверное гораздо большим опытом в этой области, чем у меня, я тоже писал - вам можно было сделать процедурные или объектные обертки для рисования элементов картинки и всё рисовать на PaintBox (точнее - рисовать на невидимом TBitmap, а потом копировать его на PaintBox). И никаких панелек. |
24 янв 20, 13:28 [22065976] Ответить | Цитировать Сообщить модератору |
s62 Member Откуда: Жуковский Сообщений: 1269 |
s62, только была бы задача обработки кликов и перетаскивания элементов картинки. Но мне кажется, что она тоже вполне решаемая. |
24 янв 20, 13:33 [22065982] Ответить | Цитировать Сообщить модератору |
Андрей Игоревич Member Откуда: Сообщений: 319 |
Очень интересно. ParentBackground:=false; при перетаскивании ( (perform(WM_SysCommand, $F012, 0) ) теперь ничего не мерцает, прям совсем, а вот при изменении размеров perform(WM_SysCommand, $F002+, 0); , мерцает, но как-то совем иначе, буду разбираться. А вот перехват обработку сообщений я пока до конца не освоил, это через так делать? Application.OnMessage:=AppMessage; procedure TForm.AppMessage(var Msg: TMsg; var Handled: Boolean); begin if Msg.message=WM_ERASEBKGND then ...; end;
Все многоугольники рисуются именно через свои компоненты, даже не PintBox, а через TComponent, где я уже сам свои Paint и прочие вещи писал. Панели используются именно для "Легенды", так как нагромождать всё через основной канвас ну очень сильно загромождает код (у меня там куча всяких событий и действий на всё привязано, один перехват мышки в едином канвасе будет просто огромным). Изначально и легенду тоже рисовал на канвасе, но в итоге это оказалось ну очень неудобно, что решил через панели, тем более их тут не более 10 всё-таки.
Всё это решено в полной мере, вплоть да кликов по тексту, Хинтам и прочим. Просто именно легенду так выводить неудобно. Сообщение было отредактировано: 24 янв 20, 14:15 |
||||||||||||
24 янв 20, 14:13 [22066019] Ответить | Цитировать Сообщить модератору |
Kazantsev Alexey Member Откуда: Сообщений: 4993 |
Нет, это делать так: TMyPanel = class procedure WMEraseBkgnd(Var AMessage : TMessage); Message WM_ERASEBKGND; end; ... procedure TMyPanel.WMEraseBkgnd(Var AMessage : TMessage); begin AMessage.Result := 1; end; |
||||
24 янв 20, 14:27 [22066028] Ответить | Цитировать Сообщить модератору |
s62 Member Откуда: Жуковский Сообщений: 1269 |
Вот события мышки обрабатывать это да, нужно было бы наверное держать данные о всех графических объектах, чтобы по клику находить, над каким из них произошло событие. |
||||
24 янв 20, 14:32 [22066033] Ответить | Цитировать Сообщить модератору |
Андрей Игоревич Member Откуда: Сообщений: 319 |
![]() Придется поразбираться :). |
||||||||
24 янв 20, 14:41 [22066044] Ответить | Цитировать Сообщить модератору |
Kazantsev Alexey Member Откуда: Сообщений: 4993 |
Я не знаю, как у тебя там происходит рисование, но, если в Paint обновляется всё содержимое панели, то никаких артефактов отрисовки быть не должно. Даже перепроверил себя, накидал демку - ничего не мерцает. |
||||
24 янв 20, 14:59 [22066060] Ответить | Цитировать Сообщить модератору |
Андрей Игоревич Member Откуда: Сообщений: 319 |
Тут скорее дело в perform(WM_SysCommand, $F00.., 0), оно вызывает paint не так уж и часто, а пока мышку не отпустишь - вызывать paint иначе не получиться. Ладно, подумаю, поковыряюсь. А как вы масштабируете панель размещенную на панели? Сообщение было отредактировано: 24 янв 20, 15:05 |
||||||||
24 янв 20, 15:04 [22066065] Ответить | Цитировать Сообщить модератору |
Kazantsev Alexey Member Откуда: Сообщений: 4993 |
Можно принудительно вызывать отрисовку из того-же WMEraseBkgnd.
В OnMouseMove пересчитываю размер. |
||||||||
24 янв 20, 15:21 [22066077] Ответить | Цитировать Сообщить модератору |
DimaBr Member Откуда: Сообщений: 11981 |
Всё есть в исходниках procedure TCustomPanel.Paint; const Alignments: array[TAlignment] of Longint = (DT_LEFT, DT_RIGHT, DT_CENTER); VerticalAlignments: array[TVerticalAlignment] of Longint = (DT_TOP, DT_BOTTOM, DT_VCENTER); var Rect: TRect; LColor: TColor; LStyle: TCustomStyleServices; LDetails: TThemedElementDetails; TopColor, BottomColor: TColor; BaseColor, BaseTopColor, BaseBottomColor: TColor; //FontHeight: Integer; Flags: Longint; begin Rect := GetClientRect; BaseColor := Color; BaseTopColor := clBtnHighlight; BaseBottomColor := clBtnShadow; LStyle := StyleServices; if LStyle.Enabled then begin LDetails := LStyle.GetElementDetails(tpPanelBackground); if LStyle.GetElementColor(LDetails, ecFillColor, LColor) and (LColor <> clNone) then BaseColor := LColor; LDetails := LStyle.GetElementDetails(tpPanelBevel); if LStyle.GetElementColor(LDetails, ecEdgeHighLightColor, LColor) and (LColor <> clNone) then BaseTopColor := LColor; if LStyle.GetElementColor(LDetails, ecEdgeShadowColor, LColor) and (LColor <> clNone) then BaseBottomColor := LColor; end; if BevelOuter <> bvNone then begin AdjustColors(BevelOuter); Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth); end; if not (LStyle.Enabled and (csParentBackground in ControlStyle)) then Frame3D(Canvas, Rect, BaseColor, BaseColor, BorderWidth) else InflateRect(Rect, -Integer(BorderWidth), -Integer(BorderWidth)); if BevelInner <> bvNone then begin AdjustColors(BevelInner); Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth); end; with Canvas do begin if not LStyle.Enabled or not ParentBackground then begin Brush.Color := BaseColor; FillRect(Rect); end; |
||||
24 янв 20, 15:43 [22066088] Ответить | Цитировать Сообщить модератору |
Андрей Игоревич Member Откуда: Сообщений: 319 |
Изначально тоже так сделал, но очень мне не понравилось, уже и не помню почему, то ли мышка слетала с панели (если не успевала обновить размер) и OnMouseMove уже не срабатывал, то ли ещё что-то было. Но что с мерцанием больше всего вызывает непонимание, это то, что в 7 - всё идеально, даже намека нет. И если суомпилирвать файл res в 7ке, то и в 10ке всё будет нормально. |
||||||||
24 янв 20, 15:45 [22066091] Ответить | Цитировать Сообщить модератору |
Kazantsev Alexey Member Откуда: Сообщений: 4993 |
У винконтролов есть возможность захватывать мышку, после чего все её события идут в этот контрол.
Не понял. Если взять .res файл от семёрки и подложить его в проект Delphi 10.3? |
||||||||
24 янв 20, 15:56 [22066096] Ответить | Цитировать Сообщить модератору |
Kazantsev Alexey Member Откуда: Сообщений: 4993 |
Так у него же Paint перекрыт. |
||||
24 янв 20, 15:57 [22066097] Ответить | Цитировать Сообщить модератору |
Топик располагается на нескольких страницах: ←Ctrl назад 1 2 3 [4] 5 вперед Ctrl→ все |
Все форумы / Delphi | ![]() |