powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TCategoryPanelGroup беда с отрисовкой.
24 сообщений из 24, страница 1 из 1
TCategoryPanelGroup беда с отрисовкой.
    #39169486
iStrannik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Никогда раньше не использовал этот компонент TCategoryPanelGroup, тут в одном проекте для экономии экранного места
решил использовать. На дочерних CategoryPanel размещены другие панели, StringGrid-ы и т.д. в некоторых ситуациях
компоненты размещенные на CategoryPanel не прорисовываются совсем или прорисовываются частично.
Может кто сталкивался?
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #39169522
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DoubleBuffered := False?
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #39169650
iStrannik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Это сразу проверил везде DoubleBuffered := true;
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #39169653
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iStrannikЭто сразу проверил везде DoubleBuffered := true;Выставь false на форме, содержащей TCategoryPanelGroup. Помогло?
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #39170429
iStrannik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пробовал тоже не помогает. Я забыл указать что я использую в проекте стиль из стандартного набора, но глюк и без него тоже есть.

Вчера 2 часа бился, создал чистый проект кинул на форму TCategoryPanelGroup, создал 2 штуки CategoryPanel1 и CategoryPanel2.
Затем кинул на вторую CategoryPanel2(которая под CategoryPanel1) Panel, а на нее TCheckBox.
Компилируем, запускаем, пытаемся свернуть и развернуть верхнюю CategoryPanel1, при этом видим что на CheckBox пропадает.

Еще поймал такой глюк CheckBox размещенный непосредственно в CategoryPanel, прорисовывается нормально при сворачивании
верхней CategoryPanel, но задний фон CheckBox задний фон XheckBox не отрисовывается в цвет стиля, а остается серым.
Этот же CheckBox размещенный на форме отображается нормально.

Проект тестировался в XE5.
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #39170431
iStrannik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Глюк 1 - см. вложение
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #39170433
iStrannik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Глюк 2 - см. вложение
Видно что свернули верхнюю CategoryPanel, и видно что на нижней CategoryPanel4 -> Panel2 --> пропал CheckBox4
Если к нему поднести курсор он прорисовывается.
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #39170443
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я уже не помню деталей, но у меня на обычных панелях при большом уровне вложенности (> 7) проявлялись артефакты при перерисовке. Может и здесь ноги растут оттуда же? Попробуйте уменьшить количество вложенных окон
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #39170738
iStrannik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да тут вложений то и нет.

А как избавиться от серого фона для СheckBox расположенного на CategoryPanel, при использования стиля.
Пробовал перехватывать WMPAINT но он работает только без использования стиля, когда же включен стиль то отрисовка идет как то подругому и уже не перехватывается.
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #39171666
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iStrannikДа тут вложений то и нет.
iStrannikЗатем кинул на вторую CategoryPanel2(которая под CategoryPanel1) Panel, а на нее TCheckBox.Я один вижу здесь 4-уровневую вложенность окон?
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #39171741
iStrannik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А как же
но у меня на обычных панелях при большом уровне вложенности (> 7)
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #39171774
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iStrannikА как жеЯ не знаю, что такое CategoryPanel и как она реализована.
Я Вам указал одно из вероятных проблемных мест. Смотреть этот момент или нет - решать Вам
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #39172022
qwertEHOK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
я тоже пытался использовать этот компонент
и тоже криво отрисовывается при потере фокуса

никак не победил((
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #39172068
Cobalt747
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В D10 Seattle не воспроизводится
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #39172070
Cobalt747
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cobalt747,

а вот если выставить DoubleBuffered := true, тогда есть баги (вообще не отрисовываются компоненты)
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #39174780
iStrannik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Проверил тоже на Seatle, специально поставил ее, собрал тестовый проект глюки появляются только если у формы DoubleBuffer = true;
Попробовал этот проект подсунуть XE5 сразу вылазит глюк с прорисовкой и фон CheckBox серый при использовании стиля, значит в какой то версии после XE5 что то допилили. Может кто знает есть какие то аналоги TCategoryPanel, не такие кривые?
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
TCategoryPanelGroup беда с отрисовкой.
    #40005006
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вылечил отрисовку (не прорисовывались докнутые формы на этих панелях).
Также снизил интенсивность мерцания при изменении размеров формы.
Delphi 10.2 Tokyo

1. Реализовал helper для TCategoryPanel, который достает прозрачную панель, на которой рисуются брошенные на панель компоненты.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
THackCP = class helper for TCategoryPanel
private
    function GetSurface: ExtCtrls.TCategoryPanelSurface;
public
    Property Surface: ExtCtrls.TCategoryPanelSurface read GetSurface;
end;

function THackCP.GetSurface: ExtCtrls.TCategoryPanelSurface;
begin
  Result := Self.FPanelSurface;
end;


2. Хакнул эту прозрачную панель TCategoryPanelSurface и переписал ее WMEraseBkgnd

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
TCategoryPanelSurfaceFix = class (ExtCtrls.TCategoryPanelSurface)
  protected
    procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND;
  end;

procedure TCategoryPanelSurfaceFix.WMEraseBkgnd(var Message: TWmEraseBkgnd);
begin
  if not FDoubleBuffered or
    (TMessage(Message).wParam = WPARAM(TMessage(Message).lParam)) then
      FillRect(Message.DC, ClientRect, NULL_BRUSH);

  Message.Result := 1;
end;


3. Написал процедуру осуществляющую накат хака

Код: pascal
1.
2.
3.
4.
5.
6.
7.
procedure PatchCategoryPanelSurface(surface: TCategoryPanelSurface);
type
  pClass = ^TClass;
begin
 if surface.ClassType = TCategoryPanelSurface then
    pClass(surface)^ := TCategoryPanelSurfaceFix;
end;



4. Далее в FormCreate или FormShow остается пройтись по всем CategoryPanel и пофиксить их свойства

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
for Index:=0 to FForm.ComponentCOunt - 1 do begin
    if FForm.Components[index] is TCategoryPanel then 
      UpdateCategoryPanel(FForm.Components[index] as TCategoryPanel);
    end;

где UpdateCategoryPanel нечто такое 

panel.ParentBackground := True;
panel.DoubleBuffered := True;
panel.Surface.DoubleBuffered := True;
panel.Surface.ParentDoubleBuffered := true;
PatchCategoryPanelSurface(panel.Surface); // хакаем навязывая свой WMERASEBckgnd.



Результатом доволен. Полный код тут, но там есть специфичные вещи для моих задач.



unit _ClassCategoryPatch;

interface

Uses Windows, Classes, SysUtils, Forms, Controls, ExtCtrls,
_ClassIObject, messages;

Type
TCategoryPanelPatch = class (IObject)
Strict Private
FForm: TCustomForm;
FLastCategoryPanel: TCategoryPanel;
FCategoryPanelCount: Integer;
procedure OnCollapse(Sender: TObject);

procedure UpdateLastCategoryPanel();
procedure UpdateCategoryPanel (panel : TCategoryPanel);
procedure UpdateCategoryPanelGroup(group: TCategoryPanelGroup);
Public
Constructor Create(Form: TCustomForm); Reintroduce;
Procedure Attach;

End;

TCategoryPanelSurfaceFix = class (ExtCtrls.TCategoryPanelSurface)
protected
procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND;
end;

THackCP = class helper for TCategoryPanel
private
function GetSurface: ExtCtrls.TCategoryPanelSurface;
public
Property Surface: ExtCtrls.TCategoryPanelSurface read GetSurface;
end;

procedure PatchCategoryPanelSurface(surface: TCategoryPanelSurface);

implementation

uses Graphics, cxPC;

{ TCategoryPanelPatch }

constructor TCategoryPanelPatch.Create(Form: TCustomForm);
begin
inherited Create();
FForm := Form;

Attach();
end;

procedure TCategoryPanelPatch.OnCollapse(Sender: TObject);
begin
TCategoryPanel(Sender).Expand()
end;

procedure TCategoryPanelPatch.UpdateCategoryPanel(panel: TCategoryPanel);
begin
panel.ParentBackground := True;
panel.DoubleBuffered := True;
panel.Surface.DoubleBuffered := True;
panel.Surface.ParentDoubleBuffered := true;
PatchCategoryPanelSurface(panel.Surface);

end;

procedure TCategoryPanelPatch.UpdateCategoryPanelGroup(
group: TCategoryPanelGroup);
begin
// group.GradientBaseColor := $00FF8306;
// group.GradientColor := $00FF8306;
group.HeaderFont.Style := [TFontStyle.fsBold];
group.HeaderFont.Size := 8;
// group.HeaderFont.Color := clWhite;
//group.DoubleBuffered := True;
end;

procedure TCategoryPanelPatch.UpdateLastCategoryPanel;
begin
if FCategoryPanelCount = 1 then begin
FLastCategoryPanel.Align := alClient;
FLastCategoryPanel.OnCollapse := OnCollapse;
end;
end;

procedure TCategoryPanelPatch.Attach;
var index: integer;
begin
FLastCategoryPanel := nil;
FCategoryPanelCount:= 0;
for Index:=0 to FForm.ComponentCOunt - 1 do begin
if FForm.Components[index] is TCategoryPanel then begin
if FCategoryPanelCount < 1 then
FLastCategoryPanel := FForm.Components[index] as TCategoryPanel;
Inc(FCategoryPanelCount);
UpdateCategoryPanel(FForm.Components[index] as TCategoryPanel);
end;

if FForm.Components[index] is TCategoryPanelGroup then
UpdateCategoryPanelGroup(FForm.Components[index] as TCategoryPanelGroup);

if FForm.Components[index] is TcxPageControl then begin
TcxPageControl(FForm.Components[index]).LookAndFeel.NativeStyle := True;
TcxPageControl(FForm.Components[index]).LookAndFeel.SkinName := 'Office11'; TcxPageControl(FForm.Components[index]).DoubleBuffered := True;
end;
end;

UpdateLastCategoryPanel;
end;

{ THackCP }

function THackCP.GetSurface: ExtCtrls.TCategoryPanelSurface;
begin
Result := Self.FPanelSurface;
end;

{ TCategoryPanelSurfaceFix }

procedure TCategoryPanelSurfaceFix.WMEraseBkgnd(var Message: TWmEraseBkgnd);
begin
if not FDoubleBuffered or
(TMessage(Message).wParam = WPARAM(TMessage(Message).lParam)) then
FillRect(Message.DC, ClientRect, NULL_BRUSH);

Message.Result := 1;
end;

procedure PatchCategoryPanelSurface(surface: TCategoryPanelSurface);
type
pClass = ^TClass;
begin
if surface.ClassType = TCategoryPanelSurface then
pClass(surface)^ := TCategoryPanelSurfaceFix;
end;

end.
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #40005107
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mixrud,

А вот если бы ты со всем этим тикет на QC запилил, чтобы в консерватории, для всех, тоже поправили, то был бы, имхо, совсем молодец.
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #40005115
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vlad F
Думаю что мое решение половинчатое. Оно будет работать только тогда, когда не используются стили (хотя не тестировал в таком режиме).

Отправлю в пятницу следующую в прод на крупный корпоративный проект.
Хотя бы теперь все выглядит на этих панелях не так убого.
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #40005123
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mixrud,

вы используете апдейты/модули "от Энди"? В одном из модулей был кумулятивный набор, решаюший похожие проблемы.
Например, глюки отрисовки при ресайзе вложенных окон. Причина: для 32 битных приложений, в Win7-64, был уменьшен стек обработки оконных сообщений. Решение - в модуле.
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #40005124
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нет не использую. У CategoryPanel даже без использования themes есть проблемы с отрисовкой обычных компонентов, например tcxcheckbox или tcxtextedit. Не только Dock Form. Dock Form докаю в TPanel, расположенный в TGridPanel. Эти GridPanel вписываются также в другие GridPanel и могут располагаться на TForm, TScrollbox или TCxTabSheet. И лишь на TCategoryPanel есть проблемы с отрисовкой.
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #40005204
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mixrud
Vlad F
Думаю что мое решение половинчатое. Оно будет работать только тогда, когда не используются стили (хотя не тестировал в таком режиме).

Считаю, что надо зарегистрировать, а дальше это будут уже их проблемы (проверка на вшивость).
Делай что должно, и будь что будет. (с)
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #40006057
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
После тщательного тестирования, пришлось изменить код.

Добавлен перехват WMPaint
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
  
TCategoryPanelSurfaceFix = class (ExtCtrls.TCategoryPanelSurface)
  protected
    procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  end;

procedure TCategoryPanelSurfaceFix.WMPaint(var Message: TWMPaint);
var I: Integer;
begin
Try
  for I:=0 to Self.ControlCount - 1 do
    if Self.Controls[I] is TWinControl then
      TWinControl(Self.Controls[I]).BeginDefferedPaint();

  inherited;

 finally
  for I:=0 to Self.ControlCount - 1 do
    if Self.Controls[I] is TWinControl then
      TWinControl(Self.Controls[I]).EndDefferedPaint();
 End;
end;



Добавлен helper для WinControl
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
  TWinControlHelper = class helper for TWinControl
    procedure BeginDefferedPaint();
    procedure EndDefferedPaint();
  end;

procedure TWinControlHelper.BeginDefferedPaint;
begin
  SendMessage(Handle, WM_SETREDRAW, 0, 0);
end;

procedure TWinControlHelper.EndDefferedPaint;
begin
   SendMessage(Handle, WM_SETREDRAW, 1, 0);
   RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_FRAME or RDW_INVALIDATE or
   RDW_ALLCHILDREN);
end;
...
Рейтинг: 0 / 0
TCategoryPanelGroup беда с отрисовкой.
    #40006422
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Борьба продолжается. Немного поправил хэлпер

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
procedure TWinControlHelper.BeginDefferedPaint;
begin
   if Self.Visible then 
       SendMessage(Handle, WM_SETREDRAW, 0, 0);
end;

procedure TWinControlHelper.EndDefferedPaint;
begin
   if Self.Visible then begin
     SendMessage(Handle, WM_SETREDRAW, 1, 0);
     RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_FRAME or RDW_INVALIDATE or
     RDW_ALLCHILDREN);
   end
end;



Тестирование из под Citrix вроде прошло нормально. В пятницу на бой. На следующей неделе отпишу по результатам боевой эксплуатации.
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TCategoryPanelGroup беда с отрисовкой.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]