在上例中,我們接觸了許多以前沒見過的函數,如MessageBox, TextOut,CreateWindow, PostQuitMessage等等,這些就是所謂的Windows API函數。
Windows操作系統通過兩種接口對外提供服務:普通用戶操作接口服務和程序員接口服務。其中用戶操作接口服務是通過最終用戶的操作來完成的,而程序員接口服務是提供一系列底層的實現操作系統最基本的函數(接口)供程序員調用來完成相關功能的。比如一個文件的拷貝,普通用戶可以通過鼠標菜單選擇操作或者命令來完成,程序員可以通過程序代碼調用文件操作的相關函數(API)來完成相同的功能。
所有這些系統底層、實現最基本功能、供程序員調用的函數集中起來形成一個集合,這就是API(Application Programming Interface)。Windows API編程是開發Windows應用程序最古老、最原始、同時又是檢驗一個程序員對windows操作系統及相關數據結構掌握程度的最好方法。
應該知道:所有其它類庫以及後面要講到的MFC,都是對這些最基本功能的函數進行封裝來實現的。任何使用MFC能實現的功能,使用API同樣能夠實現,而且能夠更加靈活。了解並學習API編程,可以看到使用MFC編程所看不到的東西,更深入了解Windows系統運行機制,同時幫助我們學習MFC編程。
API函數集是由操作系統或開發環境提供的,以DLL的形式出現。其中有三個最主要的動態連接庫:Windows內核庫(Kernel32.dll)、Windows用戶界面管理庫(User32.dll)、Windows圖形設備界面庫(Gdi32.dll),這些動態連接庫共同構成了Win32 API函數。
Windows內核庫(Kernel32.dll):所有底層的核心功能如任務管理、內存管理,進程線程文件管理等的函數都在這個動態連接庫中;
Windows用戶界面管理庫(User32.dll):窗口管理,菜單管理以及通信等相關函數都在該動態連接庫中;
Windows圖形設備界面庫(Gdi32.dll):集合了關於圖形設備的所有函數。
所有這三個動態連接庫中的函數原型說明都在頭文件windows.h中聲明,所以在使用API進行編程序的時候別忘了包括該頭文件。當然了,這只是主要的三個動態連接庫,其他比較常用的還有網絡服務(Winsock32.dll)、多媒體服務(Winmm.dll)等等。
例2、使用Windows API實現一些簡單的系統功能
建立一個控制台空工程,加入文件API.cpp,文件內容如下:
[cpp]
// API.cpp : 定義控制台應用程序的入口點。
#include <iostream>
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
//獲取計算機名稱,CPU數量,CPU類型,已用內存百分比,物理內存總數,空閒物理內存
void GetSysInfo()
{
//1. 定義數據結構存放計算機名稱信息
DWORD MaxComputerlenth = MAX_COMPUTERNAME_LENGTH;
CHAR ComputerName[MAX_COMPUTERNAME_LENGTH];
// 調用API函數GetComputerName獲取計算機名稱存放到ComputerName中。
GetComputerName(ComputerName, &MaxComputerlenth);
cout << "本台計算機的名稱為:" << ComputerName << endl;
//2. 定義數據結構存放計算機系統信息
SYSTEM_INFO siSysInfo;
TCHAR tchBuffer[100];
// 調用API函數GetSystemInfo獲取計算機名稱存放到siSysInfo中
GetSystemInfo(&siSysInfo);
// 輸出相關系統信息
sprintf(tchBuffer,"CPU的數量: %u\tCPU類型: %u",
siSysInfo.dwNumberOfProcessors, siSysInfo.dwProcessorType);
cout << tchBuffer << endl;
//3. 定義數據結構存放內存狀態信息
MEMORYSTATUS stat;
GlobalMemoryStatus(&stat);
// 進行輸出www.2cto.com
printf("%d%% 的內存在使用\n", stat.dwMemoryLoad);
printf("總共有%8ldk的物理內存空間. \n", stat.dwTotalPhys/1024);
printf("總共有%8ldk空閒的物理內存空間. \n", stat.dwAvailPhys/1024);
}
void CopyCppFile()
{
WIN32_FIND_DATA FileData;
HANDLE hSearch;
DWORD dwAttrs;
TCHAR szDirPath[] = TEXT("c:\\CppFiles\\");
TCHAR szNewPath[MAX_PATH];
BOOL fFinished = FALSE;
// Create a new directory.
if (!CreateDirectory(szDirPath, NULL))
{
printf("Could not create new directory.\n");
//return;
}
// Start searching for text files in the current directory.
hSearch = FindFirstFile(TEXT("*.cpp"), &FileData);
if (hSearch == INVALID_HANDLE_VALUE)
{
printf("No *.cpp files found.\n");
return;
}
// Copy each .TXT file to the new directory
// and change it to read only, if not already.
while (!fFinished)
{
if (CopyFile(FileData.cFileName, szNewPath, FALSE))
{
dwAttrs = GetFileAttributes(FileData.cFileName);
//if (dwAttrs==INVALID_FILE_ATTRIBUTES) return;
if (!(dwAttrs & FILE_ATTRIBUTE_READONLY))
{
SetFileAttributes(szNewPath,
dwAttrs | FILE_ATTRIBUTE_READONLY);
}
}
else
{
printf("Could not copy file.\n");
//return;
}
if (!FindNextFile(hSearch, &FileData))
{
if (GetLastError() == ERROR_NO_MORE_FILES)
{
printf("Copied all cpp files.\n");
fFinished = TRUE;
}
else
{
printf("Could not find next file.\n");
return;
}
}
}
// Close the search handle.
FindClose(hSearch);
}
void main()
{
SYSTEMTIME tm;
::GetLocalTime(&tm);
char szBuf[] = "當前時間是:2010年12月31日 23:59:59";
sprintf(szBuf, "當前時間是:%4d年%.2d月%.2d日 %.2d:%.2d:%.2d",
tm.wYear, tm.wMonth, tm.wDay, tm.wHour, tm.wMinute, tm.wSecond);
cout << szBuf <<endl;
tm.wYear--;
BOOL bDone = SetLocalTime(&tm);
tm.wYear++;
bDone = SetLocalTime(&tm);
cout << endl;
CopyCppFile();
cout << endl;
GetSysInfo();
cout << endl;
}
編譯執行,結果會顯示當前的系統時間和相關的系統信息。
由於API接口太多,這裡就不一一舉例說明了。我們就把它們理解為系統已經提供的這麼一些函數,使用的時候在程序中調用就可以。如果參數及函數功能不了解的話,可以查閱MSDN相關資料即可。
作業:
1、使用VC創建典型的“Hello World!”工程,編譯並對程序進行單步跟蹤,進一步理解Win32程序框架,熟悉相關函數。