本科畢業(yè)論文--鍵盤(pán)音樂(lè)軟件的研究與開(kāi)發(fā)_第1頁(yè)
已閱讀1頁(yè),還剩31頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、<p><b>  本科生畢業(yè)論文</b></p><p>  鍵盤(pán)音樂(lè)軟件的研究與開(kāi)發(fā)</p><p>  2011年5月23日</p><p><b>  畢業(yè) 論文開(kāi)題報(bào)告</b></p><p><b>  摘 要:</b></p><p&

2、gt;  在許多系統(tǒng)中,出于安全或其他原因,常常需要隨時(shí)對(duì)鍵盤(pán)進(jìn)行監(jiān)控,利用鉤子技術(shù)編寫(xiě)的應(yīng)用程序能夠很好的達(dá)到這個(gè)目的。本文就制作鍵盤(pán)音樂(lè)軟件進(jìn)行闡釋。在軟件運(yùn)行過(guò)程中,用戶(hù)在鍵盤(pán)上的按鍵操作就會(huì)播放聲音文件。</p><p>  本系統(tǒng)開(kāi)發(fā)的鍵盤(pán)音樂(lè)軟件是一種 利用鉤子技術(shù)編寫(xiě)的鉤子軟件,用于隨時(shí)監(jiān)控用戶(hù)的按鍵操作。鍵盤(pán)音樂(lè)軟件主要功能是利用鉤子技術(shù)監(jiān)控系統(tǒng)的鍵盤(pán)。用戶(hù)在鍵盤(pán)上的按鍵操作就會(huì)播放相應(yīng)的聲音文件

3、,不管焦點(diǎn)是否在本軟件中,一方面實(shí)現(xiàn)了對(duì)鍵盤(pán)的監(jiān)控,另一方面也改善了鍵盤(pán)按鍵聲音。</p><p>  關(guān)鍵詞:動(dòng)態(tài)鏈接庫(kù);鉤子;鉤子函數(shù);資源</p><p><b>  Abstract</b></p><p>  In many systems, we always need to monitor the keyboard for the

4、 reason of security. The hook technology can reach the aim easily. In this article, we give an explanation of how to make a keyboard sound software. It will play the wave files when user press any key of the keyboard whi

5、le it in processing.</p><p>  It is a software, basing on the hook technology. Keyboard Music software can monitor the operation of the user. Whether the focus in the current process, it will play the wave f

6、iles when user press any key. The user can monitor the keyboard and change the sound of it.</p><p>  Key Words: Dynamic link library;Hook;Hook Function;Resource</p><p><b>  目 錄</b>&l

7、t;/p><p>  中文摘要………………………………………………………………………Ⅰ </p><p>  英文摘要………………………………………………………………………Ⅱ</p><p>  目錄……………………………………………………………………………Ⅲ</p><p>  1前言……………………………………………………………………………1

8、</p><p>  2系統(tǒng)開(kāi)發(fā)背景………………………………………………………………2</p><p>  3開(kāi)發(fā)工具介紹………………………………………………………………4</p><p>  3.1開(kāi)發(fā)工具及數(shù)據(jù)庫(kù)系統(tǒng)的選擇…………………………………………4</p><p>  3.1.1 ASP簡(jiǎn)介………………………………………………

9、…………4</p><p>  3.1.2 ASP特點(diǎn) ………………………………………………………4</p><p>  3.1.3 ASP的工作原理 …………………………………………… 5</p><p>  3.1.4 SQL Server軟件概述 ………………………………………5</p><p> 

10、 3.2軟件運(yùn)行環(huán)境設(shè)置………………………………………………………5</p><p>  4 系統(tǒng)的整體設(shè)計(jì)………………………………………………………………7</p><p>  4.1 需求分析 ………………………………………………………………7</p><p>  4.2系統(tǒng)設(shè)計(jì)思想……………………………………………………………7</p>&l

11、t;p>  4.3系統(tǒng)總體結(jié)構(gòu)圖…………………………………………………………7</p><p>  4.4系統(tǒng)功能描述……………………………………………………………8</p><p>  4.5功能模塊劃分……………………………………………………………9</p><p>  4.6系統(tǒng)流程分析 …………………………………………………………10</p>

12、;<p>  4.7系統(tǒng)功能模塊圖 ………………………………………………………11</p><p>  4.8系統(tǒng)網(wǎng)絡(luò)數(shù)據(jù)庫(kù)的建立 ………………………………………………12</p><p>  4.8.1系統(tǒng)數(shù)據(jù)源的設(shè)置………………………………………………12</p><p>  4.8.2建立數(shù)據(jù)庫(kù)表……………………………………………………13&l

13、t;/p><p>  5系統(tǒng)的實(shí)現(xiàn)………………………………………………………………16</p><p>  5.1客戶(hù)端… … ……………………………………………………………16</p><p>  5.1.1 會(huì)員注冊(cè)…………………………………………………………16</p><p>  5.1.2 購(gòu)物車(chē) ……………………………………

14、……………………17</p><p>  5.1.3 商品查詢(xún) ………………………………………………………19</p><p>  5.2后臺(tái)管理端 ……………………………………………………………21</p><p>  5.2.1 商品的添加………………………………………………………22</p><p>  5.2.2 商品的審查

15、………………………………………………………25</p><p>  5.2.3 訂單的審查………………………………………………………26</p><p>  5.2.4 會(huì)員的審查………………………………………………………27</p><p>  5.2.5 管理員添加………………………………………………………29</p><p>  

16、5.2.6 管理員審查………………………………………………………30</p><p>  5主要技術(shù)難點(diǎn)及解決方法…………………………………………………32 </p><p>  7結(jié)束語(yǔ)……………………………………………………………………33</p><p>  參考文獻(xiàn)……………………………………………

17、………………………34</p><p>  致 謝…………………………………………………………………………35</p><p><b>  1 前 言</b></p><p>  為用戶(hù)提供已經(jīng)驗(yàn)證的代碼作為程序組件,歷來(lái)是各種程序開(kāi)發(fā)工具的追求。在面向過(guò)程的程序設(shè)計(jì)工具中,程序組件以函數(shù)的形式向用戶(hù)提供。一個(gè)功能強(qiáng)大的程序設(shè)計(jì)工具,往往附加有

18、豐富的函數(shù)庫(kù)。C語(yǔ)言就是這樣的一種程序開(kāi)發(fā)工具。在面向?qū)ο蟮某绦蛟O(shè)計(jì)工具中,程序組件則以類(lèi)的形式向用戶(hù)提供。一個(gè)功能強(qiáng)大的程序設(shè)計(jì)工具,往往附加有豐富的類(lèi)庫(kù)。Visual C++就是這樣的一個(gè)程序開(kāi)發(fā)工具,它的Microsoft基本類(lèi)庫(kù)——MFC 能為用戶(hù)提供大量預(yù)先編好的類(lèi)及支持代碼。這些類(lèi)封裝了大量的標(biāo)準(zhǔn)Windows 編程中使用的處理函數(shù)和數(shù)據(jù),從而大大簡(jiǎn)化了用戶(hù)的Windows編程工具。程序設(shè)計(jì)是計(jì)算機(jī)的靈魂,程序設(shè)計(jì)是計(jì)算機(jī)的

