From: http://www.pconline.com.cn
程
序作者:管寧 個(gè)人網(wǎng)站:www.cndev-lab.com
作者保留作品的所有權(quán)利,如需轉(zhuǎn)
載,請務(wù)必注明出處和作者。
被過濾廣告 VC作為一個(gè)主流的開發(fā)平臺一直深受編程愛好者的喜愛,但是很多人卻對它的入門感到難于上青天,究其原因主要是大家
對他錯(cuò)誤的認(rèn)識造成的,嚴(yán)格的來說VC++不是門語言,雖然它和C++之間有密切的關(guān)系,如果形象點(diǎn)比喻的話,可以C++看作為一種”工業(yè)標(biāo)準(zhǔn)”,而
VC++則是某種操作系統(tǒng)平臺下的”廠商標(biāo)準(zhǔn)”,而”廠商標(biāo)準(zhǔn)”是在遵循”工業(yè)標(biāo)準(zhǔn)”的前提下擴(kuò)展而來的。
VC++應(yīng)用程序的開發(fā)主要有兩種模式,一種是WIN API方式,另一種則是MFC方式,傳統(tǒng)的WIN
API開發(fā)方式比較繁瑣,而MFC則是對WIN API再次封裝,所以MFC相對于WIN
API開發(fā)更具備效率優(yōu)勢,但為了對WINDOWS開發(fā)有一個(gè)較為全面細(xì)致的認(rèn)識,筆者在這里還是以講解WIN API的相關(guān)內(nèi)容為主線。
話說到這里可能更多人關(guān)心的是學(xué)習(xí)VC++需要具備什么條件,為什么對于這扇門屢攻不破呢?
要想學(xué)習(xí)好VC必須具備良好的C/C++的基礎(chǔ),必要的英語閱讀能力也是必不可少的,因?yàn)榇罅康募夹g(shù)文檔多以英文形式發(fā)布。
許多初學(xué)VC++的人對于它怪異的寫法和程序奇特的工作方式非常不理解,為了幫助大家對它的入門有一個(gè)比較概括的了解,我們把
這一小節(jié)內(nèi)容分成若干部分講解。
第一部分: VC++中的對象的命名規(guī)則、常用宏定義的命名,以及VC++下的數(shù)據(jù)類型。
注:這部分簡單瀏覽即可。
第二部分:VC++常用技術(shù)術(shù)語的解釋。
第三部分:HelloWin程序的詳細(xì)分析。
第一部分
匈牙利命名法規(guī)則
一般情況下,變量的取名方式為:
<scope_> + <prefix_> + <qualifier>。
范圍前綴_,類型前綴_,限定詞。
特殊的類型命名,前綴表示:
類、接口
前綴
|
類型
|
例子
|
備注
|
Lm
|
Class
|
LmObject
|
表示類型本身 不與范圍前綴結(jié)合使用
|
I
|
Interface 接口
|
IUnknown
|
注:類名前綴改為Lm,對于非全局的類最好有語義表示其所屬模塊。類的實(shí)例命名與類名大致相同,只是類名語義表示類的通用含義,而類名表示此實(shí)
例的具體語義。如類名LmSketPoint表示草圖點(diǎn)的類定義,而它的兩個(gè)實(shí)例
_StartPoint,_EndPoint分別代表起點(diǎn)和終點(diǎn)的語義。類的實(shí)例命名帶上前綴_。
特殊約定:
a. MouseTool的派生類的前綴為_Mt.
b. 對話框類的前綴為CDlg.
c.
橡皮條類的前綴為_Rb.
凡圍前綴:
前綴
|
類型
|
例子
|
備注
|
g_
|
全局作用域
|
g_Servers
|
|
m_
|
成員變量
|
m_pDoc,
|
l_
|
局部作用域
|
l_strName
|
少用
|
注: 編程時(shí)盡量少用全程變量,對于全程變量還應(yīng)在類型前綴后加上如下關(guān)鍵字:
特征模塊 : Fea
草圖模塊 : Sket
裝配模塊 :
Asm
工程圖模塊: Lay
曲面模塊 : Surf
界面模塊 : Ui
常用的一般數(shù)據(jù)類型的前綴
前綴
|
類型
|
內(nèi)存規(guī)格描述
|
例子
|
ch
|
char
|
8-bit character
|
chGrade
|
ch
|
TCHAR
|
16-bit character if _UNICODE is defined
|
chName
|
b
|
BOOL
|
Boolean value
|
bEnabled
|
n
|
int
|
Integer (size dependent on operating system)
|
nLength
|
n
|
UINT
|
Unsigned value (size dependent on operating system)
|
nLength
|
w
|
WORD
|
16-bit unsigned value
|
wPos
|
l
|
LONG
|
32-bit signed integer
|
lOffset
|
dw
|
DWORD
|
32-bit unsigned integer
|
dwRange
|
p
|
*
|
Ambient memory model pointer
|
pDoc
|
lp
|
FAR*
|
Far pointer
|
lpDoc
|
lpsz
|
LPSTR
|
32-bit pointer to character string
|
lpszName
|
lpsz
|
LPCSTR
|
32-bit pointer to constant character string
|
lpszName
|
lpsz
|
LPCTSTR
|
32-bit pointer to constant character string if
_UNICODE is defined
|
lpszName
|
h
|
handle
|
Handle to Windows object
|
hWnd
|
lpfn
|
(*fn)()
|
callbackFar pointer to
CALLBACK function
|
lpfnAbort
|
常用Windows對象名稱縮寫
Windows 對象
|
例子變量
|
MFC 類
|
例子對象
|
HWND
|
hWnd;
|
CWnd*
|
pWnd;
|
HDLG
|
hDlg;
|
CDialog*
|
pDlg;
|
HDC
|
hDC;
|
CDC*
|
pDC;
|
HGDIOBJ
|
hGdiObj;
|
CGdiObject*
|
pGdiObj;
|
HPEN
|
hPen;
|
CPen*
|
pPen;
|
HBRUSH
|
hBrush;
|
CBrush*
|
pBrush;
|
HFONT
|
hFont;
|
CFont*
|
pFont;
|
HBITMAP
|
hBitmap;
|
CBitmap*
|
pBitmap;
|
HPALETTE
|
hPalette;
|
CPalette*
|
pPalette;
|
HRGN
|
hRgn;
|
CRgn*
|
pRgn;
|
HMENU
|
hMenu;
|
CMenu*
|
pMenu;
|
HWND
|
hCtl;
|
CStatic*
|
pStatic;
|
HWND
|
hCtl;
|
CButton*
|
pBtn;
|
HWND
|
hCtl;
|
CEdit*
|
pEdit;
|
HWND
|
hCtl;
|
CListBox*
|
pListBox;
|
HWND
|
hCtl;
|
CComboBox*
|
pComboBox;
|
Visual C++常用宏定義命名列表
前綴
|
符號類型
|
符號例子
|
范圍
|
IDR_
|
標(biāo)識多個(gè)資源共享的類型
|
IDR_MAINFRAME
|
1 to 0x6FFF
|
IDD_
|
對話框資源(Dialog)
|
IDD_SPELL_CHECK
|
1 to 0x6FFF
|
IDB_
|
位圖資源(Bitmap)
|
IDB_COMPANY_LOGO
|
1 to 0x6FFF
|
IDC_
|
光標(biāo)資源(Cursor)
|
IDC_PENCIL
|
1 to 0x6FFF
|
IDI_
|
圖標(biāo)資源(Icon)
|
IDI_NOTEPAD
|
1 to 0x6FFF
|
ID_IDM_
|
工具欄或菜單欄的命令項(xiàng)
|
ID_TOOLS_SPELLING
|
0x8000 to 0xDFFF
|
HID_
|
命令上下文幫助(Command Help context)
|
HID_TOOLS_SPELLING
|
0x18000 to 0x1DFFF
|
IDP_
|
消息框提示文字資源
|
IDP_INVALID_PARTNO
|
8 to 0xDFFF
|
HIDP_
|
消息框上下文幫助(Message-box Help context)
|
HIDP_INVALID_PARTNO
|
0x30008 to 0x3DFFF
|
IDS_
|
字符串資源(String)
|
IDS_COPYRIGHT
|
1 to 0x7FFF
|
IDC_
|
對話框內(nèi)的控制資源(Control)
|
IDC_RECALC
|
8 to 0xDFFF
|
VISUAL C++ 下的數(shù)據(jù)類型
類型
|
含義
|
ATOM
|
Atom. For more information, see Atoms.
|
BOOL
|
Boolean variable (should be TRUE or
FALSE).
|
BOOLEAN
|
Boolean variable (should be TRUE or
FALSE).
|
BYTE
|
Byte (8 bits).
|
CALLBACK
|
Calling convention for callback
functions.
|
CHAR
|
8-bit Windows (ANSI) character. For
more information, see Character Sets Used By Fonts.
|
COLORREF
|
Red, green, blue (RGB) color value (32
bits). See COLORREF for information on this type.
|
CONST
|
Variable whose value is to remain
constant during execution.
|
DWORD
|
32-bit unsigned integer.
|
DWORD_PTR
|
Unsigned long type for pointer
precision. Use when casting a pointer to a long type to perform pointer
arithmetic. (Also commonly used for general 32-bit parameters that have
been extended to 64 bits in 64-bit Windows. )
|
DWORD32
|
32-bit unsigned integer.
|
DWORD64
|
64-bit unsigned integer.
|
FLOAT
|
Floating-point variable.
|
HACCEL
|
Handle to an accelerator table.
|
HANDLE
|
Handle to an object.
|
HBITMAP
|
Handle to a bitmap.
|
HBRUSH
|
Handle to a brush.
|
HCONV
|
Handle to a dynamic data exchange
(DDE) conversation.
|
HCONVLIST
|
Handle to a DDE conversation list.
|
HCURSOR
|
Handle to a cursor.
|
HDC
|
Handle to a device context (DC).
|
HDDEDATA
|
Handle to DDE data.
|
HDESK
|
Handle to a desktop.
|
HDROP
|
Handle to an internal drop structure.
|
HDWP
|
Handle to a deferred window position
structure.
|
HENHMETAFILE
|
Handle to an enhanced metafile.
|
HFILE
|
Handle to a file opened by OpenFile ,
not CreateFile .
|
HFONT
|
Handle to a font.
|
HGDIOBJ
|
Handle to a GDI object.
|
HGLOBAL
|
Handle to a global memory block.
|
HHOOK
|
Handle to a hook.
|
HICON
|
Handle to an icon.
|
HIMAGELIST
|
Handle to an image list.
|
HIMC
|
Handle to input context.
|
HINSTANCE
|
Handle to an instance.
|
HKEY
|
Handle to a registry key.
|
HKL
|
Input locale identifier.
|
HLOCAL
|
Handle to a local memory block.
|
HMENU
|
Handle to a menu.
|
HMETAFILE
|
Handle to a metafile.
|
HMODULE
|
Handle to a module. The value is the
base address of the module.
|
HMONITOR
|
Handle to a display monitor.
|
HPALETTE
|
Handle to a palette.
|
HPEN
|
Handle to a pen.
|
HRGN
|
Handle to a region.
|
HRSRC
|
Handle to a resource.
|
HSZ
|
Handle to a DDE string.
|
HWINSTA
|
Handle to a window station.
|
HWND
|
Handle to a window.
|
INT
|
32-bit signed integer.
|
INT_PTR
|
Signed integral type for pointer
precision. Use when casting a pointer to an integer to perform pointer
arithmetic.
|
INT32
|
32-bit signed integer.
|
INT64
|
64-bit signed integer.
|
LANGID
|
Language identifier. For more
information, see Locales.
|
LCID
|
Locale identifier. For more
information, see Locales.
|
LCTYPE
|
Locale information type. For a list,
see Locale and Language Information.
|
LONG
|
32-bit signed integer.
|
LONG_PTR
|
Signed long type for pointer
precision. Use when casting a pointer to a long to perform pointer
arithmetic.
|
LONG32
|
32-bit signed integer.
|
LONG64
|
64-bit signed integer.
|
LONGLONG
|
64-bit signed integer.
|
LPARAM
|
Message parameter.
|
LPBOOL
|
Pointer to a BOOL .
|
LPBYTE
|
Pointer to a BYTE .
|
LPCOLORREF
|
Pointer to a COLORREF
value.
|
LPCRITICAL_SECTION
|
Pointer to a CRITICAL_SECTION .
|
LPCSTR
|
Pointer to a constant null-terminated
string of 8-bit Windows (ANSI) characters. For more information, see
Character Sets Used By Fonts.
|
LPCTSTR
|
An LPCWSTR if UNICODE
is defined, an LPCTSTR otherwise.
|
LPCVOID
|
Pointer to a constant of any type.
|
LPCWSTR
|
Pointer to a constant null-terminated
string of 16-bit Unicode characters. For more information, see Character
Sets Used By Fonts.
|
LPDWORD
|
Pointer to a DWORD .
|
LPHANDLE
|
Pointer to a HANDLE .
|
LPINT
|
Pointer to an INT .
|
LPLONG
|
Pointer to a LONG .
|
LPSTR
|
Pointer to a null-terminated string of
8-bit Windows (ANSI) characters. For more information, see Character
Sets Used By Fonts.
|
LPTSTR
|
An LPWSTR if UNICODE
is defined, an LPSTR otherwise.
|
LPVOID
|
Pointer to any type.
|
LPWORD
|
Pointer to a WORD .
|
LPWSTR
|
Pointer to a null-terminated string of
16-bit Unicode characters. For more information, see Character Sets
Used By Fonts.
|
LRESULT
|
Signed result of message processing.
|
LUID
|
Locally unique identifier.
|
PBOOL
|
Pointer to a BOOL .
|
PBOOLEAN
|
Pointer to a BOOL .
|
PBYTE
|
Pointer to a BYTE .
|
PCHAR
|
Pointer to a CHAR .
|
PCRITICAL_SECTION
|
Pointer to a CRITICAL_SECTION .
|
PCSTR
|
Pointer to a constant null-terminated
string of 8-bit Windows (ANSI) characters. For more information, see
Character Sets Used By Fonts.
|
PCTSTR
|
A PCWSTR if UNICODE
is defined, a PCSTR otherwise.
|
PCWCH
|
Pointer to a constant WCHAR .
|
PCWSTR
|
Pointer to a constant null-terminated
string of 16-bit Unicode characters. For more information, see Character
Sets Used By Fonts.
|
PDWORD
|
Pointer to a DWORD .
|
PFLOAT
|
Pointer to a FLOAT .
|
PHANDLE
|
Pointer to a HANDLE .
|
PHKEY
|
Pointer to an HKEY .
|
PINT
|
Pointer to an INT .
|
PLCID
|
Pointer to an LCID .
|
PLONG
|
Pointer to a LONG .
|
PLUID
|
Pointer to a LUID .
|
POINTER_32
|
32-bit pointer. On a 32-bit system,
this is a native pointer. On a 64-bit system, this is a truncated 64-bit
pointer.
|
POINTER_64
|
64-bit pointer. On a 64-bit system,
this is a native pointer. On a 32-bit system, this is a sign-extended
32-bit pointer.
|
PSHORT
|
Pointer to a SHORT .
|
PSTR
|
Pointer to a null-terminated string of
8-bit Windows (ANSI) characters. For more information, see Character
Sets Used By Fonts.
|
PTBYTE
|
Pointer to a TBYTE .
|
PTCHAR
|
Pointer to a TCHAR .
|
PTSTR
|
PWSTR if
UNICODE is defined, a PSTR otherwise.
|
PTBYTE
|
Pointer to a TBYTE .
|
PTCHAR
|
Pointer to a TCHAR .
|
PTSTR
|
A PWSTR if UNICODE is
defined, a PSTR otherwise.
|
PUCHAR
|
Pointer to a UCHAR .
|
PUINT
|
Pointer to a UINT .
|
PULONG
|
Pointer to a ULONG .
|
PUSHORT
|
Pointer to a USHORT .
|
PVOID
|
Pointer to any type.
|
PWCHAR
|
Pointer to a WCHAR .
|
PWORD
|
Pointer to a WORD .
|
PWSTR
|
Pointer to a null-terminated string of
16-bit Unicode characters. For more information, see Character Sets
Used By Fonts.
|
REGSAM
|
Security access mask for registry key.
|
SC_HANDLE
|
Handle to a service control manager
database. For more information, see SCM Handles.
|
SC_LOCK
|
Handle to a service control manager
database lock. For more information, see SCM Handles.
|
SERVICE_STATUS_HANDLE
|
Handle to a service status value. For
more information, see SCM Handles.
|
SHORT
|
Short integer (16 bits).
|
SIZE_T
|
The maximum number of bytes to which a
pointer can point. Use for a count that must span the full range of a
pointer.
|
SSIZE_ T
|
Signed SIZE_T .
|
TBYTE
|
A WCHAR if UNICODE is
defined, a CHAR otherwise.
|
TCHAR
|
A WCHAR if UNICODE is
defined, a CHAR otherwise.
|
UCHAR
|
Unsigned CHAR .
|
UINT
|
Unsigned INT .
|
UINT_PTR
|
Unsigned INT_PTR .
|
UINT32
|
Unsigned INT32 .
|
UINT64
|
Unsigned INT64 .
|
ULONG
|
Unsigned LONG .
|
ULONG_PTR
|
Unsigned LONG_PTR .
|
ULONG32
|
Unsigned LONG32 .
|
ULONG64
|
Unsigned LONG64 .
|
ULONGLONG
|
64-bit unsigned integer.
|
UNSIGNED
|
Unsigned attribute.
|
USHORT
|
Unsigned SHORT .
|
VOID
|
Any type.
|
WCHAR
|
16-bit Unicode character. For more
information, see Character Sets Used By Fonts.
|
WINAPI
|
Calling convention for system
functions.
|
WORD
|
16-bit unsigned integer.
|
WPARAM
|
Message parameter.
|
第
二部分
WINDOWS應(yīng)用程序設(shè)計(jì)用到的基本術(shù)語:
1.窗口
任何一個(gè)使用過Windows的人對窗口這個(gè)概念絕對不會陌生,窗口是windows應(yīng)用程序的基本操作單元,用戶通過它與應(yīng)用程序發(fā)生交互,
例如輸入輸出操作等等,從程序的內(nèi)部工作原來來看,每一個(gè)窗口對應(yīng)一個(gè)消息處理隊(duì)列,應(yīng)用程序主要通過窗口消息處理函數(shù)對用戶的輸入操作進(jìn)行響應(yīng)與處理。
要想從程序員的角度充分理解窗口的含義,那么對WNDCLASS這個(gè)數(shù)據(jù)結(jié)構(gòu)進(jìn)行充分的了解是必須的。
2.實(shí)例
單個(gè)實(shí)例代表一個(gè)可執(zhí)行程序在內(nèi)存中的拷貝,如果一個(gè)應(yīng)用程序執(zhí)行許多次,那么在內(nèi)存中就有多少個(gè)拷貝,也就可以說明有多少個(gè)實(shí)例存在。
3.句柄
句柄在windows環(huán)境下被定義成了一個(gè)無符號的整數(shù),用于標(biāo)識應(yīng)用程序中不同的對象和同類對象中的不同實(shí)例。句柄可以看成是對象的編號,聯(lián)
系上面的實(shí)例,那么一個(gè)實(shí)例句柄就可以看作是單個(gè)應(yīng)用程序在內(nèi)存中拷貝的唯一身份編號,通常系統(tǒng)只能通過實(shí)例句柄去識別不同的應(yīng)用程序,或者是相同應(yīng)用程
序的不同副本。
4.資源
Windows應(yīng)用程序包含很多資源,例如,菜單,圖標(biāo),對話框等等,VC++環(huán)境下我們不僅僅可以使用系統(tǒng)下原有的資源,我們也可以定義自己
的資源,這些資源被定義在.RC文件中,通過應(yīng)用程序最后的編譯,這些資源文件和程序代碼連接在一起,形成一個(gè)可執(zhí)行的.EXE文件或者是一個(gè).DLL的
庫文件。在使用這些資源的時(shí)候,通過WIN API函數(shù)學(xué)將這些資源調(diào)用使用。
5.窗口消息處理函數(shù)
窗口是人機(jī)交互的接口,當(dāng)窗口接受到輸入請求的時(shí)候,就會把這一請求交給某一個(gè)函數(shù)進(jìn)行處理,而這個(gè)函數(shù)就是窗口消息處理函數(shù),它能夠決定當(dāng)一
個(gè)消息被接受到的時(shí)候采取什么行動。
消息通常是由一系列的輸入操作觸發(fā)的,比如當(dāng)我按下鼠標(biāo)左鍵那么窗口消息處理函數(shù)就會收到一個(gè)WM_LBUTTONDOWN的消息信號。在窗口
消息處理函數(shù)中,我們可以利用switch和case結(jié)構(gòu)進(jìn)行控制, 針對此消息作出我們想要的操作。
6.圖形設(shè)備接口
應(yīng)用程序的任何輸出操作都需要通過圖形設(shè)備接口(GDI)中的函數(shù)來完成操作,GDI負(fù)責(zé)系統(tǒng)與用戶或繪圖程序之間的信息交換,并控制在輸出設(shè)
備上顯示圖形或者文字,它將程序員與具體的硬件設(shè)備隔離開,讓程序員不需要考慮硬件設(shè)備操作的細(xì)節(jié)。
7.回調(diào)函數(shù)
回調(diào)函數(shù)是windows操作系統(tǒng)自己調(diào)用的函數(shù),用戶是不能直接調(diào)用他們的。回調(diào)函數(shù)的定義必須嚴(yán)格的按照windows標(biāo)準(zhǔn)進(jìn)行編寫。
在下面我們將要看到的HelloWin程序中,WndProc就是一個(gè)回調(diào)函數(shù),它是是應(yīng)用程序的窗口消息處理函數(shù),當(dāng)注冊窗口類的時(shí)候,要把
窗口消息處理函數(shù)的地址告訴Windows,Windows通過調(diào)用此函數(shù)進(jìn)行消息處理。
第三部
分
Windows應(yīng)用程序的基本運(yùn)行機(jī)制與HelloWin程序詳細(xì)解
總的來說最基本的Windows應(yīng)用程序的運(yùn)行執(zhí)行順序總是以如下的基本順序執(zhí)行的。
順序結(jié)構(gòu):
調(diào)用WinMain函數(shù)開始執(zhí)行--à定義窗口類--à初始化窗口類---à窗口的實(shí)例化--à通過消息循環(huán)獲取消息并將消
息發(fā)送給消息處理函數(shù)做出相應(yīng)的操作
由于windows應(yīng)用程序運(yùn)行的邏輯結(jié)構(gòu)特殊所以代碼的詳細(xì)解釋筆者就不把程序于敘述分開了了,這樣有利于閱讀與分析。

