程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 什麼是WinAPI

什麼是WinAPI

編輯:關於C++

視窗操作系統應用程序接口(Windows API),有非正式的簡稱法為WinAPI,是微軟對於Windows操作系統中可用的內核應用程序編程接口的稱法。它設計為由C/C++程序調用,而且它也是應用軟件與Windows系統最直接的交互方式。而大多數驅動程序所需要的對Windows系統的更底層次訪問接口,由所用版本的Windows的Native API來提供接口。

Windows有一個軟件開發包(SDK, software development kit)提供相應的文檔和工具,以使程序員開發使用Windows API的軟件和利用Windows技術。

歷史

Windows API總會為程序員提供大量的構建不同Windows的底層結構,這有助於為Windows程序員開發應用程序提供大量的靈活性和功能。但是,它同樣使Windows applications要負責處理大量底層且有時是繁瑣的與圖形用戶界面(GUI)相關的操作。

Charles Petzold, 許多有關Windows API的暢銷書的作者曾經說過:[1]

“ The original hello-world program in the Windows 1.0 SDK was a bit of a scandal. HELLO.C was about 150 lines long, and the HELLO.RC resource script had another 20 or so more lines. (...) Veteran C programmers often curled up in horror or laughter when encountering the Windows hello-world program. ” —Charles Petzold, Programming Microsoft Windows with C#

常用的例子程序Hello world程序,通常是用來演示一個系統上最簡單的程序(即打印一行"Hello World")。

這些年來,Windows操作系統已經今非昔比,而Windows API也隨之改變和成長並反映出這種變化。Windows API的 Windows 1.0 版本只提供不到450個函數調用(Subroutine),而現在的版本提供了上千個。然而,整體而言,Windows接口保持了相當好的一致性,古老的Windows 1.0程序對習慣於現在版本Windows API的程序員也並不陌生。[2]

Microsoft特別強調維持軟件的向後兼容性。為了實現此一目標,有時微軟甚至不惜支持使用了非官方乃至(編程上)非法的API的軟件。Raymond Chen,一位致力於Windows API的Windows開發者,曾提及他:[3]

“ could probably write for months solely about bad things apps do and what we had to do to get them to work again (often in spite of themselves). Which is why I get particularly furious when people accuse Microsoft of maliciously breaking applications during OS upgrades. If any application failed to run on Windows 95, I took it as a personal failure. ” —Raymond Chen, What about BOZOSLIVEHERE and TABTHETEXTOUTFORWIMPS? Windows API分類

Windows API所提供的功能可以歸為七類:[4]

基礎服務(Base Services)[5],提供對Windows系統可用的基礎資源的訪問接口。比如象:文件系統(file system)、外部設備(device)、, 進程(process)、線程(thread)以及訪問注冊表(Windows registry)和錯誤處理機制(error handling)。這些功能接口位於,16位Windows下的kernel.exe、krnl286.exe或krnl386.exe系統文件中;以及32位Windows下的 kernel32.dll和advapi32.dll中。

圖形設備接口(GDI)[6],提供功能為:輸出圖形內容到顯示器、打印機以及其他外部輸出設備。它位於16位Windows下的gdi.exe;以及32位Windows下的gdi32.dll。

圖形化用戶界面(GUI)[7],提供的功能有創建和管理屏幕和大多數基本控件(control),比如按鈕和滾動條。接收鼠標和鍵盤輸入,以及其他與GUI有關的功能。這些調用接口位於:16位Windows下的user.exe, 以及32位Windows下的user32.dll。從Windows XP版本之後, 基本控件和通用對話框控件(Common Control Library)的調用接口放在comctl32.dll中。

通用對話框鏈接庫(Common Dialog Box Library)[8],為應用程序提供標准對話框,比如打開/保存文件對話框、顏色對畫框和字體對話框等等。這個鏈接庫位於:16位Windows下的commdlg.dll中,以及32位Windows下comdlg32.dll中。它被歸類為User Interface API之下。

通用控件鏈接庫(Common Control Library)[9],為應用程序提供接口來訪問操作系統提供的一些高級控件。比如像:狀態欄(status bar)、進度條(progress bars)、工具欄(toolbar)和標簽(tab)。這個鏈接庫位於:16位Windows下的commctrl.dll中,以及32位Windows下comctl32.dll中。. 它被歸類為User Interface API之下。

Windows外殼(Windows Shell)[10][11],作為Windows API的組成部分,不僅允許應用程序訪問操作系統shell提供的功能,還對之有所改進和增強。它位於16位Windows下的shell.dll中,以及32位Windows下的shell32.dll中(Windows 95則在 shlwapi.dll中)。 它被歸類為User Interface API之下。

網絡服務(Network Services)[12],為訪問操作系統提供的多種網絡 功能提供接口。它包括NetBIOS、Winsock、NetDDE及RPC等。

Web相關API

Internet Explorer網頁浏覽器也提供許多程序接口 [13],它將不會在Windows Vista中集成,特別提供以下接口:

可嵌入的網頁浏覽器控件,位於shdocvw.dll和mshtml.dll之中。

urlmon.dll中的命名服務(URL moniters service),利用COM對象為應用程序提供解析URL服務。應用程序也可以為其他程序提供自己的URL處理程序。

一個支持多種語言文本的鏈接庫(mlang.dll)。

DirectX Transforms,一組圖像過濾組件。

XML支持(MSXML組件)。