19、生命的源泉。綜觀歷史,計(jì)算機(jī)的進(jìn)步基本上是沿三條主線(xiàn)不斷進(jìn)步的:一是計(jì)算機(jī)元器件的進(jìn)步,二是計(jì)算機(jī)體系結(jié)構(gòu)的進(jìn)步,三是程序設(shè)計(jì),開(kāi)發(fā)方法和開(kāi)發(fā)工具的進(jìn)步。開(kāi)發(fā)方法和開(kāi)發(fā)工具作為程序設(shè)計(jì)的兩個(gè)車(chē)輪,相輔相成的將程序設(shè)計(jì)不斷的帶向新的水平。</p><p>  從程序設(shè)計(jì)方法上看,程序設(shè)計(jì)已經(jīng)經(jīng)過(guò)了面向過(guò)程、面向數(shù)據(jù)、面向?qū)ο?、面向資源幾個(gè)階段。從程序的表述上來(lái)看,程序設(shè)計(jì)經(jīng)過(guò)了如下階段:代碼編程,表格編程和圖形編程

20、。代碼編程是使用字符編碼書(shū)寫(xiě)源程序,既可以書(shū)寫(xiě)面向過(guò)程的程序,又可以書(shū)寫(xiě)面向?qū)ο蟮某绦?。表格是使用表格或表示圖標(biāo)設(shè)計(jì)程序邏輯,通過(guò)圖形編輯自動(dòng)產(chǎn)生程序代碼,主要用于產(chǎn)生面向數(shù)據(jù)的程序設(shè)計(jì)。圖形編程是由于通行用戶(hù)界面(GUI)的出現(xiàn)而產(chǎn)生的程序開(kāi)發(fā)平臺(tái)。 主要使用圖形單元構(gòu)建應(yīng)用程序。隨著GUI 技術(shù)的進(jìn)一步發(fā)展和系統(tǒng)提供的構(gòu)建的豐富,工具軟件包越來(lái)越多,系統(tǒng)資源的利用成為軟件開(kāi)發(fā)的關(guān)鍵,面向資源的應(yīng)用程序開(kāi)發(fā)應(yīng)運(yùn)而生。這條發(fā)展線(xiàn)路遵循著

21、一個(gè)代碼隱藏的原則。VC++ 正是循著這樣一條軌跡展現(xiàn)出的時(shí)代產(chǎn)品。它把WINDOWS 統(tǒng)一而又漂亮的界面風(fēng)格,面向?qū)ο蟮某绦蛟O(shè)計(jì)方法和面向資源的環(huán)境結(jié)合在一起,形成一個(gè)功能強(qiáng)大而復(fù)雜的C++編譯器。它能提供簡(jiǎn)單而又高效的操作方式 ,高效的內(nèi)存管理與設(shè)備無(wú)關(guān)的圖形接口,數(shù)據(jù)共享和多任務(wù)的運(yùn)行機(jī)制,同時(shí)又提供了一系列功能強(qiáng)大的開(kāi)發(fā)工具和內(nèi)容豐富的開(kāi)發(fā)資源。</p><p>  主要研究?jī)?nèi)容;本課題軟件主要研究VC+

22、+中的鉤子函數(shù)及對(duì)動(dòng)動(dòng)態(tài)鏈接庫(kù)的使用。動(dòng)態(tài)鏈接庫(kù)(DLL:Dynamic-Link Library)是Windows環(huán)境中軟件開(kāi)發(fā)的重要組成部分也是分布式計(jì)算中的組件對(duì)象模型(COM)技術(shù)的基本支柱之一。使用動(dòng)態(tài)鏈接庫(kù)就可以靈活的設(shè)計(jì)與實(shí)現(xiàn)各類(lèi)軟件系統(tǒng)。</p><p>  鍵盤(pán)奏鳴曲軟件的開(kāi)發(fā)過(guò)程,其中用到的最關(guān)鍵的技術(shù)就是鉤子技術(shù)。通過(guò)鉤子技術(shù),不但可以截獲鍵盤(pán)的輸入,還可以截獲鼠標(biāo)等的其他系統(tǒng)信息。鍵盤(pán)奏鳴

23、曲軟件的主體開(kāi)發(fā)環(huán)境的選擇是Visual C++ 6.0,選擇的理由如下:(1)本軟件的技術(shù)難度很大 ,特別是鉤子(Hook)技術(shù),應(yīng)用Visual C++ 6.0可以輕松的實(shí)現(xiàn)系統(tǒng)的調(diào)用。(2)由于本軟件規(guī)模較小,所以選用基于Visual C++ 6.0的DLL技術(shù),減少軟件所占的內(nèi)存空間,效率更高。本軟件看似簡(jiǎn)單,實(shí)現(xiàn)鍵盤(pán)奏鳴很簡(jiǎn)單,只要在鍵盤(pán)的KeyUp、KeyDown等事件中添加事件代碼,判斷用戶(hù)按鍵,根據(jù)鍵盤(pán)碼識(shí)別出各鍵,

24、播放不同的聲音文件即可。事情并非如此簡(jiǎn)單。用上面的方法,當(dāng)本軟件是在當(dāng)前進(jìn)程時(shí),鍵盤(pán)奏鳴的功能可以實(shí)現(xiàn),但是當(dāng)打開(kāi)其他應(yīng)用程序進(jìn)行一些操作時(shí),由于本軟件不再成為鍵盤(pán)輸入的焦點(diǎn),鍵盤(pán)奏鳴的功能也就消失了。而我們需要的事鍵盤(pán)的系統(tǒng)監(jiān)控,只要本軟件在運(yùn)行,無(wú)論目前計(jì)算機(jī)在做什么,都能檢測(cè)到用戶(hù)按鍵的行為并作出反應(yīng),這就要用到Hook技術(shù)。</p><p>  作為一名學(xué)生,在學(xué)習(xí)過(guò)程中發(fā)現(xiàn),在許多系統(tǒng)中,出于安全或其他

25、原因,常常需要隨時(shí)對(duì)鍵盤(pán)進(jìn)行監(jiān)控,利用鉤子技術(shù)編寫(xiě)的應(yīng)用程序能夠很好的達(dá)到這個(gè)目的。我在這里就制作一個(gè)鍵盤(pán)音樂(lè)軟件進(jìn)行闡釋。即在軟件運(yùn)行過(guò)程中,用戶(hù)在鍵盤(pán)上的按鍵操作就會(huì)播放聲音文件 ,對(duì)本軟件稍加擴(kuò)展就是一個(gè)完整的鍵盤(pán)監(jiān)控軟件。我使用的是目前在軟件開(kāi)發(fā)領(lǐng)域較為熱門(mén)的軟件開(kāi)發(fā)工具Visual C++。本課題的選用是基于目前軟件開(kāi)發(fā)行業(yè)現(xiàn)狀結(jié)合我將來(lái)所要從事的工作,所以選用較為熱門(mén)的軟件開(kāi)發(fā)工具VC++。</p><p

26、><b>  2需求分析</b></p><p>  軟件工程包含技術(shù)和管理兩方面的內(nèi)容,是管理與技術(shù)的緊密結(jié)合。目前軟件工程方法學(xué)分為傳統(tǒng)方法學(xué)和面向?qū)ο蠓椒▽W(xué)。</p><p><b>  2.1業(yè)務(wù)需求分析</b></p><p>  傳統(tǒng)的軟件工程方法學(xué)使用結(jié)構(gòu)化分析技術(shù),完成分析用戶(hù)需求工作。需求分析要了解

27、用戶(hù)的情況,接下來(lái)通過(guò)與用戶(hù)交流,對(duì)用戶(hù)的基本要求反復(fù)細(xì)化,以得出對(duì)目標(biāo)系統(tǒng)的完整、準(zhǔn)確和具體的需求。需求分析是為了發(fā)現(xiàn)用戶(hù)的真正需求,首先應(yīng)從宏觀角度調(diào)查、分析用戶(hù)所面臨的問(wèn)題,也就是說(shuō),需求分析的第一步是盡可能準(zhǔn)確地了解用戶(hù)當(dāng)前的情況和需要解決的問(wèn)題。鍵盤(pán)音樂(lè)軟件針對(duì)以下客戶(hù)群:</p><p> ?。?)計(jì)算機(jī)或網(wǎng)絡(luò)管理人員進(jìn)行計(jì)算機(jī)鍵盤(pán)的監(jiān)控。</p><p> ?。?)辦公室人員

28、可以應(yīng)用本軟件調(diào)節(jié)心情,改變單調(diào)的工作節(jié)奏。</p><p> ?。?)有意學(xué)習(xí)和研究鉤子技術(shù),使軟件實(shí)現(xiàn)一些特殊功能的程序員。</p><p>  鍵盤(pán)音樂(lè)軟件主要功能是利用鉤子技術(shù)監(jiān)控系統(tǒng)的鍵盤(pán)。用戶(hù)在鍵盤(pán)上的按鍵操作就會(huì)播放相應(yīng)的聲音文件,而不管焦點(diǎn)是否在本軟件中,一方面實(shí)現(xiàn)了對(duì)鍵盤(pán)的監(jiān)控,另一方面也改善了鍵盤(pán)按鍵的單調(diào),因?yàn)榭梢圆シ挪煌穆曇?,增加趣味性。把鍵盤(pán)監(jiān)控和休閑娛樂(lè)兩者有

29、機(jī)結(jié)合,這樣才能更好的為用戶(hù)服務(wù)。</p><p><b>  2.2系統(tǒng)特點(diǎn)</b></p><p>  鍵盤(pán)音樂(lè)軟件是一種利用鉤子技術(shù)編寫(xiě)的鉤子軟件,用于隨時(shí)監(jiān)控用戶(hù)的按鍵操作。它有以下幾個(gè)特色。</p><p><b>  1.功能封裝 </b></p><p>  本軟件中的主要功能都是通過(guò)

30、一個(gè)DLL文件實(shí)現(xiàn)的,在其中封裝了鍵盤(pán)監(jiān)控和發(fā)音等功能。需要啟動(dòng)鍵盤(pán)音樂(lè)功能時(shí)調(diào)用StartHook函數(shù),需要停止鍵盤(pán)音樂(lè)功能時(shí)調(diào)用StopHook即可。</p><p>  2.利用鉤子技術(shù)實(shí)現(xiàn)系統(tǒng)的鍵盤(pán)監(jiān)控</p><p>  只要啟動(dòng)鍵盤(pán)音樂(lè)軟件后,不管輸入焦點(diǎn)是否在本軟件中,按鍵的過(guò)程中都會(huì)播放聲音文件。</p><p>  鍵盤(pán)音樂(lè)軟件主要功能是利用鉤子技

31、術(shù)監(jiān)控系統(tǒng)的鍵盤(pán)。用戶(hù)在鍵盤(pán)上的按鍵操作就會(huì)播放相應(yīng)的聲音文件,而不管焦點(diǎn)是否在本軟件中,一方面實(shí)現(xiàn)了對(duì)鍵盤(pán)的監(jiān)控,另一方面也改善了鍵盤(pán)按鍵的單調(diào),因?yàn)榭梢圆シ挪煌穆曇簦黾尤の缎浴?lt;/p><p><b>  3系統(tǒng)的整體設(shè)計(jì)</b></p><p>  3.1 軟件工具的選型</p><p>  鍵盤(pán)音樂(lè)軟件的主體開(kāi)發(fā)環(huán)境的選擇是Vis

32、ual C++ 6.0,選擇的理由如下:</p><p> ?。?) 本軟件的技術(shù)難度很大 ,特別是鉤子(Hook)技術(shù),應(yīng)用Visual C++ 6.0可以輕松的實(shí)現(xiàn)系統(tǒng)的調(diào)用。</p><p>  (2) 由于本軟件規(guī)模較小,所以選用基于Visual C++ 6.0的DLL技術(shù),減少軟件所占的內(nèi)存空間,效率更高。</p><p>  因?yàn)楸拒浖婕暗倪@兩大技術(shù)

33、,我選擇了Visual C++6.0作為主體開(kāi)發(fā)環(huán)境,這樣可以更加方便快捷地開(kāi)發(fā)設(shè)計(jì)本軟件。研發(fā)本軟件時(shí)我用的個(gè)人電腦裝的操作系統(tǒng)為Windows XP,內(nèi)存為256M,硬盤(pán)80G。</p><p>  Visual C++ 6.0中的鉤子(Hook)技術(shù)簡(jiǎn)介:</p><p>  鉤子技術(shù)(Hook)是一段以處理系統(tǒng)消息的程序,通過(guò)系統(tǒng)調(diào)用,將其掛入系統(tǒng)。鉤子的種類(lèi)有很多,每種鉤子可以截

34、獲并處理相應(yīng)的消息,每當(dāng)特定的消息發(fā)出,在到達(dá)目的窗口之前,鉤子程序先行截獲該消息,得到對(duì)此消息的控制權(quán)。此時(shí)在鉤子函數(shù)中就可以對(duì)截獲的消息進(jìn)行加工處理,甚至可以強(qiáng)制結(jié)束消息的傳遞。從鉤子的本質(zhì)來(lái)看,可以?xún)?yōu)先截獲操作系統(tǒng)的各種消息進(jìn)行處理,所以它幾乎無(wú)所不能,因?yàn)閃indows的應(yīng)用程序都是基于消息驅(qū)動(dòng)的,應(yīng)用程序的操作都依賴(lài)于他所得到的消息類(lèi)型及內(nèi)容。</p><p>  如果Hook過(guò)程在應(yīng)用程序中實(shí)現(xiàn),若應(yīng)

35、用程序不是當(dāng)前窗口時(shí),該Hook就不起作用;如果Hook在DLL中實(shí)現(xiàn),程序在運(yùn)行中動(dòng)態(tài)調(diào)用它,它能實(shí)時(shí)對(duì)系統(tǒng)進(jìn)行監(jiān)控。根據(jù)需要,我采用的是在DLL中實(shí)現(xiàn)Hook的方式。</p><p>  Visual C++ 6.0中的動(dòng)態(tài)鏈接庫(kù)(DLL)簡(jiǎn)介:</p><p>  (1)用DLL可以實(shí)現(xiàn)不同程序之間的代碼重用。普通的函數(shù)庫(kù)也可以實(shí)現(xiàn)不同應(yīng)用程序之間的代碼重用:將一些通用程序的代碼使用

36、一些比較獨(dú)立的函數(shù)來(lái)實(shí)現(xiàn),這樣在不同應(yīng)用程序的源代碼中進(jìn)行直接調(diào)用即可。若在多個(gè)同樣的程序執(zhí)行時(shí),則系統(tǒng)中就保留了許多重復(fù)的代碼副本,就會(huì)造成內(nèi)存資源的浪費(fèi)。在這種情況下,若使用DLL,則實(shí)現(xiàn)的就是動(dòng)態(tài)鏈接,并不是將庫(kù)代碼拷貝,而只是在程序中記錄了函數(shù)的入口點(diǎn)和接口,并只在程序執(zhí)行時(shí)才將庫(kù)代碼裝入內(nèi)存。這樣,不管有多少個(gè)程序同時(shí)使用某個(gè)DLL,內(nèi)存中都只有這個(gè)DLL 的一個(gè)副本。當(dāng)沒(méi)有程序使用這個(gè)DLL時(shí),系統(tǒng)就將其移出,從而釋放了相應(yīng)

