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