Delphi TPageControl не отвечает на нажатия на вкладках - PullRequest
1 голос
/ 14 июля 2010

У меня есть приложение с TPageControl в главной форме.Управление страницей имеет несколько вкладок.Приложение может быть свернуто до иконки в трее.Иногда после запуска, свернутого в течение некоторого времени, когда я восстанавливаю главное окно (щелкнув правой кнопкой мыши на значке в области уведомлений), отображается последняя отображаемая вкладка, но я не могу выбрать другие вкладки!

Если щелкнуть другую вкладку, ее внешний вид изменится, и тогда она станет активной (то есть сама вкладка переместится в начало ряда вкладок), но тело вкладки останется прежним.У меня также есть пункты меню и сочетания клавиш для выбора других вкладок, и они ведут себя одинаково.Если я нажимаю Alt-O (параметры), вкладка параметров в верхней части становится активной, но я не вижу, что находится в теле этой вкладки - я все равно вижу содержимое другой вкладки.

Я подтвердил, чтоФокус смещается с первой вкладки, когда я нажимаю на другую вкладку, и смещается назад, когда я нажимаю на эту вкладку.

Я еще не установил, ограничено ли поведение определенной вкладкой, поскольку для этого требуется некоторое времяслучиться.

Есть идеи?

Обновление

Интересная заметка.Я установил, что проблема возникает в этих условиях.Приложение запускается, а затем сворачивается в трей.Обнаружено состояние тревоги, всплывает окно и восстанавливается главное окно (это и есть предполагаемое поведение приложения).Именно в этот момент наблюдается ошибка - т.е. я не вижу другие вкладки, когда нажимаю на них.

  • Запустите приложение.Вкладка 1 отображается
  • Свернуть приложение.в трей
  • Подождите, пока не появится всплывающее окно, основная форма восстановлена ​​
  • Нажмите на вкладку 2 ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ (тело вкладки 2 не отображается)
  • Установите точку останова в TWinControl.CreateHandle
  • Нажмите на вкладке 3 - разрывы
  • Выполнить - не показывает тело вкладки 3
  • Нажмите на вкладку 1 - не сломается
  • Нажмите на вкладку 3- не ломается
  • Нажмите на вкладку 4 - ломается
  • Выполнить - не показывает тело вкладки 4
  • Нажмите на вкладку 1, 2, 3, 4 - не ломается

Таким образом, кажется, что вкладки создают свои дескрипторы при первом нажатии, и с этого момента они думают, что существуют, но не отображаются.Если всплывающее окно отключено, неисправность не наблюдается.Всплывающее окно запускается из задачи Application.OnIdle.

Другое обновление: некоторый прогресс.Покопавшись в интернете, я внес некоторые изменения.

Я удалил следующий код:

procedure RestoreMainWindow ;

begin
MainForm.WindowState := wsNormal ;
MainForm.visible := true ;
Application.Restore ;
Application.BringToFront ;
ShowWindow (Application.Handle, SW_SHOW) ;  { show the taskbar button }
end ;

и заменил его на:

procedure RestoreMainWindow ;

begin
MainForm.Show () ;
MainForm.WindowState := wsNormal ;
Application.BringToFront () ;
ShowWindow (Application.Handle, SW_SHOW) ;  { show the taskbar button }
end ;

Я удалил:

procedure TTADMainForm.SendToTray (Sender: TObject) ;

begin
MainForm.visible := false ;
ShowWindow (Application.Handle, SW_HIDE) ;  { hide the taskbar button }
end ;
...
Application.OnMinimize := SendToTray ;    

и заменил его на:

procedure TTADMainForm.ApplicationEvents1Minimize(Sender: TObject) ;

begin
Hide();
WindowState := wsMinimized ;
TrayIcon1.Visible := True;
end ;

, и проблема, похоже, исчезла.ТЕМ НЕ МЕНИЕ.Теперь я могу свернуть приложение после запуска, всплывающее окно появляется и отображается модально, отображается основная форма, все вкладки отображаются и работают.НО.Я не могу свернуть форму снова.Обработчик OnMinimize не запускается после первого раза.Grrrrr.

Я до сих пор не могу понять, почему это работает сейчас, что немного беспокоит.И как мне заставить его минимизировать снова ??

1 Ответ

3 голосов
/ 14 июля 2010

Работает полностью из памяти 5 лет назад, но здесь идет речь:

TPageControl использует разные дескрипторы окна для каждой страницы в нем.Панель вкладок представляет собой собственный дескриптор окна, а TPageControl отвечает за прослушивание изменений вкладок и выполнение соответствующего скрытия / отображения страниц.Таким образом, когда вы нажимаете на вкладку, и вкладка переходит к передней части пакета, TPageControl должен скрывать окно текущей страницы и показывать окно страницы, соответствующее выбранной вкладке.

Обычно элементы управления VCLне создавайте их дескриптор окна, пока он действительно не понадобится - например, когда он действительно показан.Это уменьшает потребление ручки окна.Критически важно в Windows 3.1 и Win95, но не так критично в современных 32-битных ОС на базе NT.

Чтобы минимизировать загрузку ресурсов и время запуска, TPageControl не создает дескрипторы окон для всех своих скрытых страниц, когда элемент управлениясоздано.Дескрипторы окна страницы будут созданы при первом их отображении.

Существует несколько возможностей, почему страница не рисуется при нажатии на вкладку:

  1. Исчерпание GDIоконная ручка бассейна.Крайне маловероятно, если вы не используете 16-битную ОС Windows.(Win 3.1 или Win95)
  2. Утечка памяти, которая приводит к тому, что ваше приложение выливается в файл подкачки и перебивает жесткий диск.Приложение будет почти остановлено и будет выглядеть как замороженное, с порой всплесками активности пользовательского интерфейса.
  3. Описатели окна создаются в фоновом потоке, который не имеет цикла сообщений.Вы делаете что-нибудь в фоновых темах?Прикосновение к элементу управления VCL в фоновом потоке может привести к преждевременному созданию дескриптора окна, и дескриптор окна будет связан с потоком, в котором он был создан.Если в этом потоке нет цикла обработки сообщений, этот дескриптор окна никогда не будет получать никаких сообщений, поэтому он никогда не будет отображаться на экране.

Нет.3 ваш наиболее вероятный виновник.Итак, что вы делаете в этом фоновом потоке?;>

...