37、的內(nèi)存空間。</p><p> ?。?)DLL技術(shù)對(duì)于開(kāi)發(fā)大型軟件系統(tǒng)有很多可用之處。在大型軟件系統(tǒng)中,如果所有的功能均使用一個(gè)可執(zhí)行文件來(lái)完成,則最終的可執(zhí)行文件將會(huì)非常龐大,而且其中還將有許多重復(fù)的功能。另外,龐大的可執(zhí)行文件對(duì)于軟件的開(kāi)發(fā)與維護(hù)也將是一件非常困難的事情。一個(gè)比較好的方法就是使用DLL,將軟件系統(tǒng)分成一個(gè)主框架程序和一系列DLL。這樣將會(huì)大大降低軟件開(kāi)發(fā)的復(fù)雜度,同時(shí)也可以減少開(kāi)發(fā)的工作量。另

38、外,由于每個(gè)模塊都比較小,而且都相對(duì)獨(dú)立,在運(yùn)行時(shí)也可以提高訪(fǎng)問(wèn)的速度,增加軟件的運(yùn)行效率。</p><p> ?。?)DLL可以方便的實(shí)現(xiàn)軟件的多國(guó)語(yǔ)言版本。使用DLL就可以方便地支持世界各國(guó)的語(yǔ)言。程序員將依賴(lài)于語(yǔ)言的函數(shù)和資源分離出來(lái),而專(zhuān)門(mén)放進(jìn)不同的DLL中去。比如,對(duì)于中文英文和法文,各自實(shí)現(xiàn)一個(gè)相對(duì)的DLL。在軟件用戶(hù)安裝軟件時(shí),將提示選擇相應(yīng)的語(yǔ)言版本來(lái)安裝。所以使用DLL是實(shí)現(xiàn)軟件商品國(guó)際化的一項(xiàng)

39、技術(shù)。</p><p><b>  3.2 功能分析</b></p><p>  鍵盤(pán)音樂(lè)軟件的細(xì)分功能如下:</p><p>  (1) 定義鉤子函數(shù)。</p><p> ?。?) 在鉤子函數(shù)中實(shí)現(xiàn)所需功能,即無(wú)論軟件是否是當(dāng)前進(jìn)程,都能夠進(jìn)行鍵盤(pán)監(jiān)控,判斷出用戶(hù)所按鍵是哪個(gè)鍵,根據(jù)用戶(hù)按鍵的不同,播放不同的文件。&

40、lt;/p><p> ?。?) 能夠根據(jù)需要啟動(dòng)和停止鍵盤(pán)奏鳴功能,即安裝鉤子和卸載鉤子。</p><p> ?。?) 定義并使用共享數(shù)據(jù)段。</p><p>  3.3 模塊分工設(shè)計(jì)</p><p>  本軟件分成兩個(gè)模塊,一部分是DLL模塊,里面利用鉤子技術(shù)完成鍵盤(pán)監(jiān)控和播放聲音文件的功能;</p><p>  另一

41、部分是界面調(diào)用模塊,調(diào)用DLL啟動(dòng)和停止鍵盤(pán)奏鳴功能。</p><p>  圖3-1 模塊分工設(shè)計(jì)圖</p><p>  如圖3-1所示,上面的一部分是DLL模塊 ,AppWizard 是用類(lèi)別名稱(chēng)和源程序名產(chǎn)生 Windows 應(yīng)用程序的一個(gè)工作向?qū)Вㄟ^(guò)動(dòng)態(tài)鏈接庫(kù)(DLL)經(jīng)編譯生成.LIB文件,然后和界面鏈接生成.exe運(yùn)行程序。</p><p>  4系統(tǒng)的

42、技術(shù)難點(diǎn)及解決方法</p><p><b>  4.1鉤子技術(shù)</b></p><p>  本軟件看似簡(jiǎn)單,實(shí)現(xiàn)鍵盤(pán)奏鳴很簡(jiǎn)單,只要在鍵盤(pán)的KeyUp、KeyDown等事件中添加事件代碼,判斷用戶(hù)按鍵,根據(jù)鍵盤(pán)碼識(shí)別出各鍵,播放不同的聲音文件即可。事情并非如此簡(jiǎn)單。用上面的方法,當(dāng)本軟件是在當(dāng)前進(jìn)程時(shí),鍵盤(pán)奏鳴的功能可以實(shí)現(xiàn),但是當(dāng)打開(kāi)其他應(yīng)用程序進(jìn)行一些操作時(shí),由于

43、本軟件不再成為鍵盤(pán)輸入的焦點(diǎn),鍵盤(pán)奏鳴的功能也就消失了。而我們需要的是鍵盤(pán)的系統(tǒng)監(jiān)控,只要本軟件在運(yùn)行,無(wú)論目前計(jì)算機(jī)在做什么,都能檢測(cè)到用戶(hù)按鍵的行為并作出反應(yīng),這就要用到Hook技術(shù)。</p><p>  鉤子技術(shù)在很多特殊軟件中廣泛應(yīng)用,例如,金山詞霸的“取詞”功能是很奇妙的,這里就用到了鉤子技術(shù),類(lèi)似的軟件還有中文之星東方快車(chē)譯典通等等......,雖然不同的軟件的具體實(shí)現(xiàn)不同,但大致原理使相同的。<

44、;/p><p>  1.系統(tǒng)鉤子和線(xiàn)程鉤子</p><p>  在WINDOWS中,鉤子有兩種,一種是系統(tǒng)鉤子(RemoteHook),它對(duì)消息的監(jiān)控是整個(gè)系統(tǒng)范圍,另一種是線(xiàn)程鉤子(Local Hook) ,它的攔截范圍只有進(jìn)程內(nèi)部的消息。</p><p>  對(duì)于系統(tǒng)鉤子,其鉤子函數(shù)(HookFuction)應(yīng)在Windows系統(tǒng)的動(dòng)態(tài)連接庫(kù)DLL中實(shí)現(xiàn)。</

45、p><p>  設(shè)計(jì)本系統(tǒng)時(shí),Windows先在系統(tǒng)內(nèi)存中創(chuàng)建一個(gè)數(shù)據(jù)結(jié)構(gòu),該數(shù)據(jù)結(jié)構(gòu)包含了鉤子的相關(guān)信息,然后把該結(jié)構(gòu)體加到已經(jīng)存在的鉤子鏈表中去。當(dāng)發(fā)生敲擊鍵盤(pán)事件時(shí),如果安裝的是一個(gè)局部鉤子,當(dāng)前進(jìn)程的鉤子函數(shù)將被調(diào)用。如果是一個(gè)遠(yuǎn)程鉤子,系統(tǒng)就必須把鉤子函數(shù)插入到其他進(jìn)程的地址空間,要做到這一點(diǎn)就必須在一個(gè)動(dòng)態(tài)鏈接庫(kù)中去。但有兩個(gè)例外,就是日志鉤子和日志回放鉤子,它是一種比較特殊的鉤子,它可以?huà)燧d到系統(tǒng)范圍內(nèi)

46、的任何進(jìn)程中,而且不需要另外編寫(xiě)一個(gè)DLL來(lái)映射到其他進(jìn)程的內(nèi)存空間中。</p><p><b>  2.鉤子的分類(lèi)</b></p><p>  安裝不同的鉤子,可以截獲監(jiān)視不同的消息類(lèi)型,有針對(duì)性地對(duì)所需要的消息進(jìn)行過(guò)濾和處理,鉤子主要分為以下幾類(lèi):</p><p>  (1)WH_CALLWNDPROC 和 WH_CALLWNDPROCRE

