簡體   English   中英

找出TSaveDialog缺少應用程序線程消息的原因

[英]Find out why application thread messages go missing with TSaveDialog

使用RAD Studio(Delphi)v10.2.1(東京版本1)在Windows 10“Creators Update”64bit上進行開發,但是32位開發。

該應用程序是具有多個后台線程的VCL,每個線程使用Indy TidHTTP來獲取網絡資源。 主線程和后台線程之間的同步使用消息隊列(PostThreadMessage調用)實現。 這很復雜,在這里提供直接代碼將是困難和混亂的,所以我開始用口頭描述。

應該發生什么:打開一個帶有外部資源鏈接的文件,這會生成HTTP請求並將它們移交給后台處理,然后等待應用程序消息隊列上的傳入消息,說明資源已被下載。 應用程序消息在分配給TApplication.OnMessage的事件代碼中匹配(我懷疑,這是我的問題所在)。

有用。 一切都順利進行。 但是如果我打開一個TSaveDialog - 即使我取消了對話而不是實際做任何事情 - 那么應用程序消息隊列中的消息就會丟失。

通過編寫日志消息的過程(不可能直接調試,因為這會擾亂導致問題所需的時間)我已經知道后台線程確實發布消息(並從PostThreadMessage獲得肯定的響應),但是他們永遠不會出現在我的TApplication.OnMessage事件代碼中。

我已經看到各種庫中的一些偷偷摸摸的代碼將建立自己的PeekMessage / TranslateMessage / DispatchMessage循環,但並非所有人都記得檢查是否存在TApplication.OnMessage事件。 但我剛剛搜索了VCL代碼和我正在使用的十幾個第三方庫,並且沒有發現任何這種情況會在這種情況下受到影響(據我所知)。

注意:我使用的是madExcept,Indy,FastReport,AddictSpell,SynEdit,VclStyleUtils(在其他一些不太知名的庫中)

注2:我想知道它是否與Delphi 10.2.1或Windows 10 Creator的更新有關,因為我也看到了一些其他奇怪的行為(第一個例外的長延遲或第一個TOpenDialog - 但僅限於某些應用程序)絕對不會發生10.1(我沒有使用10.2.0)。 ......但這可能(可能是)有所不同。

所以我的問題是:我能做些什么呢?

有關如何查找/驗證是否有其他代碼竊取應用程序消息的任何建議? 我還應該搜索除PeekMessage之外的其他東西嗎?

是否有其他方法可以攔截可能讓我避免此問題的應用程序消息隊列消息?

如果沒有更好的選項顯示自己,我可能不得不放棄使用應用程序線程消息並實現我自己的消息/同步系統,在其他時間讓其他人工作得非常好之后我寧願不做。

你提到PostThreadMessage 不要再猶豫了。 除非您控制可能拉出線程消息的所有消息循環,否則您不能使用它。 模態文件對話框消息循環不受控制。 它將拉出用於不同消息循環的線程消息,而不知道如何處理它們。

解決方案很簡單。 將消息發布到窗口而不是線程。 這樣,所有理智的消息循環(模態文件對話框的消息循環都是健全的)將把消息分派到預期的收件人窗口。

在Delphi術語中,這將涉及使用AllocateHWnd或類似方法創建一個隱藏窗口來接收消息。

Raymond Chen在這里討論了這個主題: 為什么PostThreadMessage發布的消息會消失?

暫無
暫無

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

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