pascal之windows api簡明教程未完成_第1頁
pascal之windows api簡明教程未完成_第2頁
pascal之windows api簡明教程未完成_第3頁
pascal之windows api簡明教程未完成_第4頁
pascal之windows api簡明教程未完成_第5頁
已閱讀5頁,還剩60頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領

文檔簡介

Pascal之Windows

API簡明教程制作:ax_poklQQ:395838203不積跬步,無以至千里;不積小流,無以成江海。前言學習本教程之前請先精通英語和Pascal中有關單元庫、類型、子程序、指針等內(nèi)容,并且先初步了解關于計算機硬件組成原理、匯編語言、離散數(shù)學、高等代數(shù)、數(shù)字電路分析,電磁學,量子力學等計算機學基礎知識。本教程為用Pascal寫游戲和簡單窗體程序的同學所寫。本教程不涉及任何有關NOIP和算法有關的內(nèi)容,所以也適合學過C語言的同學們觀看。本教程編譯器以fpc為準,學習教程之前請先學會熟練運用至少一款fpc的IDE(或者學會用磁鐵操作硬盤)。由于本人對API的了解不是很深,僅給同學們API的一個大致印象。內(nèi)容膚淺,水平極渣,錯誤頗多,敬請諒解。目錄第一章Windows

API基本常識第二章Windows

API基礎知識第三章Windows

API實例第一章Windows

API基本常識什么是程序?什么是動態(tài)鏈接庫?如何使用動態(tài)鏈接庫?如何編寫動態(tài)鏈接庫?什么是Windows

API?如何使用MSDN獲取幫助?什么是程序?程序是語句的集合。語句是調(diào)用一段程序。主程序(program),unit(單元庫),子程序(subrotine)——函數(shù)(function)和過程(procedure),甚至操作符(operator)都是程序。例如i:=i+1;可以寫成:=(i,+(i,1));程序里可以包含很多程序。例如一個program里含有一個function和一個procedure。程序可以有一個返回值。什么是動態(tài)鏈接庫?庫是子程序的集合。通過聲明單元庫,可以調(diào)用單元庫中的子程序,但這僅局限于Pascal語言和指定的編譯器。鏈接庫是編譯好的子程序集合,用于不同語言之間子程序的互相調(diào)用,分為靜態(tài)鏈接庫(lib)和動態(tài)鏈接庫(dll)。靜態(tài)鏈接庫被引用后,程序在編譯鏈接時會把庫中的代碼直接拷貝到可執(zhí)行文件(exe)中。動態(tài)鏈接庫被引用后,程序在鏈接時不會拷貝代碼。待程序執(zhí)行時會尋找引用的動態(tài)鏈接庫并載入內(nèi)存。如何使用動態(tài)鏈接庫?使用external和name關鍵字聲明一個外部子程序:function

GetTickCount():longint;external

'kernel32.dll'

name

'GetTickCount';external關鍵字聲明外部子程序的dll路徑。name關鍵字申明外部子程序在dll中的名稱。接著就可以使用這個外部子程序了:writeln(GetTickCount());如果找不到dll或者這個dll里沒有這個子程序,程序執(zhí)行的時候就會報錯。子程序聲明名稱和外部子程序在dll種的名稱可以不同。如何編寫動態(tài)鏈接庫?類似寫一個程序,將program關鍵字改成library關鍵字:library

lib1;接著寫子程序,注意申明調(diào)用約定:function

inc(i:longint):longint;stdcall;begin

inc:=i+1;end;所有子程序?qū)懲旰?,用exports關鍵字導出子程序:exports

inc;類似寫一個單元庫,如需在調(diào)用dll的時候初始化,則最后寫一段begin

end.,否則直接以end.結(jié)束。編譯后一個dll就生成了。如何編寫動態(tài)鏈接庫?類似于單元庫,在沒有接口(interface)的情況下,子程序即使有實現(xiàn)(implementation),別的程序也是不能使用這個子程序的。但是在單元庫內(nèi)部,這些寫在implementation里的子程序是可以互相調(diào)用的。同樣道理,沒有導出(exports)的子程序在dll里也是找不到入口的。但是在dll內(nèi)部則可以互相調(diào)用沒有導出的子程序。所以,library更像是一個unit。關于程序的鏈接,可以看這個:什么是Windows

API?Windows

API(應用程序編程接口)是Windows操作系統(tǒng)中所有

dll的集合。在Windows操作系統(tǒng)中,除了fpc的132個內(nèi)部子程序以外,所有的子程序最終都是通過調(diào)用Windows

API中的子程序來實現(xiàn)的,不妨用EXeScope軟件查看一下你編譯后程序用到過的dll。Windows

API的所有子程序都是stdcall的。絕大多數(shù)的Windows

API都已經(jīng)在Windows單元庫中定義好了,只需要uses

Windows即可使用。如果子程序名稱有沖突,可以強制用Windows.子程序名();,例如Windows.sleep(20);和delay(20);其實是一樣的。Windows單元庫中定義的子程序請參閱附錄func.inc。Windows

API大全請參閱附錄。如何使用MSDN獲取幫助?以GetSystemTime為例。通過搜索引擎找到該子程序的頁面:當然,如果百度百科有翻譯過的條目就再好不過了。頁面中的function指的是子程序而不是函數(shù),因為C++語言中的過程是有返回值VOID(空類型)的。大字后是關于子程序的解釋??梢杂霉雀璺g一下。Syntax一欄中有C++語言關于這個子程序的定義。VOID是子程序類型(這里是空類型,即子程序是過程);WINAPI是子程序的調(diào)用約定,即stdcall;;_In_代表參數(shù)是一個值參,_Out_則是變參即Pascal中的var參,_opt_是可選參數(shù)(可設為零)。大寫的

LPSYSTEMTIME是參數(shù)的類型,LP說明是一個長指針類型,指向SYSTEMTIME的記錄結(jié)構(gòu),lpSystemTime是參數(shù)名稱。如何使用MSDN獲取幫助?Parameters一欄是關于參數(shù)的具體解釋,這里解釋了

lpSystemTime是一個指向SYSTEMTIME結(jié)構(gòu)體(struct,即

Pascal的record)的指針變量。點開SYSTEMTIME,可以看到這個結(jié)構(gòu)體的定義??梢钥吹竭@是一個8個WORD組成的record。從變量名稱也可以看出來是

WORD類型,因為都是w開頭的。然后后面可以看到各種解釋啊,包括C++中的栗子和使用方法(GetSystemTime和GetLocalTime子程序有用到)。ReturnValue一欄解釋了返回值的用途。一般是void或者BOOL或者DWORD或者HANDLE之類的東西,例如GetTickCount返回的就是一個DWORD。如何使用MSDN獲取幫助?Remark就是備注了,這里是說這個子程序在Windows

Phone

8上也支持-_-。(好吧,只玩PC的路過)Example就是具體的使用方法。好吧,因為子程序太簡單都沒有栗子了??梢詤⒖歼@個SYSTEMTIME

structure的栗子:Requirement是使用這個子程序所需的條件,說到至少是

windows

2000系統(tǒng)以上才能用。然后這個子程序位于

Kernel32.dll。Seealso可以參考其它相關的子程序,例如想設置時間可以用

SetSystemTime。第二章Windows

API基礎知識獲取錯誤信息(GetLastError)句柄(Handle)指針記錄(^record)指針字符數(shù)組(PChar)緩沖區(qū)(Buffer)設備上下文(Device

Contexts)Windows編程命名規(guī)則獲取錯誤信息(GetLastError)有時候,一個Windows

API子程序并不一定返回的是錯誤碼(可能是一個句柄)。如果執(zhí)行一個子程序出錯了,這時候需要知道錯誤出在哪,就得用上GetLastError();。任何時候都可以調(diào)用GetLastError();子程序獲得調(diào)用的上一個Windows

API子程序的錯誤信息。由于Windows

API是外部子程序無法跟蹤步入(屬于系統(tǒng)領空),所以無法得知調(diào)用子程序時出了什么錯誤(具體哪個參數(shù)不對),于是調(diào)用GetLastError();獲取錯誤信息就顯得非常重要。錯誤代碼請參閱附錄。句柄(Handle)句柄是一種類型,相當于longword,用來標識系統(tǒng)中的一個對象。例如一個窗口,一個文件。簡單來說,句柄就是一個數(shù)字標號。一個窗口(窗口類型的變量)可以有高度,寬度,標題文字等詳細信息(屬性,即記錄中的成員類型),但這個窗口類型的變量通常是不可見的。傳遞句柄可以讓Windows

