精通Windows API(函數(shù)、接口、編程實(shí)例)下篇_第1頁(yè)
精通Windows API(函數(shù)、接口、編程實(shí)例)下篇_第2頁(yè)
精通Windows API(函數(shù)、接口、編程實(shí)例)下篇_第3頁(yè)
精通Windows API(函數(shù)、接口、編程實(shí)例)下篇_第4頁(yè)
精通Windows API(函數(shù)、接口、編程實(shí)例)下篇_第5頁(yè)
已閱讀5頁(yè),還剩291頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

精通WindowsAPI(函數(shù)、接口、編程實(shí)例)下篇目錄\h第10章系統(tǒng)信息的管理295\h10.1inos系統(tǒng)信息295\h10.1.1獲系統(tǒng)版本295\h10.1.2獲計(jì)算機(jī)硬件信息297\h10.1.3獲系統(tǒng)目錄等信息299\h10.1.4用名、計(jì)算機(jī)名、域名300\h10.1.5處系統(tǒng)顏色信息、尺度信息等302\h10.1.6鼠、鍵盤等外設(shè)信息303\h10.2時(shí)間息304\h10.2.1設(shè)、獲取系統(tǒng)時(shí)間304\h10.2.2獲開(kāi)機(jī)至現(xiàn)在持續(xù)的時(shí)間305\h10.2.3文時(shí)間與系統(tǒng)時(shí)間的轉(zhuǎn)換305\h10.3注冊(cè)表306\h10.3.1注表的作用及組織形式306\h10.3.2鍵子鍵、鍵屬性及鍵值的相關(guān)操作307\h10.3.3列注冊(cè)表項(xiàng)及鍵值309\h10.3.5設(shè)隨程序啟動(dòng)而啟動(dòng)的調(diào)試器(任何程序)312\h10.3.6指程序崩潰實(shí)時(shí)調(diào)試器312\h第1章進(jìn)程間通信313\h1.1郵槽(Maillot)313\h1.1.1創(chuàng)郵槽、從郵槽中讀取消息313\h1.1.2通郵槽發(fā)送消息317\h1.2管道(ipe)318\h1.2.1創(chuàng)命名管道318\h1.2.2管監(jiān)聽(tīng)320\h1.2.3使異步I/O進(jìn)行讀寫321\h1.2.4關(guān)管道實(shí)例325\h1.2.5客端325\h1.3剪貼板328\h1.3.1獲、設(shè)置剪貼板數(shù)據(jù)328\h1.3.2監(jiān)剪貼板334\h1.3.3剪板數(shù)據(jù)格式343\h1.4數(shù)據(jù)制消息(WM_COPYDA)345\h1.4.1數(shù)發(fā)送端345\h1.4.2數(shù)接收端348\h1.5其他程間通信方式350\h1.5.1動(dòng)數(shù)據(jù)交換(DE)和網(wǎng)絡(luò)動(dòng)態(tài)數(shù)據(jù)交換(NDDE)350\h1.5.3indowsSocket351\h第12章ndowsShel程序設(shè)計(jì)352\h12.1indowsShell目錄管理352\h12.1.1Shell對(duì)目錄和文件的管理形式353\h12.1.2我的文檔”等特殊目錄相關(guān)操作353\h12.1.3綁、遍歷、屬性獲取354\h12.1.4瀏文件對(duì)話框357\h12.2文件助(FileAssociations)358\h12.2.1文類型相關(guān)注冊(cè)表鍵值359\h12.2.2為件指定默認(rèn)打開(kāi)程序359\h12.2.3定文件類型的圖標(biāo)360\h12.3Sell擴(kuò)展361\h12.3.1對(duì)及概念361\h12.3.2CLSI,處理例程的GUD362\h12.3.3注Shell擴(kuò)展363\h12.34COM程序開(kāi)發(fā)基礎(chǔ)364\h12.3.5編Handler程序364\h12.3.6Shell擴(kuò)展程序的調(diào)試380\h12.3.7總結(jié)381\h12.4任務(wù)通知區(qū)域ray)圖標(biāo)381\h12.4.1創(chuàng)圖標(biāo)窗口382\h12.4.2創(chuàng)圖標(biāo)和圖標(biāo)菜單386\h12.4.4彈氣泡通知391\h12.4.5動(dòng)圖標(biāo)393\h12.4.6其功能395\h第13章ndowsGDI398\h13.1GI編程接口概述398\h13.11inowsGDI的功能398\h13.1.2鏈庫(kù)與頭文件398\h13.2設(shè)備下文(C)\輸出操作與圖形對(duì)象398\h13.2.1設(shè)上下文類型與關(guān)聯(lián)設(shè)備399\h13.2.2圖對(duì)象的作用及與DC的關(guān)系399\h13.2.3各圖形對(duì)象的具體屬性與作用401\h13.2.4繪、填充、寫入等圖形輸出操作402\h13.2.5修與坐標(biāo)變換403\h13.2.6設(shè)上下文的圖形模式403\h13.3一個(gè)簡(jiǎn)單的DI程序404\h13.3.1示例404\h13.3.2D的操作406\h13.3.3顏的表示407\h13.3.4圖對(duì)象:畫刷和畫筆407\h13.3.5輸操作:繪制圖形和線條409\h13.4文字字體409\h13.4.1選、設(shè)置字體412\h13.4.2選字體圖形對(duì)象413\h13.4.3文的顏色413\h13.4.4輸文字413\h13.4.5C圖形模式設(shè)置414\h13.4.6遍字體415\h13.4.7為統(tǒng)安裝、刪除字體文件417\h13.5繪制條417\h13.5.1選畫筆對(duì)象417\h13.5.2直線418\h13.5.3繪任意曲線418\h13.5.4跟鼠標(biāo)軌跡418\h13.5.5弧線424\h13.6繪制形424\h13.6.1填顏色與邊緣勾勒425\h13.6.2繪矩形、橢圓、圓角矩形425\h13.6.3橢弓形和橢圓扇形431\h13.6.4多形431\h13.65RET結(jié)構(gòu)及對(duì)RECT的操作432\h13.7位圖作434\h13.7.1截屏幕、保存位圖文件434\h13.7.2將圖顯示在界面上439\h13.8區(qū)域(Regions)、路徑(Paths)與修剪(Clip)操作442\h13.8.1區(qū)的創(chuàng)建及形狀、位置等屬性442\h13.8.2區(qū)邊沿、區(qū)域填充、反轉(zhuǎn)與勾勒操作443\h13.8.3組、比較、移動(dòng)等操作446\h13.8.4點(diǎn)測(cè)試(Hitesting)447\h13.8.5路的創(chuàng)建與操作451\h13.8.6路轉(zhuǎn)換為區(qū)域452\h13.8.7使區(qū)域和路徑進(jìn)行修剪操作,限制輸出452\h13.9坐標(biāo)換458\h13.9.1縮放459\h13.9.2旋轉(zhuǎn)460\h13.10調(diào)板460\h第14章網(wǎng)絡(luò)通信與配置463\h14.1Socket通信463\h14.1.1客端464\h14.1.2服端469\h14.1.3處并發(fā)的客戶端連接475\h14.1.4網(wǎng)通信的異步I/O模式476\h14.2IPHeler476\h第15章程序安裝與設(shè)置483\h15.11akecab.exe483\h15.1.2壓多個(gè)文件484\h15.13Cabinet軟件開(kāi)發(fā)工具包(CASDK)485\h15.2編寫NF文件486\h15.2.1INF文件格式486\h15.2.2Install節(jié)488\h15.2.3CopyFiles和AddReg等安裝過(guò)程488\h15.2.4源徑和目的路徑489\h15.2.5字串表489\h15.3安裝程序setup.exe編號(hào)489\h15.4使用si文件進(jìn)行安裝493\h15.41indowsInstallerService493\h15.4.2si文件的創(chuàng)建與修改工具orca.exe495\h15.4.3準(zhǔn)工作496\h15.4.4編表組496\h第16章設(shè)備驅(qū)動(dòng)管理與內(nèi)核通信497\h16.1設(shè)備理497\h16.1.1列設(shè)備接口497\h16.1.2監(jiān)設(shè)備的加載和卸載504\h16.2I/o控制、內(nèi)核通信509\h16.2.1加驅(qū)動(dòng)程序509\h16.2.2控驅(qū)動(dòng)程序、與驅(qū)動(dòng)程序進(jìn)行通信516\h16.3編寫備驅(qū)動(dòng)程序519\h16.3.1驅(qū)程序開(kāi)發(fā)包:DK520\h16.4I/O模式,同步與異步525\h第17章用戶、認(rèn)證和對(duì)象安全527\h17.1基本念527\h17.1.1訪令牌、權(quán)限和用戶標(biāo)識(shí)527\h17.1.2進(jìn)的系統(tǒng)操作權(quán)限528\h17.1.3安對(duì)象528\h17.1.4訪控制列表(ACL)529\h17.2安全制程序示例530\h17.2.1列進(jìn)程訪問(wèn)令牌內(nèi)容和權(quán)限530\h17.2.2修進(jìn)程的權(quán)限536\h17.2.3列安全對(duì)象的安全描述符537\h17.2.4修安全描述符543\h17.3用戶544\h17.3.1創(chuàng)用戶544\h17.3.2用組545\h17.3.3刪用戶546\h17.3.4列用戶和用戶組、獲取用戶信息547\h第18章ndowsPI的內(nèi)部原理554\h18.1關(guān)于PI的補(bǔ)充說(shuō)明554\h18.1.1indowsAPI的版本演進(jìn)和ista新增API554\h18.1.264位操作系統(tǒng)的接口555\h18.2inos系統(tǒng)中的對(duì)象封裝555\h18.2.1什是對(duì)象555\h18.2.2面對(duì)象的思想555\h18.2.3indows系統(tǒng)中的對(duì)象:內(nèi)核對(duì)象、D對(duì)象等556\h18.3iFidows程序設(shè)計(jì)參考:文檔資源與樣例代碼556\h18.3.1SDK文檔和MSDN556\h18.3.2SDK示例代碼556\h18.486臺(tái)程序函數(shù)調(diào)用原理557\h18.4.1函調(diào)用的真實(shí)過(guò)程557\h18.4.2函調(diào)用約定561\h18.4.3為么通過(guò)參數(shù)返回?cái)?shù)據(jù)時(shí)只能使用指針562\h18.4.4緩區(qū)溢出562\h18.4.5程運(yùn)行錯(cuò)誤的調(diào)試技巧562\h18.5可執(zhí)程序結(jié)構(gòu)與II函數(shù)接口內(nèi)部機(jī)理563\h18.5.1indows可執(zhí)行程序結(jié)構(gòu)563\h18.5.2導(dǎo)表、導(dǎo)出表、動(dòng)態(tài)鏈接565\h18.5.3NTDLL.DLL、NIVEAPI和SSDT566\h18.5.4PIOK568\h18.6發(fā)布序569\h18.6.1合選擇編譯鏈接選項(xiàng)569\h18.6.2構(gòu)到指定路徑569\h18.7模塊,向indowsPl學(xué)習(xí)接口定義569\h18.71lib件569\h18.7.2頭件570\h18.7.3為三方應(yīng)用軟件提供SK570第10章系統(tǒng)信息的管理獲取管理的Windows系統(tǒng)信包括系統(tǒng)基本信息、時(shí)間信息、注冊(cè)表。本章10.1節(jié)主要介紹Windows的系統(tǒng)信息的獲取包系統(tǒng)目錄Windows安裝目錄、用戶名、計(jì)算機(jī)名、域名等。10.2節(jié)主要介紹系統(tǒng)時(shí)間的獲取和修改。10.3節(jié)主要介紹如何操作注冊(cè)表。101indows系統(tǒng)信息Windows系統(tǒng)信息包括系統(tǒng)版本目錄計(jì)算機(jī)名用戶名系統(tǒng)時(shí)間系統(tǒng)顏色設(shè)置信息等。本節(jié)將介紹如何使用API獲取這些信息。首先給出本節(jié)所有實(shí)例的運(yùn)行效果,實(shí)例10-1~實(shí)例10-5的綜合運(yùn)行結(jié)果如圖10-1所示。10.1.1 獲取系統(tǒng)版本1.系統(tǒng)版本的表示與獲取Windows對(duì)系統(tǒng)版本的表示分為主版本號(hào)次版本號(hào)構(gòu)建(Build)號(hào)P主版本號(hào)SP次版本號(hào)來(lái)表示系統(tǒng)版本。比如筆者的主機(jī)系統(tǒng)版本號(hào)為5.1Build2600ServicePack2。SP版本號(hào)會(huì)隨著ServicePack的安而改變。一般系統(tǒng)的主版本號(hào)與次版本號(hào)會(huì)對(duì)應(yīng)用程序開(kāi)發(fā)人員有比較大的影響。比如5.0表示W(wǎng)indows000,5.1表示W(wǎng)indowsXP5.2表示W(wǎng)indowsServer20036.0表示W(wǎng)indowsVista。一般每一個(gè)新版本的系統(tǒng)都會(huì)新增加一些API因此有些API只在新版本的Windows上使用而不能在較老版本的Windows上使用。2.關(guān)鍵API與數(shù)據(jù)結(jié)構(gòu)(1)GeVersionEx??梢允褂肎etVersionEx函數(shù)獲取系統(tǒng)版信息,函數(shù)原型如下:

參數(shù)lpVersionInfo:輸入、輸出參數(shù),此參數(shù)為OSVERSIONINFO或者OSVERSIONINFOEX結(jié)構(gòu)的指針,用于存儲(chǔ)獲取的系統(tǒng)版本信息。這兩個(gè)結(jié)構(gòu)的第一個(gè)成員都是dwOSVersionInfoSize果使用OSVERSIONINFO結(jié)構(gòu)么將此成員設(shè)置為sizeof(OSVERSIONINFO)如果使用OSVERSIONINFOEX結(jié)構(gòu),那么設(shè)此成員為sizeof(OSVERSONINFOEX。

返回值BOOL類型,表示是否成功。使用GetLastError函數(shù)獲錯(cuò)誤代碼。(2)OSVERSONINFOEX構(gòu)。實(shí)例10-1獲取系統(tǒng)版本本實(shí)使用GetVersionEx函數(shù)獲取系統(tǒng)版本、產(chǎn)品類型等,并打印出結(jié)果,以版本所對(duì)應(yīng)的真實(shí)版本名稱的形式打印。實(shí)例運(yùn)行結(jié)果如圖10-1所示。10.1.2 獲取計(jì)算機(jī)硬件信息1.獲取硬件相關(guān)信息GetSystemInfo函數(shù)可以獲取很多系統(tǒng)硬件相關(guān)信息包括內(nèi)存分頁(yè)的大小內(nèi)存的最小分配單位、粒度,處理器的類型和個(gè)數(shù)等。2.關(guān)鍵API與數(shù)據(jù)結(jié)構(gòu)(1)GetSystemInfo。函數(shù)原型如下:

參數(shù)lpSystemInfo:輸出參數(shù),獲取的信息保存于SYSTEM_INFO結(jié)構(gòu)中。lpSystemInfo參數(shù)為指向SYSTEMINFO構(gòu)類型變量的指針。

返回值無(wú)返回值。(2)SYSTEMINFO結(jié)構(gòu)的定義如下:成員變量的意義見(jiàn)實(shí)例8-2。實(shí)例10-2獲取系統(tǒng)件相關(guān)信息本實(shí)使用GetSystemInfo獲系統(tǒng)硬件信息并打印出來(lái)包括內(nèi)存分頁(yè)大小處理器數(shù)量和類型、處理器架構(gòu)等。運(yùn)行結(jié)果見(jiàn)圖10-1。10.1.3 獲取系統(tǒng)目錄等信息1.系統(tǒng)目錄和Windows安裝目錄Windows的系統(tǒng)目錄會(huì)在安裝的時(shí)候確定,在不同主機(jī)上運(yùn)行的系統(tǒng)可能不相同。另外,不同Windows版本其系目錄的默認(rèn)情況也不是相同的。獲取統(tǒng)目錄使用函數(shù)GetSystemDirectory,獲取Windows系統(tǒng)的安裝目錄可以使用函數(shù)GetWindowsDirectory。2.關(guān)鍵API(1)GetSystemDirectory,函數(shù)原型如下:

參數(shù)lpBuffer輸出參數(shù)保存系統(tǒng)路徑的緩沖區(qū)由調(diào)用者分配參數(shù)uSize為其大(字符數(shù)。一般大小為MAX_PATH可。uSize:輸出參數(shù),必須設(shè)置為lpBuffer所指向的緩沖區(qū)的大小,字符數(shù)不能大于lpBuffer緩沖區(qū)的大小,否則可能會(huì)引起溢出。

返回值如果回值大于uSize,說(shuō)明沖區(qū)小于返回的字符串,返回值為所需的緩沖區(qū)大小。如果返回0則表示失敗如果返回非0且小于nSize的值則執(zhí)行成功返回值大小為系統(tǒng)目錄的字符數(shù)。(2)GetWindowsDirectoy。GetWindowsDirectory函數(shù)的參數(shù)與返回值的意義與GetSystemDirectory函數(shù)相似。實(shí)例10-3取系統(tǒng)目錄和Windows安裝目錄本實(shí)例使用GetSystemDirectory與GetWindowsDirectory函獲取系統(tǒng)相關(guān)路徑并打印出來(lái)。運(yùn)行結(jié)果見(jiàn)圖10-1。10.1.4 用戶名、計(jì)算機(jī)名、域名獲取前登錄用戶使用API函數(shù)GetUserName獲取計(jì)機(jī)名使用API函數(shù)GetComputerName,獲取特定格式的計(jì)算機(jī)名使用API函數(shù)GetComputerNameEx,設(shè)置計(jì)算機(jī)名使用API函數(shù)SetComputerName和SetComputeNameEX.1.關(guān)鍵API(1)GetUserName。獲取當(dāng)前登錄的用戶名:

參數(shù)lpBuffer:輸出參數(shù),指向保存登錄用戶名的內(nèi)存緩沖區(qū)。其大小最好不小于(UNLEN+1),UNLEN定在Lmconsh中。nSize:輸入、輸出參數(shù),指向表示lpBuffer的大?。ㄗ址麛?shù))的DWORD型變量如果小于所需要的大小,那么lpnSize返回需要的大小,函數(shù)返回失敗。(2)GetComputerNae。函數(shù)定義如下:

參數(shù)lpBuffer:輸出參數(shù),指向保存計(jì)算機(jī)名的內(nèi)存緩沖區(qū),其大小最好不小于(MAXCOMPUTERNAME一LENGTH+1)。lpnSize輸入輸出參數(shù)指向表示lpBuffer的大字符數(shù)的DWORD型變量如果小于所需要的大小,那么lpnSize返回需要大小,函數(shù)返回失敗。

返回值BOOL型,表示是否成功。使用GetLastError獲取錯(cuò)誤信息。(3)GetComputerNameEx.除了以獲得計(jì)算機(jī)名外,還可以獲得NetBIOS或者DNS名,函數(shù)定義如下:

參數(shù)NameType:所需要取的計(jì)算機(jī)名的類型COMPTERNAMEFORMAT枚類型詳見(jiàn)示例。其他個(gè)參數(shù)使用方法與GetComputerName參數(shù)相同。

返回值BOOL型,表示是否成功。使用GetLastError獲取錯(cuò)誤信息。(4)SetComputerName、etComputerNameEx.SetComputerName設(shè)置算機(jī)NetBIOS名。SetComputerNmeEx可以設(shè)置DnsDomain、DnsHostnam、NetBOS。2.實(shí)例10-4用戶名、計(jì)算機(jī)名本實(shí)使用GetUserName獲取用戶名使用GetComputerName獲取計(jì)機(jī)名并演示了GetComDuterNameEx的使用方法。運(yùn)行果如圖10-1所示。10.1.5 處理系統(tǒng)顏色信息、尺度信息等GetSysColor可以獲取系統(tǒng)中與顏色有關(guān)的信息包括桌面顏色窗口顏色等與圖10-2所示“控制面版一顯示一外觀一高級(jí)”選項(xiàng)中所能進(jìn)行的設(shè)置相同。函數(shù)原型如下:與GetSysColor函數(shù)功相對(duì)的函數(shù)是SetSysColors,可以設(shè)置系統(tǒng)顏色。GetSystemMetrics可以獲取系統(tǒng)中各種尺度信息,包括圖標(biāo)大小(SMYSMICON)、窗標(biāo)題欄的系統(tǒng)按鈕大小(SM_CYIZE)等。圖10-2所高級(jí)外觀設(shè)置對(duì)話框可獲取和設(shè)置尺度大小信息,GetSystmMetricsAPI函數(shù)用于對(duì)尺度信息獲取,函數(shù)原型如下:10.1.6 鼠標(biāo)、鍵盤等外設(shè)信息1.關(guān)鍵API與數(shù)據(jù)結(jié)構(gòu)SystemParameterInfoAPI函數(shù)可以設(shè)置和獲取多種系統(tǒng)參數(shù),包括Windows輔助功能參數(shù)桌面設(shè)置參數(shù)圖標(biāo)參數(shù)輸入輸出參(包括鼠標(biāo)鍵盤設(shè)置語(yǔ)言設(shè)置警告音設(shè)置)菜單參數(shù)、電源設(shè)置參數(shù)、屏幕參數(shù)。函數(shù)定義如下:

參數(shù)uiAction是最主要參數(shù)需要設(shè)置和獲取的系統(tǒng)參數(shù)具有種類有很多可參見(jiàn)MSDN和SDK文檔。這個(gè)參數(shù)也決定了uiParampvParam的設(shè)置況。fWinIni:輸入?yún)?shù)指明設(shè)置的改變是否發(fā)送WM_SETTINGCHANGE消息給當(dāng)前系統(tǒng)中的窗口程序以及是否修改用戶剖(profile配信息參數(shù)可以是SPIF__UPDATEINIFLE或SPIF_SENDCHANGE或組合。

返回值表示作是否成功。使用GetLastError獲取錯(cuò)誤信息。2.實(shí)例10-5鼠標(biāo)速度本實(shí)是使用SystemParametersInfo函數(shù)獲取和設(shè)置當(dāng)前系統(tǒng)的鼠標(biāo)速度實(shí)例代碼如下:程序行后,可以感覺(jué)到鼠標(biāo)移動(dòng)速度有所提升。102時(shí)間信息本節(jié)介紹如何獲取和設(shè)置系統(tǒng)時(shí)間。10.2.1 設(shè)置、獲取系統(tǒng)時(shí)間獲取和設(shè)置系統(tǒng)時(shí)間使用API函數(shù)GetLocalTime、etSystemTime、GetSystemAdjustment、GetSystemTimeAsFileTime和GetSystemTimes等。相應(yīng)設(shè)置函數(shù)包括SetLocalTime、SetSystemTime、SetSytemTimeAdjustment等。GetTimZoneInforatin函數(shù)可以獲取系統(tǒng)時(shí)區(qū)設(shè)置。SysteTimeoTzSpeciicLocalTime和TzSpecificLocalTimeToystemTime用于標(biāo)準(zhǔn)時(shí)間和特定時(shí)區(qū)的時(shí)間之間進(jìn)行轉(zhuǎn)換。SetTimeZoneInformation用于設(shè)置時(shí)區(qū)信息。此外還有GetDynamicTimeoneInformation函數(shù)。以上API函數(shù)在進(jìn)行操作時(shí),大都使用了SYSTEMTIME結(jié)構(gòu),用于保存系統(tǒng)時(shí)間,此結(jié)構(gòu)定義如下:在涉及時(shí)區(qū)信息操作時(shí),使用TIME_ZONE_INFORMATION結(jié)構(gòu)表示時(shí)信息,定義如下:以上函數(shù)的參數(shù)設(shè)置都較簡(jiǎn)單,具體參見(jiàn)實(shí)例10-6。實(shí)例10-6設(shè)置、獲系統(tǒng)時(shí)間本實(shí)使用本節(jié)所述函數(shù)獲取系統(tǒng)當(dāng)前的國(guó)際標(biāo)準(zhǔn)時(shí)間當(dāng)前的本時(shí)區(qū)時(shí)間獲取系統(tǒng)所設(shè)置的時(shí)區(qū),并將時(shí)間在各時(shí)區(qū)內(nèi)進(jìn)行了轉(zhuǎn)換,然后修改系統(tǒng)時(shí)間,使其提前1小時(shí)。運(yùn)行結(jié)果如圖10-3和圖10-4所示。從運(yùn)行結(jié)果可以看出,實(shí)例獲取了當(dāng)前的系統(tǒng)時(shí)間,并將時(shí)間提前了一個(gè)小時(shí)。10.2.2 獲取開(kāi)機(jī)至現(xiàn)在持續(xù)的時(shí)間GetTickCount和GeTickCount64函數(shù)可以獲取系統(tǒng)開(kāi)機(jī)到現(xiàn)在所持續(xù)的時(shí)間,以ms為單位。使用GetTickCount和GetTickCount64函數(shù)獲取開(kāi)機(jī)至現(xiàn)在持續(xù)的秒數(shù)然后獲取當(dāng)前時(shí)間,并通過(guò)轉(zhuǎn)換計(jì)算出系統(tǒng)開(kāi)機(jī)時(shí)間。10.2.3 文件時(shí)間與系統(tǒng)時(shí)間的轉(zhuǎn)換Windows使用了不同的數(shù)據(jù)類型來(lái)存儲(chǔ)文件時(shí)間和系統(tǒng)時(shí)間由于文件系統(tǒng)中的每個(gè)文件都有若干種文件時(shí)間文件時(shí)間的數(shù)據(jù)量很大所以Windows使用了最少的數(shù)據(jù)來(lái)表示文件時(shí)間,F(xiàn)ILETIME結(jié)構(gòu)的小只有兩個(gè)DWORD,結(jié)定義如下:可以使用SystemTimeToFileTime和FileTimeToSstemTime將間信息在文件時(shí)間格式和系統(tǒng)時(shí)間格式之間轉(zhuǎn)換。文件時(shí)間屬性及操作方法見(jiàn)第4章有于這個(gè)兩函數(shù)的使用詳見(jiàn)第4章文件時(shí)間相關(guān)的實(shí)例。103注冊(cè)表本節(jié)紹與注冊(cè)表相關(guān)的操作首先簡(jiǎn)單介紹注冊(cè)表的組織形式使用注冊(cè)表編輯器查閱和修改注冊(cè)表然后介紹如何使用程序操作注冊(cè)表包括獲取注冊(cè)表的內(nèi)容修改注冊(cè)表等。10.3.1 注冊(cè)表的作用及組織形式Windows系統(tǒng)使用注冊(cè)表來(lái)存儲(chǔ)系統(tǒng)和應(yīng)用程序配置數(shù)據(jù)。很多系統(tǒng)和應(yīng)用程序重要的配置的信息都存儲(chǔ)在注冊(cè)表中注冊(cè)表是一種以樹(shù)型結(jié)構(gòu)組織的數(shù)據(jù)庫(kù)樹(shù)的每一個(gè)節(jié)點(diǎn)稱作鍵(key)每個(gè)節(jié)點(diǎn)可以包含若干子鍵,鍵可以存儲(chǔ)數(shù)據(jù),存儲(chǔ)的數(shù)據(jù)稱作鍵值。一個(gè)鍵無(wú)論其是否有子鍵都可以有鍵值一個(gè)鍵可以有很多個(gè)鍵值每個(gè)鍵值都有一個(gè)名字包含若干數(shù)據(jù),所包含的數(shù)據(jù)類型可以有很多種,表10.1出了注冊(cè)表數(shù)據(jù)類型。系統(tǒng)自帶的注冊(cè)表編輯(regedit.exe圖10-5所示以列舉查看修改增加、刪除鍵和子鍵、鍵值。從上可以看出,鍵“HKEYLOCALMACHINE\HARDWARE\DESCRITION\System”有6個(gè)鍵值,每個(gè)鍵值都有名稱,各鍵值的數(shù)據(jù)類型不相同,并且,此鍵還具有子鍵。10.3.2 鍵、子鍵、鍵屬性及鍵值的相關(guān)操作1.原理在對(duì)注表鍵進(jìn)行操作前,需要使用API函數(shù)RegOpenKey、RegOpenKeyEx打開(kāi)鍵。在打開(kāi)鍵后,如果需要?jiǎng)?chuàng)建新的鍵,使用API函數(shù)RegCreateKey、RegCreateKeyEx。這兩組函數(shù)都將返回鍵的句柄(HKEY類型。在得到鍵的句柄后,可以對(duì)鍵進(jìn)行操作。創(chuàng)建子鍵使用前述RegCreateKey、RegCreateKeyExAPI函數(shù)刪除鍵使用RegDeleteKeyRegDeleteKeyEx函數(shù)egQueryInfoKeyAPI函數(shù)獲取鍵多方面的信息包括鍵值子鍵等獲取和設(shè)置鍵值還可以使用RegGetValue、RegQueryValueEx、RegStValueEx、RegQueryMulipleValues等函數(shù);刪除指定的鍵值使用RegDeleteValue函數(shù)如果需要遍歷子鍵和鍵值,可以使用API函數(shù)RegEnumKeyEx和RegEnumValue函數(shù)。2.關(guān)鍵API(1)ReOpenKeyEx。打開(kāi)已經(jīng)存在的鍵,函數(shù)原型如下:

參數(shù)hKey:輸入?yún)?shù),需要打開(kāi)的鍵,可以是RegCreateKeyEx或者RegOpenKeyEx等函數(shù)的返回值??墒荋KEYCLASSES_ROT、HKEYCURRENTUSERHKEYUSERS、KEYLOAL_MACHINE.lpSubKey:輸入?yún)?shù),子鍵名稱字符串,如“SOFTWARE\\Microsot\\WindowsT\\CurrentVersion\\ImageFileExecuionOptionS''''。u10ptions:系統(tǒng)保留,調(diào)用時(shí)設(shè)置為0。samDesired:輸入?yún)?shù),存取權(quán)限,可以設(shè)置為NULL詳見(jiàn)SDK文檔。phkResult:輸出參數(shù)指向保存鍵句柄的HEY類型的變量RegCloseKey關(guān)閉鍵時(shí)需要這個(gè)值。

返回值LONG類型,如果成功返回ERROR_SUCCESS,否則返回FormatMessage函數(shù)設(shè)置FORMAT_MESAGE_FROM_SYSTM獲取錯(cuò)信息。(2)ReCreateKey。創(chuàng)建新的鍵,函數(shù)原型如下:

參數(shù)參數(shù)的使用方法可類比RegOpenKeyEx函數(shù)的相應(yīng)參數(shù)。

返回值類比RegOpenKeyEx函數(shù)的返回值。(3)RegGetValue、RgSetValue.分別為獲取和設(shè)置鍵值,RegGetValue函數(shù)原型如下所示:

參數(shù)Hkey:輸入?yún)?shù)由ReCreateKeyExRegOpenKeyEx等函數(shù)獲得的鍵句柄也可以是如下值:HKEY_CLASSES_ROOT、HEY_CURRET_CONFIG、HKEY_CURRENTUSER、HKEY_PERFORMANCENLSTEXT、KEYPERFORMANCE_TEXT、HKEY_USER_HKEY_LOCAL_MACHINE.HKEYPERFORMANCE__DATA.lpSubKey:輸入?yún)?shù)相對(duì)于hkey的子鍵如對(duì)hkey鍵本身的值進(jìn)行操作則為NULL。lpValue:輸入?yún)?shù)鍵值名如果為NULL或空字符串則獲取未命名鍵值或默認(rèn)鍵值。dwFlags:輸入?yún)?shù)類型限制如果指定的鍵值類型不符則執(zhí)行失敗也可以為設(shè)置為RRF_RT_ANY,不做限。參見(jiàn)實(shí)例10-1。pdwType:輸出參數(shù)類型信息。pvData:輸入?yún)?shù)保存值的緩沖區(qū)。pcbData:輸入、輸參數(shù),指向表示pvData緩沖區(qū)大小的變量。

返回值LONG類型的數(shù)據(jù)。如果成功,返回ERROR_SUCCESS;果緩沖區(qū)大小不足,返回ERROR_MORE__-DATA。RegGetValue函數(shù)原型如下所示:(4)RegDeleteValue。刪除鍵值,函數(shù)原型如下:(5)RegDeleteKeyEx。刪除鍵,函數(shù)原型如下:實(shí)例10-7注冊(cè)表操作本實(shí)例演示了對(duì)注冊(cè)表的常規(guī)操作,包括打開(kāi)、創(chuàng)建子鍵、設(shè)置鍵值,鍵值類型等。程序行后,在HKEY_CURRENTUSER\otfware鍵下多了一個(gè)子鍵MySoftware,并且設(shè)置了一個(gè)REG_DWORD類的鍵值“TEST”,值為Ox64(100),如圖10-6示。10.3.3 列舉注冊(cè)表項(xiàng)及鍵值1.原理遍歷子鍵和鍵值可以使用API函數(shù)RegEnumKeyEx和RegEnumValue函數(shù)。RegQueryInoKey,RegEnumKeyEx和RegEnumValue相配合可以完成對(duì)一個(gè)鍵的有子鍵及鍵值的列舉。函數(shù)參數(shù)設(shè)置情況參見(jiàn)實(shí)例10-8。2.實(shí)例10-8遍歷子鍵和鍵值本實(shí)是實(shí)例10-7中所調(diào)用的QueryKey函的代碼本實(shí)例獲取指定鍵下的所有鍵值及所有子鍵。如果將函數(shù)進(jìn)行遞歸調(diào)用就可以遍歷注冊(cè)表樹(shù)。函數(shù)將HKEY_CURRENTUSER\Sotfware下的所有鍵打印出來(lái),對(duì)比圖10-6和圖10-7,說(shuō)明結(jié)果正確。10.3.4通過(guò)注冊(cè)表設(shè)置一個(gè)自啟動(dòng)的程序10.3.410.3.7小節(jié)將說(shuō)明一些注冊(cè)表的應(yīng)用,都是應(yīng)用程序開(kāi)發(fā)人員常用的應(yīng)用方式。本節(jié)將介紹通過(guò)注冊(cè)表設(shè)置開(kāi)機(jī)自啟動(dòng)的程序。程序自啟動(dòng)有很多種方法注冊(cè)表是其中最常用的一種有多個(gè)鍵具有這種功能最常用的有:HKEY_LOCAL_MACHINE\SOFTWARE\Micrsoft\WindowsCurrentVersion\Run,只需設(shè)置REG二SZ類型的鍵值,將值設(shè)置為程序的路徑即可使用程序在系統(tǒng)啟動(dòng)時(shí)自啟動(dòng)。如果只需要在下次系統(tǒng)啟動(dòng)時(shí)自啟動(dòng)一次,那么可以設(shè)置鍵HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce的鍵值。10.3.5 設(shè)置隨程序啟動(dòng)而啟動(dòng)的調(diào)試器(任何程序)本節(jié)將紹如何在程序啟動(dòng)時(shí)加載調(diào)試器(讀者也可以用于設(shè)置自啟動(dòng)程序?!癏KEY_LOCAL_MACHINE\OFTWAREYMicrosoft,\WindowsNT\CurrentVerso\ImageFileExecutionOptions”下的子鍵可以用于指定啟動(dòng)調(diào)試器。如需要調(diào)試os_info.exe,在“ImageFileExecutionOptions”鍵下創(chuàng)建子鍵“os_info.exe”;然后創(chuàng)建鍵值,名為“Debugger”,類型為REG_SZ,數(shù)據(jù)為啟動(dòng)調(diào)試器的命令行,這里指向Windbg,如:“C:\ProgrmFiles\DebggingToolsorWindows\windbg.exe(可以是何可執(zhí)行文件,比如notepad.exe在載鍵名稱程序模塊時(shí)會(huì)首先啟“Debugger”鍵值指定的應(yīng)用程序,并以鍵名指向的可執(zhí)行程序?yàn)閰?shù)。運(yùn)行os_info.exe就會(huì)啟動(dòng)Windbg運(yùn)行調(diào)試。10.3.6 指定程序崩潰實(shí)時(shí)調(diào)試器本小節(jié)介紹如何在程序崩潰時(shí)使用調(diào)試器用于調(diào)試一些特殊的程序在使用Windows時(shí)會(huì)經(jīng)常發(fā)生程序崩潰的情況程序開(kāi)發(fā)人員可以設(shè)置注冊(cè)表鍵以在程序崩潰時(shí)可以啟動(dòng)調(diào)試器運(yùn)行調(diào)試。一般況下,在程序崩潰后會(huì)有如圖10-8所示的對(duì)話框。如果單擊“調(diào)試”按鈕將會(huì)啟動(dòng)實(shí)時(shí)調(diào)試器,如圖10-9示。可以通過(guò)注冊(cè)表指定實(shí)時(shí)調(diào)試器,比如指定為WinDBG或OllyDBG等調(diào)試器。指定實(shí)時(shí)調(diào)試器的方法為指定注冊(cè)表鍵“HKEYLOCALMACHIN\SOFTARE\Microsoft\WindowsNT\Currentersion\AeDebug”的Dbugger”鍵值。第1章進(jìn)程間通信進(jìn)程地址空間是私有的出于安全性的目的如果一個(gè)進(jìn)程不具有特殊的權(quán)限是無(wú)法訪問(wèn)另外一個(gè)進(jìn)程的內(nèi)存空間的也無(wú)法知道內(nèi)存中保存的數(shù)據(jù)的意義但是在一些具體的應(yīng)用情況下需要多個(gè)進(jìn)行相互配合,有時(shí)計(jì)算機(jī)用戶也需要在多個(gè)應(yīng)用程序之間交換數(shù)據(jù)。Windows系統(tǒng)下,在進(jìn)程間通信或共享數(shù)據(jù)的方式如下。

郵(Mailslot。郵槽最為簡(jiǎn)單的進(jìn)程間數(shù)據(jù)共享方式一個(gè)進(jìn)程創(chuàng)建并擁有一個(gè)郵槽其他進(jìn)程都可以打開(kāi)這個(gè)郵槽并向其發(fā)送消息。11.1節(jié)及相關(guān)實(shí)例介紹了郵槽的使用。

管(Pipe)。實(shí)質(zhì)一種共享的內(nèi)存由一個(gè)進(jìn)程創(chuàng)建其他進(jìn)程連接并可進(jìn)行雙向的通信11.2節(jié)及相關(guān)實(shí)例介紹了管道的使用。

剪板(Clipboard)。剪貼是重要的進(jìn)程間數(shù)據(jù)共享方式所有的進(jìn)程都可以設(shè)置和修改剪貼板也都可以從剪貼板獲取內(nèi)容。11.3節(jié)及相關(guān)實(shí)例介紹了剪貼板使用。

息,具體是指WM_COPYDATA消息。消息具有參數(shù)wParam和lParam但是wParam和lParam最多是32位的而WM_COPYDATA消息的參數(shù)不受wParam和lParam數(shù)據(jù)大小的限制,可以用于在進(jìn)程間傳遞數(shù)據(jù)。11.4節(jié)及相關(guān)實(shí)例介紹了WM-COPYDATA消息的用方法。

網(wǎng)絡(luò)。網(wǎng)絡(luò)可以在不同主機(jī)上的不同程序間通信,當(dāng)然也可以在相同主機(jī)上的不同程序間通信。

ileMapping第4章已經(jīng)介紹了FileMapping的使用方法實(shí)例4-15已實(shí)現(xiàn)了通過(guò)Fileapping進(jìn)行進(jìn)程間通信的方法。.1郵槽(MailSlot)使用槽通信的進(jìn)程分為服務(wù)端和客戶端郵槽由服務(wù)端創(chuàng)建在創(chuàng)建時(shí)需要指定郵槽名創(chuàng)建后服務(wù)端得到郵槽的句柄在郵槽創(chuàng)建后客戶端可以通過(guò)郵槽名打開(kāi)郵槽在獲得句柄后可以向郵槽寫入消息。郵槽信是單向的只有服務(wù)端才能從郵槽中讀取消息客戶端只能寫入消息消息是先入先出的??蛻舳讼葘懭氲南⒃诜?wù)端先被讀取。通過(guò)槽通信的數(shù)據(jù)可以是任意格式的,但是一條消息不能大于424字節(jié)。郵槽了在本機(jī)內(nèi)進(jìn)行進(jìn)程間通信外在主機(jī)間也可以通信但是在主機(jī)間進(jìn)行郵槽通信數(shù)據(jù)通過(guò)網(wǎng)絡(luò)傳播時(shí)使用的是數(shù)據(jù)報(bào)協(xié)議(UDP)所是一種不可靠的通信通過(guò)網(wǎng)絡(luò)進(jìn)行郵槽通信時(shí),客戶端必須知道服務(wù)端的主機(jī)名或域名。1.1.1 創(chuàng)建郵槽、從郵槽中讀取消息首先介服務(wù)端的編寫。服務(wù)端調(diào)用CreateMailslotAPI函數(shù)創(chuàng)建郵槽,然后使用GetMailslotInfoAPI數(shù)獲取郵槽信息。讀取消息使用ReadFile函數(shù)。1.郵槽的命名在本機(jī)上郵槽命名的格式為:比如:也可以使用如下格式的命名,用于在不同主機(jī)間的進(jìn)程通信。可以使用通配符,以進(jìn)行廣播。2.關(guān)鍵API(1)CreateMailslot。CreateMailslot函數(shù)的功能是創(chuàng)建一個(gè)郵對(duì)象,CreateMailslot函數(shù)的原型如下:lpName:參數(shù)是郵槽名。nMaxMessageSize:制了最大消息長(zhǎng)度。lReadTimeout:限制了讀超時(shí)的時(shí)間(ms),也可設(shè)置0(如果沒(méi)有消息立即返回)或MAILSLOT_WAIT_FOREVER(直到讀到消息才返回。lpSecurityAttributes:安全屬。(2)GetMailslotIno。GetMailslotInfo函數(shù)的功能是獲取郵槽的相關(guān)信息,函數(shù)原型如下:GetMailslotInfo數(shù)獲取了郵槽的相關(guān)信息,包括通過(guò)lpMaxMessageSize參數(shù)返回的消息最大的長(zhǎng)度通過(guò)lpNextSize消息返回下一條消息的長(zhǎng)度通過(guò)lpMessageCount返回的消息數(shù)量,通過(guò)lpReadTimeout返回的讀時(shí)時(shí)間。(3)SetMailslotIno。另外郵件被創(chuàng)建后仍然可以修改讀操作時(shí)間超時(shí)時(shí)間通過(guò)APISetMailslotInfo函數(shù)設(shè)置。3.實(shí)例11-1郵槽通信服務(wù)端程序本實(shí)例中創(chuàng)建了一個(gè)名為“\\\\.\\mailslt\\sample_ailslot”的郵槽,然后使用GetMailslotInfo函數(shù)讀取消息數(shù)量如果沒(méi)有消息則等待20s獲信息循環(huán)直至有消息到達(dá),然后一次性讀出全部消息。這種式只有在固定的時(shí)間間隔才讀取如果需要在有消息到達(dá)時(shí)立刻獲得消息可以將讀操作超時(shí)時(shí)間設(shè)置為MAILSLOT_WAITFOREVER,然后調(diào)用ReadFile,ReadFile在有消息可讀時(shí)才會(huì)讀取消息并返回。1.1.2 通過(guò)郵槽發(fā)送消息客戶端郵槽發(fā)送消息需要首先打開(kāi)郵槽然后直接使用WriteFile函數(shù)寫入打開(kāi)郵槽使用CreateFile函數(shù)??蛻舳嗽诖蜷_(kāi)郵槽需要知道郵槽名。1.實(shí)例11-2郵槽通信服務(wù)端程序本實(shí)打開(kāi)了名為\\\\.\\mailslot\\sample_mailslot郵槽然后寫入了一條消息。消息的內(nèi)容是“TestMesageformailslot”。2.實(shí)例11-1、11-2運(yùn)行結(jié)果進(jìn)行服務(wù)端程序,再運(yùn)行客戶端程序(可運(yùn)行多次,客戶端程序運(yùn)行結(jié)束后退出,服務(wù)端程序輸出如圖11-1所示。.2管道(Pipe)管道一種用于在進(jìn)程間共享數(shù)據(jù)的機(jī)制其實(shí)質(zhì)是一段共享內(nèi)存Windows系統(tǒng)為這段共享的內(nèi)存設(shè)計(jì)采用數(shù)據(jù)流I/0的方式來(lái)訪問(wèn)由一個(gè)進(jìn)程讀另一個(gè)進(jìn)程寫類似于一個(gè)管道兩端,因此這種進(jìn)程間的通信方式稱作“管道。管道為匿名管道和命名管道。匿名道只能在父子進(jìn)程間進(jìn)行通信不能在網(wǎng)絡(luò)間通信而且數(shù)據(jù)傳輸是單向的只能一端寫,另一端讀。命令道可以在任意進(jìn)程間通信通信是雙向的任意一端都可讀可寫但是在同一時(shí)間只能有一端讀、一端寫。由于令管道更具有通用性,本節(jié)介紹命名管道。1.2.1 創(chuàng)建命名管道創(chuàng)建名管道有專門的API函數(shù)。1.關(guān)鍵APICreateNamedPiDe是用于創(chuàng)建命令管道的API數(shù),原型如下:

參數(shù)lpName參數(shù):管道名。命名方式如下所示:dwOpenMode參數(shù)是打開(kāi)模式。包括存取模式、I/0式等,其值如表11.1所示。dwPipeMode參數(shù):管道模式,包括管道類型模式、管道讀模式和管道等待模式。管道類型模式有PIPE_TYPE_YTE或PIPE_TYPEMESSAGE,如果設(shè)置為前一種模式,那么所有寫入管道的數(shù)據(jù)都是以連接字節(jié)的形式存在,而后一個(gè)模式,系統(tǒng)會(huì)將每一次調(diào)用WriteFile寫入管理的數(shù)據(jù)作為一個(gè)消息,管道中的內(nèi)容是分塊的。管道讀模式可以是PIPE_-READMODE_YTE或者PIPE_READMODEMESSAGE,分別表示從管道中讀取的信息是連續(xù)的還是以獨(dú)立消息的形式存在的。等待模式可以是PIPE_WAIT或者PIPE__NOWAIT,分表示讀寫操作是否阻塞(是否在無(wú)數(shù)據(jù)時(shí)立刻返回。nMaxInstances參數(shù)表示指定了一個(gè)pipe所能立的最多的實(shí)例同名的pipe可以被創(chuàng)建多次,一次稱作一個(gè)實(shí)例,每個(gè)實(shí)例可以接收一個(gè)連接。nOutBufferSze和nInBufferSize:別是輸出和輸入的緩存大。nDefaultTimeOut:超時(shí)間。lpSecurityAttributes:安全屬性。

返回值返回創(chuàng)建的管道的句柄。2.實(shí)例11-3創(chuàng)建命令管道以下代創(chuàng)建了一個(gè)名為“\\\\.\\pipe\\samlenamedpipe”的管道這是一個(gè)用于本機(jī)內(nèi)兩個(gè)進(jìn)程通信的管道設(shè)置了存取模式為可讀可寫而且采用了異步重疊模式(FILEFLAG_OVERLAPPED),管道類型為消息型,讀取時(shí)也是按消息讀取。代碼中的CreateAndConnectInstance函數(shù)最后調(diào)用了ConnectToNewClient函數(shù)監(jiān)聽(tīng)客戶端的連接。ConnectToewClient函數(shù)實(shí)例代見(jiàn)11.2.2小節(jié)。1.2.2 管道監(jiān)聽(tīng)ConnectToNewClient函數(shù)功能是監(jiān)聽(tīng)?wèi)舳说倪B接用了API函數(shù)ConnectNamedPpe。1.關(guān)鍵APIConnectNamedPipe函數(shù)是pipe服端用于等待客戶端連接的函數(shù),函原型如下:參數(shù)hNamedPipe是pipe句柄,直接使用CreateNamedPipe函數(shù)的返回值即可。lpOverlapped是指向OVERLAPPED結(jié)構(gòu)的指如果在創(chuàng)建管道時(shí)指明了I/O模式為重疊的(lpOverlapped),么必須指定本參數(shù);否則設(shè)置為NULL。2.實(shí)例11-4創(chuàng)建命令管道本實(shí)調(diào)用了ConnectNamedPipeAPI函數(shù)。當(dāng)有客戶連接時(shí),函數(shù)返回,后根據(jù)返回值判斷狀態(tài)。1.2.3 使用異步I/O進(jìn)行讀寫本書前章節(jié)在使用到I/O時(shí)例如文件I/O時(shí),都是用同步I/O模式,在使用異步I/O時(shí),先了解以下基本概念。1.110模式由于些進(jìn)程間通信的方法(pipe)涉及到了Windows系統(tǒng)的I/O模式I]O模式不僅在進(jìn)程間通信時(shí)使用任何具有數(shù)據(jù)流形式的輸入輸(包括文件輸入輸出內(nèi)核通信網(wǎng)絡(luò)輸入輸出等)都涉及I/O模式。異(Asynchronous)和同步Synchonous)I/O是兩種基本的I/O模式。其中涉及許多細(xì)節(jié),同步I/O和步I/0的詳細(xì)區(qū)別,本書將在16.4節(jié)介紹。由于第4章第14章和第16章分別介紹了文件I/O和網(wǎng)絡(luò)I/O和設(shè)備I/O內(nèi)通信。在學(xué)習(xí)這部分內(nèi)容時(shí)可以和相關(guān)章節(jié)相聯(lián)系。2.異步I/O所謂步I/O是指在調(diào)用ReadFileWriteFile等函數(shù)進(jìn)行入輸出操作時(shí)系統(tǒng)完成了輸入輸出ReedFileWriteFile才返回在操作系統(tǒng)進(jìn)行I/O操作的過(guò)上用戶態(tài)線程不能執(zhí)行,因此在同步I/O時(shí),如果需要在I/0時(shí)進(jìn)行其他操作就只能再開(kāi)啟線程。而異步I/O是在用ReadFileWriteFile等函數(shù)后函數(shù)立即返回線程可以進(jìn)行其他操作。剩下的I/O操作在系統(tǒng)內(nèi)核中自動(dòng)完成。那么在系統(tǒng)內(nèi)核完成輸入輸出后,程序如何知道I/O是否已完成?在本實(shí)例中采用了一種方法,稱作完成函數(shù)(CompletionRoutines,如果使用ReadFileEx、WriteFileEx等進(jìn)行I/O,可以指定完成函數(shù),所謂完成函數(shù)是指內(nèi)核在完成I/O后,內(nèi)核會(huì)回調(diào)這個(gè)函數(shù)。當(dāng)完成函數(shù)被調(diào)用時(shí),就指明內(nèi)核已經(jīng)完成了I/O,程序可以在這個(gè)函數(shù)中進(jìn)行一個(gè)I/O完后需要的操作(例如釋放內(nèi)存。實(shí)例11-5就使用了種方式。3.實(shí)例11-5對(duì)Pipe進(jìn)行讀寫讀和操作的完成函數(shù)如下所示:在讀操作完成后,調(diào)用讀操作的完成函數(shù)CompletedReadRoutine。而CompletedReadRoutine函數(shù)又開(kāi)始新的寫操作。在CompletedReadRoutine函數(shù)進(jìn)行的寫操作I/O完成后寫操作的完成函數(shù)CompletedWriteRoutine被調(diào)用,而正是在CompletedriteRoutine中進(jìn)行的寫作。如果環(huán)往復(fù),形成交替讀寫的流程。下面來(lái)分析讀寫操作循環(huán)的入口點(diǎn)。分析maIn函數(shù):在maln函數(shù)中進(jìn)行了一次CompleteWriteRoutine函數(shù)調(diào)用。這次調(diào)用開(kāi)始了循環(huán)交替讀寫。在調(diào)用CompletedWriteRoutine之前,mam函數(shù)還行若干與重疊I/O相關(guān)的操作。CompletedReaRoutne函數(shù)調(diào)用了GetAnswerToRequest函數(shù),GetAnswerToRequest函數(shù)用于處理不同的客戶端輸入可以根據(jù)不同輸入給出不同的反饋在本實(shí)例中對(duì)所有輸入都回復(fù)"Defautanswerfromserver"。各函之間的參數(shù)傳遞主要是通過(guò)PIPEINST結(jié)構(gòu)傳遞,定義在maln函數(shù)之前。1.2.4 關(guān)閉管道實(shí)例如果在讀寫過(guò)程中發(fā)生了錯(cuò)誤服務(wù)端程序會(huì)斷開(kāi)管道的連接并關(guān)閉實(shí)例句柄關(guān)閉連接使用API函數(shù)DisconnectNamedPipe,參數(shù)為實(shí)例句柄。1.2.5 客戶端與服務(wù)相比客戶端實(shí)例程序的功能相對(duì)較簡(jiǎn)單首先是打開(kāi)命名管道獲得句柄然后向管道中寫入數(shù)據(jù),之后等待服務(wù)端的回復(fù)。1.原理與關(guān)鍵API在實(shí)例11-6中,首先有一個(gè)while循環(huán),本循環(huán)在客戶端成功打開(kāi)命名管道(管道名需與服務(wù)端所創(chuàng)建的一致后結(jié)束如果打開(kāi)管道時(shí)管道繁忙將等待一段時(shí)間再連接或者在程序發(fā)生錯(cuò)誤時(shí)直接退出。打開(kāi)名管道使用的函數(shù)是CreateFile調(diào)用CreateFile時(shí)服務(wù)端會(huì)收到客端的連接請(qǐng)求,打開(kāi)成功后會(huì)連接管道。等待一個(gè)管道變?yōu)榭捎脿罱艿腁PI函數(shù)是WaitNamedPipe。WaitNamedPipe函數(shù)一直等待,直到管道實(shí)例可用或者超時(shí)。如果程序成功連接到服務(wù)端使用SetNamedPipeHandleState函數(shù)設(shè)置管道的讀寫模式由于客戶端使用CreateFile函數(shù)打開(kāi)管道,而在打開(kāi)時(shí)法指定讀寫模式,因此在打開(kāi)成功后要再調(diào)用SetNamedPipeHandleState函數(shù)設(shè)置讀寫模式實(shí)例中設(shè)置為以消息方式讀。SetNamedPipeHanleState函數(shù)原型下:hNamedPipe參數(shù)是道句柄lpMode用于設(shè)置管道的模式lpMaxColletionCount和lpCollectDataTimeout用于設(shè)置數(shù)據(jù)的緩存大小,在同一主機(jī)進(jìn)程間通信時(shí)無(wú)意義。2.實(shí)例11-6管道通信客戶端程序管道信和客戶端實(shí)現(xiàn)代碼如下:3.運(yùn)行結(jié)果先運(yùn)行服務(wù)端程序,再運(yùn)行客戶端程序??蛻舳顺绦蚩梢赃\(yùn)行多次。運(yùn)行兩次服務(wù)端程序,程序運(yùn)行結(jié)果如圖11-2所示。客戶端程序運(yùn)行結(jié)果如圖11-3所示。.3剪貼板剪貼是最常用的系統(tǒng)特性之一計(jì)算機(jī)用戶在使用計(jì)算機(jī)時(shí)經(jīng)常會(huì)使用到剪貼板剪貼板由系統(tǒng)定義并不屬于任何一個(gè)特定的進(jìn)程系統(tǒng)中所有進(jìn)程都可以訪問(wèn)和設(shè)置剪貼板。很多具有“復(fù)制“貼”功能的文字編譯程序都是通過(guò)剪貼板進(jìn)行操作的。剪貼最大的特點(diǎn)就是數(shù)據(jù)傳輸沒(méi)有明確的目標(biāo)數(shù)據(jù)是被動(dòng)訪問(wèn)的設(shè)置剪貼板的程序并不知道所設(shè)置的數(shù)據(jù)什么時(shí)候被訪問(wèn)也不知道被哪個(gè)進(jìn)程訪問(wèn)剪貼板中的內(nèi)容也可以多次訪問(wèn),直到新的數(shù)據(jù)寫入。正是此特性決定了剪貼板便于計(jì)算機(jī)用戶進(jìn)行直接操作。因此過(guò)剪貼板也是一種可供選擇的進(jìn)程間通信方式但是由于系統(tǒng)中任何一個(gè)進(jìn)程都可以無(wú)限制地訪問(wèn)剪貼板,剪貼板也是一種不可靠的通信方式。本節(jié)中11.3.1小節(jié)通過(guò)實(shí)例介紹了對(duì)剪貼板的基本操作,包括設(shè)置剪貼板中的數(shù)據(jù)、從剪貼板獲取數(shù)據(jù)等。11.3.2小節(jié)通過(guò)實(shí)例介紹了如何對(duì)剪貼板的修改進(jìn)行監(jiān)視,這種機(jī)制可以使用程序及時(shí)發(fā)現(xiàn)剪貼板中的數(shù)據(jù)變化。使用通過(guò)剪貼板傳輸數(shù)據(jù)可以具有實(shí)時(shí)性。11.3.3小節(jié)介紹了剪貼板中數(shù)據(jù)的格式及自定義數(shù)據(jù)格式的方法。1.3.1 獲取、設(shè)置剪貼板數(shù)據(jù)系統(tǒng)提供了專門的API函數(shù)來(lái)設(shè)置和獲取剪貼板,包括OpenClipboard、EmptyClipboard、etClipboardData、GetClipboardData、CoseClipboard等。1.關(guān)鍵API(1)OpenClipboard。OpenClipboard函數(shù)的功能是打開(kāi)剪貼板獲得剪貼板的句柄后續(xù)所有對(duì)剪貼板的操作都需要該句柄。函數(shù)原型如下:參數(shù)hWndNewOwner定了與剪貼板句柄相配合的窗口句柄。指定的窗口可以收到剪貼板操作所產(chǎn)生的消息(參見(jiàn)11.3.2小節(jié),如指定NULL采用當(dāng)前任務(wù)的窗口。(2)EmptClipboard。在得到剪貼板句柄后,可以對(duì)剪貼板進(jìn)行操作。EmptyClipboard的功能是清空剪貼板中的內(nèi)容,無(wú)參數(shù)。(3)SetCliboardData。SetClipboardData函數(shù)的功能是設(shè)置剪板內(nèi)容,函數(shù)原型如下:uFormat參數(shù)指定了數(shù)據(jù)的格式可以是標(biāo)準(zhǔn)系統(tǒng)格式也可以是用戶自定義格式剪貼板的數(shù)據(jù)格式見(jiàn)11.3.3小節(jié)。hMem是需要設(shè)置的數(shù)據(jù)的內(nèi)存句柄。需使用全局內(nèi)存管理的函數(shù)分配和設(shè)置,且在分配時(shí)需指定GMEM-一MOVEABLE標(biāo)志(參考第5章。(4)GetClipboardData。GetCliDboardData函數(shù)功能是從剪貼板獲取數(shù)據(jù),函數(shù)原型如下:參數(shù)uFormat指定獲取的數(shù)據(jù)的格式獲取的數(shù)據(jù)使用句柄返回根據(jù)設(shè)置的格式不同,返回的數(shù)據(jù)類型不同。如果指定為CF_TEXT,回的是字符串指針。2.實(shí)例11-7管道通信客戶端程序本實(shí)例ClipText.exe演示了對(duì)文本復(fù)制粘貼等操作程序包括一個(gè)窗口一組菜單。菜單中包括“復(fù)制剪切“貼”等項(xiàng)。在單擊菜單后作相應(yīng)的處理。程序在窗口客戶區(qū)顯示文本,顯示的文本由全局變量lpszText指定。在窗口消息處理函數(shù)每次收到窗口繪制(WM_PAINT)函數(shù)時(shí),調(diào)用DrawTextAPI函數(shù)將字符串顯示在客戶區(qū)(原理參第13章GDI相關(guān)內(nèi)。如果通過(guò)菜單輸入“復(fù)制”(命令I(lǐng)D為IDMCOPY),序調(diào)用SetClipboardData函數(shù)將窗口上顯示的內(nèi)容(lpszText)設(shè)到剪貼板由于本程序只支持文本操作所以將格式設(shè)置為CF_TEXT。如果輸入的命令是“剪切”(命令I(lǐng)D為IDM_CUT),除了成復(fù)制的功能處,還將lpszText字符串釋放。如果過(guò)菜單輸入“粘貼(命令I(lǐng)D為IDM_PASTE程序調(diào)用GetClipboardData從剪貼板中獲得數(shù)據(jù),賦值給lpszText。然后在界面上顯示內(nèi)容。為了到顯示的效果,本實(shí)例直接使用GDI接口函數(shù)在主窗口的客戶區(qū)上繪制出文本,而沒(méi)有采用本身就具有剪貼板操作功能的EDIT、RichEdit等控件。3.運(yùn)行結(jié)果運(yùn)行實(shí)例后可以從其他應(yīng)用程序復(fù)制數(shù)據(jù)到本程序也可以從本程序復(fù)制數(shù)據(jù)到其他應(yīng)用程序。參見(jiàn)圖11-4和圖11-5。1.3.2 監(jiān)視剪貼板實(shí)例11-7中的程序在通過(guò)剪貼板進(jìn)行數(shù)據(jù)通信時(shí)不具有實(shí)時(shí)性所有操作都依賴于用戶。如果要立即知道剪貼板中的內(nèi)容變化,需要使用剪貼板查看器(Viewer)。1.原理與關(guān)鍵API(1)WM_DRAWCLIPBOARD消息。系統(tǒng)供了WM_DRAWCLIPBOARD消息用于監(jiān)視剪貼板的變化。如果調(diào)用SetClipboardViewer函數(shù)設(shè)置了窗口為剪貼板查看器,那么當(dāng)剪貼板中的內(nèi)容變化時(shí),所注冊(cè)的查看器窗口會(huì)收到WM_CHANGECBCHAIN消息和WM_DRAWCLIPBOARD消息。當(dāng)剪板中的內(nèi)容變化時(shí),窗口會(huì)收到WMDRAWCLIPBOARD消息。當(dāng)查看器鏈表中有新的節(jié)點(diǎn)加入或有節(jié)點(diǎn)退出窗口會(huì)收到WM_CHANGECBCHAIN消息。(2)SetClipboardViewer函數(shù)原型如下:hWndNewViewer參數(shù)指定了監(jiān)視窗口,也即是用于接收WM_CHANECBCHAIN消息和WM_DRAWCLIPOARD消息窗口。2.實(shí)例11-8剪貼板查看器本實(shí)例ClipView.exe是一個(gè)剪貼板查看器在窗口創(chuàng)建(WM_CREATE消息用了API函數(shù)SetClipbardViewer將程主窗口設(shè)置為查看器。窗口收到WM_CHANGECBCHAIN時(shí)根據(jù)情況更新鏈表。窗口在收到WM.DRAWCLIPBOARD消息后調(diào)用了SetAutoView數(shù),而SetAutoView函數(shù),在調(diào)用GetPriorityClipboardFormatAPI函數(shù)獲得剪貼板中數(shù)據(jù)的主要格式后,調(diào)用UpdateWindow刷新窗口。因此,一旦剪貼板變化,ClipView.exe的窗口就會(huì)刷新。而如本實(shí)例代碼所示,而窗口刷新過(guò)程(WM_PAINT消息)中,程序會(huì)獲取剪貼板中的數(shù)據(jù),并根據(jù)剪貼板數(shù)據(jù)的格式進(jìn)行顯示。本實(shí)例主要演示了如何監(jiān)視剪貼板內(nèi)容的變化;同時(shí)還演示了如何使用剪貼板數(shù)據(jù)格式。數(shù)據(jù)格式的相關(guān)原理解釋參見(jiàn)11.3.3小節(jié)。3.運(yùn)行結(jié)果如圖11-6示,運(yùn)行ClipView.exe,如果截屏,那么會(huì)顯示所截獲的位圖。如果在Word中復(fù)制數(shù)據(jù)那么可以顯示所復(fù)制的文本文件具有格式果如圖11-7所示。1.3.3 剪貼板數(shù)據(jù)格式剪貼板可能會(huì)存在各種各樣的數(shù)據(jù)因此剪貼板中在保存數(shù)據(jù)的同時(shí)還需要保存數(shù)據(jù)的格式信息。系統(tǒng)用一個(gè)UINT類型的數(shù)據(jù)來(lái)表示剪貼板中的數(shù)據(jù)格式。在這格式信息中有很多是各種應(yīng)用程序之間通用的比如文本位圖等這些數(shù)據(jù)格式已經(jīng)由系統(tǒng)預(yù)先定義,稱為標(biāo)準(zhǔn)格式。當(dāng)然一些應(yīng)用程序也希望自行定義剪貼板的數(shù)據(jù)格式這樣可以方便地在同一個(gè)應(yīng)用程序的不同實(shí)例間進(jìn)行數(shù)據(jù)傳遞而不需要對(duì)數(shù)據(jù)的格式進(jìn)行過(guò)多的處理(典型的就包括Word)。1.標(biāo)準(zhǔn)格式標(biāo)準(zhǔn)式有很多種,表11.2列舉出最為常用的幾種。2.自定義格式如果需要自定義格式,那么調(diào)用RegisterClipboardFormatAPI函數(shù),函數(shù)型如下:在調(diào)時(shí),便用lpszFormat參數(shù)指定一個(gè)格式名,函數(shù)會(huì)返回系統(tǒng)為其分配的格式類型值(UINT)。3.多種格式在很情況下,數(shù)據(jù)的格式不止一種,比如格式化的文本(如從Word中復(fù)制的數(shù)據(jù)、從網(wǎng)頁(yè)中復(fù)制的數(shù)據(jù)等)有效的格式不止一種,就可能會(huì)具有多重格式。以下個(gè)API函數(shù)都是用于獲取當(dāng)前剪貼板中格式信息。(1)GetPriorityClipboardFormt.GetPriorityClipboardFrmat函數(shù)的功能是檢測(cè)剪貼板中是否有特定格式的數(shù)據(jù),函數(shù)原型如下:檢測(cè)否有paFormatPriorityList參數(shù)所指定的格式數(shù)組中的格式,如有則返回?cái)?shù)組中的第一個(gè)剪貼板前具有的格式。cFrmats是paFormatPriorityList數(shù)組的小。(2)CountClipboardFrmatS。CountClipboardFormts函數(shù)返回當(dāng)前剪貼板中的具有的不同格式的數(shù)量,函數(shù)原型如下:(3)EnumClipboardFormatS。EnumClipboardFormats函數(shù)可以列舉當(dāng)前剪貼板中的所有格式,函數(shù)原型如下:通過(guò)format參數(shù)指定一個(gè)已知的格式,通過(guò)返回值返回下一個(gè)格式。(4)GetUpdatedClipboardFormatSaGetUpdatedCipboardFormats函數(shù)取當(dāng)前剪貼板的所有格式,函數(shù)原型如下:lpuiFormats參數(shù)指向用于保存返回的格式數(shù)組的緩存。cFormats表示lpuiFormats可以容納的格式信息的數(shù)量,即lpuiFormats數(shù)組的大小。pcFormatsOut返回真實(shí)的數(shù)組大小。4.剪貼板數(shù)據(jù)的格式信息每一個(gè)剪貼板格式都有一個(gè)格式名,格式名是一個(gè)字符串,使用GetClipboardFormatNameAPI函數(shù)可以獲得。GetClipboardFormatName函數(shù)型如下:.4數(shù)據(jù)復(fù)制消息(WM_COPYDA)WM_COPYDATA是一個(gè)非常特殊的消息此消息可能攜帶一個(gè)比較大的消息參數(shù)而其他消息都只能攜帶兩個(gè)固定大小的參數(shù)(WPARAM和LPARAM)。在發(fā)送WM_COPYDATA消息時(shí),WM_COPYDATA的wParam參數(shù)應(yīng)該賦值為發(fā)送此消息的窗口,而lParam消息數(shù)指向一個(gè)COPYDATASTRUCT結(jié)構(gòu)類的變量。COPYDATASTRUCT結(jié)構(gòu)如下:dwData可以是任意值lpata是需要發(fā)送給目錄窗口所在進(jìn)程的數(shù)據(jù)cbData字符指定了lpData內(nèi)存區(qū)域的字節(jié)數(shù)也是需要發(fā)送給目標(biāo)進(jìn)程的lpData所指向的數(shù)據(jù)的大小。在消發(fā)送時(shí),系統(tǒng)會(huì)將整個(gè)COPYDATASTRUCT及l(fā)pData所指向的內(nèi)容全部發(fā)送給目標(biāo)進(jìn)程。目標(biāo)進(jìn)程窗口在收到WM—COPYDATA后,可以從lParam參數(shù)提取出數(shù)據(jù)。1.4.1 數(shù)據(jù)發(fā)送端下面通實(shí)例說(shuō)明WM_COPYDATA消息的使用,實(shí)例11-9是使用WM_COPYDATA消息的消息發(fā)送端。實(shí)例11-9發(fā)送WM_COPYDATA消息實(shí)例序創(chuàng)建了一個(gè)文本框控件,用戶可以在控件中輸入文字,單擊“Send”按鈕后,向窗口名為“RECVCOPYDATA”的口發(fā)送WM_COPYDATA消息,將用戶在文本框中輸入的內(nèi)容全部發(fā)送給“RECVCOPYDATA”口。運(yùn)行實(shí)例,用戶可以輸入任何內(nèi)容,單擊菜單中的Send,如果存在名為“RECVCOPYDATA”標(biāo)題的窗口,則向其發(fā)送數(shù)據(jù)。1.4.2 數(shù)據(jù)接收端實(shí)例11-10是ⅥrM_COPYDATA消息接收端。實(shí)例11-10接收WM_COPYDATA消息實(shí)例創(chuàng)了名為“RECVCOPYDATA”的窗口,并創(chuàng)建了一個(gè)文本框控,在主窗口收到WMCOPYDATA消息后,將消息的lParam消息提取出來(lái),顯示在文本框中。程序接收到消息后,將消息提取并顯示內(nèi)容。運(yùn)行果表示,接收端收到了發(fā)送端發(fā)送的消息,并收到數(shù)據(jù)。.5其他進(jìn)程間通信方式本節(jié)單介紹幾種其他的進(jìn)程間通信方式包括動(dòng)態(tài)數(shù)據(jù)交換FileMapping和Socket等。1.5.1 動(dòng)態(tài)數(shù)據(jù)交換(DDE)和網(wǎng)絡(luò)動(dòng)態(tài)數(shù)據(jù)交換(NDDE)DDE可能是最為強(qiáng)大的進(jìn)程間通信方式實(shí)現(xiàn)也非常復(fù)雜通信的兩端分為服務(wù)端與客戶端,兩端都需要具有窗口。一個(gè)DDE的通信過(guò)程大致如下。DDE會(huì)由客戶端發(fā)起,先初始化一個(gè)會(huì)話。DDE客戶端會(huì)向服務(wù)端發(fā)送一個(gè)WM_DDEINITIATE窗口息。服務(wù)窗口收到此消息后,根據(jù)條件判斷是否需要響應(yīng)此消息,如果服務(wù)端確定可以與客戶端建立會(huì)話,那么會(huì)返回WM__DDE_ACK消息。如果客戶端成功收到了服務(wù)端發(fā)送的WM—DDE-ACK窗口消息,那么會(huì)話就已經(jīng)建立,之后就進(jìn)行數(shù)據(jù)的傳輸。數(shù)據(jù)輸分為很多種方式可以只傳輸一個(gè)單獨(dú)的數(shù)據(jù)項(xiàng)也可以再建立一個(gè)永久數(shù)據(jù)連(PermanentDataink)。如果行獨(dú)立數(shù)據(jù)項(xiàng)傳輸,數(shù)據(jù)傳輸?shù)膯挝皇菙?shù)據(jù)項(xiàng)。客戶端使用WM_DDE_REQUEST和WM_DDE_POKE消息向服務(wù)端接收和發(fā)送數(shù)據(jù)項(xiàng)。數(shù)據(jù)的傳輸使用WM_DDE_DATA息。而永數(shù)據(jù)連接的建立也是通過(guò)客戶端發(fā)起客戶端服務(wù)端發(fā)送WMDDE_ADVISE消息,服務(wù)端根據(jù)情況做出回應(yīng),根據(jù)是否能夠建立連接而返回不同的WM_DDE_ACK消。終止數(shù)據(jù)連接使用消息WM_DDE_UNADVISE??蛻暨€可以使用WM_DDE_EXECUTE請(qǐng)服務(wù)端發(fā)送命令。終止個(gè)DDE會(huì)話使用WMDDE_TERMINATE消息。幾乎有的過(guò)程都是由客戶端發(fā)起請(qǐng)求而服務(wù)端響應(yīng)服務(wù)端響應(yīng)的方向大多是發(fā)送一個(gè)WM__DE_ACK消息。DDE的信需要操作系統(tǒng)ATOM表的幫助,用于索引據(jù)。操作ATOM表有專門的API。11.5.2通過(guò)FileMapping在進(jìn)程間共享數(shù)據(jù)共享件是一種高效的進(jìn)程間通信方式因?yàn)橹苯庸蚕韮?nèi)存所以訪問(wèn)速度非??於以试S大量數(shù)據(jù)傳輸。共享存的進(jìn)程間通信與其他進(jìn)程間通信方式相比限制條件要少比如郵槽對(duì)數(shù)據(jù)大小和數(shù)據(jù)流向有限制,管道只能采用半雙工通信形式等,剪貼板容易受其他進(jìn)程影響等。本書4.4.2小節(jié)已經(jīng)詳細(xì)介紹了通過(guò)FileMapping進(jìn)行進(jìn)程間數(shù)據(jù)共享的完整的實(shí)現(xiàn)原理和實(shí)例代碼。使用FileMapping享數(shù)據(jù)也有缺點(diǎn)。最大的缺點(diǎn)是無(wú)法實(shí)現(xiàn)實(shí)時(shí)性,一個(gè)進(jìn)程無(wú)論是寫入還是讀出數(shù)據(jù)后,另一個(gè)進(jìn)程都不知道對(duì)方的操作是否已經(jīng)完成。因此在要求實(shí)時(shí)數(shù)據(jù)傳輸時(shí),F(xiàn)ileMapping通常與其他進(jìn)程通信方式配合使用,用于傳輸大量的數(shù)據(jù)。1.5.3 indowsSocket利用WindowsSocket實(shí)現(xiàn)的進(jìn)程間通信完全借用了Socket通信的原其實(shí)任何可以在兩臺(tái)主機(jī)間進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)通信的機(jī)制都可以用于進(jìn)程間通信。如果一臺(tái)主機(jī)上既使用Socket服務(wù)端又現(xiàn)Socket客戶端那么客戶端在連接服務(wù)端時(shí)將IP指定為本機(jī),就可以實(shí)現(xiàn)同一主機(jī)上的Socket務(wù)端進(jìn)程和Socket客戶端進(jìn)程間的通信了。使用Socket進(jìn)行進(jìn)間通信既可以實(shí)現(xiàn)實(shí)時(shí)性,又可以傳輸大數(shù)據(jù)量信息,且數(shù)據(jù)傳輸?shù)乃俣纫埠芸欤虼藨?yīng)用范圍很廣泛。在進(jìn)程間實(shí)現(xiàn)Socket通信的原理和程序?qū)崿F(xiàn)方法與實(shí)現(xiàn)不同主機(jī)間的Socket通信沒(méi)有區(qū)別,請(qǐng)參考本書第14章相關(guān)內(nèi)容。第12章indowsShell程序設(shè)計(jì)幾乎有的操作系統(tǒng)都有“Shell”的概所謂Shel(殼一般是指由操作系統(tǒng)提供的用于計(jì)算機(jī)用戶向操作系統(tǒng)輸入相關(guān)指令并得到結(jié)果的程序Shell可以字符形式的,也可以是圖形界面形式的。本章所介紹是圖形界面形式的Shell。WindowsShell最重要的組成部件是explorer.exe。在使用Windows操作系統(tǒng)時(shí),開(kāi)始菜單、任務(wù)欄、資源管理器等都是explorer.exe提供的。因此Shell程序設(shè)也是圖形用戶界面設(shè)計(jì)的重要組成部分掌握Shell程序計(jì)需首先了解下面4個(gè)方的內(nèi)容。(1)WindowsShell編程接口。WindowsShell提供系列編程接口,例如可以獲取特殊文件夾,使用文件瀏覽對(duì)話框等。Shell編程接口的函數(shù)名通常是以“SH”開(kāi)始。(2)WindowsShell擴(kuò)展。Windows平臺(tái)的Shell是可擴(kuò)展的??梢詾閃indowsShell開(kāi)發(fā)擴(kuò)展程序(Extention),例如:

定不同類型的文件的右鍵菜單拖拽菜(比如WinRARAdobeArobat應(yīng)用程序具有這樣的功能;

開(kāi)發(fā)系統(tǒng)通知區(qū)域圖標(biāo)并為圖標(biāo)定制菜單和氣泡彈出功能(QQSNVisualStudio等應(yīng)用程序具有這樣的功能);

定任務(wù)欄、定制工具欄等;

增自動(dòng)播放對(duì)話框中的選項(xiàng);

添控制面板項(xiàng);

為同文件類型文件屬性頁(yè)、文件夾的屬性頁(yè)(右鍵屬性)增加選項(xiàng)頁(yè)。上面幾種典型的Shell擴(kuò)展應(yīng)用但是Shell擴(kuò)展應(yīng)用遠(yuǎn)不止這幾種情況本章將介紹其中幾種的實(shí)現(xiàn)方法。(3)注表在Shell應(yīng)用中具有重要作用。Shell應(yīng)用在很大程度上依賴于注冊(cè)表,舉例如下。

文類型輔助:特定擴(kuò)展名的文件的圖標(biāo)、默認(rèn)打開(kāi)程序等是通過(guò)注冊(cè)表來(lái)配置的。

Shell擴(kuò)展的安裝:比如特定類型文件的右鍵菜單、拖拽菜單(ContextMeun)的菜單項(xiàng)及輸入處理函數(shù)所在的動(dòng)態(tài)鏈接庫(kù)。(4)相頭文件和庫(kù)文件。進(jìn)行Shell程序的設(shè)計(jì),需要使用一些頭文件和庫(kù)文件。一般ShellAPI都在shlobj.h頭文件中聲明,由She1132.dll導(dǎo)出鏈接時(shí)需要使用到She1132.lib庫(kù)。12.1indowsShell目錄管理計(jì)算用戶使用Shell最常進(jìn)的操作就是文件操作Shell最重要的功能之一是進(jìn)行文件瀏覽、查找、管理以及將文件和應(yīng)用程序關(guān)聯(lián)。WindowsShell中有多特殊目錄和文件,比如所有Windows用戶都經(jīng)常接觸到的“我的文檔桌面“收站“序件”(Programfiles)等。這些錄都是Shell特殊目錄。可以通過(guò)Shell程序設(shè)計(jì)接口開(kāi)發(fā)程序,獲取和操作這些特殊目錄。12.1.1 Shell對(duì)目錄和文件的管理形式Shell有一種特殊的件和目錄管理方式,每個(gè)目錄都有一個(gè)PIDL(PointerofItemidentifierlist,項(xiàng)識(shí)符表指針)值,這個(gè)值惟一標(biāo)識(shí)一個(gè)文件夾。由系定義的特殊文件夾的CSIDL(constantspecialiemIDlist)是常數(shù),比如:CSIDL_DESKTOP代表“桌面”文件夾;CSIDL_FAVORITES代表“收藏夾”;CSIDL_FONTS代表字體文件夾;CSIDL_MYDOCUMENTS,代表“我的文檔”;CSIDL_MYMUSIC代表“我的音樂(lè)”;CSIDLPROFIE代表“用戶”文件夾,一般情況下是C:\DocumentsandSettings\username;CSIDL_PROGRAMS代表“程序”文件夾,一情況下是C:\ProgramFiles;.CSIDLRECENT,代“最近的文檔”;CSIDL_STARTMENU,代表“開(kāi)始菜單”目錄;CSIDL_SYSTE、CSIDL_WINDOWS分別代表“系統(tǒng)”和“Windows”目。SHGetNameFromIDList、SHGetPathFromIDist等ShellAPI函數(shù)通過(guò)CSIDL獲得有關(guān)于目錄的詳細(xì)信息。12.1.2 “我的文檔”等特殊目錄相關(guān)操作本節(jié)通過(guò)示例說(shuō)明系統(tǒng)特殊目錄的操作。1.關(guān)鍵API及數(shù)據(jù)(1)SHGetSpecialFlderPath函數(shù)。通過(guò)件夾的CSIDL,獲得文件夾的路徑,函數(shù)原型如下:(2)SHGetFolderocation函數(shù)。獲取文件夾的路徑,并保存在ITEMIDLIST結(jié)構(gòu),函數(shù)原型如下:(3)SHGetPathFrmIDList函數(shù)。從PIDL轉(zhuǎn)換為路徑函數(shù)原型如下:2.實(shí)例12-1獲取并顯示“我的文檔”等特殊目錄本實(shí)使用了若干表示系統(tǒng)特殊目錄的CSIDL常數(shù)通這些常數(shù)獲取文件夾的真實(shí)路徑,并顯示。本實(shí)例使用了兩種方法來(lái)獲取特殊文件夾的路徑,一種是直接使用SHGetSpecialFolderPathAPI,另外一種更為通用,使用SHGetFolderLocation從PIDL或CSIDL獲得文件夾位置后,再使用SHGetPathromIDList獲取文件路徑字符串。3.運(yùn)行結(jié)果本實(shí)的運(yùn)行結(jié)果參見(jiàn)12.1.3小節(jié)的圖12-1。12.1.3 綁定、遍歷、屬性獲取本小節(jié)將通過(guò)實(shí)例介紹通過(guò)ShellAPI編寫更一般的文件操作程序,包括

溫馨提示

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

評(píng)論

0/150

提交評(píng)論