win32 sdk gui編程的一點經驗

一、系統維持一個全局惟一的消息隊列。web

二、各個建立了window的線程,每一個都有且只有一個消息隊列,甭管它建立了多少窗口。有多少建立了window的線程,就有多少消息隊列。相應就有多少消息循環。編程

三、鼠標、鍵盤等硬件靠各自驅動程序將用戶的輸入搞成message發到系統消息隊列。系統有消息循環,將其Dispatch到正確的線程消息隊列。GUI線程裏也有消息循環,將其最終Dispatch到正確的WNDPROC處理。ide

四、只要用戶有按鍵行爲,必然觸發且只觸發虛擬按鍵消息,如WM_KEYDOWN/WM_KEYUP/WM_SYSKEYDOWN/WM_SYSKEYUP。不會產生WM_CHAR消息,WM_CHAR消息永遠不會由敲擊鍵盤行爲產生。(不帶alt的按鍵稱爲nonsystem key)函數

五、消息循環中,通常TranslateMessage與DispatchMessage成一對,就是解決上面的問題,即TranslateMessage的惟一做用就是將WM_KEYDOWN/UP等虛擬按鍵消息作個解析,好比檢測到你按的是A鍵,就產生一個WM_CHAR消息並放到消息隊列裏,但正被解析的虛擬按鍵消息自己不發生任何變化,會繼續被傳給DispatchMessage去分發,顯然,這個新生的WM_CHAR消息只能在之後的新的消息循環裏才能獲得處理。即只要碰到WM_CHAR消息,它必定是由TranslateMessage函數產生的。固然應用程序主動製造的除外。並且,若是被解析的消息不是虛擬按鍵消息,那TranslateMessage啥也不幹。spa

六、搞清window之間的兩對關係:Parent與Child,Owner與Owned。父子關係中的關注點僅僅要知道:對child進行繪製時,所用的座標的參考系是其Parent的客戶區的左上角,child畫在其Parent客戶區以外的部分不可見,僅此無它。Owner就是擁有者,被它擁有的東西自稱Be Owned。Be Owned的東西永遠遮在其Owner之上,當其Owner最小化時,它自身會被隱藏。當其Owner被銷燬時,它自身也會被銷燬,即Owner是關係到其生死存亡的東西。通常Parent與Owner是同一個window,但理論上是能夠不一樣的。但你本身應搞清這兩種關係的區別。線程

七、鑑於上面這兩種關係的重要性,CreateWindow系列函數,都須要指定將被建立的window的Parent。若是一個window沒有Parent,或者其Parent是系統桌面Desktop(桌面是一個window,只是它沒標題欄而已),那麼這個window稱爲top-level窗口。orm

八、CreateWindow與CreateWindowEx的惟一區別是,後者多一個風格參數。CreateWindow裏用的窗口風格叫Window Style,以WS_開頭;CreateWindowEx裏多出來的風格叫Extended Window Style,以WS_EX_開頭。CreateWindow內部實現是CreateWindowEx(0, ...)隊列

九、Subclassing在win32 sdk編程裏全稱是Window Procedure Subclassing.別扯什麼子類化,我徹底不懂子類化在漢語裏是啥意思,也別扯什麼派生,這個和派生沒半毛錢關係。Subclassing只能在同一個進程裏進行,是指更換窗口類或具體窗口的WNDPROC,僅此而已,沒有其餘。進程

十、Superclassing。同上,全稱是Window Procedure Superclassing.也別跟我扯什麼超類化,在個人漢語裏徹底聽不懂。Superclassing的實質是填一張WNDCLASS單子,經過RegisterClass提交給系統註冊一下。看到沒,這實際上就是構造一個全新的窗口類而已嘛。只是,這張單子的大部份內容,咱們是從一張已有的WNDCLASS單子中拷貝過來的,手段是GetClassInfo函數。很顯然,既然咱們是提交一張新的WNDCLASS單子給系統,咱們天然得將單子上的hInstance項、lpszClassName項改爲咱們本身的。實際上GetClassInfo返回的單子中沒有填寫hInstance和lpszClassName這兩項,也沒有hMenu那一項。這裏咱們天然就得考慮一下menu的問題了,menu有什麼問題呢?事件

若是原先的窗口類沒有menu,咱們天然不需考慮menu了;若是原先的窗口類有menu,那麼在它的窗口類裏極有可能有對menu各item項的響應 ,即響應WM_COMMAND消息,case語句比對menu item的id,做出相應處理;若是咱們新的窗口過程也處理WM_COMMAND,並且處理完後不交給原先的窗口過程,那咱們天然不用擔憂新的窗口類的MENU的問題;但除了這種狀況呢?咱們必須保證當有WM_COMMAND消息傳遞給原先的窗口過程時,能正確運做,那咱們就必須將原先窗口類所用的menu資源克隆出一份,其各identifiers保持和原先一致,而後將新的menu資源填到咱們的新窗口類單子裏。固然,若是新老窗口類在同一個應用程序工程裏,共享一份已有的menu資源的話,menu問題也不成爲問題,新窗口類只需將那個menu資源填到單子裏就能夠了,無需拷貝一份menu資源,並且也應該這樣幹。

很明顯,由於咱們如今提交了一張新的WNDCLASS單子,因此固然可使用單子裏的cbClsExtra和cbWndExtra這倆玩意兒,這倆玩意兒的意思參考WNDCLASS的MSDN文檔。可是要注意了,原先的窗口過程裏可能有依賴於這倆玩意的代碼,因此爲保證原先的窗口過程能正常運做,咱們在使用這倆玩意兒時應作到,咱們須要多大的額外空間,則給cbClsExtra和cbWndExtra賦值時應指定各自原來的大小加上如今須要的大小,在新的窗口過程裏使用時也要注意咱們新的額外內存是在原先大小的額外內存結尾處開始的。

十一、子控件,也叫子窗口,是窗口。子控件在工做時,可能有時會通知或知會一下它的Parent,通知的方式只有一種,給Parent發消息。發的消息只有兩種:WM_COMMAND、WM_NOTIFY。notify比command能夠攜帶的信息量大。好比BUTTON控件被用戶單擊時,會給其Parent發一條WM_COMMAND消息,消息的lParent參數是這個控件的窗口句柄,消息的wParent高半部分整數值是BN_CLICKED,低半部分整數值是這個控件的id。父窗口想知道本身哪個子控件被點了的話,只須要在本身的窗口過程裏響應WM_COMMAND消息,並依據wParam和lParam這兩個消息參數作出正確的判斷。全部的父子窗口之間的交互都是經過這種簡單的方式,是否是簡單得不能再簡單了。不一樣的控件依據不一樣的事件給其Parent發的是WM_COMMAND仍是WM_NOTIFY,消息參數如何解釋等等這些東西,都在MSDN的控件本身那一頁上能夠直接查詢到。

十二、自繪。我不知道「自繪」這個詞是哪一個傻B發明的,反正它讓我長久以來一直沒搞懂啥叫「自繪」。「自繪」英文是Owner-Draw。看到沒,是Owner在Draw,Owner是啥,Owner是控件的擁有者,不是控件自身,所謂的Owner-Draw就是控件窗口須要繪製顯示在屏幕上時,會給其Owner發一條WM_DRAWITEM消息,通知其Owner,讓它負責把控件本身給畫出來。這尼瑪是自繪嗎???是本身繪製本身嗎???明明是讓別人畫本身!

看了大半夜的MSDN文檔,目前就總結出這些東西吧,接着看。

相關文章
相關標籤/搜索