這次寫這篇文章,還是重復我上兩篇的寫作風格,(數據結構篇“老調重提,利用SDK實現迷宮算法”,算法篇,“老調重提,利用SDK實現五子棋”),而現在這篇則是面向對象技術篇,當然還是老調重提!不過我們是利用面向對象技術實現Windows的SDK開發,對於剛開始學習Win32 SDK的VcKbase的朋友們,你們一定可以在此獲益!
這次,我會利用面向對象技術實現對Windows窗口的封裝!
剛開始編寫SDK的程序的時候,都需要寫重復的代碼,注冊窗口類( RegisterWindow ),創建窗口( CreateWindow ),進入消息循環,然後不停地根據消息類型增加消息處理函數!如此重復,解決方法就是Copy And Paste,但是也有很多的不便之處,比如說,我不想這個窗口用這個類名,我不想要這個窗口處理這個消息,哎呀,這個消息處理又忘記加了,真是的,加到哪兒,代碼密密麻麻的......當Framework(MFC,OWL,VCL,WTL,Qt......)出現的時候,這才擺脫這些煩勞事情,那時候,我認識Framework後,都不願意回到SDK的開發了!
擁有Framework後就不等於不需要SDK編程了,Framework是用面向對象的技術把這些基本,重復的開發封裝起來(還為開發者提供更加便利,更快,更強的開發了),所以這次我們也要用面向對象的方法對SDK封裝,當然,是演示簡單的封裝和普通的應用,讓初學Win32 SDK的開發者對面向對象技術的利用有一個認識,好了,我們開始了!
第一步,我們要封裝什麼,要找封裝的對象!(建立類)
第二步,確定封裝對象的特點,特征!(屬性)
第三步,確定對象的行為特點,有什麼動作!(方法)
Win32 SDK的基本對象是窗口,所以我們這次確定要封裝的是一個基本的窗口類,第二步,窗口類具有的特征(這個難,各取所需吧)這個演示程序就是一個窗口程序,所以這個程序的特征是要有Handle(程序的HINSTANCE, HWND),窗口的存在所需要的(WNDCLS,類名...),最後一個,方法當然是窗口要處理各種消息的函數(需要時才用,虛函數在這兒出現)
好了,先看看我們根據這三步設計出來的類!
整個類只有一個成員m_hwnd,和一個回調函數WindowProc,這個類就是作為我們所有的窗口的基類,所有窗口的消息都在這裡得到處理,每一個消息對應一個虛函數,當派生類的窗口類需要處理特定的消息時,只要重寫虛函數即可!比如,需要處理WM_PAINT消息時,只要派生類中重寫OnPaint,即可以處理該消息!
對於一個消息,一個對應的虛函數,聽起來很合理,但是在實際中,這是一個很不合理的設計,看過MFC設計的朋友,都應該知道MFC不是這樣設計的,它使用的是消息鏈表!因為虛函數是占空間的,對於每一個類,它需要維護一個虛函數表,當基類存在不需要處理的消息時,它還要維護這樣的消息對應的虛函數,是很浪費空間的,所以在實際的開發中,這樣的設計是很少采用的,但是我在這裡是演示一種對SDK封裝的方法而采用這種方式!(只是封裝了幾個消息,演示目的)
封裝後,創建一個窗口只需要幾行代碼!!
在類中我最主要實現的,也是最重要的,就是要把一個窗口的所有消息封裝起來,而這是如何做到的呢?每個窗口都不再存在一個唯一的窗口過程函數,取代的是每一個窗口對象都存在一個唯一的消息處理函數!C/C++中的指針特性幫我們做到了這一點.看如下代碼.
通過CreateWindowEx調用時傳入當前窗口對象指針,在WM_NCCREATE消息中,就實現了一個窗口類窗口消息處理函數的封裝,神不知鬼不覺得把全局消息處理的功能轉移到類中,你不再看到以前SDK開發時一大堆全局函數了!!每個窗口類自已負責自已的消息處理!
面向對象的最大優勢是繼承復用,現在我們已實現了一個非常簡單的窗口基類,現在,通過繼承這個簡單基類,實現一個新的窗口類,這個窗口類有菜單,處理WM_PAINT消息,看看如下繼承類:
只需要幾行代碼,就可以實現原來的SDK的需要幾十行代碼實現的功能,因為繼承已經封裝好的基類!
上面對窗口的封裝是簡單的,但是也說明了對Windows窗口封裝的一些要點,也許會對你有一些幫助!!
學習Windows編程,SDK是一個基礎,只有在此扎實的基礎上,才能在Windows平台上進行技術深耕,這也是我的"老調重提"系列文章目的!
本文配套源碼