2010-11-24 110 views
1

在Windows中,假設您有多個打開相同窗口類的窗口(HWND)。如何跟蹤窗口過程中的上下文數據,以便在用戶嘗試鍵入窗口2時窗口1不會被修改?C/C++ - Windows - 如何跟蹤HWND上下文數據

在多次調用WndProc()之後,CreateWindow()不會返回,因此您不能簡單地將生成的HWND設置爲上下文數據並在WndProc()中執行查找。你確實需要在WndProc()中設置它。

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

將HWND存儲在鏈表類型的存儲機制中對於大量窗口來說效率不高:窗口中的每個控件都只是另一種類型的窗口,因此您需要跟蹤另一個HWND;在幾百個控件之後,在短時間內將幾十條消息傳遞給程序後,在HWND中搜索鏈表將成爲程序中的主要瓶頸!

從我所聽到的,有些人使用SetWindowLong() - 但我也聽說有些庫也喜歡用它來存儲自己的上下文信息與程序分開,並且有時會發生窗口數據衝突。這怎麼可以避免?

+0

你能不只是排序HWNDs的名單? – James 2010-11-24 19:25:18

+0

我沒有關注這個..你想區分你的窗戶嗎?爲什麼在window2中輸入時會修改window1? – Default 2010-11-24 19:32:16

+2

`SetWindowLongPtr(GWL_USERDATA)`是要走的路。除非他們創建窗口,否則庫不應該使用它。窗口的用戶數據屬於創建窗口的人 - 如果圖書館想要附加自己的用戶數據,它需要請求您獲得許可(例如將其存儲爲窗口類包裝的成員)。 – 2010-11-24 19:53:57

回答

4

如果我正確地理解了你,你想要避免一個窗口捕捉來自另一個窗口的消息。避免這種情況的一種方法是使用this線程中提出的解決方案,該解決方案跟蹤由您創建的窗口並確保正確的窗口通過將調用者的指針存儲在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); 
} 
// ... 

您還可以趕上WM_NCCREATE消息,提議Moo-Juice
我不認爲你應該擔心在WM_CREATE之前的消息,因爲窗口甚至沒有完全初始化。如果您需要設置文本,則在撥打CreateWindow(Ex)之後執行該操作,無論是用戶輸入還是撥打SendMessage

0

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

2

無論誰創建窗口都擁有該窗口100%。如果你是調用CreateWindow()的人,那麼你可以使用GetWindowLong,知道它是你的。

但是,如果庫創建窗口,則不能,因爲它不是你的。

(旁白:沒有什麼能阻止任何人踩到別人的腳趾,但這個約定很標準)。

如果您使用這樣做的庫,它通常會有一些機制將您自己的數據與窗口關聯起來。當然,你需要參考文檔。