API子程序知道調(diào)用的是哪個對象。例如:窗口句柄HWND只是一個數(shù)字,并不包含結(jié)構(gòu)等詳細的信息。但是如果知道了這個數(shù)字,就可以通過一些子程序如

GetWindowText();來獲取窗口的標題文字等信息了。指針記錄(^record)以下為照抄Windows單元庫中struct.inc中的定義。typeSYSTEMTIME

=

recordwYear

:

WORD; wMonth

:

WORD;wDayOfWeek

:

WORD;

wDay

:

WORD;wMinute

:

WORD;wMilliseconds

:

WORD;wHour

:

WORD;wSecond

:

WORD;end;LPSYSTEMTIME

=

^SYSTEMTIME;PSYSTEMTIME

=^SYSTEMTIME;_SYSTEMTIME

=

SYSTEMTIME;TSYSTEMTIME=

SYSTEMTIME;指針記錄(^record)指針記錄類型的參數(shù)是Windows

API中極為常用的東西。Windows

API的返回值通常只是用來標識子程序調(diào)用的錯誤代碼的。如果需要返回一些數(shù)據(jù),則需要用到指針記錄變量。GetSystemTime(lpSystemTime:LPSYSTEMTIME);中的

LPSYSTEMTIME就是一個指針記錄類型,lpSystemTime就是一個指針記錄類型的參數(shù)。這個LPSYSTEMTIME類型是一個指向

SYSTEMTIME類型的指針類型,而SYSTEMTIME類型則是一個記錄類型。在使用這個子程序之前先定義一個LPSYSTEMTIME類型的變量,例如var

st:LPSYSTEMTIME;然后再調(diào)用這個子程序。此時st所指向的記錄已發(fā)生改變,通過writeln(st^.wHour);就可輸出當前時鐘小時數(shù)。(C++語言中,->即^.相當于取類型的成員對象)指針字符數(shù)組(PChar)PChar是Windows

API中最常見的字符串類型,它是一個指向一段內(nèi)存(字符數(shù)組)的指針變量,即^Char。在內(nèi)存中,PChar所指向的內(nèi)存單元存儲第一個字符數(shù)據(jù),之后的每一個字節(jié)存儲后面的字符,最后以#0結(jié)束。String和PChar不同。String雖然也是指針,但指向的內(nèi)存單元(字節(jié))存儲整個String的長度,隨后的n個字節(jié)存儲String的字符數(shù)據(jù),因此String的長度最多是255字節(jié)。將一個String轉(zhuǎn)為PChar,可以先將#0添加到String末尾,然后再將PChar指向String的第一個字符,實現(xiàn)如下:var

s:

String;

pc:

PChar;

s

:=

s

+

#0;

pc

:=

@s[1];一個PChar可以隱式的轉(zhuǎn)為String,即:s:=pc;Windows

API文獻(C++)中,PChar又叫做LPCSTR,只要

Uses

Windows一下就都可以用了。緩沖區(qū)(Buffer)緩沖區(qū)是Windows

API返回大量數(shù)據(jù)時存放數(shù)據(jù)的地方。一般來說緩沖區(qū)定義成一個定長字節(jié)數(shù)組array

of

byte[]或者一個字符串PChar,例如var

buf:array[1..256]of

byte;然后調(diào)用某個API的時候,將這個buf變量和長度n傳遞進去,API就會修改這個buf。接著你就可以得到API返回的信息了,例如你可以writeln(buf[1]);。如果緩存區(qū)是一個指針,使用前可能需要清空內(nèi)存,可以用freemem(buf,sizeof(buf));來完成這個動作。注意傳遞進去的是指針還是變量,如果是變量,可能要用@buf或者pointer(buf)。一般來說API只接受指針變量,因為API參數(shù)長度是固定的。設備上下文(Device

Contexts)Windows編程命名規(guī)則常量c_靜態(tài)s_句柄h無符號u短整n計數(shù)c雙精d雙字dw字符ch無效vWindows編程使用使用匈牙利命名

?

屬性:法。

全局g_類型和常量使用全大寫的形式。

成員m_函數(shù)名單詞名稱之間無符號,單詞

?

類型:為首字母大寫剩余部分小寫。

指針p變量名如同函數(shù)名,但需要在開頭

整型I增加屬性,類型和描述前綴。長整l即變量名=屬性+類型+描述+名稱。布爾b描述:單精f字w字串sz函數(shù)fn最大Max初始化Init源對象Src最小Min臨時Temp目的對象Dest第三章Windows

API實例第一節(jié)簡單API第二節(jié)文件API第三節(jié)窗口API第四節(jié)內(nèi)存API第五節(jié)管道API第六節(jié)網(wǎng)絡API第一節(jié)簡單APISleep();Sound();timeGetTime();mouse_event();mciSendString();CreateThread();Sleep();延遲一段時間,以毫秒為單位。usesWindows;后就可以使用了。效果和CRT單元庫中的Delay();一樣。參數(shù)類型是longword??梢杂肳indows.Sleep();以免混淆重載的Sleep();。Sound();在一段時間內(nèi)發(fā)出一個固定頻率的聲響。這個子程序有兩個參數(shù)都是longword類型。前一個參數(shù)是頻率,后一個參數(shù)是延遲時間。如同Sleep();,這個子程序直到聲音停止后才會返回。CRT單元庫中的Beep();子程序是用Sound();實現(xiàn)的。注意頻率的取值范圍,過高或過低可能會導致延遲時間不正確。timeGetTime();獲取開機到現(xiàn)在時間,以毫秒計。這是一個外部子程序,必須先聲明才能使用:function

timeGetTime():longword;external

'winmm.dll';注意子程序的調(diào)用約定。這個子程序?qū)儆赪indows多媒體API的一部分,所以返回的值較為精確??梢允褂肎etTickCount();子程序替代。該子程序返回較快,但是精度不如timeGetTime();高。GetTickCount();是randomize();子程序的一部分(RandSeed:=GetTickCount();)。mouse_event();模擬鼠標動作。該子程序沒有返回值。參數(shù)較多,有dwFlags,dx,dy,dwData,dwExtraInfo。除了dwExtraInfo為指針外,其余四個為longword。dwFlags為動作類型,dx、dy為移動的距離,dwData為滾輪滾動距離,dwExtraInfo為返回的附加信息,一般設為nil即可。dwFlags可直接使用Windows單元庫預設好的值,例如MOUSEEVENTF_ABSOLUTE、

MOUSEEVENTF_LEFTDOWN等,具體參看MSDN。mciSendString();winmm.dll中的子程序,用以給MCI發(fā)送一條指令。lpszCommand,lpszReturnString,cchReturn,hwndCallback,分別為發(fā)送的指令、返回的指令、返回指令的長度、回調(diào)子程序的入口句柄。指令都為PChar類型,返回值為MCIERROR類型。回調(diào)子程序入口句柄可設為0。鑒于處理PChar比較麻煩,返回的指令可用字符數(shù)組接收后再轉(zhuǎn)換成String,具體參見第二章相關內(nèi)容??捎胢ciExecute();替代,僅一個參數(shù)pszCommand。MCI指令可參考這個:(v=vs.85).aspxCreateThread();用以創(chuàng)建一個線程,返回值為線程句柄。線程營造了“多個子程序在同時運行”的假象,本質(zhì)上并不能加快程序的運行速度。子程序的同時運行會引發(fā)很多問題,同時訪問同一個

內(nèi)存單元會發(fā)生錯誤,所以不能同時給一個變量賦值。因此在沒有必要使用的時候不要使用多線程。例如使用Sound(1000,5000);發(fā)出一個1000Hz的5秒的聲音,在聲音停止之前程序是不會繼續(xù)執(zhí)行下去的。如果想在Sound();的時候同時readln();,那么可以建立一個Sound();的線程,這樣子程序會立刻返回(主程序)。CreateThread();參數(shù)較多,比較重要的有兩個,其余可以用nil或0替代。lpStartAddress為子程序入口地址,為指針類型。例如用@Sound或者pointer(Sound)代表Sound();子程序。lpParameter為傳遞給子程序的參數(shù),為指針類型。由于傳遞的參數(shù)只有一個,所以當子程序的參數(shù)多余一個(Sound(hz,t:longword);)時,可以定義一個記錄類型(TSound=record

hz,t:longword;end;),然后重載一個同名的子程序(Sound(para:^TSound);),并在這個重載的子程序中調(diào)用(Sound(para^.hz,para^.t);)。第二節(jié)文件APICreateFile();ReadFile();GetFileSize();GetFileInformationByHandle();CreateFile();該子程序不僅限于創(chuàng)建文件,還可用于打開文件,設置文件訪問權(quán)限,設置文件屬性等操作。文件的定義不僅限于磁盤文件,還包括控制臺,輸入輸出流,目錄,磁盤驅(qū)動器,管道等。事實上,文件是一個具有特定結(jié)構(gòu)的對象。子程序有7個參數(shù)。lpFileName為文件名稱,

dwDesiredAccess為文件的訪問權(quán)限(是否可讀可

寫),dwShareMode為共享模式(允許別的程序讀寫文件),dwCreationDisposition為創(chuàng)建并文件打開方式(是否清除原內(nèi)容)。操作成功后則返回文件句柄。ReadFile();正如其名,該子程序用來讀取文件內(nèi)容。我們一般讀取一個類型文件(例如fileofbyte)時都是一個byte一個byte讀的,這樣會導致讀取十分緩慢。

ReadFile();就給了我們一個快速讀取文件內(nèi)容的辦法。首先你需要一個緩沖區(qū)用以存放數(shù)據(jù)。用CreateFile();打開文件以后,使用返回的文件句柄就可以將文件內(nèi)容讀到緩沖區(qū)里了。文件讀取分為同步和異步兩種方式。如果文件是管道或者I/O,那么同步讀取時可能會卡住直到有數(shù)據(jù)輸入到管道或是I/O里。ReadFile();五個參數(shù)分別為:HANDLEhFile文件句柄,

LPVOIDlpBuffer緩沖區(qū)指針,

DWORDnNumberOfBytesToRead寫入緩沖區(qū)的字節(jié)數(shù),

LPDWORDlpNumberOfBytesRead剩余的字節(jié)數(shù),

LPOVERLAPPEDlpOverlapped同步或異步標識。寫到緩沖區(qū)是需要時間的。異步模式下讀完就會返回,于是LPDWORDlpNumberOfBytesRead(var參)會顯示還沒讀取的剩余字節(jié)數(shù)。返回值為布爾類型。如果需要寫入緩沖區(qū)的字節(jié)超過了文件剩余大?。ㄗx到文件尾),那么GestLastError();不會是零。GetFileSize();獲取文件大?。ㄗ止?jié)為單位)。第一個參數(shù)為文件句柄,返回值為文件大小。如果文件大小超過4G,那么使用第二個參數(shù)(var參)來獲取高位雙字的文件大小,否則設為nil即可。(這個子程序額外的簡單)GetFileInformationByHandle();有時候我們不滿足于只獲取文件大小,我們還想知道文件屬性,修改時間等其它信息。沒關系,這個子程序就能滿足你。你以為參數(shù)會很多?這個子程序只有兩個參數(shù),而且返回值只是個布爾類型(用以標記是否調(diào)用成功)。如同GetFilesize();,第一個參數(shù)是文件句柄。第二個參數(shù)是一個BY_HANDLE_FILE_INFORMATION記錄類型指針類型的var參。類型具體成員變量的用途MSDN里講了。時間類型FILETIME是兩個DWORD組成的記錄,標識1601年1月1日到現(xiàn)在100ns時間單位數(shù)量。還有一種常用時間類型稱為

SYSTEMTIME,這種就是用年月日星期時分秒毫秒記的。兩種類型可以用FileTimeToSystemTime();和SystemTimeToFileTime();子程序轉(zhuǎn)換,具體用法參看MSDN吧。第三節(jié)窗口APICreateWindow();正如其名,窗口是Windows操作系統(tǒng)中最重要的東西。有了窗口,我們就可以同時運行并操控多個程序。窗口的產(chǎn)生標識著操作系統(tǒng)從單線程到多線程的轉(zhuǎn)變。要創(chuàng)建窗口,我們必須用RegisterClass();子程序在系統(tǒng)中注冊一個窗口對象。注冊的時候,我們必須提供窗口名、進程句柄、畫筆顏色、光標類型、程序縮略圖以及回調(diào)子程序等信息,這個過程就如同在網(wǎng)站上注冊一個帳號一樣。注冊窗口以后,我們就可以創(chuàng)建窗口了。為了讓系統(tǒng)知道創(chuàng)建的是哪個窗口,我們必須提

溫馨提示

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

評論

0/150

提交評論