訪問Windows Address Book。

多媒體相關API

自從Windows 95 OSR2以來,Microsoft把DirectX API 作為Windows安裝的一部分。DirectX提供一組松散相關的多媒體和游戲服務,包括:

Direct3D可以作為OpenGL的替代,來訪問3D加速硬件。

DirectDraw提供硬件加速2D framebuffer(幀緩沖)訪問接口。自DirectX 9以來,相比Direct3D更傾向於後者,因為Direct3D提供更全面的高性能圖形功能(畢竟2D渲染只是3D渲染的子集)。

DirectSound提供底層次的硬件加速聲卡訪問。

DirectInput用來與輸入設備(搖桿和gamepad)進行通信。

DirectPlay提供一個多人游戲的架構(multiplayer gaming infrastructure)。它已經被DirectX 9所替代,Microsoft不建議用它進行游戲開發。

DirectShow可以創建和運行一般的多媒體管道(generic multimedia pipelines)。它可以與GStreamer框架相媲美,並且經常被用來渲染游戲視頻和創建media players(Windows Media Player正是基於此)。DirectShow不被建議進行游戲開發。

DirectMusic

程序通信API

Windows API的功能主要通過使操作系統和應用程序之間的交互來實現。為了實現不同Windows應用程序的通信,微軟隨著主要Windows API,推出一系列的技術。最初的DDE(Dynamic Data Exchange)升級為對象連接與嵌入(Object Linking and Embedding),再後來是組件對象模型(COM)。

封裝庫

微軟利用許多更底層的Windows API函數,開發出許多封裝庫(wrapper),讓應用程序以更抽象的方式與Windows API進行交互。MFC(Microsoft Foundation Class Library)用C++ 類來封裝Windows API的功能,因而允許用更為面向對象的方式與API進行交互。ATL(Active Template Library)是對COM的面向模板(template oriented)的封裝。WTL(Windows Template Library)作為ATL的增強,被用來作為MFC的輕型的替代物。

其他著名的封裝庫是Borland公司的產品,為了與MFC競爭而推出的OWL(Object Windows Library)提供了類似的面向對象封裝。不久Borland又推出VCL(Visual Component Library)來取而代之。

大多數的Windows 程序框架(application framework)是對Windows API的封裝,因而.NET Framework、Java以及其他在Windows下的程序語言,都是(或者包含)封裝庫。

其它實現

盡管微軟的Windows API實現有版權保護,但被普遍認可的是,根據美國的法律先例,其他廠商仍然可以通過提供一致的API來模擬Windows,而不會侵犯版權。

Wine是為Unix類平台提供Win32 API兼容層的嘗試。ReactOS走得更遠,提供了整個Windows操作系統的模擬,與Wine項目緊密結合,以便促進代碼重用和兼容。HX DOS-Extender是另一個模擬Windows API的項目,允許通過DOS命令行來運行簡單的Windows程序。

編譯器支持

為了開發使用 Windows API的軟件,編譯器必須能處理和導入微軟相關的DLLs和COM對象。編譯器必須接受一種C或C++方言,並處理揭示了內部API函數名稱的接口定義語言(Interface description language)文件和頭文件。概括而言,這些預備條件(編譯器、開發工具、庫和頭文件)被統稱為Microsoft Platform SDK。很長時間以來,包含了編譯器和開發工具的專利產品如Microsoft Visual Studio系列和Borland編譯器(盡管至少在Windows下,SDK是可以從整個IDE環境中剝離出來單獨免費下載的,據 Microsoft Platform SDK Update),是僅有的能提供整套開發環境的選擇。如今MinGW和Cygwin也能提供一套這樣的開發環境——是基於采用一種獨立頭文件集合來保證能與微軟DLL連接的GCC。LCC-Win32是由Jacob Navia維護的一種“非商業用途免費”的C編譯器。Pellesc是由Pelle Orinius維護的一種免費C編譯器。MASM32是一個成熟的項目,它通過自制或由SDK平台轉換的頭文件和庫,並利用32位微軟匯編器來實現支持Windows API。

微軟相關的編譯器支持也是異常處理(Structured Exception Handling)特性所需要的。這個體制有雙重目的:它提供了語言相關的異常處理賴以實現的基礎,同時也是內核藉以通知程序發生諸如解除一個非法指針的引用或堆棧溢出之類異常狀況的渠道。甫一被引入Windows 95和NT,微軟/Borland C++編譯器就有使用這種體制的能力,然而實際實現未被公開,而且必須經過反向工程方可用於Wine項目和免費編譯器。SEH的運行機制是先把異常的句柄推入堆棧,繼而將它們添加到存儲於線程本地資源(即線程環境塊的首字段)的一個鏈表裡。事實上,每一個未有程序本身處理的異常,都將由會彈出常規Windows崩潰對話框的默認backstop處理器處理。

API在Visual Basic中的實現示例(這個簡化的例子使得用戶可以讓命令按鈕在窗體上四處移動):

Private Const WM_NCLBUTTONDOWN As Long = &HA1&
Private Const HTCAPTION As Long = 2&
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd&, ByVal wMsg&, wParam As Any, lParam As Any) As Long
If Command1.MousePointer = 14 Then
  Call ReleaseCapture
  Call SendMessage(Command1.hWnd, WM_NCLBUTTONDOWN, ByVal HTCAPTION, ByVal 0&)
End If

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved