創建窗體,不搶奪焦點
http://www.cnblogs.com/cartler/
經過資料查找,發現可以設置WS_EX_NOACTIVATE
?
界面編程里面,經常碰到焦點問題,以下幾點可注意:
1. Create時指定 WS_EX_NOACTIVATE屬性,注意同時去掉WS_VISIBLE,這樣創建窗口時不會搶焦點。
2.響應 WM_MOUSEACTIVATE 消息,返回 MA_NOACTIVATE,這樣鼠標在其上操作時不會搶焦點,在popup窗口上做這條即可,對其子窗口一並有效。?
3.可以用 GetGUIThreadInfo() 取得當前焦點相應信息,用於查看焦點搶占情況。
經過這樣設置的窗口,基本上解決不了我的問題。原因如下:
WINDOWS為每一個線程創建一個數據結構稱為"線程本地輸入狀態",里面記錄了該線程創建的窗口中哪個是活動窗口,哪個具有輸入焦點,以及光標等信息(由操作系統維護)。
根據以上原理,如果是一個線程創建的兩個窗口,用戶是無法控制輸入焦點的。因此要想在激活另一個窗口時,同時不能改變輸入焦點,只能讓這兩個窗口分屬於不同的線程(不必是不同的進程)。
看了你的問題后,我有個方案覺得很適合你的要求:
1)Frame1始終讓edit控件具有輸入焦點;
2)Frame2由另一個線程來創建;
3)使用WIN32?API的AttachThreadInput(Thread1ID,?Thread2ID,?TRUE)將Frame1和Frame2兩個窗口的線程本地狀態關聯起來;
說得通俗點,Frame1和Frame2共享一個輸入焦點,且兩個窗口共享所有的鼠標,鍵盤操作。這或許是AttachThreadInput這個API的命名又來。具體使用情況樓主看下MSDN,自己碼下代碼!
也就是說同一個線程創建的窗口用WS_EX_NOACTIVATE樣式是沒有效果的。
問題還是需要解決,經過查證已找到正確方法:
?
-
創建窗口時去掉WS_VISIBLE屬性,加上WS_DISABLED屬性。
-
創建窗口,得到窗口句柄。
-
::ShowWindow(m_hWnd,SW_SHOWNOACTIVATE)顯示窗口,則不會搶奪焦點。
-
更進一步,可以屏蔽鼠標點擊時獲得焦點的行為,響應WM_MOUSEACTIVATE,返回MA_NOACTIVATE。
完美收工!