程序運(yùn)行預(yù)覽圖
下載該程序:點(diǎn)
擊這里下載(82K, winzip壓縮文件)
分析代碼如下:
//程序作者:管寧
//站點(diǎn):www.cndev-lab.com
//所有稿件均有版權(quán),如要轉(zhuǎn)載,請務(wù)必注明出處和作者

#include <windows.h>
#pragma comment(lib,"winmm.lib")//為了要播放聲音,必須導(dǎo)入這個(gè)庫

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)

/**//*
HINSTANCE 類型的含義為實(shí)例句柄。
hInstance 事實(shí)上就是當(dāng)前應(yīng)用程序自身的標(biāo)識代號,代號通常都是一個(gè)32位整數(shù)。
hPrevInstance 與過去的16位應(yīng)用程序有關(guān)系,表示指向前一個(gè)實(shí)例的句柄。

PSTR 類型的含義是指向以\0結(jié)尾的字符串指針。
szCmdLine 前面的sz同樣是表示指向以\0結(jié)尾的字符串指針,這個(gè)對象用于保存命令行。

最后iCmdShow是一個(gè)整型數(shù)據(jù),標(biāo)記了程序最初的顯示狀態(tài)。
為SW_SHOWNORAML的時(shí)候?yàn)橐话愦笮★@示方式。
為SW_SHOWMAXIMIZED的時(shí)候?yàn)樽畲蠡@示方式。
為SW_SHOWMINNOACTIVE的時(shí)候程序?qū)@示在任務(wù)欄上。
*/


