版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
Visual
C++第5章Windows應(yīng)用程序編程接口教學(xué)要點(diǎn)本章內(nèi)容主要包括API的概念及分類,從API的使用看操作系統(tǒng)所提供的服務(wù),操作系統(tǒng)內(nèi)核中的文件操作API的使用,網(wǎng)絡(luò)服務(wù)API函數(shù)的使用,利用圖形設(shè)備接口API編寫圖形用戶界面程序的方法。要求了解API的分類及其對(duì)應(yīng)的磁盤上的物理文件.DLL的名稱、網(wǎng)絡(luò)服務(wù)API的含義和網(wǎng)絡(luò)編程的一些基本概念、進(jìn)程概念及建立新進(jìn)程的方法、WM_PAINT消息
含義。握握API概念和其與操作系統(tǒng)提供的程序員接口的關(guān)系、內(nèi)核中文件操作API的調(diào)用,熟悉API編寫圖形用戶界面程序的步驟,熟練掌握API編寫的圖形用戶界面程序的主要組成模塊及含義。Visual
C++第5章目錄API概述內(nèi)核服務(wù)API函數(shù)的使用網(wǎng)絡(luò)接口服務(wù)Win32
API編寫圖形界面程序圖形設(shè)備接口與用戶接口服務(wù)
習(xí)題本章以一些API設(shè)計(jì)的控制臺(tái)程序和具有圖形界面的Win32程序?yàn)槔?,闡述了利用API函數(shù)開(kāi)發(fā)程序的過(guò)程,重點(diǎn)在于理解操作系統(tǒng)所提供的各種服務(wù)以及程序員如何進(jìn)行調(diào)用。Visual
C++5.1
API概述關(guān)于Windows
API編程模式API簡(jiǎn)介Windows核心——三個(gè)動(dòng)態(tài)鏈接庫(kù)Windows
API分類*5.1.5
操作系統(tǒng)的認(rèn)識(shí)Visual
C++Windows
API編程是一種原始的開(kāi)發(fā)Windows應(yīng)用程序模式,它主要使用的是C語(yǔ)言、少量的C++通用類及“原始”的Windows應(yīng)用程序編程接口API(Application
Programming
Interface)。這些函數(shù)都是比較底層的函數(shù),其地位大致相當(dāng)于字符界面環(huán)境下C語(yǔ)言的標(biāo)準(zhǔn)庫(kù)函數(shù),只不過(guò)其運(yùn)行環(huán)境為Windows的圖形界面環(huán)境。本篇的后多半部分雖然采用的是相對(duì)比較簡(jiǎn)單的MFC編程,但使用底層的API函數(shù)編寫程序可以看到許多MFC編程看不到的東西,從而對(duì)Windows的內(nèi)部運(yùn)作有更深入的了解。進(jìn)行API編程,要求用戶對(duì)Windows環(huán)境比較熟悉,并且熟悉C語(yǔ)言。在API編程中用到大量的有關(guān)操作系統(tǒng)的結(jié)構(gòu)體變量和控制操作系統(tǒng)的函數(shù),當(dāng)在使用API函數(shù)遇到問(wèn)題時(shí),可以隨時(shí)查閱Windows的API文檔,它位于MSDN的Platform
SDK部分。5.1.1關(guān)于WindowsAPI編程模式Visual
C++5.1.2
API簡(jiǎn)介Windows操作系統(tǒng)向程序員提供了可以實(shí)現(xiàn)開(kāi)啟窗口、繪制圖形,使用系統(tǒng)各種設(shè)備等的一組函數(shù)服務(wù),稱之為Application
Programming
Interface(應(yīng)用程序編程接口),即API函數(shù)。利用VC進(jìn)行Windows應(yīng)用程序的開(kāi)發(fā),除了用到各種.h頭文件中的庫(kù)函數(shù)及數(shù)據(jù)結(jié)構(gòu)外,還需要使用WindowsSDK(Software
Development
Kit,軟件開(kāi)發(fā)工具包)提供的使用于Windows應(yīng)用程序的特殊庫(kù)函數(shù)和數(shù)據(jù)結(jié)構(gòu)、語(yǔ)句、文件結(jié)構(gòu)。所有這些內(nèi)容組成了Windows應(yīng)用程序設(shè)計(jì)接口API。使用Win32 API,應(yīng)用程序可以充分挖掘出Windows 32位操作系統(tǒng)的潛力,Microsoft的所有32位平臺(tái)都支持統(tǒng)一的API,包括函數(shù)、結(jié)構(gòu)、消息、宏及接口。使用Win32
API,不但可以開(kāi)發(fā)出在各種平臺(tái)上都能運(yùn)行的應(yīng)用程序,而且還可以充分利用每個(gè)平臺(tái)上特有的功能和屬性。Visual
C++5.1.3
Windows核心——三個(gè)動(dòng)態(tài)鏈接庫(kù)Windows操作系統(tǒng)核心有三個(gè)動(dòng)態(tài)鏈接庫(kù)(Kernel32.dll,User32.dll,Gdi32.dll),這些動(dòng)態(tài)鏈接庫(kù)構(gòu)成了Win32
API函數(shù)。Windows內(nèi)核庫(kù)(Kernel32.dll)內(nèi)核庫(kù)中的函數(shù)用于處理操作系統(tǒng)功能的所有核心工作,例如多任務(wù)管理、內(nèi)存管理等。另外內(nèi)核庫(kù)還管理系統(tǒng)注冊(cè)表。Windows用戶界面管理庫(kù)(User32.dll)用戶界面管理庫(kù)包括了Windows管理、菜單、光標(biāo)、定時(shí)器和通信等有關(guān)的函數(shù)。在Windows中,窗口的標(biāo)識(shí)被稱為“句柄”。Windows圖形設(shè)備界面庫(kù)(Gdi32.dll)圖形設(shè)備界面庫(kù)提供了用于管理系統(tǒng)支持的所有圖形設(shè)備函數(shù),包括屏幕、打印機(jī)等設(shè)備的管理。GDI庫(kù)中的函數(shù)為應(yīng)用程序提供與設(shè)備無(wú)關(guān)的繪圖內(nèi)容。應(yīng)用程序中通過(guò)GDI庫(kù)中的函數(shù)繪圖,不是直接面向硬件操作,而是通過(guò)“設(shè)備描述表”來(lái)進(jìn)行操作,它通過(guò)句柄hDC來(lái)跟蹤。Windows三個(gè)核心庫(kù)中的API函數(shù)的原型聲名在windows.h中有說(shuō)明,這就是我們?cè)诰帉慦in32應(yīng)用程序時(shí)要在程序開(kāi)頭放#include“windows.h”語(yǔ)句的原因。Visual
C++5.1.4
Windows
API分類
根據(jù)Windows
API函數(shù)完成的功能,可以將其分為如下的類別:1.內(nèi)核服務(wù)通過(guò)內(nèi)核服務(wù)函數(shù),應(yīng)用程序可以使用計(jì)算機(jī)中的資源和操作系統(tǒng)的特性,例如內(nèi)存,文件系統(tǒng)、設(shè)備、進(jìn)程、線程等。拿一個(gè)簡(jiǎn)單的文件輸入輸出函數(shù)來(lái)說(shuō),通過(guò)這些函數(shù),程序員可以存取本地計(jì)算機(jī)或網(wǎng)絡(luò)中某臺(tái)計(jì)算機(jī)中的文件、目錄、輸入輸出設(shè)備,并且這些文件函數(shù)支持各種各樣的文件系統(tǒng),包括FAT、NTFS的文件系統(tǒng)。內(nèi)核服務(wù)體現(xiàn)了Windows操作系統(tǒng)“服務(wù)”的觀點(diǎn)。作為一個(gè)程序員我們應(yīng)該利用這些服務(wù)函數(shù)來(lái)充分發(fā)揮操作系統(tǒng)的功能。對(duì)于這部分API函數(shù)的使用,我們可以在基于控制臺(tái)的應(yīng)用程序中編寫,因?yàn)檫@些函數(shù)都是一些與Windows圖形用戶界面無(wú)關(guān)的,在字符方式下操作比較簡(jiǎn)單。后面有關(guān)這方面函數(shù)的操作就是在基于控制臺(tái)的應(yīng)用程序中使用的。內(nèi)核服務(wù)的函數(shù)大部分包含在Windows內(nèi)核庫(kù)——Kernel32.dll中。Visual
C++5.1.4
WindowsAPI分類(續(xù))2.圖形設(shè)備接口■■■圖形設(shè)備接口是Windows最原始的圖形輸出庫(kù)(最原始意味著除了GDI外,還有工業(yè)界用的OpenGl和游戲界用的DirectX,VC都對(duì)他們提供支持)。當(dāng)看到圖形或文本顯示在屏幕上時(shí),這就是GDI的功勞。它提供了在顯示器、打印機(jī)或其它設(shè)備
上生成圖形的函數(shù)與相關(guān)的數(shù)據(jù)結(jié)構(gòu)。利用GDI函數(shù),你可以畫直
線、曲線、文本、位圖等。你還可以使用各種各樣的繪圖對(duì)象如筆、畫刷、字體等,使得所繪制的圖形更加豐富多彩。另外,Windows本身也是通過(guò)GDI來(lái)繪制其用戶界面,包括窗口、菜單和對(duì)話框。顧名思義,圖形設(shè)備接口是與圖形界面有關(guān)的,因此這些函數(shù)的使用要在圖形用戶界面下操作。即必須建立基于Win32的應(yīng)用程序,建立的步驟如4.4節(jié)所示。圖形設(shè)備接口的函數(shù)是包含在Windows圖形設(shè)備界面庫(kù)——
Gdi32.dll中。Visual
C++5.1.4
Windows
API分類(續(xù))用戶接口服務(wù)用戶接口服務(wù)函數(shù)可以創(chuàng)建和使用Windows來(lái)顯示輸出、提示用戶輸入和執(zhí)行與用戶交互的任務(wù)。用戶接口服務(wù)是通過(guò)一些常見(jiàn)的Windows對(duì)象來(lái)實(shí)現(xiàn)的,例如按鈕、組合框、編輯框、菜單、鍵盤輸入、定時(shí)器等。用戶接口服務(wù)的函數(shù)是在Windows用戶界面管理庫(kù)——User32.dll中。網(wǎng)絡(luò)服務(wù)網(wǎng)絡(luò)服務(wù)允許分布在網(wǎng)絡(luò)中不同計(jì)算機(jī)上的應(yīng)用程序進(jìn)行通訊。通過(guò)這些函數(shù)可以創(chuàng)建和管理共享資源,例如共享目錄和網(wǎng)絡(luò)打印機(jī)。網(wǎng)絡(luò)服務(wù)的函數(shù)是在網(wǎng)絡(luò)接口函數(shù)庫(kù)——Mpr.dll、Wininet.dll和Winsock32.dll中。多媒體服務(wù)多媒體技術(shù)是指利用計(jì)算機(jī)綜合處理多媒體信息——文本、圖形、圖象和聲音等,使多種信息建立邏輯連接,集成為一個(gè)系統(tǒng)并具有交互性。多媒體服務(wù)提供了數(shù)字音頻、視頻、圖形、圖象等服務(wù)。該服務(wù)的函數(shù)主要包含在多媒體函數(shù)庫(kù)——Winmm.dll中。Visual
C++5.1.4
WindowsAPI分類(續(xù))客戶/服務(wù)方式存取服務(wù)在客戶/服務(wù)方式存取模式中,客戶可以連接到服務(wù)器上以使用服務(wù)器的功能和數(shù)據(jù),服務(wù)器通過(guò)客戶端的標(biāo)識(shí)和權(quán)限來(lái)決定客戶端可以使用的功能。Win2K提供了一套函數(shù)來(lái)限制和允許客戶端對(duì)服務(wù)端的訪問(wèn)。這些函數(shù)擴(kuò)展了Win2k的存取控制模型來(lái)使用服務(wù)端的私有對(duì)象和使用服務(wù)端的功能。客戶/服務(wù)方式存取服務(wù)又稱操作系統(tǒng)高級(jí)編
程接口,這些函數(shù)包含在高級(jí)編程接口函數(shù)庫(kù)——Advapi32.dll中。版本服務(wù)版本服務(wù)主要提供有關(guān)文件的版本信息。這些服務(wù)所對(duì)應(yīng)的函數(shù)包含在版本函數(shù)庫(kù)——Version.dll中。公共對(duì)話框服務(wù)公共對(duì)話框,又叫通用對(duì)話框,是Windows預(yù)定義的對(duì)話框,可以使用通用對(duì)話框來(lái)執(zhí)行六種標(biāo)準(zhǔn)操作,選擇文件,指定字體、選擇顏色、打印設(shè)置、查找文本、保存文件。這些服務(wù)所對(duì)應(yīng)的函數(shù)包含在公共對(duì)話框函數(shù)庫(kù)——Comdlg32.dll中。Visual
C++5.1.4
WindowsAPI分類(續(xù))打印管理服務(wù)在Windows操作系統(tǒng)下,可以實(shí)現(xiàn)在各種設(shè)備下的打印。打印管理服務(wù)提供了完整的函數(shù)集支持這些操作,例如檢索打印機(jī),準(zhǔn)備打印等。這些服務(wù)所對(duì)應(yīng)的函數(shù)包含在打印管理函數(shù)庫(kù)——Winspool.drv中。解/壓縮文件服務(wù)該服務(wù)提供了對(duì)文件的壓縮和解壓服務(wù)。這些服務(wù)所對(duì)應(yīng)的函數(shù)包含在函數(shù)庫(kù)——Lz32.dll。在VC6.0中提供了一個(gè)文件Win32api.csv。它是一個(gè)Win16與Win32函數(shù)的對(duì)照表。通過(guò)它讀者可以瀏覽到Windows各種版本下API函數(shù)的原型說(shuō)明。Visual
C++5.1.5
操作系統(tǒng)的認(rèn)識(shí)操作系統(tǒng)有兩個(gè)接口:一個(gè)是用戶接口,另一個(gè)是程序員接口。VC開(kāi)發(fā)工具的強(qiáng)大,其中很重要的一個(gè)方面就是對(duì)于WindowsAPI的直接調(diào)用,其它任何開(kāi)發(fā)工具中的函數(shù)都是對(duì)其的一個(gè)封裝。凡是在Windows工作環(huán)境下執(zhí)行的應(yīng)用程序,都可以通過(guò)某種特定方式調(diào)用Woindows
API函數(shù)??梢院敛豢鋸埖卣f(shuō),Windows
API函數(shù)是構(gòu)建整個(gè)Windows框架的基石,在它下面是Windows操作系統(tǒng)核心,在它上面則是所有華麗的Windows應(yīng)用程序。事實(shí)上,任何開(kāi)發(fā)工具提供的類庫(kù)和構(gòu)件都是架構(gòu)在Win32API函數(shù)基礎(chǔ)上,是封裝了的API函數(shù)集合。這些類庫(kù)和構(gòu)件簡(jiǎn)化了程序的開(kāi)發(fā),但其功能有限。在實(shí)際應(yīng)用中,如果我們希望開(kāi)發(fā)出更靈活、更實(shí)用、更具效率的程序時(shí),則必須要涉及直接使用API函數(shù)。雖然類庫(kù)和構(gòu)件使應(yīng)用程序的開(kāi)發(fā)簡(jiǎn)單了,但它們只提供Windows的常用的一般功能,對(duì)于比較復(fù)雜和特殊的功能來(lái)說(shuō),使用類庫(kù)和構(gòu)件中提供的方法是非常難以實(shí)現(xiàn)的,這時(shí)就需要直接調(diào)用特定的API函數(shù)。Visual
C++5.2內(nèi)核服務(wù)API函數(shù)的使用內(nèi)核服務(wù)是最能體現(xiàn)API函數(shù)威力的地方,通過(guò)這些函數(shù),用戶能夠使用操作系統(tǒng)內(nèi)核所提供的核心功能。操作系統(tǒng)的進(jìn)程管理、文件管理、內(nèi)存管理都是屬于內(nèi)核的功能。文件管理內(nèi)核服務(wù)進(jìn)程操作計(jì)算機(jī)系統(tǒng)信息操作Visual
C++5.2.1文件管理內(nèi)核服務(wù)VC下提供了對(duì)文件操作的四種方式:使用C語(yǔ)言中的fopen()、fprintf()、fread()等基本的函數(shù)進(jìn)行文件操作;使用C++中的流式文件接口fstream中的函數(shù)進(jìn)行操作;使用面向?qū)ο蟮念怌File進(jìn)行操作;使用有關(guān)的文件API進(jìn)行操作。文件操作驅(qū)動(dòng)器操作Visual
C++API為一般的文件操作提供了三個(gè)函數(shù):移動(dòng)、復(fù)制和刪除。文件拷貝的API函數(shù)如下所示:BOOL
CopyFile(
//從源文件向目標(biāo)文件復(fù)制內(nèi)容LPCTSTR
lpExistingFileName,
//
源文件名稱LPCTSTR
lpNewFileName,
//
目標(biāo)文件名稱BOOL
bFailIfExists/*目標(biāo)文件存在時(shí)的操作模式,為true時(shí),函數(shù)調(diào)用失敗,為False時(shí),現(xiàn)有文件將被覆蓋*/);文件移動(dòng)和文件刪除的API函數(shù)是MoveFileEx()和DeleteFile()【例5-1】調(diào)用API函數(shù)CopyFile實(shí)現(xiàn)文件拷貝實(shí)例。Windows的內(nèi)核功能的實(shí)現(xiàn)不一定要在Windows的圖形界面下完成,在字符方式下也可以。由于目前Windows圖形用戶接口程序的開(kāi)發(fā)還沒(méi)有講(5.4節(jié)和5.5節(jié)中講),并且我們目前掌握的重點(diǎn)是利用API函數(shù)實(shí)現(xiàn)Windows內(nèi)核功能的演示,所以下面的程序仍然是字符界面下的單文件控制臺(tái)工程,該程序的主文件的名稱為FileCopy.cpp。1.文件操作Visual
C++#include<windows.h>//windows操作系統(tǒng)API函數(shù)的頭文件#include<iostream.h>void
main(){char
SourceFileName[MAX_PATH];char
DestFileName[MAX_PATH];BOOL
Success;cout<<"請(qǐng)輸入待拷貝的源文件的名稱\n";cin>>SourceFileName;cout<<"請(qǐng)輸入待拷貝的目標(biāo)文件的名稱\n";cin>>DestFileName;Success=CopyFile(SourceFileName,DestFileName,TRUE);//調(diào)用API函數(shù)CopyFile實(shí)現(xiàn)文件拷貝if(!Success)cout<<"拷貝失敗,錯(cuò)誤的代碼為:"<<GetLastError()<<endl;//調(diào)用API函數(shù)GetLastError()求出錯(cuò)的代碼elsecout<<"文件拷貝成功\n";}文件移動(dòng)和文件刪除的API函數(shù)是MoveFileEx()和DeleteFile(),詳細(xì)請(qǐng)查看MSDN的說(shuō)明。程序Visual
C++(1)取驅(qū)動(dòng)器個(gè)數(shù)計(jì)算機(jī)上一般都有軟盤、硬盤和光盤,有時(shí)候應(yīng)用程序需要查看系統(tǒng)中一共有多少個(gè)邏輯驅(qū)動(dòng)器,這時(shí)可以調(diào)用API函數(shù)GetLogicalDrives()來(lái)完成。其函數(shù)的原型為:DWORD
GetLogicalDrives(VOID);該函數(shù)返回一個(gè)DWORD類型的值,這32位的每一位代表某個(gè)驅(qū)動(dòng)器是否存在。如果存在A盤,則第0位被設(shè)置為1;依次類推,如果存在C盤,則第2位被設(shè)置為1。當(dāng)我們需要知道在該計(jì)算機(jī)上總共有幾個(gè)驅(qū)動(dòng)器時(shí),可以用如下的代碼完成:DWORD
DiskInfo;
_int8
DiskCount=0;
//定義8位的整型變量DiskInfo=GetLogicalDrives();while(DiskInfo){if(DiskInfo&1)//看該位是否為1,為1代表有對(duì)應(yīng)的驅(qū)動(dòng)器DiskCount++;DiskInfo>>=1;
//DiskInfo=DiskInfo>>1}2.驅(qū)動(dòng)器操作Visual
C++DWORD
nBufferLength,LPTSTR
lpBuffer//緩沖區(qū)的長(zhǎng)度//指向所有驅(qū)動(dòng)器字符串的指針);使用該函數(shù)一般分兩個(gè)步驟:①求所有驅(qū)動(dòng)器的字符串信息長(zhǎng)度把0傳遞給API函數(shù)GetLogicalDriveStrings()的兩個(gè)形參,函數(shù)的返回值就是所有驅(qū)動(dòng)器的字符串信息長(zhǎng)度。語(yǔ)句為:DriveStringLength=GetLogicalDriveStrings(0,NULL);②動(dòng)態(tài)分配內(nèi)存空間保存所有驅(qū)動(dòng)器的字符串信息通過(guò)new函數(shù)在棧區(qū)申請(qǐng)內(nèi)存于字符指針變量DriverStr,然后把上一步求的所有驅(qū)動(dòng)器的字符串信息長(zhǎng)度DriveStringLength和準(zhǔn)備保存所有驅(qū)動(dòng)器的字符串緩沖區(qū)地址DriverStr傳遞給API函數(shù)
GetLogicalDriveStrings()的兩個(gè)形參,2.驅(qū)動(dòng)器操作(續(xù))(2)取所有驅(qū)動(dòng)器字符串信息取所有驅(qū)動(dòng)器字符串信息通過(guò)API函數(shù)GetLogicalDriveStrings()來(lái)完成,其原型為:DWORD
GetLogicalDriveStrings(Visual
C++2.驅(qū)動(dòng)器操作(續(xù))這樣求得的所有驅(qū)動(dòng)器的字符串信息就保存到緩沖區(qū)DriverStr中,注意每個(gè)驅(qū)動(dòng)器字符串的長(zhǎng)度為4,假設(shè)該機(jī)器有A、B、C、D四個(gè)驅(qū)動(dòng)器則在緩沖區(qū)DriverStr保存的內(nèi)容是A:\<NULL>B:\<NULL>C:\<NULL>D:\<NULL><NULL>,其中<NULL>表示的是空字符,各個(gè)驅(qū)動(dòng)器之間靠<NULL>來(lái)分隔,最后以<NULL>結(jié)束。典型的代碼為:DriverStr=new
char[DriveStringLength+1];GetLogicalDriveStrings(DriveStringLength,(LPTSTR)DriverStr);③取驅(qū)動(dòng)器類型倘若還要知道每個(gè)驅(qū)動(dòng)器標(biāo)識(shí)符各代表什么類型的驅(qū)動(dòng)器時(shí),如A:代表軟盤還是硬盤,F(xiàn):代表光盤還是U盤(可移動(dòng)盤),就要使用API函數(shù)GetDriveType(),該函數(shù)的原型為:UINT
GetDriveType(LPCTSTR
lpRootPathName
//驅(qū)動(dòng)器的根目錄);函數(shù)返回值為驅(qū)動(dòng)器的類型,若值為DRIVE_REMOVABLE,代表的是可移動(dòng)U盤,若值為DRIVE_FIXED,代表的是固定盤,若值為CDROM,代表的是光盤等。Visual
C++【例5-2】調(diào)用驅(qū)動(dòng)器操作API函數(shù)的演示實(shí)例程序主文件為:DrivesInfo.cpp。#include
<iostream.h>void
main(){DWORD
DiskInfo;char
*DriverStr;UINT
type;short
DriveStringLength;_int8
DiskCount=0;//定義8位的整型變量DiskInfo=GetLogicalDrives();//取機(jī)器上的驅(qū)動(dòng)器信息于DiskInfowhile(DiskInfo){if(DiskInfo&1)//看該位是否為1,為1代表有對(duì)應(yīng)的驅(qū)動(dòng)器DiskCount++;DiskInfo>>=1;}Visual
C++【例5-2】(續(xù))cout<<"該機(jī)器共有"<<DiskCount<<"個(gè)邏輯驅(qū)動(dòng)器n";DriveStringLength=GetLogicalDriveStrings(0,NULL);//求整個(gè)驅(qū)動(dòng)器的字符串信息的長(zhǎng)度,每個(gè)驅(qū)動(dòng)器字符串的長(zhǎng)度為4DriverStr=new
char[DriveStringLength+1];GetLogicalDriveStrings(DriveStringLength,(LPTSTR)DriverStr);//求整個(gè)驅(qū)動(dòng)器的字符串信息于DriverStrfor(short
i=0;i<(int)(DriveStringLength/4);i++){type=GetDriveType(DriverStr+i*4);//取驅(qū)動(dòng)器的類型是軟盤、硬盤、光盤、可移動(dòng)U盤if(type==DRIVE_CDROM)
//如果是光驅(qū)的話cout<<"驅(qū)動(dòng)器"<<DriverStr+i*4<<"是光驅(qū)n";}}Visual
C++5.2.2
進(jìn)程操作Windows是多任務(wù)操作系統(tǒng),它支持兩種類型的多任務(wù):一種是多進(jìn)程,另一種是多線程。進(jìn)程是應(yīng)用程序的運(yùn)行實(shí)例,它是應(yīng)用程序的一
次動(dòng)態(tài)執(zhí)行。所謂的多進(jìn)程就是,Windows允許多個(gè)程序同時(shí)駐留在內(nèi)存
或同一個(gè)應(yīng)用程序可以在內(nèi)存中有多個(gè)副本。我們知道,進(jìn)程指獨(dú)立運(yùn)行著的應(yīng)用程序。當(dāng)啟動(dòng)Word字處理程序,便啟動(dòng)了一個(gè)進(jìn)程。同樣,當(dāng)我們編譯并運(yùn)行我們自己所編寫的一個(gè)VC程序時(shí),也啟動(dòng)了一個(gè)進(jìn)程。下面的例子就要演示在一個(gè)控制臺(tái)的應(yīng)用程序中,啟動(dòng)Windows附件中的“記事本”程序,從而啟動(dòng)一個(gè)新的進(jìn)程。進(jìn)程的創(chuàng)建Windows以對(duì)象的方式來(lái)管理進(jìn)程的,它由Win32子系統(tǒng)來(lái)創(chuàng)建和維護(hù),并且可以由此進(jìn)程的句柄來(lái)進(jìn)行管理。進(jìn)程創(chuàng)建是調(diào)用Win32
API函數(shù)
CreateProcess()來(lái)實(shí)現(xiàn),創(chuàng)建后的進(jìn)程可以和原進(jìn)程共享資源(例如句柄和變量)。在Windows中,這兩個(gè)進(jìn)程不存在緊密的父子關(guān)系,即使原進(jìn)程終止后,這個(gè)新進(jìn)程仍然可以繼續(xù)執(zhí)行。進(jìn)程創(chuàng)建函數(shù)的原型說(shuō)明Visual
C++BOOL
CreateProcess(LPCTSTR
lpApplicationName,//
name
of
executable
moduleLPTSTR
lpCommandLine,LPSECURITY_ATTRIBUTES//
command
line
stringlpProcessAttributes,LPSECURITY_ATTRIBUTES
lpThreadAttributes,BOOL
bInheritHandles,DWORD
dwCreationFlags,//
handle
inheritance
option//
creation
flagsLPVOID
lpEnvironment,//
new
environment
blockLPCTSTR
lpCurrentDirectory,//current
directory
name
LPSTARTUPINFO
lpStartupInfo,
//startup
informationLPPROCESS_INFORMATION
lpProcessInformation//process
information);3.函數(shù)的參數(shù)說(shuō)明(1)參數(shù)lpApplicationName
它是一個(gè)以NULL結(jié)尾的字符串指針,指向待執(zhí)行的可執(zhí)行文件名字,它可以為全路徑,也可以只是單獨(dú)一個(gè)文件名。如果只是一個(gè)單獨(dú)的文件名,則系統(tǒng)會(huì)在當(dāng)前路徑下尋找,然后在系統(tǒng)目錄和PATH所指的目錄中去查找。5.2.2 進(jìn)程操作(續(xù))Visual
C++當(dāng)這個(gè)參數(shù)為NULL時(shí),這個(gè)文件的名稱必須是第二個(gè)參數(shù)lpCommandLine的第一個(gè)空格前的字符所代表的文件名。參數(shù)lpCommandLine
它是一個(gè)以NULL結(jié)尾的字符串的指針,指向命令行參數(shù)。參數(shù)lpApplicationName和參數(shù)lpCommandLine不允許同時(shí)空,否則系統(tǒng)找不見(jiàn)新進(jìn)程所對(duì)應(yīng)的可執(zhí)行程序的文件名。參數(shù)lpProcessAttributes和參數(shù)lpThreadAttributes用來(lái)確定新進(jìn)程和它的主線程的安全屬性,即用來(lái)決定所返回的句柄是否可以被這個(gè)新進(jìn)程的子進(jìn)程繼承。它們都是指向SECURITY_ATTRIBUTES結(jié)構(gòu)的指針,若它們?yōu)镹ULL,則不能被繼承。參數(shù)bInheritHandles用來(lái)確定新建進(jìn)程能否繼承產(chǎn)生它的進(jìn)程的句柄。若它的值為TRUE,則這個(gè)進(jìn)程和線程所建立的句柄都可以被這個(gè)進(jìn)程所建立的新進(jìn)程所繼承,即繼承的句柄和原先的句柄有相同的值和存取權(quán)限。參數(shù)dwCreationFlags該參數(shù)決定新進(jìn)程產(chǎn)生的方式,它可以用邏輯或的方式把下列值組合起來(lái):5.2.2 進(jìn)程操作(續(xù))Visual
C++5.2.2 進(jìn)程操作(續(xù))<1>CREATE_NEW_CONSOLE為新進(jìn)程建立一個(gè)新的控制臺(tái)窗口。<2>DETACHED_PROCESS在默認(rèn)情況下,新進(jìn)程使用的是父進(jìn)程的控制臺(tái)窗口,而如果指明此標(biāo)志,則新進(jìn)程的輸出消息將發(fā)送到新的控制臺(tái)窗口。<3>CREATE_NEW_PROCESS_GROUP這個(gè)新進(jìn)程將是一個(gè)新進(jìn)程組的根,進(jìn)程組包括該進(jìn)程的所有子進(jìn)程。<4>CREATE_SUSPENDED這個(gè)新進(jìn)程的主線程在它被創(chuàng)建時(shí)處于掛起狀態(tài),即不被執(zhí)行,一直等到調(diào)用ResumeThread()時(shí),主線程才開(kāi)始執(zhí)行。<5>DEBUG_PROCESS如果該標(biāo)志設(shè)置的話,調(diào)用進(jìn)程被當(dāng)作調(diào)試者,新進(jìn)程正準(zhǔn)備接收調(diào)試。系統(tǒng)把在進(jìn)程被調(diào)試時(shí)所發(fā)生的調(diào)試事件通知給父進(jìn)程。<6>參數(shù)lpEnvironment指向環(huán)境塊內(nèi)存的指針,若該值為NULL,則新進(jìn)程和父進(jìn)程使用相同的環(huán)境塊。<7>參數(shù)lpCurrentDirectory新進(jìn)程的工作目錄和驅(qū)動(dòng)器,若其為NULL,則新進(jìn)程的工作目錄和驅(qū)動(dòng)器與父進(jìn)程相同。Visual
C++5.2.2 進(jìn)程操作(續(xù))<8>參數(shù)lpStartupInfo這是一個(gè)指向STARTUPINFO結(jié)構(gòu)的指針,說(shuō)明新進(jìn)程以怎樣的形式加以顯示。<9>參數(shù)lpProcessInformation一個(gè)指向PROCESS_INFORMATION結(jié)構(gòu)的指針,用來(lái)存放返回值。如果函數(shù)CreateProcess成功被調(diào)用,則返回TRUE,否則返回FALSE。如果函數(shù)返回FALSE,則可以調(diào)用函數(shù)GetLastError取得進(jìn)一步的錯(cuò)誤信息。【例5-3】調(diào)用Windows內(nèi)核API函數(shù)實(shí)現(xiàn)多任務(wù)的執(zhí)行實(shí)例。程序的主文件為:MultiProcess.cpp。#include
"windows.h"#include
<iostream.h>void
main(){char
InChar;cout<<"輸入Y將調(diào)用內(nèi)核函數(shù)創(chuàng)建新的進(jìn)程n";cin>>InChar;if(InChar=="Y"||InChar=="y"){Visual
C++【例5-3】(續(xù))BOOL
IsSuccess;char
NotePadFile[255];//存放記事本程序的路徑UINT
uSize=255;GetWindowsDirectory(NotePadFile,uSize);//調(diào)用API函數(shù)GetWindowsDirectory()取得Windows的系統(tǒng)目錄strcat(NotePadFile,“\\notepad.exe”);//取得記事本程序的完整路徑PROCESS_INFORMATION
NewProcessInformation;//建立進(jìn)程信息變量NewProcessInformationSTARTUPINFO
StartUpInformation;//建立進(jìn)程的啟動(dòng)信息變量StartUpInformationmemset(&StartUpInformation,0,sizeof(StartUpInformation));//將緩沖區(qū)StartUpInformation設(shè)置為0StartUpInformation.cb=sizeof(StartUpInformation);
StartUpInformation.wShowWindow=SW_SHOW;//新進(jìn)程的顯示方式為正常顯示StartUpInformation.dwFlags=STARTF_USESHOWWINDOW;……Visual
C++Windows內(nèi)核Kernel32.dll中包含了大量有關(guān)計(jì)算機(jī)系統(tǒng)的信息。這些信息包括計(jì)算機(jī)的硬件配置信息、計(jì)算機(jī)的名稱、用戶的名稱、操作系統(tǒng)的版本信息等。一個(gè)應(yīng)用程序的可移植性,往往反映在程序運(yùn)行時(shí),要檢測(cè)當(dāng)前程序運(yùn)行的外部環(huán)境,其中獲取計(jì)算機(jī)系統(tǒng)信息是很重要的,Win32
API提供了這些服務(wù)。其中:GetComputerName()可以取得本機(jī)器的名稱,GetSystemInfo()可以取得CPU的信息,GlobalMemoryStatus()可以取得內(nèi)存的狀態(tài)信息例5-45.2.3
計(jì)算機(jī)系統(tǒng)信息操作Visual
C++5.3
網(wǎng)絡(luò)接口服務(wù)當(dāng)今,計(jì)算機(jī)網(wǎng)絡(luò)的發(fā)展一日千里,就連蜜蜂這個(gè)“空姐”找對(duì)象時(shí)都想找蜘蛛,原因是蜘蛛好賴是一個(gè)搞“網(wǎng)絡(luò)”的。隨著因特網(wǎng)“飛入尋常百姓家”,人們對(duì)網(wǎng)絡(luò)服務(wù)應(yīng)用程序的要求越來(lái)越高,如何開(kāi)發(fā)網(wǎng)絡(luò)應(yīng)用程序,最基本的是搞清楚Windows操作系統(tǒng)對(duì)網(wǎng)絡(luò)的支持,對(duì)程序員來(lái)說(shuō),要掌握網(wǎng)絡(luò)編程的一些概念,最終掌握有關(guān)網(wǎng)絡(luò)使用的一些API函數(shù)。套接字的使用與Winsock
API因特網(wǎng)服務(wù)WinInetVisual
C++5.3.1
套接字的使用與Winsock
API什么是套接字套接字(socket)是一種網(wǎng)絡(luò)編程接口,它是對(duì)通信端點(diǎn)的一種抽象,提供了一種發(fā)送數(shù)據(jù)和接收數(shù)據(jù)的機(jī)制。Winsock是Windows操作系統(tǒng)下的套接字,它是一套Microsoft
Windows下的網(wǎng)絡(luò)編程接口,使用該接口可以充分利用Windows消息驅(qū)動(dòng)機(jī)制進(jìn)行編程,在應(yīng)用程序中是通過(guò)調(diào)用WinSock
API實(shí)現(xiàn)相互之間的通訊。Visual
C++5.3.1
套接字的使用與WinsockAPI(續(xù))初始化套接字在使用Winsock進(jìn)行編程之前,必須對(duì)它進(jìn)行初始化,使用WSAStartup()就可以完成。該函數(shù)的原型為:int
WSAStartup(WORD
wVersionRequested,//Socket動(dòng)態(tài)鏈接庫(kù)的版本號(hào)LPWSADATA
lpWSAData//指向一個(gè)WSADATA數(shù)據(jù)結(jié)構(gòu),//該數(shù)據(jù)結(jié)構(gòu)返回Windows
Socket實(shí)現(xiàn)的詳細(xì)信息);第一個(gè)參數(shù)指明了要調(diào)用的Socket動(dòng)態(tài)鏈接庫(kù)的版本號(hào);第二個(gè)參數(shù)為指針類型,指向一個(gè)WSADATA數(shù)據(jù)結(jié)構(gòu),該數(shù)據(jù)結(jié)構(gòu)返回Windows
Socket實(shí)現(xiàn)的詳細(xì)信息。該函數(shù)通過(guò)一個(gè)過(guò)程調(diào)用來(lái)完成使用Windows中Socket動(dòng)態(tài)鏈接庫(kù)的初始化工作,它調(diào)用成功后就可以調(diào)用WindowsSocket
API函數(shù)。Visual
C++5.3.1
套接字的使用與WinsockAPI(續(xù))用WinsockAPI函數(shù)取本機(jī)名和IP地址取本機(jī)名稱的函數(shù)為:int
gethostname(char
FAR
*name,
int
namelen);其中參數(shù)name為傳出參數(shù),指向接收主機(jī)名稱的緩沖區(qū);后面的參數(shù)為傳入?yún)?shù),它指定了緩沖區(qū)的長(zhǎng)度。取主機(jī)信息的函數(shù)為:struct
hostent
FAR
*gethostbyname(const
char
FAR
*name);該函數(shù)用來(lái)通過(guò)主機(jī)名稱獲取主機(jī)的詳細(xì)信息。參數(shù)name就是
gethostname()函數(shù)的返回結(jié)果,該函數(shù)執(zhí)行成功后,將返回一個(gè)hostent結(jié)構(gòu)的指針,該結(jié)構(gòu)包含了當(dāng)前主機(jī)的詳細(xì)信息。該結(jié)構(gòu)定義如下:Visual
C++charFAR*
h_name;//主機(jī)的官方名稱charFAR*
FAR
*
h_aliases;//主機(jī)的別名shorth_addrtype;//地址類型shorth_length;//該數(shù)據(jù)結(jié)構(gòu)的大小char
FAR*
FAR*
h_addr_list;//主機(jī)地址列表,包含了主機(jī)的IP};【例5-5】調(diào)用Windows網(wǎng)絡(luò)API函數(shù)取計(jì)算機(jī)的名稱和IP地址。程序主文件為MyComputer.cpp。例5-55.3.1
套接字的使用與WinsockAPI(續(xù))struct
hostent
{Visual
C++WinInet是Windows
Internet擴(kuò)展應(yīng)用程序的接口,它包含了一個(gè)C語(yǔ)言的函數(shù)集。使用WinInet可以為應(yīng)用程序添加向InterNet服務(wù)器的連接,而無(wú)需考慮基本的通訊協(xié)議和底層的數(shù)據(jù)傳輸工作。WinInet支持文本傳輸協(xié)議(FTP)、超文本傳輸協(xié)議(HTTP)等。1.利用WinInet檢測(cè)計(jì)算機(jī)是否接入因特網(wǎng)及接入方式在開(kāi)發(fā)網(wǎng)絡(luò)應(yīng)用程序的時(shí)候,如果設(shè)計(jì)到Internet方面的處理問(wèn)題,則首先必須要能判斷當(dāng)前計(jì)算機(jī)是否接入Internet。因?yàn)?,如果用戶?dāng)前的計(jì)算機(jī)沒(méi)有接入網(wǎng)的話,隨后的任何操作過(guò)程都必出現(xiàn)錯(cuò)誤。我們可以通過(guò)軟件的方式檢測(cè)當(dāng)前計(jì)算機(jī)是否接入Internet及當(dāng)前的接入方式。5.3.2 因特網(wǎng)服務(wù)WinInetVisual
C++2.WinInet中的API函數(shù)InternetGetConnectedState通過(guò)API函數(shù)InternetGetConnectedState可以檢測(cè)當(dāng)前計(jì)算機(jī)是否接入Internet及接入的方式。該函數(shù)原型為:BOOL
InternetGetConnectedState(OUT
LPDWORD
lpdwFlags,IN
DWORD
dwReserved);該函數(shù)第一個(gè)參數(shù)表示網(wǎng)絡(luò)的接入類型,第二個(gè)值保留,一般取0,當(dāng)函數(shù)返回值為真時(shí),代表已經(jīng)接入因特網(wǎng)。否則,沒(méi)有接入。【例5-6】調(diào)用因特網(wǎng)API函數(shù)檢測(cè)本機(jī)是否接入因特網(wǎng)的實(shí)例例。5-6程序的主文件為L(zhǎng)inkInternet.cpp程序。5.3.2 因特網(wǎng)服務(wù)WinInet(續(xù))Visual
C++5.4
Win32API編寫圖形界面程序本章的前幾節(jié)利用API函數(shù)來(lái)操縱操作系統(tǒng),編寫的都是控制臺(tái)工程,下面講解利用API函數(shù)來(lái)編寫圖形界面的程序,它是本節(jié)的重點(diǎn)和難點(diǎn),讀者要花大力氣去學(xué)習(xí)。使用AppWizard生成W32應(yīng)用程序程序的入口WinMain()定義和注冊(cè)窗口類初始化實(shí)例維護(hù)消息循環(huán)窗口函數(shù)和消息處理常見(jiàn)消息的處理幾個(gè)重要的結(jié)構(gòu)*5.4.9
WinMain()執(zhí)行規(guī)程描述*5.4.10
利用Win32
API編寫圖形界面的關(guān)鍵Visual
C++5.4.1 使用AppWizard生成Win32應(yīng)用程序【例5-7】調(diào)用API函數(shù)建立一個(gè)圖形界面的程序Hello。1.建立Hello工程啟動(dòng)Visual
C++的集成開(kāi)發(fā)環(huán)境Developer
Studio。選擇菜單命令“File|New|Projects|Win32
Application”。在Project
Name的編輯框中輸入一個(gè)應(yīng)用程序的名稱“Hello”,界面如圖5.1
所示。完后單擊OK按鈕。進(jìn)入下一個(gè)界面,如圖5.2所示。選擇一個(gè)Windows應(yīng)用程序的類型——A
Typical“HelloWorld!”Application。完后單擊Finish按鈕。進(jìn)入下一個(gè)界面,單擊OK按鈕,一個(gè)應(yīng)用程序已經(jīng)生成。單擊WorkSpace視圖的ClassView標(biāo)簽下HelloClasses根結(jié)點(diǎn)下的子結(jié)點(diǎn)Globals。界面如圖5.3
所示。雙擊WinMain()函數(shù)結(jié)點(diǎn),進(jìn)入到程序的主文件
Hello.cpp文件中。我們的主要工作就是剖析該文件的內(nèi)容。文件的主要內(nèi)容如2小節(jié)所示(作了簡(jiǎn)單修改)。2.Hello.cpp的主要內(nèi)容(詳細(xì)內(nèi)容請(qǐng)參見(jiàn)程序)Visual
C++圖(一)圖5.1選擇工程類型窗口圖5.2選擇win32應(yīng)用程序類型窗口圖5.3選擇WinMain函數(shù)的界面WinMain()函數(shù)是所有Windows應(yīng)用程序的入口,類似于C語(yǔ)言中的Main()函數(shù),其功能是完成一些初始化工作并維持一個(gè)消息循環(huán)。消息循環(huán)是整個(gè)程序運(yùn)行的核心。在WinMain()函數(shù)中,要完成以下幾步工作:利用自定義函數(shù)MyRegisterClass()注冊(cè)應(yīng)用程序窗口類利用自定義函數(shù)InitInstance()初始化應(yīng)用程序的實(shí)例,該函數(shù)主要完成創(chuàng)建和顯示窗口,并進(jìn)行其它必要的初始化處理利用API函數(shù)GetMessage()啟動(dòng)應(yīng)用程序的消息循環(huán),把從應(yīng)用程序消息隊(duì)列接收的消息進(jìn)行翻譯,并送到窗口函數(shù)中進(jìn)行處理窗口函數(shù)WinProc()是Windows應(yīng)用程序的消息處理中心,它能夠處理所有的消息,當(dāng)消息循環(huán)檢索到WM_QUIT消息時(shí),則退出應(yīng)用程序。如果WinMain()調(diào)用成功,那么將會(huì)在接收到WM_QUIT時(shí)退出。Visual
C++5.4.2程序的入口WinMain()Windows下窗口的生成都是基于窗口類的。每個(gè)窗口都有一些基本屬性,如標(biāo)題欄文字、窗口大小和位置、圖標(biāo)、窗
體的背景顏色等,窗口類就是充當(dāng)定義這些屬性的模板。WinMain()函數(shù)中,通常要對(duì)主窗口定義一個(gè)窗口類,即把窗口類的具體屬性填入WNDCLASSEX結(jié)構(gòu)的相應(yīng)成員中。然后進(jìn)行注冊(cè),它是通過(guò)調(diào)用RegisterClassEx()來(lái)完成。窗口創(chuàng)建函數(shù)CreateWindows創(chuàng)建窗體。窗口類的注冊(cè)在函數(shù)MyRegisterClass()中完成。
代碼Visual
C++5.4.3定義和注冊(cè)窗口類Visual
C++5.4.4初始化實(shí)例在初始化應(yīng)用程序?qū)嵗^(guò)程中,主要作的工作有:創(chuàng)建窗口;顯示窗口;更新窗口。這些步驟的完成是放在向?qū)傻暮瘮?shù)InitInstance()中。BOOL
InitInstance(HINSTANCE
hInstance,
int
nCmdShow){HWND
hWnd;hInst
=
hInstance;
//
Store
instance
handle
in
our
globalvariablehWnd
=
CreateWindow(szWindowClass,
szTitle,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,
hInstance,NULL);if
(!hWnd)
{
return
FALSE;
}ShowWindow(hWnd,
nCmdShow);UpdateWindow(hWnd);return
TRUE;}Visual
C++1.創(chuàng)建窗口窗口類定義了窗口的一般特性,而窗口與顯示關(guān)系比較密切的一些細(xì)節(jié)尚未指定。因此,基于同一個(gè)窗口類可以創(chuàng)建多個(gè)不完全相同的窗口,這一工作在
API函數(shù)CreateWindow()函數(shù)中完成。
創(chuàng)建窗口類所需要的各個(gè)信息“打包”在一個(gè)WNDCLASS結(jié)構(gòu)中傳遞給
RegisterClass()函數(shù),而創(chuàng)建具體窗口所需的信息則各自作為單獨(dú)的參數(shù)傳遞給CreateWindow()函數(shù)。5.4.4初始化實(shí)例(續(xù))Visual
C++CreateWindow()的參數(shù)參數(shù)lpClassName是窗口類的名字
參數(shù)lpWindowName是指定窗口的標(biāo)題參數(shù)dwStyle是指定窗口的顯示風(fēng)格參數(shù)x,y,nWidth,nHeight指定了窗口的位置和大小參數(shù)hWndParent為父窗口的句柄參數(shù)hMenu為主菜單句柄參數(shù)hInstance為應(yīng)用程序的當(dāng)前句柄最后一個(gè)參數(shù)lpParam為創(chuàng)建參數(shù)CreateWindow()的返回值CreateWindow()函數(shù)返回被創(chuàng)建窗口的窗口句柄。Windows的每一個(gè)窗口都有一個(gè)句柄,程序通過(guò)窗口句柄來(lái)引用窗口,許多
Windows函數(shù)都需要使用窗口句柄做參數(shù)。這樣,Windows才知道
操作是針對(duì)哪一個(gè)窗口的。如果一個(gè)程序創(chuàng)建了多個(gè)窗口,則每
一個(gè)窗口都擁有各自的句柄。Visual
C++顯示窗口把窗口顯示在屏幕上,得調(diào)用函數(shù)ShowWindow(),其中,參數(shù)hWnd指定要顯示的窗口句柄,用來(lái)確定顯
示哪一個(gè)窗口參數(shù)nCmdShow指定窗口的顯示方式,該值從WinMain()函數(shù)傳遞過(guò)來(lái)。更新窗口應(yīng)用程序調(diào)用UpdateWindow()函數(shù)迫使窗口立即重畫客戶區(qū)域,并發(fā)出WM_PAINT消息,如果更新區(qū)域是空的,就不發(fā)送任何消息。窗口的客戶區(qū)域是指窗口菜單欄下面的矩形區(qū)域,除了客戶區(qū)域之外,窗口所覆蓋的其它區(qū)域,包括標(biāo)題欄、菜單、滾動(dòng)條、邊框等都是屬于非客戶區(qū)域。窗口的顯示與更新Visual
C++5.4.5
維護(hù)消息循環(huán)調(diào)用UpdateWindow()函數(shù)后,應(yīng)用程序主窗口就顯示在屏幕上,即程序的輸入輸出界面已經(jīng)準(zhǔn)備好,剩下來(lái)要完成的任務(wù)是處理消息。Windows應(yīng)用程序接收以各種形式輸入的消息,包括鍵盤、鼠標(biāo)、計(jì)時(shí)器等產(chǎn)生的消息,也可以是其它應(yīng)用程序發(fā)來(lái)的消息。Windows監(jiān)控所有的輸入設(shè)備,將外部發(fā)生的事件轉(zhuǎn)化為對(duì)應(yīng)的消息,并將信息放入消息隊(duì)列中。最后,應(yīng)用程序從自己的消息隊(duì)列中按一定的次序檢索消息并將每一個(gè)消息發(fā)送到相應(yīng)的窗口函數(shù)中進(jìn)行處理。維護(hù)消息循環(huán)的主要代碼Visual
C++5.4.6窗口函數(shù)和消息處理(上)利用WindowsAPI進(jìn)行Windows圖形用戶界面程序設(shè)計(jì)的實(shí)質(zhì)性的工作在于對(duì)消息的處理,這個(gè)任務(wù)是由窗口函數(shù)來(lái)?yè)?dān)當(dāng)。在該函數(shù)中,要定義對(duì)各種消息的響應(yīng)動(dòng)作,包括內(nèi)容的顯示、對(duì)用戶輸入的響應(yīng),只要是屬于該窗口的不同的消息都將會(huì)得到相應(yīng)的處理。因此,窗口函數(shù)是窗口的核心,函數(shù)的原型如下:LRESULT
CALLBACK
WndProc(HWND
hWnd,UINT
message,WPARAMwParam,
LPARAM
lParam)其中CALLBACK表明該函數(shù)是一個(gè)回調(diào)函數(shù)。該函數(shù)的返回類型為L(zhǎng)RESULT,它是一個(gè)長(zhǎng)整型。窗口函數(shù)可以任意命名,只要它和其他窗口函數(shù)名稱不發(fā)生沖突,但它的返回值及參數(shù)類型和順序都必須按照系統(tǒng)的規(guī)定來(lái)定義。該函數(shù)的第一個(gè)參數(shù)hWnd是窗口句柄,它的值與CreateWindow()的返回值相同。第二個(gè)參數(shù)message是無(wú)符號(hào)整數(shù)類型(UINT),用來(lái)標(biāo)識(shí)接收的消息。最后兩個(gè)參數(shù)提供了有關(guān)消息message的進(jìn)一步的信息,我們將它們統(tǒng)稱為“消息參數(shù)”。WPARAM與LPARAM表示的都是長(zhǎng)整數(shù)。該函數(shù)的四個(gè)參數(shù)與MSG結(jié)構(gòu)的前四個(gè)域相同。Visual
C++5.4.6 窗口函數(shù)和消息處理(下)窗口函數(shù)是Windows應(yīng)用程序的核心,Windows操作系統(tǒng)定義了上千種消息,每種消息的生成條件不一樣,消息參數(shù)的意義也不一樣,處理方式也有很大的差異。因此必須了解在什么樣的條件下窗口會(huì)收到什么樣的消息。所有窗口函數(shù)的代碼都是非常相似的,都是使用switch和case結(jié)構(gòu)來(lái)確定窗口函數(shù)接收什么樣的消息,以
及如何處理所接收到的消息。如果成功地處理了某個(gè)消息,窗口函數(shù)應(yīng)返回一個(gè)0;如果不想處理某個(gè)消息,就將這個(gè)消息傳遞給系統(tǒng)默認(rèn)的窗口過(guò)程DefWindowProc();如果在處理消息的過(guò)程中出現(xiàn)失敗,則要返回一個(gè)非零值,具體返回什么值要根據(jù)特定的消息來(lái)決定,窗口函數(shù)的返回值類似于DOS應(yīng)用程序的退出代碼。Visual
C++5.4.7
常見(jiàn)的消息處理示例程序代碼比較簡(jiǎn)單,它的窗口函數(shù)只處理了三個(gè)消息:WM_COMMAND消息、WM_PAINT消息和WM_DESTROY消息。當(dāng)用戶選擇一個(gè)菜單的選項(xiàng)時(shí),發(fā)送WM_COMMAND消息,示例程序中有一個(gè)退出選項(xiàng)和幫助選項(xiàng),該消息的處理暫時(shí)不講。WM_PAINT消息WM_PAINT消息是窗口函數(shù)WinProc()需要處理的一個(gè)很重要消息,該消息牽涉到應(yīng)用程序的界面維護(hù)。當(dāng)窗口中的用戶區(qū)域一部分或全部“無(wú)效”而需要“刷新”時(shí),都通過(guò)該消息實(shí)現(xiàn)界面的清理。消息的生成條件消息的處理方法當(dāng)窗口收到WM_PAINT消息時(shí),應(yīng)用程序窗口將該窗口的客戶區(qū)重繪。Visual
C++WM_DESTROY消息消息的生成條件當(dāng)窗口被摧毀撤消后(當(dāng)用戶按下ALT+F4鍵或單擊關(guān)閉窗口按鈕時(shí)),Windows向窗口發(fā)送WM_DESTROY消息。系統(tǒng)默認(rèn)的響應(yīng)是調(diào)用DestroyWindow()函數(shù)撤消窗口。消息的處理方法響應(yīng)WM_DESTROY消息時(shí),必須要調(diào)用PostQuitMessage()函數(shù)。該函數(shù)向消息隊(duì)列中放入WM_QUIT消息,使程序退出消息循環(huán),進(jìn)而退出應(yīng)用程序。應(yīng)用程序可在響應(yīng)這個(gè)消息時(shí)做一些收尾工作。典型的代碼如下:case
WM_DESTROY:PostQuitMessage(0);break;5.4.7 常見(jiàn)的消息處理(續(xù))Visual
C++■消息的生成條件當(dāng)Windows應(yīng)用程序要求重新在窗口客戶區(qū)域繪圖時(shí),要發(fā)送該消息,典型的情況有:(1)一個(gè)窗口由不活動(dòng)狀態(tài)變?yōu)榛顒?dòng)狀態(tài)時(shí),如果客戶區(qū)域有部分被其它窗口覆蓋,則被覆蓋區(qū)域變?yōu)闊o(wú)效時(shí),會(huì)生成該消息;(2)如果一個(gè)窗口由隱藏狀態(tài)變?yōu)轱@示狀態(tài)時(shí),整個(gè)客戶區(qū)域都無(wú)效,會(huì)生成該消息;(3)窗口類的風(fēng)格設(shè)置為CS_HREDRAW或
CS_VREDRAW時(shí),那么當(dāng)窗口大小在水平或垂直方向發(fā)生變化時(shí),會(huì)生成該消息;(4)在移動(dòng)窗口使得它和其它窗口相互重疊時(shí),Windows并不保存被覆蓋的內(nèi)容,它是通過(guò),當(dāng)被覆蓋的部分不再被覆蓋時(shí)(如移走另一個(gè)窗口),Windows將其標(biāo)志為無(wú)效,發(fā)送該消息;(5)程序顯式地調(diào)用Invalidate()、InvalidateRect()或InvalidateRgn()函數(shù)將產(chǎn)生WM_PAINT消息。當(dāng)窗口收到WM_PAINT消息時(shí),相當(dāng)于操作系統(tǒng)告訴你的應(yīng)用程序窗口“該窗口的客戶區(qū)域已經(jīng)混亂了,請(qǐng)你重新把窗口的客戶區(qū)域繪制一下”。我們?cè)谙鄳?yīng)WM_PAINT消息時(shí)的作圖稱為“被動(dòng)作圖”,在任何時(shí)候,我們都可以在窗口區(qū)域中作圖,這種情況被稱作“主動(dòng)作圖”。Visual
C++消息的處理方法響應(yīng)WM_PAINT消息的主要目的是在客戶區(qū)域作圖。典型的代碼如下:case
WM_PAINT:hdc
=
BeginPaint(hWnd,
&ps);//準(zhǔn)備在hWnd所指的窗口內(nèi)繪圖RECT
rt;//定義矩形變量rtGetClientRect(hWnd,&rt);//取hWnd窗口的客戶區(qū)域保存在矩形變量rtDrawText(hdc,szHello,strlen(szHello),&rt,DT_CENTER);//在矩形rt中顯示文本szHelloEndPaint(hWnd,
&ps);//結(jié)束在hWnd所指的窗口內(nèi)繪圖break;上述示例代碼中,BeginPaint()與EndPaint()函數(shù)必須成對(duì)調(diào)用,并且當(dāng)且僅當(dāng)在響應(yīng)WM_PAINT消息時(shí)調(diào)用。所有作圖代碼都必須位于這對(duì)函數(shù)調(diào)用中間,這對(duì)函數(shù)的第一參數(shù)為程序的窗口句柄,第二個(gè)參數(shù)是指向PAINTSTRUCT(參見(jiàn)下一節(jié)的介紹,它主要用于刷新客戶區(qū)中的內(nèi)容)結(jié)構(gòu)的指針。Visual
C++typedef
struct
tagMSG
{
HWND
hwnd;WPARAM
wParam;UINTLPARAMPOINTmessage;lParam;pt;DWORD
time;}
MSG;消息結(jié)構(gòu)MSG的各個(gè)成員的含義如下:hwnd:接收消息的窗口句柄,用以檢索消息。若此參數(shù)為0(NULL),則可以檢索所有駐留在消息對(duì)列中的消息。message:消息標(biāo)識(shí)符。每個(gè)Windows消息都有一個(gè)確定的值,該值由windows.h頭文件中的宏來(lái)識(shí)別,以WM_前綴開(kāi)頭。wParam、lParam:32位的消息附加參數(shù),此值隨不同的message而有所改變。time:消息進(jìn)入消息隊(duì)列時(shí)的時(shí)間。pt:
消息進(jìn)入消息隊(duì)列時(shí)鼠標(biāo)的位置坐標(biāo)。上述消息結(jié)構(gòu)MSG的各個(gè)成員中,最為重要的成員是消息標(biāo)識(shí)符。所有的窗口消息定義為具有指定的宏,并帶有WM_前綴,緊隨其后的是描述消息名。例如,當(dāng)窗口重新確定尺寸時(shí),則具有WM_SIZE值的消息被放入消息隊(duì)列中。5.4.8
幾個(gè)重要的結(jié)構(gòu)1.消息結(jié)構(gòu)Windows的消息結(jié)構(gòu)MSG,其定義如下Visual
C++5.4.8 幾個(gè)重要的結(jié)構(gòu)(續(xù))HDC
hdc;BOOL
fErase;RECT
rcPaint;BOOL
fRestore;BOOL
fIncUpdate;//設(shè)備環(huán)境句柄//是否擦除背景//無(wú)效的矩形區(qū)域//保留,系統(tǒng)內(nèi)部使用//保留,系統(tǒng)內(nèi)部使用BYTE
rgbReserved[32];//保留,系統(tǒng)內(nèi)部使用}
PAINTSTRUCT,
*PPAINTSTRUCT;參數(shù)fErase用于指定應(yīng)用程序是否需要自己擦除無(wú)效區(qū)域的背景,若其值為FALSE,則意味著由Windows將利用WNDCLASS結(jié)構(gòu)中hbrBackground域指定的畫刷來(lái)自動(dòng)擦除背景。若其值為TRUE,則意味著由應(yīng)用程序自己來(lái)負(fù)責(zé)無(wú)效區(qū)域的擦除。2.PAINTSTRUCT結(jié)構(gòu)typedef
struct
tagPAINTSTRUCT
{Visual
C++5.4.9
WinMain()執(zhí)行規(guī)程描述程序的主函數(shù)WinMain()首先調(diào)用字符串資源函數(shù),
將窗口標(biāo)題和窗口類的名稱取出來(lái)。然后注冊(cè)窗口類,
創(chuàng)建一個(gè)窗口。創(chuàng)建窗口是由CreateWindow()函數(shù)完成,該函數(shù)向窗口發(fā)送WM_CREATE消息,通知應(yīng)用程序要?jiǎng)?chuàng)建窗口。創(chuàng)建窗口后,緊接著要顯示窗口,這時(shí)會(huì)收到WM_SIZE消息,窗口的客戶區(qū)全部無(wú)效,收到WM_PAINT消息。對(duì)WM_PAINT消息的響應(yīng)則是在窗口的客戶區(qū)域顯示
一行字符串。此時(shí)窗口已經(jīng)被正常的顯示,主函數(shù)也進(jìn)
入了一個(gè)消息循環(huán),開(kāi)始了應(yīng)用程序的正常運(yùn)轉(zhuǎn)。最后
當(dāng)用戶關(guān)閉窗口時(shí),窗口函數(shù)會(huì)收到WM_DESTROY消息,
表明窗口已經(jīng)被撤消了。應(yīng)用程序最后調(diào)用PostQuitMessage()函數(shù)終止主函數(shù)中的消息循環(huán)。至此,窗口已經(jīng)被撤消,主函數(shù)也退出了,整個(gè)應(yīng)用程序終止。Visual
C++5.4.10利用Win32API編寫圖形界面的關(guān)鍵用VC進(jìn)行Windows編程的關(guān)鍵在于明白其消息驅(qū)動(dòng)機(jī)制,程序的基本流程交由Windows管理,Windows掌握著一定的主
動(dòng)權(quán),而程序員只需要集中精力做真正需要做的事情,如設(shè)
計(jì)函數(shù),編寫消息的響應(yīng)代碼,至于消息響應(yīng)函數(shù)如何被調(diào)
用的則無(wú)須管理,交由Windows去處理。用VC進(jìn)行Windows編程的一個(gè)重要工作就是編寫窗口函數(shù)。程序員的主要精力是編寫自己的窗口函數(shù),將接收到的消息所對(duì)應(yīng)的響應(yīng)代碼編好,而調(diào)用工作由Windows進(jìn)行處理。通過(guò)消息循環(huán)機(jī)制,Windows會(huì)全心全意地為“接收到的消息找到對(duì)應(yīng)的處理函數(shù)執(zhí)行”而服務(wù)。Visual
C++圖形設(shè)備接口與用戶服務(wù)Windows應(yīng)用程序使用圖形設(shè)備接口和Windows設(shè)備驅(qū)動(dòng)程序來(lái)支持與設(shè)備無(wú)關(guān)的圖形。圖形設(shè)備接口(GDI)是構(gòu)造Microsoft的
Windows操作系統(tǒng)核心的三個(gè)動(dòng)態(tài)鏈接庫(kù)之一,它的任務(wù)是負(fù)責(zé)系統(tǒng)與繪圖程序之間的信息交換,處理所有Windows程序的圖形輸出。為了適應(yīng)不同的設(shè)備,Windows系統(tǒng)提供應(yīng)用程序與具體設(shè)備分離的功能,由操作系統(tǒng)來(lái)管理設(shè)備驅(qū)動(dòng)程序,將應(yīng)用程序的圖形輸出轉(zhuǎn)化為具體物理設(shè)備上的輸出。設(shè)備描述表文本函數(shù)畫直線函數(shù)用戶接口服務(wù)綜合實(shí)例*5.5.6
在VC中使用FileView視圖瀏覽文件Visual
C++5.5.1
設(shè)備描述表設(shè)備描述表(Device
Context,又稱設(shè)備環(huán)境,設(shè)備上下文),它是VC進(jìn)行繪圖操作碰到最多的一個(gè)技術(shù)名詞。“設(shè)備描述表”中的設(shè)備含義為圖形既可以在屏幕上顯示,還可以在打印機(jī)、繪圖儀等上顯示,而具體是什么外部設(shè)備,應(yīng)用程序并不需要關(guān)心,它是設(shè)備無(wú)關(guān)的。在Windows下程序員對(duì)所有繪圖功能的調(diào)用,都是通
過(guò)設(shè)備描述表來(lái)進(jìn)行的,在進(jìn)行繪圖之前,必須先獲取設(shè)備描述表句柄。獲取和釋放設(shè)備描述表句柄在應(yīng)用程序中,有兩種方法來(lái)獲取和釋放設(shè)備描述表句柄?!觯?)通過(guò)BeginPaint和EndPaint函數(shù)程序在響應(yīng)WM_PAINT消息進(jìn)行繪圖操作時(shí),要調(diào)用
BeginPaint函數(shù)來(lái)獲取設(shè)備描述表句柄,使用完后用EndPaint來(lái)釋放設(shè)備描述表句柄?!觯?)通過(guò)GetDC和ReleaseDC函數(shù)在處理非WM_PAINT消息時(shí),通過(guò)調(diào)用GetDC函數(shù)來(lái)獲取設(shè)備描述表信息。該函數(shù)的原型為:Visual
C++//
handle
to
windowHDC
GetDC(HWND
hWnd);該函數(shù)中參數(shù)hWnd代表窗口函數(shù)所屬的窗口句柄,它返回所獲得的設(shè)備描述表句柄。當(dāng)使用完畢,要調(diào)用ReleaseDC函數(shù)來(lái)釋放該設(shè)備描述表句柄。其原型為:int
ReleaseDC(//所屬窗口的句柄//需要釋放的設(shè)備描述表句柄HWND
hWnd,
HDC
hDC);兩種方法的區(qū)別:(1)通過(guò)BeginPaint函數(shù)獲得的操作區(qū)域是客戶區(qū)中的無(wú)效矩形區(qū)域,隨后的繪圖操作只能在該無(wú)效區(qū)域內(nèi)進(jìn)行,而該區(qū)域之外的操作將被忽略。GetDC函數(shù)獲得的操作區(qū)域是整個(gè)客戶區(qū)域,隨后的繪圖操作可以在客戶區(qū)的任意部分進(jìn)行,而不只是在無(wú)效區(qū)域內(nèi)進(jìn)行;5.5.1 設(shè)備描述表(續(xù))Visual
C++5.5.1 設(shè)備描述表(續(xù))(2)BeginPaint函數(shù)會(huì)自動(dòng)將無(wú)效矩形區(qū)域變?yōu)橛行В?/p>
GetDC函數(shù)不會(huì)將任何無(wú)效矩形區(qū)域變?yōu)橛行?,它必須?qiáng)行調(diào)用ValidateRect函數(shù),并將第二個(gè)參數(shù)設(shè)置
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 科室內(nèi)停水停電應(yīng)急演練預(yù)案
- 糖尿病足外用用藥指導(dǎo)
- 2023年舟山岱山醫(yī)療健康集團(tuán)招聘緊缺專業(yè)人才考試真題
- 2023年綿陽(yáng)科技城科技服務(wù)有限責(zé)任公司招聘工作人員考試真題
- 展區(qū)合同范本
- 2023年景寧縣機(jī)關(guān)事業(yè)單位選調(diào)考試真題
- 2023年呼和浩特市文化旅游投資集團(tuán)有限公司招聘專業(yè)藝術(shù)人才考試真題
- 對(duì)公購(gòu)銷合同范本
- 水工程合同范本
- 語(yǔ)言講述活動(dòng):愛(ài)吃糖的小熊
- 中考李清照《漁家傲》理解性默寫(含答案)
- 北京旅行4天3夜課件
- 河海大學(xué)5結(jié)構(gòu)力學(xué)全部核心考點(diǎn)講義
- 靈芝的歷史文化與現(xiàn)代研究
- 采煤教學(xué)課件
- 湖北省荊門市各縣區(qū)鄉(xiāng)鎮(zhèn)行政村村莊村名居民村民委員會(huì)明細(xì)及行政區(qū)劃代碼
- 少兒美術(shù)畫畫課件6-8歲《一盆生機(jī)盎然的綠籮》
- 醫(yī)院對(duì)口支援月度工作統(tǒng)計(jì)表
- 物業(yè)環(huán)境因素識(shí)別評(píng)價(jià)表
- 材料進(jìn)場(chǎng)檢驗(yàn)項(xiàng)目清單
- 《日語(yǔ)古典文法》課程教學(xué)大綱
評(píng)論
0/150
提交評(píng)論