powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TCategoryPanelGroup: саморазворачивание CategoryPanel при максимизации формы
6 сообщений из 6, страница 1 из 1
TCategoryPanelGroup: саморазворачивание CategoryPanel при максимизации формы
    #40064044
AlexDX4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Столкнулся с такой проблемой в Delphi XE4 (возможно, в новых версиях уже исправлено).

На форме размещена группа свёрнутых панелей TCategoryPanel .
При разворачивании окна формы во весь экран (двойным кликом по заголовку формы) раскрывается одна из панелей .
Заголовок этой панели после разворачивания окна располагается точно на месте заголовка окна до разворачивания.
Получается, окно развернулось (заголовок прижался кверху, группа панелей сместилась вверх), а двойной клик ложно обрабатывается CategoryPanel.
Проблемы нет при разворачивании окна по системной кнопке или программно (wsMaximized).



Пытался отловить двойной клик по заголовку окна :

1 вариант: Добавляю обработку OnExpand/OnCollapse, меняю состояние панели при ложном срабатывании.

2 вариант: После максимизации можно разместить поверх модальное окно (фокус переходит на него).
Можно использовать диалоговое окно или форму с ProgressBar и закрытием по таймеру.
Решение рабочее, но некрасивое.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
  TCategoryPanelF = class(TForm)
    CategoryPanelGroup: TCategoryPanelGroup;
    ...
    procedure CategoryPanel1Expand(Sender: TObject);
  private
    captionDblClicked: boolean;
    procedure WMNCLBUTTONDBLCLK(var Msg: TMessage); message WM_NCLBUTTONDBLCLK;
    procedure WMGETMINMAXINFO(var Msg:TWMGETMINMAXINFO); message WM_GETMINMAXINFO;    
  end;

//Уведомляет окно о двойном клике вне области пользователя
procedure TCategoryPanelF.WMNCLBUTTONDBLCLK(var Msg: TMessage);
var i:integer;
begin
  if Msg.wParam = HTCAPTION then
     captionDblClicked:= WindowState = wsNormal; //при сворачивании окна проблемы нет, Y клика выше панелей     
     if captionDblClicked then
     begin
        // 1 вариант - отлавливаем OnCollapse/OnExpand
        for i:= 0 to CategoryPanelGroup.Panels.Count-1 do
        begin
         TCustomCategoryPanel(CategoryPanelGroup.Panels.Items[i]).OnCollapse:= CategoryPanel1Expand;
         TCustomCategoryPanel(CategoryPanelGroup.Panels.Items[i]).OnExpand:=   CategoryPanel1Expand;
        end;
        inherited; // максимизация
     end;

     //inherited; // 2 вариант с модальным окном
     //if captionDblClicked then
     // ShowMessage('модально окно');
end;

//сворачиваем/разворачиваем панель при ложном срабатывании
procedure TCategoryPanelF.CategoryPanel1Expand(Sender: TObject);
var i: integer;
begin
   if captionDblClicked then
   begin
     captionDblClicked:= false;
       for i:= 0 to CategoryPanelGroup.Panels.Count-1 do
       begin
         TCustomCategoryPanel(CategoryPanelGroup.Panels.Items[i]).OnCollapse:= nil;
         TCustomCategoryPanel(CategoryPanelGroup.Panels.Items[i]).OnExpand:=   nil;
       end;
       TCategoryPanel(Sender).Collapsed:= not TCategoryPanel(Sender).Collapsed;
   end;
end;

//размер и положение окна при максимизации
procedure TCategoryPanelF.WMGetMinMaxInfo(var Msg:TWMGetMinMaxInfo);
begin
  //inherited;
  with Msg.MinMaxInfo^ do
  begin
    ptMaxPosition.x:= BoundsRect.Left; // максимальная позиция окна по оси Х после максимизации
    ptMaxPosition.y:= - GetSystemMetrics(SM_CYBORDER); //вычитаем высоту огибающей окно рамки
    ptMaxSize.x:= Width; // максимальная ширина по оси Х после максимизации
  end;
end;



Решение по 1 варианту неполное. Не обрабатывается ситуация, когда DBLCLK не попадает по координатам заголовка панели.
В результате первый клик по заголовку будет проигнорирован (captionDblClicked=true).
Нужно предварительно вычислять координаты (попадет ли DBLCLK по заголовку) и пр.

Можете предложить более оптимальное решение?
...
Рейтинг: 0 / 0
TCategoryPanelGroup: саморазворачивание CategoryPanel при максимизации формы
    #40064096
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexDX4,

можно попробовать что то типа
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
procedure TForm1.FormResize(Sender: TObject);
begin
  if WindowState = wsMaximized then
    FMaximizeClickTime := GetTickCount;
end;

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
begin
  if (Msg.hwnd = CategoryPanel1.Handle) and ((GetTickCount - FMaximizeClickTime) < 100) then
    Handled := True;
end;
...
Рейтинг: 0 / 0
TCategoryPanelGroup: саморазворачивание CategoryPanel при максимизации формы
    #40064327
AlexDX4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Zelius,

Спасибо за предложение, но не сработало.
Handled := True не оказывает влияния на этот ложный DBLCLCK и с отсрочкой по времени и без (GetTickCount).

Ранее я пытался отлавливать нажатие через ApplicationEvents.OnMessage ,
но убедился, что Handled := True не влияет в этом случае.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
procedure TCategoryPanelF.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
begin
   if Msg.message = WM_NCLBUTTONDBLCLK then
   begin  
    if Msg.wParam = HTCAPTION then // Return value HTCAPTION = 2
    begin
     Handled:= true; // не влияет
     if WindowState = wsNormal then
          WindowState:= wsMaximized
     else WindowState:= wsNormal;
     Handled:= true; // и так не влияет
     ApplicationEvents1.CancelDispatch; // не влияет
     captionDblClicked:= true;
    end;
   end
   else
   if captionDblClicked then
    if Msg.message = 49299 then // именно здесь происходит Expand
    begin
      Handled:= true;
      ApplicationEvents1.CancelDispatch;
      captionDblClicked:= false;
    end;
end;
...
Рейтинг: 0 / 0
TCategoryPanelGroup: саморазворачивание CategoryPanel при максимизации формы
    #40064329
AlexDX4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В приведённом выше Варианте 1 можно было бы обойтись без присваивания событий OnExpand/OnCollapse если влезть в процедуры Expand/Collapse . Но так не получилось:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
TCategoryPanel = class(ExtCtrls.TCategoryPanel)
  public
    procedure Expand;
    procedure Collapse; 
  end;

procedure TCategoryPanel.Expand;
begin
  if captionDblClicked then
    captionDblClicked:= false  
  else
    Inherited;  
end;
...
Рейтинг: 0 / 0
TCategoryPanelGroup: саморазворачивание CategoryPanel при максимизации формы
    #40064410
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
мдаа, задачка... тут имхо либо наследовать и переписывать или
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
procedure TForm3.FormResize(Sender: TObject);
begin
  CategoryPanel1.Enabled := False;
  CategoryPanel2.Enabled := False;
  CategoryPanel3.Enabled := False;
  Timer1.Enabled := True;
end;

procedure TForm3.Timer1Timer(Sender: TObject);
begin
   Timer1.Enabled := False;
   CategoryPanel1.Enabled := True;
   CategoryPanel2.Enabled := True;
   CategoryPanel3.Enabled := True;
end;
...
Рейтинг: 0 / 0
TCategoryPanelGroup: саморазворачивание CategoryPanel при максимизации формы
    #40064600
AlexDX4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Zelius, Спасибо большое! Работает "заморозка" железно, глушит DBLCLCK .

Ещё бы таймер задавать "не с потолка", но и так, вполне, можно оставить.
Если первый клик по панели не сработает, можно списать на мышку.
Вместо onResize, думаю, лучше оставить отлов DBLCLCK при максимизации, меньше шансов попасть на "заморозку" панелей.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
procedure TCategoryPanelF.WMNCLBUTTONDBLCLK(var Msg: TMessage);
var i:integer;
begin
  if Msg.wParam = HTCAPTION then
    if WindowState = wsNormal then
    begin
        for i:=0 to CategoryPanelGroup.Panels.Count-1 do
          TCustomCategoryPanel(CategoryPanelGroup.Panels.Items[i]).Enabled:= False;
        Timer1.Enabled:= True;
        WindowState:= wsMaximized;
    end
    else
     WindowState:= wsNormal;
end;
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TCategoryPanelGroup: саморазворачивание CategoryPanel при максимизации формы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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