簡體   English   中英

Delphi TPageControl不響應選項卡上的單擊

[英]Delphi TPageControl not responding to clicks on tabs

我在主窗體上有一個帶有TPageControl的應用程序。 頁面控件有幾個選項卡。 該應用程序可以最小化到一個托盤圖標。 有時在最小化運行一段時間后,當我還原主窗口時(通過右鍵單擊任務欄圖標),將顯示最后顯示的選項卡,但是我無法選擇其他任何選項卡!

如果單擊另一個選項卡,則外觀會發生變化,因此該選項卡看起來像是活動的選項卡(即,選項卡本身移至選項卡行的前面),但選項卡的主體保持原樣。 我也有菜單項和快捷鍵來選擇其他選項卡,它們的行為相同。 如果我鍵入Alt-O(選項),則頂部的“選項”選項卡將變為活動狀態,但看不到該選項卡主體上的內容-我仍然看到另一個選項卡的內容。

我已經驗證,當我單擊另一個選項卡時焦點將移出第一個選項卡,而當我單擊該選項卡時將焦點移回。

我還不確定行為是否僅限於特定選項卡,因為它需要一段時間才能實現。

有任何想法嗎?

更新

有趣的筆記。 我已經確定在這種情況下會出現問題。 該應用程序已啟動,然后最小化到任務欄中。 檢測到警報條件,彈出一個窗口並還原主窗口(這是應用程序的預期行為)。 正是在這一點上可以觀察到故障-即單擊其他選項卡時看不到它們。

  • 啟動應用程序。 顯示選項卡1
  • 最小化應用程序。 到托盤
  • 等待彈出窗口顯示,主窗體已恢復
  • 單擊選項卡2觀察到的故障(選項卡2的主體不顯示)
  • 將斷點放在TWinControl.CreateHandle中
  • 點擊標簽3-休息
  • 運行-不顯示Tab 3正文
  • 單擊選項卡1-不中斷
  • 單擊選項卡3-不中斷
  • 單擊選項卡4-休息
  • 運行-不顯示Tab 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。

我仍然無法理解為什么它現在可以工作,這有點令人擔憂。 以及如何使它再次最小化?

完全從5年前的內存開始工作,但是這里有:

TPageControl對其中的每個頁面使用不同的窗口句柄。 標簽欄是它自己的窗口句柄,TPageControl負責偵聽標簽的更改並進行相應的頁面隱藏/顯示。 因此,當您單擊一個選項卡並且該選項卡跳到包的最前面時,TPageControl應該隱藏當前頁面窗口並顯示與所選選項卡相對應的頁面窗口。

通常,VCL控件在實際需要時才創建窗口句柄-例如,在實際顯示時。 這減少了窗把手的消耗。 在Windows 3.1和Win95中非常重要,但在當今基於NT的32位操作系統中卻不那么重要。

為了最小化資源負載和啟動時間,在創建控件時,TPageControl不會為其所有隱藏頁面創建窗口句柄。 頁面窗口句柄將在首次顯示時創建。

單擊選項卡時,為什么無法繪制頁面有幾種可能性:

  1. 耗盡GDI窗口句柄池。 除非您使用的是16位Windows操作系統,否則這種情況極不可能發生。 (Win 3.1或Win95)
  2. 導致您的應用溢出到交換文件並損壞硬盤的內存泄漏。 該應用程序將磨碎到幾乎停止並且看起來像被凍結一樣,時不時出現UI活動。
  3. 在沒有消息循環的后台線程上創建窗口句柄。 您在后台線程中做什么? 在后台線程中觸摸VCL控件可能導致過早創建窗口句柄,並且窗口句柄將綁定到在其上創建的線程。 如果該線程沒有消息循環,則該窗口句柄將永遠不會收到任何消息,因此它將永遠不會在屏幕上繪制自身。

第三名是您最有可能的罪魁禍首。 那么,您在該后台線程中正在做什么? ;>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM