上兩張Demo的圖,方便朋友們選擇是否繼續看文章.
在子窗口的白色區域按下鼠標左鍵不放並移動鼠標可以拖拽子窗口跟隨鼠標移動.
選擇繼續看下去的朋友不要擔心,接下來就是正文了.
PART 1:Demo功能
呵呵呵,就是純win32 API方式創建窗口和關聯的子窗口,為計划中的小工具做准備吧,計划中要有一個稍復雜的配置界面,采用子窗口的顯示和隱藏來切換配置窗口.
PART 2:技術難題
這部分不存在吧,都是win32的基礎知識,創建主窗口和子窗口基本相同,都是定義窗口對象的屬性和關聯方法,屬性即WNDCLASS,關聯方法即消息處理的回調函數; 讓子窗口跟隨鼠標左鍵移動的關鍵在於理解win32的消息機制並勤快查找MSDN.
PART 3:知識積累
使用win32 API而非MFC的方式對windows的底層機制理解更清晰一些,多個窗口仍然是單線程處理,窗口創建以后循環從消息隊列中獲取消息並在解析后發給對應的窗口去處理,這里其實就是解析消息歸屬窗口后調用窗口對應的回調函數處理,整個流程中任何一個地方阻塞都會導致窗口無法響應.
在鼠標移動時候檢測鼠標是否按下比想象中的要簡單,MSDN查看WM_MOUSEMOVE即可,窗口過程中已經傳遞了鼠標左鍵狀態.原本是打算用GetKeyStat去獲取鍵盤和鼠標的虛鍵狀態呢.
PART 4:找BUG心得
分享一個小心得吧,win32編程時候如果不明白錯誤詳細,調用GetLastError獲取錯誤信息,錯誤碼+報錯函數問度娘,度娘會熱心幫忙的.
本次卡殼的地方是創建子窗口調用CreateWindow終返回NULL,GetLastError返回錯誤碼1047,度娘咨詢下錯誤碼的意思:1.沒有初始WNDCLASS對象的hInstance成員;2.注冊的類名是亂碼.關注CreateWindow的類名參數解決bug.
PART 5:主要思路
1.生成主窗口,基本是windows的標准創建窗口.
2.創建子窗口,子窗口的創建和主窗口沒有明顯的區別,注冊WNDCLASS類,CreateWindow關聯新注冊的類和父窗口句柄.
3.子窗口的消息處理,在子窗口的關聯方法中處理子窗口相對主窗口的偏移量,采用GetWindowRect分別獲取父窗口和子窗口相對屏幕左上角的偏移量,之后計算子窗口相對父窗口左上角的偏移量;在WM_MOUSEMOVE消息中判斷鼠標左鍵是否按下,如果鼠標位於子窗口上且按下鼠標左鍵移動鼠標,則獲取鼠標的偏移並調用MoveWindow移動子窗口,制造一個子窗口跟隨鼠標移動的現象.