首先:對于區域,我不是指該視窗所針對的區域(地球上的位置),而是視窗區域:https : //docs.microsoft.com/en-us/windows/win32 /api/wingdi/nf-wingdi-createrectrgn
作業系統:Windows 10
編碼環境:C\Win32
要在 Windows 中更改視窗的形狀,可以使用SetWindowRgn()函式。作為它的第二個引數,它需要一個創建的視窗區域 - 例如 - 使用上面的 CreateRectRgn 等等。
我正在使用此函式以每秒 10 次的速度更新視窗的形狀。
程式運行幾秒鐘后,SetWindowRgn 回傳 0,這意味著出現問題。
我的第一個想法是,其中一個引數無效,但我會跟蹤它們的狀態(我先檢查 1 行,如果它們的狀態有效): Window Handle 永遠不會改變,據我所知,永遠不會改變無效,直到視窗存在/正在關閉(它沒有/不是,即使在它回傳 0 之后)。
區域句柄也不是無效的,因為我 (1st) 檢查它是否已初始化(要將一個區域與另一個區域組合,目標區域需要存在),然后(2nd)檢查它是否為 NULL(它不是作為好吧),然后(第三)如果它是一個有效的句柄(它也是)。我還使用 GetLastError() 來檢查是否設定了錯誤(不是)。第三個引數不會改變結果。
然后我想,即使 Windows 檔案說:
尤其不要洗掉這個區域句柄。當不再需要時,系統會洗掉區域句柄。
句柄沒有被洗掉,并且未使用的句柄在記憶體中堆積:情??況并非如此(我使用執行緒回圈檢查,檢查 GetProcessHandleCount() 是否已更改)
然后我開始對整個事情計時,看看是否有一些一致性,一些事情,總是在 SetWindowRgn 回傳 0 之前發生:時間并不總是相同,但我添加了一個變數來檢查我使用 SetWindowRgn 的次數() 函式:對于那個特定的視窗,我在代碼中總是準確地呼叫這個函式 4993,但是我確實有 2 個來自同一個行程的其他 Windows,總而言之,這讓我在代碼中呼叫了這個 Windows 函式 4995 次。
想象一下,CreateWindow 函式也呼叫這個函式,它可能是 4998 次呼叫。在這么多之后, SetWindowRgn() 對該視窗失敗。(我不會在其他 2 個視窗中再次使用它)。
整個事情目前在一個大執行緒中運行。我正在檢查幾乎每個 win32 呼叫,以查看是否發生錯誤(但有時我希望它只會崩潰 :S )。
TL;DR:Windows 讓我只使用SetWindowRgn()大約 5000 次
我現在的問題是:這是真的嗎?使用該功能的頻率是否有限制?有沒有可能,圖形設備上的所有其他區域都雜亂無章,無法清除,從而導致記憶體溢位?(也許以某種方式沖洗會有所幫助..)我是否剛剛解開了一個未記錄的硬編碼限制?我能做什么,仍然使用 SetWindowRgn()?
如果有些事情可能仍然不清楚,我會道歉,如果您問,我會澄清:),也感謝您的時間和回答!
uj5u.com熱心網友回復:
正如問題下的評論正確表明的那樣:問題是 GDI 資源泄漏。在檢查任務管理器中的幾個細節后,我注意到了這一點。正如 Barmark Shemirani 評論的那樣: SetWindowRgn() 在恰好 10000 個 GDI 物件之后開始失敗。
檢查串列中所有可能的物件對于查明泄漏點來說是微不足道的。
代碼中的問題是:我忘記洗掉不同 CombineRgn() 函式的 2 個結果。現在,我添加了 2 個 DeleteObject() 函式呼叫,現在一切正常。
指出問題的積分歸評論者所有!:)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/345298.html
