[英]Win32 API - HWND “{unused = ???} Unable to read memory” error
[英]Validate HWND using Win32 API
從使用C ++的本機Win32 API可以確定與HWND關聯的窗口是否仍然有效?
您可以使用Win32 API IsWindow 。
不建議使用它,原因有兩個:
從MSDN(與上面相同的鏈接):
線程不應該將IsWindow用於它沒有創建的窗口,因為在調用此函數后窗口可能會被銷毀。 此外,由於窗口把手被回收,手柄甚至可以指向不同的窗口。
可以做些什么?
也許您的問題可以重新設計,這樣您就不需要檢查有效的句柄。 例如,您可以建立從客戶端到服務器的管道。
您還可以創建一個Windows掛鈎來檢測何時發生某些消息,但這對於大多數需求來說可能是過度的。
這個問題已經過時了,但我自己需要這個功能,在閱讀了有關警告之后有點失望。 然而,在做了一點挖掘后,似乎一切都很順利。 除非你正在處理16位程序,否則IsWindow似乎是要走的路。 手柄重復使用的問題似乎已經充分解決了這個問題:
http://blogs.msdn.com/b/oldnewthing/archive/2007/07/17/3903614.aspx
因此,由於高16位重用計數器,您不太可能遇到窗口重用問題。
您可以使用IsWindow()或嘗試使用SendMessage (hWnd,WM_NULL)向窗口發送WM_NULL消息,並查看它是否成功。
此外,如果窗口不在您的控制范圍內,則可以隨時銷毀窗口。 正如其他人所說,當句柄被重用時,句柄可能屬於另一個窗口。 實際上我不知道這有多大可能性。
我知道的唯一解決方案是創建一個系統范圍的鈎子 ,查找指示窗口的消息被破壞(WM_CLOSE,WM_DESTROY)。 然后,您將比較消息窗口句柄與您持有的句柄,以查看您關心的任何窗口是否受到影響。 有關系統范圍掛鈎的更多信息,請參見此處。
如果有問題的窗口的窗口過程在您的控制之下(或者您可以將其子類化),那么我建議注冊窗口響應的自定義消息,其結果為非零。 將該消息發送到任何其他窗口(或無效的HWND)將導致0。
當然,這只會告訴您HWND是否指向您控制的其中一個窗口 - 但可能會給出上面的其他答案甚至可能是有利的。
使用RegisterWindowMessage使用足夠唯一的名稱注冊消息。
也許IsWindow
, FindWindow
和GetWindowThreadProcessId
的組合會更准確
HWND windowHandle = FindWindow(NULL, TEXT("window_title"));
LPDWORD oldpid = 0;
GetWindowThreadProcessId(windowHandle, &oldpid);
//after some time
if (IsWindow(windowHandle))
{
LPDWORD newpid = 0;
GetWindowThreadProcessId(windowHandle, &newpid);
if (newpid == oldpid)
{
//the window is still running
}else
{
//the window exists but has changed
}
}
if(IsWindow(FindWindow(NULL , TEXT("Example Window Name")))){
// do stuff
}
將檢查窗口是否存在並具有適當的名稱
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.