Delphi TPageControl对选项卡上的单击没有响应

Delphi TPageControl对选项卡上的单击没有响应,delphi,focus,tabs,click,tpagecontrol,Delphi,Focus,Tabs,Click,Tpagecontrol,我有一个主窗体上带有TPageControl的应用程序。pagecontrol有几个选项卡。应用程序可以最小化为一个托盘图标。有时在运行Minimize一段时间后,当我恢复主窗口时(通过在托盘图标上单击鼠标右键),会显示上次显示的选项卡,但我无法选择任何其他选项卡 如果单击另一个选项卡,外观会发生变化,使该选项卡显示为活动选项卡(即选项卡本身移动到选项卡行的前面),但选项卡的主体仍保持原样。我也有菜单项和快捷键来选择其他选项卡,它们的行为相同。如果我键入Alt-O(选项),顶部的“选项”选项卡将

我有一个主窗体上带有TPageControl的应用程序。pagecontrol有几个选项卡。应用程序可以最小化为一个托盘图标。有时在运行Minimize一段时间后,当我恢复主窗口时(通过在托盘图标上单击鼠标右键),会显示上次显示的选项卡,但我无法选择任何其他选项卡

如果单击另一个选项卡,外观会发生变化,使该选项卡显示为活动选项卡(即选项卡本身移动到选项卡行的前面),但选项卡的主体仍保持原样。我也有菜单项和快捷键来选择其他选项卡,它们的行为相同。如果我键入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.ApplicationEvents1Minimize(Sender: TObject) ;

begin
Hide();
WindowState := wsMinimized ;
TrayIcon1.Visible := True;
end ;
我删除了:

procedure TTADMainForm.SendToTray (Sender: TObject) ;

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

procedure RestoreMainWindow ;

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

begin
Hide();
WindowState := wsMinimized ;
TrayIcon1.Visible := True;
end ;
问题似乎已经解决了。然而。现在我可以最小化应用程序启动后,弹出出现和显示模式,主要形式显示,所有的标签显示和工作。但是我不能再把表格最小化了。OnMinimize处理程序在第一次之后不会被触发。Grrrrr


我仍然不明白为什么它现在起作用,这有点令人担忧。我怎样才能让它再次最小化呢???

完全从5年前的记忆中工作,但下面是:

TPageControl对其中的每个页面使用不同的窗口句柄。选项卡栏是它自己的窗口句柄,TPageControl负责监听选项卡更改并进行相应的页面隐藏/显示。因此,当您单击一个选项卡,该选项卡跳转到包的前面时,TPageControl应该隐藏当前页面窗口,并显示与所选选项卡相对应的页面窗口

通常,VCL控件在实际需要时才创建其窗口句柄,例如,当它实际显示时。这减少了窗口句柄的消耗。在Windows 3.1和Win95中非常重要,但在今天基于NT的32位操作系统中就不那么重要了

为了最小化资源负载和启动时间,TPageControl在创建控件时不会为其所有隐藏页创建窗口句柄。页面窗口句柄将在首次显示时创建

单击选项卡时,页面未被绘制的原因有几种可能:

  • 正在耗尽GDI窗口句柄池。除非您使用的是16位Windows操作系统,否则不太可能。(Win 3.1或Win95)
  • 内存泄漏,导致你的应用程序溢出到交换文件并重击硬盘。该应用程序将几乎停止运行,看起来就像被冻结了一样,不时会出现用户界面活动的打嗝
  • 在没有消息循环的后台线程上创建的窗口句柄。你在后台线程中做什么?在后台线程中触摸VCL控件可能会导致过早创建窗口句柄,并且窗口句柄将绑定到创建它的线程。若该线程并没有消息循环,那个么窗口句柄将永远不会接收任何消息,所以它将永远不会在屏幕上绘制自己

  • 3号是你最有可能的罪魁祸首。那么,你在后台线程中做什么?;>

    以防万一,它帮助什么版本的德尔福?谢谢你的详细回答。没有明显的抖动,在事件发生后,应用程序的行为与我所看到的控件的预期完全一致。有一个背景线程-但我不相信它触及VCL。您是否希望控件(共有7个)上的所有页面都没有响应?如果后台线程场景中的windows句柄是cuplrit,那么紧急解决方法是在启动时以编程方式依次选择每个页面吗?您需要检查TPageControl的文档或VCL源代码,查看它在隐藏页面时是否会破坏页面窗口句柄。我记不起来是不是。可能在Win32 3.1中使用过,但在Win32中不再需要。如果在页面隐藏时窗口句柄没有被破坏,那么是的,在启动时触摸所有页面句柄将强制创建所有句柄。但是,这里要小心,因为如果您有十几个选项卡页面,并且每个页面上都有20个控件,那么创建所有这些句柄将花费大量时间。这就是为什么我们将TPageControl更改为lazy-l