“進行Windows程式設計,實際上是在進行一種對象導向的程式設計(OOP)。這一點在Windows中使用得最多的對象上表現最為明顯。”
“作為對象,使用者會在螢幕上看到這些視窗,並通過鍵盤和滑鼠直接與它們進行互動操作。更有趣的是,程式寫作者的觀點與使用者的觀點極其類似。視窗以「訊息」的形式接收視窗的輸入,視窗也用訊息與其它視窗通訊。對訊息的理解將是學習如何寫作Windows程式所必須越過的障礙之一。”
“所謂「Windows給程式發送訊息」,是指Windows呼叫程式中的一個函數,該函數的參數描述了這個特定訊息。這種位於Windows程式中的函數稱為「視窗訊息處理常式」。”
“程式建立的每一個視窗都有相關的視窗訊息處理常式。這個視窗訊息處理常式是一個函數,既可以在程式中,也可以在動態連結程式庫中。Windows通過呼叫視窗訊息處理常式來給視窗發送訊息。視窗訊息處理常式根據此訊息進行處理,然後將控制傳回給Windows。”
“視窗訊息處理常式處理給視窗發送訊息。這些訊息經常是告知視窗,使用者正使用鍵盤或者滑鼠進行輸入。這正是按鍵視窗知道它被「按下」的奧妙所在。在視窗大小改變,或者視窗表面需要重畫時,由其它訊息通知視窗。”
“在對象導向的程式設計中,對象是程式與資料的組合。視窗是一種對象,其程式是視窗訊息處理常式。資料是視窗訊息處理常式儲存的資訊和Windows為每個視窗以及系統中那個視窗類別別儲存的資訊。”
“Windows程式開始執行後,Windows為該程式建立一個「訊息佇列」。這個訊息佇列用來存放該程式可能建立的各種不同視窗的訊息。程式中有一小段程式碼,叫做「訊息迴圈」,用來從隊列中取出訊息,並且將它們發送給相應的視窗訊息處理常式。有些訊息直接發送給視窗訊息處理常式,不用放入訊息佇列中。”
/*------------------------------------------------------------------------
HELLOWIN.C -- Displays "Hello, Windows 98!" in client area
(c) Charles Petzold, 1998
-----------------------------------------------------------------------*/
#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HelloWin") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName= szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox ( NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow( szAppName, // window class name
TEXT ("The Hello Program"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT,// initial x position
CW_USEDEFAULT,// initial y position
CW_USEDEFAULT,// initial x size
CW_USEDEFAULT,// initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;
switch (message)
{
case WM_CREATE:
PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rect) ;
DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
“雖然只有80行程式碼,這個視窗卻令人驚訝地具有許多功能。您可以用滑鼠按住標題列,在螢幕上移動視窗;可以按住大小邊框,改變視窗的大小。在視窗大小改變時,程式自動地將「Hello, Windows 98!」字串重新置放在顯示地區的中央。您可以按最大化按鈕,放大HELLOWIN以充滿整個螢幕;也可以按最小化按鈕,將程式縮小成一個圖示。您可以在系統功能表中執行所有選項(就是按下在標題列最左端的小圖示);也可以從系統功能表中選擇 Close選項,或者單擊標題列最右端的關閉按鈕,或者雙擊標題列最左端的表徵圖,來關閉視窗以終止程式的執行。”
“不要費力氣去記憶Windows程式設計中的數值常數。實際上,Windows中使用的每個數值常數在表標頭檔中均有相應的標識符定義。”
“HELLOWIN.C也有一個WinMain函數,但它還有另外一個函數,名為WndProc。這就是視窗訊息處理常式。注意,在HELLOWIN.C中沒有呼叫WndProc的程式碼。當然,在WinMain中有對WndProc的參考,而這就是該函數要在程式開頭附近聲明的原因”
Windows表標頭檔中定義的四種資料結構
結構 |
含義 |
MSG |
訊息結構 |
WNDCLASS |
視窗類別別結構 |
PAINTSTRUCT |
繪圖結構 |
RECT |
矩形結構 |
還有三個大寫標識符,用於不同型態的「控制代碼」:
標識符 |
含義 |
HINSTANCE |
執行實體(程式自身)控制代碼 |
HWND |
視窗控制代碼 |
HDC |
裝置內容控制代碼 |
控制代碼在Windows中使用非常頻繁。還有HICON(表徵圖控制代碼)、HCURSOR(滑鼠游標控制代碼)和HBRUSH(畫刷控制代碼)。
“控制代碼是一個(通常為32位的)整數,它代表一個對象。Windows中的控制代碼類似傳統C或者MS-DOS程式設計中使用的檔案控制代碼。程式幾乎總是通過呼叫Windows函數取得控制代碼。程式在其它Windows函數中使用這個控制代碼,以使用它代表的對象。代號的實際值對程式來說是無關緊要的。但是,向您的程式提供代號的Windows模組知道如何利用它來使用相對應的對象。”
經常用到的變數首碼
首碼 |
資料型態 |
c |
char或WCHAR或TCHAR |
by |
BYTE (無加號或減號字元) |
n |
short |
i |
int |
x, y |
int分別用作x座標和y座標 |
cx, cy |
int分別用作x長度和y長度;C代表「計數器」 |
b或f |
BOOL (int);f代表「旗標」 |
w |
WORD (無加號或減號短整數) |
l |
LONG (長整數) |
dw |
DWORD (無加號或減號長整數) |
fn |
function(函數) |
s |
string(字串) |
sz |
以位元組值0結尾的字串 |
h |
控制代碼 |
p |
指標 |