{

static char szAppName[] = TEXT("HelloWin");//預(yù)先定義一個(gè)c風(fēng)格字符串,稍后用于設(shè)置窗口類名稱。
WNDCLASS wndclass;//定義窗口類對象

/**//*
在這里不得不說一下的是,窗口類事實(shí)上是struct結(jié)構(gòu)體,內(nèi)部有10個(gè)分量,他們是用來于初始化窗口類對象而用
的。
這個(gè)結(jié)構(gòu)體在winuser.h頭文件中定義,從方式上來說,分為ASCII版的WNDCLASSA和
Unicode版的WNDCLASSW兩個(gè)。
typedef struct tagWNDCLASSA {
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
} WNDCLASSA, *PWNDCLASSA, NEAR *NPWNDCLASSA, FAR *LPWNDCLASSA;
typedef struct tagWNDCLASSW {
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCWSTR lpszMenuName;
LPCWSTR lpszClassName;
} WNDCLASSW, *PWNDCLASSW, NEAR *NPWNDCLASSW, FAR *LPWNDCLASSW;
*/

//------------------------------- 窗口類對象初始化過
程 ------------------------------------ wndclass.style = CS_HREDRAW | CS_VREDRAW;

/**//*
設(shè)置窗口類對象的樣式風(fēng)格,CS_HREDRAW | CS_VREDRAW這兩個(gè)值是通過位運(yùn)算的與運(yùn)算
結(jié)合起來的。
表示了窗口在改變了水平和垂直大小的時(shí)候,窗口要強(qiáng)迫刷新。
這些通過define定義的標(biāo)識,可以在WinUser.h頭文件中找到。
#define CS_VREDRAW 0x0001
#define CS_HREDRAW 0x0002
#define CS_DBLCLKS 0x0008
#define CS_OWNDC 0x0020
#define CS_CLASSDC 0x0040
#define CS_PARENTDC 0x0080
#define CS_NOCLOSE 0x0200
#define CS_SAVEBITS 0x0800
#define CS_BYTEALIGNCLIENT 0x1000
#define CS_BYTEALIGNWINDOW 0x2000
#define CS_GLOBALCLASS 0x4000
#define CS_IME 0x00010000
*/

wndclass.lpfnWndProc = WndProc ;//指定窗口的處理函數(shù)為WndProc,WndProc將處理windows消息。
wndclass.cbClsExtra = 0;//窗口類無擴(kuò)展
wndclass.cbWndExtra = 0;//窗口實(shí)例無擴(kuò)展
wndclass.hInstance = hInstance;//指定當(dāng)前應(yīng)用程序?qū)嵗浔?也就是程序當(dāng)前的標(biāo)識號。
wndclass.hIcon = LoadIcon (NULL,IDI_APPLICATION);

/**//*
通過LoadIcon函數(shù)設(shè)置應(yīng)用程序窗口標(biāo)題的icon圖標(biāo)。
HICON LoadIcon(HINSTANCE hInstance,LPCTSTR lpIconName);
函數(shù)返回HICON類型的圖標(biāo)句柄。
第一個(gè)參數(shù)表示當(dāng)前應(yīng)用程序的窗口句柄,第二個(gè)參數(shù)表示圖標(biāo)。
默認(rèn)狀態(tài)下,第一個(gè)參數(shù)為NULL,第二個(gè)為IDI_APPLICATION,表示使用系統(tǒng)默認(rèn)提供的圖
標(biāo),可以在WinUser.h頭文件中找到。
#define IDI_APPLICATION 32512
*/
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;

/**//*
通過LoadCursor函數(shù)設(shè)置應(yīng)用程序窗口光標(biāo)樣式。
HCURSOR LoadCursor(HINSTANCE hInstance,LPCTSTR lpCursorName);
函數(shù)返回HCURSOR類型的光標(biāo)句柄。
第一個(gè)參數(shù)表示當(dāng)前應(yīng)用程序的窗口句柄,第二個(gè)參數(shù)表示光標(biāo)。
默認(rèn)狀態(tài)下,第一個(gè)參數(shù)為NULL,第二個(gè)為IDC_ARROW,表示使用系統(tǒng)默認(rèn)提供的光標(biāo),可以在
WinUser.h頭文件中找到。
#define IDC_ARROW MAKEINTRESOURCE(32512)
*/
wndclass.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);

/**//*
通過GetStockObject函數(shù)設(shè)置應(yīng)用程序窗口的背景顏色。
HGDIOBJ GetStockObject(int fnObject);
函數(shù)返回HCURSOR類型的GDI對象句柄,為了程序能夠正確執(zhí)行,必須把HGDIOBJ類型強(qiáng)制轉(zhuǎn)換成
HBRUSH畫刷句柄。
參數(shù)表示當(dāng)前使用的畫刷顏色。
這些常量的定義可以在WinGDI.h頭文件中找到。
#define WHITE_BRUSH 0
#define LTGRAY_BRUSH 1
#define GRAY_BRUSH 2
#define DKGRAY_BRUSH 3
#define BLACK_BRUSH 4
#define NULL_BRUSH 5
#define HOLLOW_BRUSH NULL_BRUSH
*/
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;//窗口類對象的名稱
//-----------------------------------------------------------------------------------------
RegisterClass (&wndclass);

/**//*
注冊窗口類,參數(shù)為窗口類對象的指針。
函數(shù)原形為:
ATOM RegisterClass(CONST WNDCLASS *lpWndClass);
*/

//-------------------------- 實(shí)例化過
程 -------------------------------------------------
HWND hwnd ; //創(chuàng)建用于保存窗口句柄的對象,窗口句柄是系統(tǒng)識別不同窗口的依據(jù),它只是個(gè)代號。
hwnd = CreateWindow(
szAppName, // 窗口類名稱
"你
好世界", // 窗口標(biāo)題
WS_OVERLAPPEDWINDOW, // 窗口樣式
CW_USEDEFAULT, // 初始的窗口x軸位置
CW_USEDEFAULT, // 初始的窗口y軸位置
CW_USEDEFAULT, // 初始的窗口x軸大小
CW_USEDEFAULT, // 初始的窗口y軸大小
NULL, // 父窗口句柄
NULL, // 窗口功能表句柄
hInstance, // 應(yīng)用程序?qū)嵗浔?br>
NULL // 建立參數(shù),這個(gè)參數(shù)可以存取后面程序中可能引用到的資料。
);

/**//*
在窗口類對象的初始化過程中,我們定義了窗口的一些簡單一般特征,比如背景顏色呀,光標(biāo)呀,等等。
但是在利用CreateWindow創(chuàng)建窗口的時(shí)候可以設(shè)置更多的細(xì)節(jié),比如窗口標(biāo)題這些。
函數(shù)原形如下:
HWND CreateWindow( LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
一旦窗口創(chuàng)建成功,那么CreateWindow將返回窗口句柄,也就是窗口代號,值保存在窗口句柄對象
hwnd中。
*/
ShowWindow(hwnd, iCmdShow);

/**//*
在執(zhí)行過CreateWindow函數(shù)后,在系統(tǒng)的內(nèi)部窗口已經(jīng)創(chuàng)建成功了。
但為了要把窗口顯示在桌面上,我們還必須調(diào)用ShowWindow函數(shù)。
其函數(shù)原形如下:
BOOL ShowWindow(WND hWnd,int iCmdShow);
參數(shù)1是需要顯示的窗口句柄,第二個(gè)則是傳遞給WinMain的iCmdShow,用來確定最開始窗口的顯
示方式。
在這里窗口的顯示方式,主要是指最大化,最小化這些。
*/
UpdateWindow (hwnd);

/**//*
UpdateWindow這個(gè)函數(shù)的作用是用于重繪顯示區(qū)域。
因?yàn)槿绻鸖howWindow函數(shù)的iCmdShow從WinMain獲得的參數(shù)是SW——
SHOWNORMAL,那么窗口的顯示區(qū)域就會被背景畫刷覆蓋,
調(diào)用UpdateWindow函數(shù)會通過發(fā)送給窗口消息處理函數(shù)WndProc一個(gè)WM_PAINT消息,
通過這個(gè)消息完成重繪顯示區(qū)域的工作。
*/
//-----------------------------------------------------------------------------------------
//---------------------------- 消息循
環(huán) -------------------------------------------------

/**//*
當(dāng)調(diào)用過UpdateWindow函數(shù)后,窗口已經(jīng)顯示在了桌面屏幕上,接下來要做的工作是處理消息。
windows應(yīng)用程序可以接受各種消息包括鍵盤,鼠標(biāo),等等。
windows是通過監(jiān)視各種輸入設(shè)備,把發(fā)生的事件轉(zhuǎn)化為消息的,并將消息保存在消息隊(duì)列中。
最后當(dāng)前的應(yīng)用程序從自己的消息隊(duì)列中按順序檢索消息,并把每一個(gè)消息發(fā)送到所對應(yīng)的窗口消息處理函數(shù)總
去,這里是指WndProc。
*/
MSG msg ;//建立消息對象。

/**//*
MSG是個(gè)結(jié)構(gòu)體類型,在WinUser.h頭文件中可以找到。
typedef struct tagMSG{
HWND hwnd;//窗口句柄
UINT message;//消息識別字,在WinUser.h頭文件中可以找到,以WM
開頭,這里就不全部舉出來了。
WPARAM wParam;//32位的消息參數(shù),其含義和值根據(jù)消息的不同而不同。
LPARAM lParam;//32位的消息參數(shù),其值和消息無關(guān)。
DWORD time;//消息進(jìn)入消息隊(duì)列的時(shí)間。
POINT pt;//消息進(jìn)入消息隊(duì)列時(shí)候的鼠標(biāo)坐標(biāo)。
#ifdef _MAC
DWORD lPrivate;
#endif
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;
其中POINT也是個(gè)結(jié)構(gòu)體類型,在WinDef.h頭文件中可以找到

typedef struct tagPOINT
{
LONG x;
LONG y;
} POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;
*/
while (GetMessage (&msg, NULL, 0, 0))

{

/**//*
我們通過這個(gè)循環(huán)代碼來維護(hù)消息循環(huán),循環(huán)的執(zhí)行條件是通過GetMessage函數(shù)獲得的。
函數(shù)原型如下:
BOOL GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax);
參數(shù)一是一個(gè)指向msg對象的指針,剩余的參數(shù)為NULL或0表示程序接受它自己建立的所有窗口
的消息。
windows從消息隊(duì)列取出的下一個(gè)消息將填充MSG結(jié)構(gòu)中的各成員分量。
*/
TranslateMessage (&msg);//把虛擬鍵盤消息轉(zhuǎn)換到字符消息,滿足鍵盤輸入的需要,參數(shù)為msg消息對象的指針。
DispatchMessage (&msg);

/**//*
把當(dāng)前的消息發(fā)送到窗口消息處理函數(shù)中去處理,在這里為WndProc。
當(dāng)DispatchMessage調(diào)用結(jié)束后,循環(huán)再次重復(fù),重新回到
GetMessage處,接著獲取消息。
如果消息循環(huán)接收到WM_QUIT消息則跳出消息循環(huán)。
*/
}
//----------------------------------------------------------------------------------------
return msg.wParam;//返回消息結(jié)構(gòu)中的wParam成員信息。

/**//*
MSG結(jié)構(gòu)的wParam成員的值是傳遞給PostQuitMessage函數(shù)參數(shù),通常是0。
因?yàn)镻ostQuitMessage函數(shù)是在結(jié)束消息循環(huán)必須調(diào)用的函數(shù)。
系統(tǒng)其實(shí)是執(zhí)行了return 0;結(jié)束了WinMain函數(shù)退出了程序,很想控制臺應(yīng)用程序main結(jié)束
的時(shí)候的return 0;,所以直接寫return 0;也不會導(dǎo)致程序錯(cuò)誤。
*/
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)//窗口消息處理函數(shù)