47、T Hooks</p><p>  WH_CALLWNDPROC 和 WH_CALLWNDPROCRET Hooks使你可以監(jiān)視發(fā)送到窗口過(guò)程的消息。使本系統(tǒng)在消息發(fā)送到接收窗口過(guò)程之前調(diào)用WH_CALLWNDPROC Hooks子程,并且在窗口過(guò)程處理完消息之后調(diào)用 WH_CALLWNDPROCRET Hooks子程。</p><p>  WH_CALLWNDPROCRET Hooks傳

48、遞指針到CWPRETSTRUCT結(jié)構(gòu),再傳遞到Hook子程。 CWPRETSTRUCT結(jié)構(gòu)包含了來(lái)自處理消息的窗口過(guò)程的返回值,同樣也包括了與這個(gè)消息關(guān)聯(lián)的消息參數(shù)。</p><p>  (2)WH_DEBUG Hook</p><p>  在系統(tǒng)調(diào)用系統(tǒng)中與其他Hook關(guān)聯(lián)的Hook子程之前,系統(tǒng)會(huì)調(diào)用WH_DEBUG Hook子程??梢允褂眠@個(gè)Hook來(lái)決定是否允許系統(tǒng)調(diào)用與其他 Ho

49、ok關(guān)聯(lián)的Hook子程。</p><p>  (3)WH_GETMESSAGE Hook</p><p>  應(yīng)用程序使用WH_GETMESSAGE Hook來(lái)監(jiān)視從GetMessage or peekMessage函數(shù)返回的消息。你可以使用WH_GETESSAGE Hook去監(jiān)視鍵盤(pán)輸入,以及其他發(fā)送到消息隊(duì)列中的消息。</p><p>  (4)WH_JOURN

50、ALPAYBACK Hook</p><p>  WH_JOURNALPAYBACK Hook使應(yīng)用程序可以插入消息到系統(tǒng)隊(duì)列??梢允褂眠@個(gè)Hook回放通過(guò)使用WH_JOURNALPAYBACK Hook記錄下來(lái)的連續(xù)的鍵盤(pán)事件。</p><p>  只要WH_JOURNALPAYBACK Hook已經(jīng)安裝,正常的鍵盤(pán)事件就是無(wú)效的。WH_JOURNALPAYBACK Hook是全局Hoo

51、k,它不能像線(xiàn)程特定Hook一樣使用。WH_JOURNALPAYBACK Hook返回超時(shí)值,這個(gè)值告訴系統(tǒng)在處理來(lái)自回放Hook當(dāng)前消息之前需要等待多長(zhǎng)時(shí)間(毫秒).這就使Hook可以控制實(shí)時(shí)事件的回放。WH_JOURNALPAYBACK是system-wide local hooks,他們不會(huì)被映射到任何行程位址空間(有一些練習(xí)大字的軟件是用這個(gè)Hook做的)。</p><p>  (5)WH_JOURNAL

52、RECORD Hook </p><p>  WH_JOURNALRECORD Hook是用來(lái)監(jiān)視和記錄輸入事件。典型的,可以使用這個(gè)Hook記錄連續(xù)的鼠標(biāo)和鍵盤(pán)事件,然后通過(guò)使用WH_JOURNALRECORD Hook來(lái)回放。WH_JOURNALRECORD Hook是全局Hook,它不能像線(xiàn)程特定Hook一樣使用。</p><p>  (6)WH_KEYBORD Hook</p

53、><p>  在應(yīng)用程序中,WH_KEYBORD Hook用來(lái)監(jiān)視WM_KEYDOWN和WM_KEYUP消息,這些消息通過(guò)GETMessage or PeekMessage函數(shù)返回。可以使用這個(gè)Hook來(lái)監(jiān)視輸入到消息隊(duì)列中的鍵盤(pán)消息。</p><p>  (7)WH_KEYBORD_LL Hook</p><p>  WH_KEYBORD_LL Hook監(jiān)視輸入到線(xiàn)程

54、消息隊(duì)列中的鍵盤(pán)消息。</p><p>  (8)WH_MSGFILTERWH_SYSMSGFILTER Hooks</p><p>  WH_SYSMSGFILTER Hooks監(jiān)視所有應(yīng)用程序消息。WH_MSGFILTER和WH_SYSMSGFILTER Hooks使我們可以在模式循環(huán)期間過(guò)濾消息,這等價(jià)于在住消息循環(huán)中過(guò)濾消息。通過(guò)調(diào)用CallMsgFilter函數(shù)可以直接調(diào)用WH_

55、MSGFILTER Hook。通過(guò)使用這個(gè)函數(shù),應(yīng)用程序能夠在模式循環(huán)期間使用相同的代碼去過(guò)濾消息,如同在主消息循環(huán)里一樣。</p><p>  應(yīng)用程序可以在鉤子上設(shè)置多個(gè)鉤子函數(shù),由其組成一個(gè)與鉤子相關(guān)的指向鉤子函數(shù)的指針列表(鉤子鏈表)當(dāng)鉤子所監(jiān)視的消息出現(xiàn)時(shí),Windows首先將其送到調(diào)用鏈表中所指向的第一個(gè)鉤子函數(shù)中,鉤子函數(shù)將根據(jù)其各自的功能對(duì)消息進(jìn)行監(jiān)視、修改和控制,并在處理完成后把消息傳遞給下一個(gè)

56、鉤子函數(shù)直至到達(dá)鉤子鏈表的末尾。</p><p>  在鉤子函數(shù)交出控制權(quán)后,被攔截的消息最終仍將交還給窗口處理函數(shù)。雖然鉤子鉤子程序的步驟分為三步:定義鉤子函數(shù)、安裝鉤子和卸載鉤子。</p><p>  首先需要定義鉤子函數(shù)。</p><p>  鉤子函數(shù)是一種特殊的回調(diào)函數(shù)。鉤子監(jiān)視的特殊事件發(fā)生后,系統(tǒng)會(huì)調(diào)用鉤子函數(shù)函數(shù)對(duì)消息的過(guò)濾將略加影響系統(tǒng)的運(yùn)行效率,但

57、在很多場(chǎng)合下通過(guò)鉤子對(duì)消息的過(guò)濾處理可以完成一些其他方法所不能完成的特殊功能。</p><p>  如果安裝多個(gè)鉤子,那么最近安裝的鉤子將被置于鉤子鏈的開(kāi)始,最早安裝的鉤子則放在最后。在鉤子監(jiān)視的消息出現(xiàn)時(shí),操作系統(tǒng)調(diào)用鏈表開(kāi)始處的第一個(gè)鉤子函數(shù)進(jìn)行處理,也就是說(shuō)最后加入的鉤子最先獲得控制權(quán)。</p><p>  3. 編寫(xiě)鉤子函數(shù) </p><p>  編寫(xiě)進(jìn)

58、行處理。不同事件的鉤子函數(shù)的形式是各不相同的。下面以鼠標(biāo)鉤子函數(shù)舉例說(shuō)明鉤子函數(shù)原型:</p><p>  LRESULT CALLBACK HookProc(int nCode ,WPARAM wParam,LARAM lParam)</p><p>  參數(shù)wParam和lParam包含所“鉤”消息的信息,比如鼠標(biāo)位置、狀態(tài)、鍵盤(pán)按鍵等。</p><p>  n

59、Code包含有關(guān)消息本身的信息,比如是否從消息的隊(duì)列中移出??梢韵葟你^子函數(shù)中實(shí)現(xiàn)自定義功能,然后調(diào)用函數(shù)CallNextHookEx. 把鉤子信息傳遞給鉤子鏈的下一個(gè)鉤子函數(shù)。CallNextHookEx.的原型如下:</p><p>  LRESULT CallNextHookEx(HHOOK hhk,int nCode, WPARAM wParam,LPARAM lParam)</p><

60、;p><b>  參數(shù)說(shuō)明如下:</b></p><p><b>  hhk:鉤子句柄。</b></p><p>  nCode,wParam和 lParam:鉤子函數(shù)。</p><p>  當(dāng)然也可以通過(guò)TRUE來(lái)丟棄該消息,就阻止了該消息的傳遞。</p><p>  安裝鉤子使用SetWi

61、ndowsHookEx 函數(shù)。</p><p>  當(dāng)不再使用鉤子時(shí),必須及時(shí)卸載。簡(jiǎn)單的調(diào)用UnhookWindowsHookEx函數(shù)即可。</p><p>  4. Win32 DLL</p><p>  由于本軟件所有的系統(tǒng)鉤子要DLL,所以先介紹一下Win32 DLL與本軟件有關(guān)的特點(diǎn)。</p><p>  無(wú)論何時(shí)當(dāng)一個(gè)進(jìn)程或線(xiàn)程載

62、入和卸載DLL時(shí),都要調(diào)用該函數(shù),它的原型為:</p><p>  BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)</p><p><b>  參數(shù)說(shuō)明如下:</b></p><p>  hinstDLL :表示DLL的實(shí)例句柄。</

63、p><p>  fdwReason:根據(jù)該參數(shù)對(duì)DLL進(jìn)行必要的初始化或者清理工作。</p><p>  lpvReserved:系統(tǒng)保留。</p><p>  第二個(gè)參數(shù)有四個(gè)可能值:DLL_PROCESS_ATTACH(進(jìn)程載入)DLL_THREAD_ATTACH(線(xiàn)程載入)DLL_THREAD_DETACH(線(xiàn)程卸載)DLL_PROCESS_DETACH(進(jìn)程卸載

64、)在DLLMain函數(shù)中可以對(duì)傳遞進(jìn)來(lái)的這個(gè)參數(shù)的值進(jìn)行判別并根據(jù)不同的參數(shù)值對(duì)DLL進(jìn)行必要的初始化或清理工作。舉例來(lái)說(shuō)當(dāng)有一個(gè)進(jìn)程載入一個(gè)DLL時(shí)系統(tǒng)分配給DLL的第二個(gè)參數(shù)為DLL_PROCESS_ATTACH,這時(shí),你可以根據(jù)這個(gè)參數(shù)初始化特定的數(shù)據(jù)。</p><p>  在Win32環(huán)境下要想在多個(gè)進(jìn)程中共享數(shù)據(jù)就必須進(jìn)行必要的設(shè)置。亦即把這些需要共享的數(shù)據(jù)分離出來(lái)放置在一個(gè)獨(dú)立的數(shù)據(jù)段里,并把該段的屬

65、性設(shè)置為共享。</p><p>  下面簡(jiǎn)述VC++6.0中全局共享數(shù)據(jù)的實(shí)現(xiàn)。再主文件中,用#pragma data_seg建立一個(gè)新的數(shù)據(jù)段并定義共享數(shù)據(jù),其具體格式為:</p><p>  # pragma data_seg(“shareddata”)</p><p>  HWND sharedwnd=NULL;//共享數(shù)據(jù)</p><

66、p>  #pragma data_seg()</p><p>  僅定義一個(gè)數(shù)據(jù)段還不能達(dá)到共享數(shù)據(jù)的目的,還要告訴編譯器該段的屬性,有兩種方法可以實(shí)現(xiàn)該目的(其效果是相同的)一種方法是在.def文件中加入如下語(yǔ)句:SECTIONS</p><p>  Shareddata READ WRITE SHARED</p><p>  另一種方法是在項(xiàng)目設(shè)置

67、鏈接選項(xiàng)中加入如下語(yǔ)句:</p><p>  /SECTION:shareddata.rws</p><p>  有了上面的基礎(chǔ),開(kāi)發(fā)鍵盤(pán)音樂(lè)軟件的關(guān)鍵技術(shù)都已經(jīng)解決,下面開(kāi)始進(jìn)入編碼階段。</p><p>  4.2 動(dòng)態(tài)鏈接庫(kù)技術(shù)</p><p>  本軟件分成兩部分,一部分是DLL模塊,里面利用鉤子技術(shù)完成鍵盤(pán)監(jiān)控和播放聲音文件的功能

68、;另一部分是界面部分,調(diào)用DLL和停止鍵盤(pán)奏鳴功能。動(dòng)態(tài)鏈接庫(kù)(DLL:Dynamic-Link Library)是Windows環(huán)境中軟件開(kāi)發(fā)的重要組成部分也是分布式計(jì)算中的組件對(duì)象模型(COM)技術(shù)的基本支柱之一。使用動(dòng)態(tài)鏈接庫(kù)就可以靈活的設(shè)計(jì)與實(shí)現(xiàn)各類(lèi)軟件系統(tǒng)。</p><p>  我們可以將動(dòng)態(tài)鏈接庫(kù)看成軟件系統(tǒng)中比較獨(dú)立的代碼和資源包。當(dāng)運(yùn)行應(yīng)用程序的可執(zhí)行文件時(shí),在通常情況下,動(dòng)態(tài)鏈接庫(kù)并不立即裝載到

69、系統(tǒng)的內(nèi)存中去,而只是在需要的時(shí)候進(jìn)行動(dòng)態(tài)的裝載,并將動(dòng)態(tài)鏈接庫(kù)與應(yīng)用程序的可執(zhí)行文件有機(jī)的結(jié)合在一起,以共同完成軟件系統(tǒng)的功能。</p><p>  作為Windows系統(tǒng)程序模塊的DLL,不僅可以包含可執(zhí)行代碼,還可以包含數(shù)據(jù)以及其他各種資源。另外,一些設(shè)備的驅(qū)動(dòng)程序也是使用動(dòng)態(tài)鏈接庫(kù)實(shí)現(xiàn)的(擴(kuò)展名一般是DRV)。比如:在Windows系統(tǒng)目錄下有一個(gè)名為Comdlg32.DDL的文件,其中就包括了公共對(duì)話(huà)框

70、的代碼和資源。DLL的用途非常廣泛,這主要是由其特性來(lái)決定的。</p><p> ?。?)用DLL可以實(shí)現(xiàn)不同程序之間的代碼重用。</p><p>  普通的函數(shù)庫(kù)也可以實(shí)現(xiàn)不同應(yīng)用程序之間的代碼重用:將一些通用程序的代碼使用一些比較獨(dú)立的函數(shù)來(lái)實(shí)現(xiàn),這樣在不同應(yīng)用程序的源代碼中進(jìn)行直接調(diào)用即可。比如大部分的WindowsAPI函數(shù)就是以函數(shù)庫(kù)的形式來(lái)提供的。但是使用普通的函數(shù)庫(kù),在程序鏈

71、接時(shí),是將庫(kù)中的代碼直接拷貝到可執(zhí)行文件中,這知識(shí)一種靜態(tài)鏈接。若在多個(gè)同樣的程序執(zhí)行時(shí),則系統(tǒng)中就保留了許多重復(fù)的代碼副本,就會(huì)造成內(nèi)存資源的浪費(fèi)。在這種情況下,若使用DLL,則實(shí)現(xiàn)的就是動(dòng)態(tài)鏈接,并不是將庫(kù)代碼拷貝,而只是在程序中記錄了函數(shù)的入口點(diǎn)和接口,并只在程序執(zhí)行時(shí)才將庫(kù)代碼裝入內(nèi)存。這樣,不管有多少個(gè)程序同時(shí)使用某個(gè)DLL,內(nèi)存中都只有這個(gè)DLL 的一個(gè)副本。當(dāng)沒(méi)有程序使用這個(gè)DLL時(shí),系統(tǒng)就將其移出,從而釋放了相應(yīng)的內(nèi)存空

72、間。</p><p>  本系統(tǒng)利用DLL的這一特點(diǎn),各個(gè)鍵位與音頻鏈接的不同代碼實(shí)現(xiàn)了代碼重用,使不同的鍵盤(pán)應(yīng)用程序的源代碼可直接調(diào)用。</p><p> ?。?)DLL技術(shù)對(duì)于開(kāi)發(fā)大型軟件系統(tǒng)有很多可用之處。</p><p>  在大型軟件系統(tǒng)中,如果所有的功能均使用一個(gè)可執(zhí)行文件來(lái)完成,則最終的可執(zhí)行文件將會(huì)非常龐大,而且其中還將有許多重復(fù)的功能。另外,龐大的

73、可執(zhí)行文件對(duì)于軟件的開(kāi)發(fā)與維護(hù)也將是一件非常困難的事情。</p><p>  一個(gè)比較好的方法就是使用DLL,將軟件系統(tǒng)分成一個(gè)主框架程序和一系列DLL。這樣將會(huì)大大降低軟件開(kāi)發(fā)的復(fù)雜度,同時(shí)也可以減少開(kāi)發(fā)的工作量。另外,由于每個(gè)模塊都比較小,而且都相對(duì)獨(dú)立,在運(yùn)行時(shí)也可以提高訪(fǎng)問(wèn)的速度,增加軟件的運(yùn)行效率。</p><p>  (3)DLL可以方便的實(shí)現(xiàn)軟件的多國(guó)語(yǔ)言版本。</p&

74、gt;<p>  使用DLL就可以方便地支持世界各國(guó)的語(yǔ)言。程序員將依賴(lài)于語(yǔ)言的函數(shù)和資源分離出來(lái),而專(zhuān)門(mén)放進(jìn)不同的DLL中去。比如,對(duì)于中文英文和法文,各自實(shí)現(xiàn)一個(gè)相對(duì)的DLL。在軟件用戶(hù)安裝軟件時(shí),將提示選擇相應(yīng)的語(yǔ)言版本來(lái)安裝。所以使用DLL是實(shí)現(xiàn)軟件商品國(guó)際化的一項(xiàng)技術(shù)。</p><p>  本系統(tǒng)可以利用DLL的這一特點(diǎn),把多種語(yǔ)言的函數(shù)和資源分離,放進(jìn)專(zhuān)門(mén)的DLL中去,可以實(shí)現(xiàn)中文、英文

75、等其他語(yǔ)言。</p><p><b>  5系統(tǒng)的詳細(xì)設(shè)計(jì) </b></p><p>  因本軟件涉及的技術(shù)含量較高,技術(shù)難度較大,所以詳細(xì)設(shè)計(jì)部分選寫(xiě)了一部分代碼,此部分代碼是理解這一軟件精華思想所不可或缺的。</p><p>  5.1 設(shè)計(jì)DLL模塊</p><p>  新建一個(gè)project,名稱(chēng)為Keyboa

76、rdHook, project類(lèi)型為選擇MFC AppWizard(DLL), DLL類(lèi)型為MFC Extension DLL(using shared MFC DLL)。</p><p>  步驟1 準(zhǔn)備資源文件</p><p>  因本軟件為嘗試性研究,故我未將鍵盤(pán)上的按鍵全盤(pán)選取,而是精心選取了四十個(gè)有代表性的按鍵,每一按鍵對(duì)應(yīng)一個(gè)同名聲音文件。</p><p&g

77、t;  將以下聲音文件放到軟件的res子目錄下,在鍵盤(pán)上按鍵時(shí),就會(huì)播放相應(yīng)的聲音文件:</p><p>  0.wav、1.wav、2.wav、3 .wav………A.wav、 B.wav、C.wav……LEFT ARROW.wav、 DOWN ARROW.wav……</p><p>  步驟2 創(chuàng)建KeyboardHook.h文件</p><p>  由于VC+

78、+6.0中沒(méi)有現(xiàn)成的鉤子類(lèi),所以要?jiǎng)?chuàng)建KeyboardHook.h文件,在其中建立鉤子類(lèi)。KeyboardHook.h文件內(nèi)容如下:</p><p>  #if _MSC_VER > 1000</p><p>  #pragma once</p><p>  #endif // _MSC_VER > 1000</p><p>  

79、**************************************************************</p><p>  class AFX_EXT_CLASS CKeyboradHook : public CObject</p><p><b>  {</b></p><p>  // Construction<

80、/p><p><b>  public:</b></p><p>  CKeyboradHook();</p><p>  ~CKeyboradHook();</p><p>  BOOL StartHook();</p><p>  BOOL StopHook();</p><p

81、><b>  };</b></p><p>  **************************************************************</p><p>  StartHook()函數(shù)實(shí)現(xiàn)安裝鉤子,函數(shù)實(shí)現(xiàn)卸載鉤子。</p><p>  在KeyboardHook.cpp 文件的頂部加入#include

82、 “ KeyboardHook.h”語(yǔ)句。</p><p>  步驟3 加入全局共享數(shù)據(jù)變量</p><p>  在KeyboardHook.cpp文件中加入共享數(shù)據(jù)段mydata,其中定義兩個(gè)變量分別代表安裝的鉤子句柄和DLL實(shí)例句柄:</p><p>  #pragma data_seg("mydata") </p><

83、p>  HHOOK glhKeyboradHook=NULL; //安裝的鍵盤(pán)勾子句柄</p><p>  HINSTANCE glhkInstance=NULL; //DLL實(shí)例句柄</p><p>  #pragma data_seg()</p><p>  在KeyboardHook.def 文件中定義段屬性:</p><p>&

84、lt;b>  SECTIONS </b></p><p>  Mydata READ WRITE SHARED</p><p>  步驟4 類(lèi)CKeyboardHook的成員函數(shù)</p><p><b>  構(gòu)造函數(shù)如下:</b></p><p>  CKeyboradHook::CKeyboradH

85、ook()</p><p><b>  {</b></p><p><b>  }</b></p><p><b>  析構(gòu)函數(shù)如下:</b></p><p>  CKeyboradHook::~CKeyboradHook()</p><p><b

86、>  {</b></p><p>  StopHook();}</p><p>  調(diào)用StartHook函數(shù)可以安裝鉤子:</p><p>  **************************************************************</p><p>  BOOL CKeyboradHoo

87、k::StartHook() </p><p><b>  { </b></p><p>  glhKeyboradHook=SetWindowsHookEx(WH_KEYBOARD,KeyboradProc,</p><p>  glhkInstance,0); </p><p>  if(glhKeyboradHoo

88、k!=NULL) </p><p>  return TRUE; </p><p>  return FALSE; </p><p><b>  }</b></p><p>  **************************************************************</p>

89、<p>  在StartHook函數(shù)中主要通過(guò)SetWindowsHookEx函數(shù)安裝鉤子。其函數(shù)原形為:</p><p>  HHOOK SetWindowsHookEx (int idHook, HOOKPROC lpfn,INSTANCE hMod,DWORD,dwThreadId)</p><p><b>  參數(shù)說(shuō)明如下:</b></

