簡體   English   中英

C / C ++-Windows-如何跟蹤HWND上下文數據

[英]C/C++ - Windows - how to keep track of HWND context data

在Windows中,假設您打開了同一窗口類的多個窗口(HWND)。 您如何在窗口過程中跟蹤上下文數據,例如,當用戶嘗試在窗口2中鍵入內容時,不會修改窗口1?

在多次調用WndProc()之后,CreateWindow()才返回,因此您不能簡單地將結果HWND設置為上下文數據並在WndProc()中進行查找; 您確實需要在WndProc()中進行設置。

除了窗口創建消息外,WndProc()沒有直接將上下文信息傳遞給它,但是不幸的是,窗口創建消息並不是要傳遞給WndProc()的第一條消息。 不,我發現諸如WM_SIZE,WM_NCSIZE之類的東西,甚至其他一些東西,在我看到WM_CREATE之前都已通過。

在具有大量窗口的情況下,將HWND存儲在鏈接列表類型的存儲機制中會效率低下:一個窗口中的每個控件只是另一種類型的窗口,因此,您需要跟蹤另一個HWND; 經過幾百個控件之后,在短時間內將幾十條消息傳遞給程序后,在鏈接列表中搜索HWND將成為程序的主要瓶頸!

據我所知,有些人使用SetWindowLong()-但我還聽說有些庫也喜歡使用SetWindowLong()將自己的上下文信息與程序分開存儲,並且有時會發生窗口數據沖突。 如何避免呢?

如果我對您的理解正確,則希望避免一個窗口捕獲另一窗口的消息。 避免這種情況的一種方法是使用線程中提出的解決方案, 解決方案跟蹤您創建的窗口,並通過將調用者的指針存儲在GWL_USERDATA中來確保正確的窗口獲取與其關聯的消息。

// ...
m_hWnd = CreateWindowEx(0,"Classname","Title",WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,CW_USEDEFAULT,
                        320,200,NULL,NULL,hInstance, /*the magic pointer*/ this);

// ...

if(uMsg == WM_CREATE)
{
    // collected here..
    pParent = (CWindow*)((LPCREATESTRUCT)lParam)->lpCreateParams;
    // .. and then stored for later lookup
    SetWindowLongPtr(hWnd,GWL_USERDATA,(LONG_PTR)pParent); 
}
// ...

您還可以按照Moo-Juice的建議捕獲WM_NCCREATE消息。
而且我不認為您應該擔心WM_CREATE之前的消息,因為此時窗口還沒有完全初始化。 如果您需要設置文本,則可以在調用CreateWindow(Ex)之后執行此操作,無論是用戶輸入還是SendMessage調用。

創建該窗口的人將擁有該窗口100%的所有權。 如果您是一個調用CreateWindow()的人,那么您可以使用GetWindowLong,因為它是您的。

但是,如果庫創建了窗口,則不能,因為它不是您的。

(順便說一句:沒有什么能阻止任何人踩踏別人的腳趾,但慣例是相當標准的)。

如果您正在使用執行此操作的庫,則該庫通常具有將您自己的數據與窗口關聯的某種機制。 當然,您將需要參考文檔。

您不能使用WNDCLASS.cbWndExtra來聲明您的類需要的任何私有存儲,然后只要Windows創建該類的窗口,它就會由Windows分配。

暫無
暫無

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

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