/**//*
函數(shù)返回類型為LRESULT,是一個(gè)長整數(shù),修飾CALLBACK表示此函數(shù)為回調(diào)函數(shù),函數(shù)的返回類型,和參數(shù)
順序都必須按照系統(tǒng)的規(guī)定設(shè)置。
參數(shù)一為窗口句柄,第二個(gè)參數(shù)是無符號整型數(shù)據(jù),用于標(biāo)識接受的消息,最后兩個(gè)參數(shù)為32位的消息參數(shù),提供了更多
關(guān)于消息的信息。
WPARAM和LPARAM都表示的是長整數(shù),該函數(shù)的四個(gè)參數(shù)與MSG結(jié)構(gòu)的前四個(gè)成員相同。
消息處理函數(shù),通常是windows自己調(diào)用的,當(dāng)然程序作者也可以通過調(diào)用SendMessage函數(shù)直接呼叫自
己的窗口消息處理函數(shù),只是在這里暫時(shí)不討論。
*/


{
HDC hdc;//創(chuàng)建設(shè)備描述句柄對象
PAINTSTRUCT ps;//創(chuàng)建繪制結(jié)構(gòu)對象

/**//*
PAINTSTRUCT結(jié)構(gòu)包含了一些窗口消息處理程序,可以用來更新窗口顯示區(qū)域中的信息。
結(jié)構(gòu)如下:
typedef struct tagPAINTSTRUCT {
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32];
} PAINTSTRUCT, *PPAINTSTRUCT;
*/
RECT rect;//創(chuàng)建矩形結(jié)構(gòu)對象

/**//*
此結(jié)構(gòu)的定義如下:
typedef struct _RECT {
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT;
*/
switch (message)//通過switch和
case結(jié)構(gòu)來確定處理什么樣的消息,如果不想處理某些消息則把消息傳遞給DefWindowProc函數(shù)處理。

{
case WM_CREATE://當(dāng)窗口創(chuàng)建的時(shí)候獲
得WM_CREATE消息
PlaySound (TEXT("C:\\online.wav"),NULL,SND_FILENAME|SND_ASYNC);//播放聲音
return 0;//窗口消息處理函數(shù)如果正在處理消息必須返回0
case WM_PAINT://通知窗口更新顯示區(qū)域的信息

/**//*
當(dāng)窗口剛開始建立的時(shí)候,整個(gè)顯示區(qū)域都是無效的,因?yàn)槌绦蜻€沒有在窗口上繪制任何東
西。
第一條WM_PAINT消息通常發(fā)生在調(diào)用UpdateWindows函數(shù)的時(shí)候,告
訴窗口消息處理函數(shù)在顯示區(qū)域繪制一些東西。
事實(shí)上當(dāng)用戶把wndclass.style設(shè)置成
CS_HREDRAW | CS_VREDRAW后,一旦用戶改變窗口大小,就會把顯示區(qū)域當(dāng)作無效,這時(shí)候就會收到WM_PAINT消息。
*/

/**//*
通常在處理WM_PAINT消息的時(shí)候,總是以BeginPaint開頭和
EndPaint結(jié)尾的。
*/
hdc = BeginPaint (hwnd, &ps);

/**//*
調(diào)用BeginPaint函數(shù)可以傳回設(shè)備句柄,這里指的是顯示器的代號和顯示器的驅(qū)
動程序。
因?yàn)樵诖翱陲@示區(qū)域要顯示文字或者圖形都需要用到設(shè)備句柄。
它的函數(shù)原形為:
HDC BeginPaint(
HWND hwnd, // handle to window
LPPAINTSTRUCT lpPaint // paint information
);
它實(shí)際的功能是:當(dāng)發(fā)現(xiàn)窗口顯示區(qū)域的背景還沒有被清除的時(shí)候,則由windows來
刪除它。
我們前面在wndclass結(jié)構(gòu)中設(shè)置了畫刷為白色,這么以來系統(tǒng)就用白色來遮蓋桌面
的顏色,這樣窗口顯示區(qū)域就變成白色了。
*/
GetClientRect (hwnd,&rect);//設(shè)置窗口顯示區(qū)域的尺寸,同時(shí)它也負(fù)責(zé)獲得窗口改變后的窗口顯示區(qū)域的尺寸信息。
DrawText (hdc,TEXT("中
國軟件開發(fā)實(shí)驗(yàn)室,http://www.cndev-lab.com"),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);//繪制文字在窗口顯示區(qū)域中

/**//*
DT_SINGLELINE|DT_CENTER|DT_VCENTER 表示的是文
字顯示的方式,這些在WinUser.h頭文件中定義。
*/
EndPaint (hwnd,&ps);//結(jié)束指定窗口的繪圖
return 0;
case WM_DESTROY://當(dāng)窗口銷毀的時(shí)候會
返回此信息,比如ALT+F4或關(guān)閉窗口的時(shí)候,系統(tǒng)默認(rèn)調(diào)用DestroyWindow()函數(shù)撤消窗口。
PostQuitMessage (0);

/**//*
處理WM_DESTROY消息必須調(diào)用PostQuitMessage函數(shù),該函數(shù)向
消息隊(duì)列中發(fā)送WM_QUIT消息,讓程序退出消息循環(huán)。
應(yīng)用程序可以在響應(yīng)這個(gè)消息的同時(shí)做一些其它結(jié)束的工作。
*/
return 0;
}
return DefWindowProc (hwnd, message, wParam, lParam);//處理不于處理的消息
}