Windows API

Windows應用程式介面，或俗稱的WinAPI，是微軟Windows作業系統中的一套核心應用程式介面。Windows API這一叫法實際上是多個Windows平臺上相似介面的統稱，這些介面也擁有各自的名字，如Win32 API。幾乎所有的Windows應用程式都在與 Windows API 進行互動。Windows API將與Windows系統有關的複雜操作封裝在簡單的函式當中，編譯成動態連結庫，再隨Windows一同釋出。開發者可以簡單地藉助這些函式來完成複雜的操作，有效降低了編寫Windows程式的難度。Windows有一個軟體開發套件提供相應的文件和工具，以使程式設計師開發使用Windows API的軟體和利用Windows技術。C是Windows API使這種面向物件的結構更加清晰。例如，Windows 8提供的Windows API和WinRT API就是用C++實現的，並且在設計上也是面向物件的。概述.Windows API所提供的功能可以歸為八類：基礎服務.提供了對Windows系統可用的基礎資源的訪問介面，包括檔案系統等。這些功能介面在16位Windows中位於kernel.exe、krnl286.exe或krnl386.exe中；在32位和64位Windows下位於kernel32.dll和KernelBase.dll中。這些檔案在所有Windows的 目錄中都可以被找到。高階服務.提供了對核心以外功能的訪問，包括登錄檔、使用者賬戶（user accounts)等。這些函式位於32位Windows上的中。圖形裝置介面.提供了將圖形內容輸出到顯示器、印表機和其他外部輸出裝置的功能。它位於16位Windows下的gdi.exe，以及32位Windows下的gdi32.dll中。圖形化使用者介面.提供了建立和管理視窗和大多數基本控制元件的呼叫介面放在comctl32.dll中。通用對話方塊連結庫.為應用程式提供標準對話方塊。這個連結庫位於：16位Windows下的commdlg.dll中，以及32位Windows下的comdlg32.dll中。它被歸類為User Interface API之下。通用控制元件連結庫.為應用程式提供介面來訪問作業系統提供的一些高階控制元件。比如像：狀態列相應的視窗類。InitCommonControlsEx實際註冊指定的通用控制元件的視窗類。注意ICC_WIN95_CLASSES代表12個控制元件類的集合。InitCommonControls是個空函式，但會使應用程式載入comctl32.dll；在comctl32.dll載入到程序時會在DLL的入口點呼叫InitCommonControlsEx註冊ICC_WIN95_CLASSES控制元件類。Windows Shell.作為Windows API的組成部分，不僅允許應用程式訪問Windows Shell提供的功能，還對之有所改進和增強。它位於16位Windows下的shell.dll中，以及32位Windows下的shell32.dll中。它被歸類為User Interface API之下。網路服務.為訪問作業系統提供的多種網路功能提供介面。它包括NetBIOS、Winsock、NetDDE及遠端過程呼叫等。Web相關API.Internet Explorer網頁瀏覽器還公開了許多經常被應用程式呼叫的API，因此通常其也被視為是Windows API的一部分。IE從Windows 95 OSR2起就包含在了Windows系統中，並從Windows 98起開始為應用程式提供Web相關服務。具體來說，它提供：和Windows的郵件功能相關的API，例如地址本和郵件API，在Windows 7取消郵件功能之後也隨之從Windows API中去除。由於Windows Mail在Windows Vista上取代了Outlook Express，對應的API也隨之變化。多媒體相關API.經典的Windows多媒體API位於winmm.dll中，包含了播放音訊、MIDI通訊、遊戲手柄及其他促進多媒體體驗的功能。該API源自Windows 3.x。自從Windows 95 OSR2以來，Microsoft把DirectX API作為Windows安裝的一部分。DirectX提供一組鬆散相關的多媒體和遊戲服務，包括：Microsoft還提供了多個用於媒體編碼和播放的API：程式通訊API.Windows API最重要功能即為此：處理作業系統和應用程式之間的互動。對於不同的Windows應用程式之間的通訊，Microsoft發展了一系列的技術並開發了最主要的Windows API。這些技術從動態資料交換、自動化物件、ActiveX控制元件和.NET框架取代。不過，這些技術之間區別並不總是十分明顯，並且有很多重疊之處。這些技術的多樣性基本上是對軟體開發的不同方面進行細分的結果。自動化特別涉及了匯出應用程式和元件的功能為API，以便使其可以由其他應用程式而不是人類來進行控制。.NET是一種自包含的通用方法和技術，用於開發各種使用即時編譯語言編寫的桌面和Web應用程式。Windows.pas是一個Pascal/Delphi單元，其中包含了Windows特定的API宣告。它在Pascal中的作用就像C中的windows.h一樣。封裝庫.微軟利用許多更底層的Windows API函式，開發出許多封裝庫作為ATL的增強，被用來作為MFC的輕型的替代物。其他著名的封裝庫是Borland公司的產品，為了與MFC競爭而推出的OWL來取而代之。大多數的Windows 程式框架封裝庫。歷史.Windows API總會為程式設計師提供大量的構建不同 Windows的底層結構，這有助於為 Windows 程式設計師開發應用程式提供大量的靈活性和功能。但是，它同樣使Windows應用程式要負責處理大量底層且有時是繁瑣的與圖形使用者介面相關的操作。例如，初學C的程式設計師通常會把編寫簡單的“Hello world”作為他們的第一項任務。程式的工作部分僅僅是主程式中的一個printf行，在連結到標準I/O庫時也僅需要一個include行：int main(void) {printf("Hello, World!\n");Windows版本的工作部分仍然只有一行程式碼，但除此之外它需要很多很多行的額外開銷。許多有關Windows API的暢銷書的作者查爾斯·佩佐德曾經說過：這些年來，Windows作業系統已經今非昔比，而Windows API也隨之改變和成長並反映出這種變化。Windows API的Windows 1.0版本只提供不到450個函式呼叫，而現在的版本提供上千個。然而，整體而言，Windows介面保持了相當好的一致性，習慣於現在版本Windows API的程式設計師對古老的Windows 1.0程式也並不會陌生。微軟特別強調維持軟體的向後相容性。為了實現此一目標，有時微軟甚至不惜支援使用了非官方乃至曾提及：對Windows API來說，其歷史上最大的變化之一就是從Win16，反之亦然。同樣的，64位的Windows也可以透過WoW64執行32位的應用程式，而位於Windows目錄下的SysWOW64資料夾中包含了多個用於支援32位應用程式的工具。版本.幾乎每個版本的Windows都引入了其對Windows API的新增和修改，但是API的名稱在不同版本的Windows間保持了一致，並且僅當Windows主要的架構和平臺都更改時API的名稱才會改變。Microsoft最終將當時名叫Win32的API家族改名為Windows API，並使其成為過去和未來API版本的統稱。其它實現.儘管微軟的Windows API實現有版權保護，但被普遍認可的是，根據美國的法律先例，其他廠商仍然可以透過提供一致的API來模擬Windows，而不會侵犯版權。Wine專案為類Unix平臺提供了一個在Linux核心API與Windows API程式之間的Win32 API相容層。ReactOS則更進一步，想要實現一個完整的Windows作業系統；它透過與Wine專案的密切合作來促進其程式碼的重用和相容。DosWin32和HX DOS-Extender是另外兩個模擬Windows API的專案，它們允許透過DOS命令列來執行簡單的Windows程式。Odin是一個在OS/2平臺上模擬Win32的專案。編譯器支援.為了開發使用Windows API的軟體，編譯器必須能處理和匯入微軟相關的DLLs或者COM物件。編譯器必須接受一種C或C++方言，或者能夠處理揭示了內部API函式名稱的介面定義語言，是僅有的能提供整套開發環境的選擇。如今MinGW和Cygwin也能提供一套這樣的開發環境——是基於採用一種獨立標頭檔案集合來保證能與微軟DLL連線的GCC。LCC-Win32是由Jacob Navia維護的一種“非商業用途免費”的C編譯器。Pellesc是由Pelle Orinius維護的一種免費C編譯器。MASM32是一個成熟的專案，它透過自制或由SDK平臺轉換的標頭檔案和庫，並利用32位微軟彙編器來實現支援Windows API。微軟相關的編譯器支援也是異常處理的一個連結串列裡。事實上，每一個未有程式本身處理的異常，都將由會彈出常規Windows崩潰對話方塊的預設backstop處理器處理。API在Visual Basic中的實現示例：Private Const WM_NCLBUTTONDOWN As Long = &amp;HA1&amp;Private Const HTCAPTION As Long = 2&amp;Private Declare Function ReleaseCapture Lib "user32" () As LongPrivate Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd&amp;, ByVal wMsg&amp;, wParam As Any, lParam As Any) As LongIf Command1.MousePointer = 14 ThenCall ReleaseCaptureCall SendMessage(Command1.hWnd, WM_NCLBUTTONDOWN, ByVal HTCAPTION, ByVal 0&amp;)End If