Windows编程之使用外部动态链接库——纸牌
C語言功能強(qiáng)大的一個(gè)重要原因是因?yàn)榫哂胸S富的庫函數(shù),例如字符串處理有string庫,數(shù)學(xué)處理有math庫。微軟公司對程序庫的支持又更進(jìn)一步,提供了豐富的動(dòng)態(tài)鏈接庫。下面以微軟操作系統(tǒng)內(nèi)嵌的紙牌鏈接庫為例寫一個(gè)簡單的小程序。
由于我們已經(jīng)較為理解Windows應(yīng)用程序的框架了,因此這次拓展練習(xí)將所有的代碼由手工完成一個(gè)最簡潔的框架。
在WinLearn中創(chuàng)建新的Win32 Application,項(xiàng)目名叫做WinStep6。在選項(xiàng)中注意選擇簡單的應(yīng)用程序。
 
 圖1 創(chuàng)建簡單應(yīng)用程序
初始的代碼應(yīng)該是這樣的:
 
 我們首先在WinMain中注冊一個(gè)窗口類。窗口類的代碼可以從早期的WinStep1中的MyRegistClass函數(shù)中復(fù)制過來:
 
 注意其中刪除了和資源相關(guān)的代碼。
然后通過剛注冊的WinStep6窗口類,生成紙牌的主窗口。相應(yīng)的代碼可以從WinStep1中的InitInstance函數(shù)中復(fù)制過來。
 
 向主函數(shù)中增加主循環(huán)代碼。主循環(huán)代碼可以從WinStep1中的WinMain復(fù)制過來。
 
 向程序中添加消息處理函數(shù)MainProc。消息處理函數(shù)可以由WinStep1中的MainWndProc復(fù)制并改編而來。因?yàn)槲覀儾挥锰幚聿藛魏涂旖萱I,因此將相關(guān)的代碼刪除了。剩下的框架如下:
 
 將一些變量的聲明,函數(shù)的聲明補(bǔ)充完整,這個(gè)最簡單的框架就可以運(yùn)行了。
 
 我們自定義的框架程序運(yùn)行結(jié)果:
 
 在這個(gè)最簡框架基礎(chǔ)上,我們來做一個(gè)簡單的紙牌顯示和操作的演示。
微軟提供的紙盤鏈接庫叫做cards.dll,通常在Windows\System32目錄下。若是找不到該鏈接庫,可以從網(wǎng)絡(luò)或者網(wǎng)絡(luò)課堂下載。
動(dòng)態(tài)鏈接庫(.dll)和常見的靜態(tài)鏈接庫(.lib,例如math.lib)類似,都存放了函數(shù)的二進(jìn)制代碼。但是動(dòng)態(tài)鏈接庫要多一些步驟。首先是程序執(zhí)行時(shí)根據(jù)需要加載動(dòng)態(tài)鏈接庫,和程序不再需要庫函數(shù)時(shí)從內(nèi)存中卸載動(dòng)態(tài)鏈接庫以節(jié)約內(nèi)存開銷。這兩個(gè)函數(shù)分別是LoadLibrary和FreeLibrary。在剛才的最簡框架基礎(chǔ)上添加對cards的打開和關(guān)閉:
 
 程序片段34 動(dòng)態(tài)鏈接庫的加載
 
 程序片段35 動(dòng)態(tài)鏈接庫的釋放
然后需要從動(dòng)態(tài)鏈接庫中獲得函數(shù)的入口。
微軟的cards.dll提供了5個(gè)函數(shù)來繪制紙牌,和大多數(shù)靜態(tài)鏈接庫不同,微軟的cards.dll沒有提供頭文件,因此需要我們手工建立這5個(gè)函數(shù)的聲明。一般而言,我們應(yīng)該為cards.dll的函數(shù)專門建立一個(gè)cards.h頭文件,但是為了簡潔起見,在WinStep6中,僅僅將這幾個(gè)頭文件放置在WinStep6.cpp開頭的位置。
 
 并且在函數(shù)聲明后面立即為這5個(gè)函數(shù)建立全局函數(shù)指針備用:
 
 注意這5個(gè)typedef定義了一種函數(shù)指針類型,舉例而言,第一行的函數(shù)定義如下:
 
 這行定義了一個(gè)接受兩個(gè)整型指針作為形參并且返回BOOL類型(其實(shí)BOOL就是int類型)的函數(shù)指針,凡是這樣的函數(shù)指針都可以叫做pfcdtInit類型。
因此下面的全局變量定義中,使用pfcdtInit定義了一個(gè)函數(shù)指針:
 
 在應(yīng)用程序設(shè)計(jì)中,這樣的書寫方式很常見,希望同學(xué)們能夠模仿并書寫自己的函數(shù)指針定義。
在主函數(shù)中,等動(dòng)態(tài)鏈接庫加載成功后,便可以從動(dòng)態(tài)鏈接庫中獲得這5個(gè)函數(shù)的入口地址(即給前述5個(gè)指針變量賦值)
 
 在正式繪圖前,需要知道所繪制的一張完整的紙牌的大小(所占用的像素)。這使用cdtInit函數(shù)可以獲得。
因?yàn)樵诶L圖中會(huì)反復(fù)用到紙牌的大小,因此將這大小數(shù)據(jù)以全局變量形式存放:
 
 并且在主函數(shù)中獲得牌的大小:
 
 下面在WM_PAINT中繪制我們的第一張牌:紅桃K。注意為了后面的繪圖,下面的代碼中增加了一個(gè)矩形結(jié)構(gòu)體RECT,并且在繪圖代碼WM_PAINT中增加了獲得窗口位置大小的信息的代碼。
 
 現(xiàn)在程序可以運(yùn)行并且繪制一張圖片了。
 
 繪圖函數(shù)cdtDraw的參數(shù)很直接:hdc表示在哪個(gè)窗口繪圖,20,20表示左上角20,20坐標(biāo)位置;50表示第50號(hào)牌。cards每張牌均有一個(gè)牌號(hào),若定義花色為suit(03),點(diǎn)數(shù)為face(012),則有公式card = suit + face * 4例如紅桃K的卡號(hào)為2+12×4=50。卡號(hào)53~68為各種牌的背面。type為顯示類型,type=0時(shí)表示顯示正面,這時(shí)候卡號(hào)card只能是0~51,當(dāng)type=1時(shí)表示顯示牌背面,這時(shí)候卡號(hào)card只能是53~68.使用其他卡號(hào)將繪制錯(cuò)誤的牌。
總結(jié)
以上是生活随笔為你收集整理的Windows编程之使用外部动态链接库——纸牌的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 去哪儿旅行怎么退票在哪取消(汉典去字的基
 - 下一篇: 好看漂亮带符号的微信昵称100个