90、p><p>  (1)idHook:鉤子類(lèi)型,它是和鉤子函數(shù)類(lèi)型一一對(duì)應(yīng)的。例如,WH_KEYBOARD表示安裝的是鍵盤(pán)鉤子,WH_MOUSE表示是鼠標(biāo)鉤子等等。</p><p>  (2) lpfn:鉤子函數(shù)的地址。</p><p>  (3) hMod:鉤子函數(shù)所在的實(shí)例的句柄,對(duì)于線(xiàn)程鉤子,該參數(shù)為NULL;對(duì)于系統(tǒng)鉤子,該參數(shù)為鉤子函數(shù)所在的DLL句柄。<

91、/p><p>  (4) dwThreadId:指定鉤子所監(jiān)視的線(xiàn)程的線(xiàn)程號(hào)。對(duì)于全局鉤子,該參數(shù)為NULL。</p><p>  SetWindowsHookEx反回所安裝的鉤子句柄。</p><p>  步驟5 根據(jù)判斷播放相應(yīng)的音樂(lè)</p><p>  調(diào)用StartHook函數(shù)后,所有鍵盤(pán)的消息都會(huì)轉(zhuǎn)移到KeyboradPro函數(shù)中,通

92、過(guò)數(shù)組nkey的值與wParam參數(shù)相比較,可以知道用戶(hù)按下的是哪個(gè)鍵,通過(guò)對(duì)lParam值的判斷,可以知道用戶(hù)按下鍵還是釋放鍵然后播放鍵對(duì)應(yīng)的聲音文件即可:</p><p>  LRESULT WINAPI KeyboradProc (int nCode,WPARAM wParam,LPARAM lParam)</p><p><b>  {</b></p&g

93、t;<p>  for(int i =0;i<TOTAL_KEYS;i++)</p><p><b>  {</b></p><p>  if(nkey[i]==(int)wParam)</p><p><b>  {</b></p><p>  int nKeyStatus=l

94、Param & 0x80000000;</p><p>  //根據(jù)用戶(hù)按鍵播放對(duì)應(yīng)的聲音文件。</p><p>  switch(nKeyStatus)</p><p>  case 0://WM_KEYDOWN</p><p>  //case 0x80000000://WM_KEYUP</p><p>&

95、lt;b>  {</b></p><p>  CString strFileName;</p><p>  char szBuf[256]; </p><p>  char *pPath; </p><p>  CString strPath; </p><p>  GetModuleFileName

96、(glhkInstance,szBuf,sizeof(szBuf)); </p><p>  pPath = szBuf; </p><p>  while(strchr(pPath,'\\')) </p><p><b>  { </b></p><p>  pPath = strchr(pPath,&

97、#39;\\'); </p><p><b>  pPath++; </b></p><p><b>  } </b></p><p>  *pPath = '\0'; </p><p>  strPath=szBuf; </p><p>  strF

98、ileName.Format("%sres\\%s.wav",strPath,cskey[i]); </p><p>  sndPlaySound(strFileName,SND_ASYNC);</p><p><b>  break;}</b></p><p><b>  }</b></p>

99、;<p><b>  }</b></p><p>  在此,需要解釋多媒體編程中的一個(gè)重要函數(shù):SndPlaySound函數(shù)。SndPlaySound函數(shù)可以直接播放.wav音頻文件。SndPlaySound函數(shù)的第一個(gè)參數(shù)lpszPlaySound可以是指定的一個(gè).wav音頻文件名,文件名可以帶絕對(duì)路徑,也可以不帶路徑,而只提供文件名。在不帶路徑的情況下,函數(shù)首先在當(dāng)前目錄下

100、尋找該文件。如果沒(méi)有找到的話(huà),那么再根據(jù)標(biāo)準(zhǔn)的目錄搜索次序進(jìn)行進(jìn)一步的尋找。SndPlaySound函數(shù)首先假定lpszSound指定的是系統(tǒng)聲音。如果在注冊(cè)表中查找不到對(duì)應(yīng)的入口項(xiàng),則認(rèn)為lpszSound的值是NULL,則終止當(dāng)前正在播放的聲音。</p><p>  步驟6 鉤子函數(shù)的卸載</p><p>  在StopHook函數(shù)中,主要通過(guò)UnhookWindowsHookEx函

101、數(shù)卸載指定的鉤子。</p><p>  BOOL CKeyboradHook::StopHook() </p><p><b>  { </b></p><p>  BOOL bResult=FALSE; </p><p>  if(glhKeyboradHook) </p><p><b&

102、gt;  { </b></p><p>  bResult= UnhookWindowsHookEx(glhKeyboradHook); </p><p>  if(bResult) </p><p><b>  { </b></p><p>  glhKeyboradHook=NULL; </p>

103、;<p><b>  } </b></p><p><b>  } </b></p><p>  return bResult; </p><p><b>  }</b></p><p>  ************************************

104、******************************</p><p>  KeyboardHook.cpp文件的內(nèi)容如下:</p><p>  // KeyboardHook.cpp : Defines the initialization routines for the DLL.</p><p><b>  //文件包含。</b>&

105、lt;/p><p>  #include "stdafx.h"</p><p>  #include "Mmsystem.h"</p><p>  #include <afxdllx.h></p><p>  #include "KeyboardHook.h"</p&g

106、t;<p><b>  //預(yù)編譯。</b></p><p>  #ifdef _DEBUG</p><p>  #define new DEBUG_NEW</p><p>  #undef THIS_FILE</p><p>  static char THIS_FILE[] = __FILE__;<

107、;/p><p><b>  #endif</b></p><p>  #define TOTAL_KEYS 40</p><p>  //存儲(chǔ)各個(gè)鍵對(duì)應(yīng)的鍵值。</p><p>  CString cskey[TOTAL_KEYS]=</p><p>  {"LEFT ARROW"

108、,//VK_LEFT 25 LEFT ARROW key </p><p>  "UP ARROW",//VK_UP 26 UP ARROW key </p><p>  "0",//30 0 key</p><p>  "1",//31 1 key </p><p>&

109、lt;b>  ……………</b></p><p>  "A",//41 A key </p><p>  "B",//42 B key </p><p><b>  …………… </b></p><p><b>  };</b>&

110、lt;/p><p>  int nkey[TOTAL_KEYS]=</p><p><b>  {</b></p><p>  0x25,//"LEFT ARROW",//VK_LEFT 25 LEFT ARROW key </p><p>  0x26,//"UP ARROW",/

111、/VK_UP 26 UP ARROW key </p><p><b>  …………</b></p><p>  0x30,//"0",//30 0 key </p><p>  0x31,//"1",//31 1 key </p><p><b>  ……………&

112、lt;/b></p><p>  0x41,//"A",//41 A key </p><p>  0x42,//"B",//42 B key </p><p><b>  ……………</b></p><p><b>  };</b></p&g

113、t;<p>  #pragma data_seg("mydata") </p><p>  //安裝的鍵盤(pán)勾子句柄</p><p>  HHOOK glhKeyboradHook=NULL;</p><p>  //DLL實(shí)例句柄 </p><p>  HINSTANCE glhkInstance=NULL;

114、</p><p>  #pragma data_seg() </p><p>  //#pragma comment(linker,"/SECTION:mydata,RWS")</p><p>  static AFX_EXTENSION_MODULE KeyboardHookDLL = { NULL, NULL };</p>&l

115、t;p>  extern "C" int APIENTRY</p><p>  DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID </p><p>  lpReserved) //類(lèi)構(gòu)造函數(shù) </p><p>  CKeyboradHook::CKeyboradHook(){}

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論