簡體   English   中英

使用Win32 API驗證HWND

[英]Validate HWND using Win32 API

從使用C ++的本機Win32 API可以確定與HWND關聯的窗口是否仍然有效?

您可以使用Win32 API IsWindow

不建議使用它,原因有兩個:

  1. 窗口被破壞后,Windows句柄可以重復使用,因此您不知道是否有完全不同窗口的句柄。
  2. 在調用之后狀態可以直接改變,你會認為它是有效的,但它可能真的無效。

從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使用足夠唯一的名稱注冊消息。

也許IsWindowFindWindowGetWindowThreadProcessId的組合會更准確

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.

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