From: http://www.pconline.com.cn
程
序作者:管寧 個人網站:www.cndev-lab.com
作者保留作品的所有權利,如需轉
載,請務必注明出處和作者。
被過濾廣告 VC作為一個主流的開發平臺一直深受編程愛好者的喜愛,但是很多人卻對它的入門感到難于上青天,究其原因主要是大家
對他錯誤的認識造成的,嚴格的來說VC++不是門語言,雖然它和C++之間有密切的關系,如果形象點比喻的話,可以C++看作為一種”工業標準”,而
VC++則是某種操作系統平臺下的”廠商標準”,而”廠商標準”是在遵循”工業標準”的前提下擴展而來的。
VC++應用程序的開發主要有兩種模式,一種是WIN API方式,另一種則是MFC方式,傳統的WIN
API開發方式比較繁瑣,而MFC則是對WIN API再次封裝,所以MFC相對于WIN
API開發更具備效率優勢,但為了對WINDOWS開發有一個較為全面細致的認識,筆者在這里還是以講解WIN API的相關內容為主線。
話說到這里可能更多人關心的是學習VC++需要具備什么條件,為什么對于這扇門屢攻不破呢?
要想學習好VC必須具備良好的C/C++的基礎,必要的英語閱讀能力也是必不可少的,因為大量的技術文檔多以英文形式發布。
許多初學VC++的人對于它怪異的寫法和程序奇特的工作方式非常不理解,為了幫助大家對它的入門有一個比較概括的了解,我們把
這一小節內容分成若干部分講解。
第一部分: VC++中的對象的命名規則、常用宏定義的命名,以及VC++下的數據類型。
注:這部分簡單瀏覽即可。
第二部分:VC++常用技術術語的解釋。
第三部分:HelloWin程序的詳細分析。
第一部分
匈牙利命名法規則
一般情況下,變量的取名方式為:
<scope_> + <prefix_> + <qualifier>。
范圍前綴_,類型前綴_,限定詞。
特殊的類型命名,前綴表示:
類、接口
前綴
|
類型
|
例子
|
備注
|
Lm
|
Class
|
LmObject
|
表示類型本身 不與范圍前綴結合使用
|
I
|
Interface 接口
|
IUnknown
|
注:類名前綴改為Lm,對于非全局的類最好有語義表示其所屬模塊。類的實例命名與類名大致相同,只是類名語義表示類的通用含義,而類名表示此實
例的具體語義。如類名LmSketPoint表示草圖點的類定義,而它的兩個實例
_StartPoint,_EndPoint分別代表起點和終點的語義。類的實例命名帶上前綴_。
特殊約定:
a. MouseTool的派生類的前綴為_Mt.
b. 對話框類的前綴為CDlg.
c.
橡皮條類的前綴為_Rb.
凡圍前綴:
前綴
|
類型
|
例子
|
備注
|
g_
|
全局作用域
|
g_Servers
|
|
m_
|
成員變量
|
m_pDoc,
|
l_
|
局部作用域
|
l_strName
|
少用
|
注: 編程時盡量少用全程變量,對于全程變量還應在類型前綴后加上如下關鍵字:
特征模塊 : Fea
草圖模塊 : Sket
裝配模塊 :
Asm
工程圖模塊: Lay
曲面模塊 : Surf
界面模塊 : Ui
常用的一般數據類型的前綴
前綴
|
類型
|
內存規格描述
|
例子
|
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_
|
標識多個資源共享的類型
|
IDR_MAINFRAME
|
1 to 0x6FFF
|
IDD_
|
對話框資源(Dialog)
|
IDD_SPELL_CHECK
|
1 to 0x6FFF
|
IDB_
|
位圖資源(Bitmap)
|
IDB_COMPANY_LOGO
|
1 to 0x6FFF
|
IDC_
|
光標資源(Cursor)
|
IDC_PENCIL
|
1 to 0x6FFF
|
IDI_
|
圖標資源(Icon)
|
IDI_NOTEPAD
|
1 to 0x6FFF
|
ID_IDM_
|
工具欄或菜單欄的命令項
|
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_
|
對話框內的控制資源(Control)
|
IDC_RECALC
|
8 to 0xDFFF
|
VISUAL C++ 下的數據類型
類型
|
含義
|
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應用程序設計用到的基本術語:
1.窗口
任何一個使用過Windows的人對窗口這個概念絕對不會陌生,窗口是windows應用程序的基本操作單元,用戶通過它與應用程序發生交互,
例如輸入輸出操作等等,從程序的內部工作原來來看,每一個窗口對應一個消息處理隊列,應用程序主要通過窗口消息處理函數對用戶的輸入操作進行響應與處理。
要想從程序員的角度充分理解窗口的含義,那么對WNDCLASS這個數據結構進行充分的了解是必須的。
2.實例
單個實例代表一個可執行程序在內存中的拷貝,如果一個應用程序執行許多次,那么在內存中就有多少個拷貝,也就可以說明有多少個實例存在。
3.句柄
句柄在windows環境下被定義成了一個無符號的整數,用于標識應用程序中不同的對象和同類對象中的不同實例。句柄可以看成是對象的編號,聯
系上面的實例,那么一個實例句柄就可以看作是單個應用程序在內存中拷貝的唯一身份編號,通常系統只能通過實例句柄去識別不同的應用程序,或者是相同應用程
序的不同副本。
4.資源
Windows應用程序包含很多資源,例如,菜單,圖標,對話框等等,VC++環境下我們不僅僅可以使用系統下原有的資源,我們也可以定義自己
的資源,這些資源被定義在.RC文件中,通過應用程序最后的編譯,這些資源文件和程序代碼連接在一起,形成一個可執行的.EXE文件或者是一個.DLL的
庫文件。在使用這些資源的時候,通過WIN API函數學將這些資源調用使用。
5.窗口消息處理函數
窗口是人機交互的接口,當窗口接受到輸入請求的時候,就會把這一請求交給某一個函數進行處理,而這個函數就是窗口消息處理函數,它能夠決定當一
個消息被接受到的時候采取什么行動。
消息通常是由一系列的輸入操作觸發的,比如當我按下鼠標左鍵那么窗口消息處理函數就會收到一個WM_LBUTTONDOWN的消息信號。在窗口
消息處理函數中,我們可以利用switch和case結構進行控制, 針對此消息作出我們想要的操作。
6.圖形設備接口
應用程序的任何輸出操作都需要通過圖形設備接口(GDI)中的函數來完成操作,GDI負責系統與用戶或繪圖程序之間的信息交換,并控制在輸出設
備上顯示圖形或者文字,它將程序員與具體的硬件設備隔離開,讓程序員不需要考慮硬件設備操作的細節。
7.回調函數
回調函數是windows操作系統自己調用的函數,用戶是不能直接調用他們的。回調函數的定義必須嚴格的按照windows標準進行編寫。
在下面我們將要看到的HelloWin程序中,WndProc就是一個回調函數,它是是應用程序的窗口消息處理函數,當注冊窗口類的時候,要把
窗口消息處理函數的地址告訴Windows,Windows通過調用此函數進行消息處理。
第三部
分
Windows應用程序的基本運行機制與HelloWin程序詳細解
總的來說最基本的Windows應用程序的運行執行順序總是以如下的基本順序執行的。
順序結構:
調用WinMain函數開始執行--à定義窗口類--à初始化窗口類---à窗口的實例化--à通過消息循環獲取消息并將消
息發送給消息處理函數做出相應的操作
由于windows應用程序運行的邏輯結構特殊所以代碼的詳細解釋筆者就不把程序于敘述分開了了,這樣有利于閱讀與分析。

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

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

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

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

/**//*
HINSTANCE 類型的含義為實例句柄。
hInstance 事實上就是當前應用程序自身的標識代號,代號通常都是一個32位整數。
hPrevInstance 與過去的16位應用程序有關系,表示指向前一個實例的句柄。

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

最后iCmdShow是一個整型數據,標記了程序最初的顯示狀態。
為SW_SHOWNORAML的時候為一般大小顯示方式。
為SW_SHOWMAXIMIZED的時候為最大化顯示方式。
為SW_SHOWMINNOACTIVE的時候程序將顯示在任務欄上。
*/


{

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

/**//*
在這里不得不說一下的是,窗口類事實上是struct結構體,內部有10個分量,他們是用來于初始化窗口類對象而用
的。
這個結構體在winuser.h頭文件中定義,從方式上來說,分為ASCII版的WNDCLASSA和
Unicode版的WNDCLASSW兩個。
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;

/**//*
設置窗口類對象的樣式風格,CS_HREDRAW | CS_VREDRAW這兩個值是通過位運算的與運算
結合起來的。
表示了窗口在改變了水平和垂直大小的時候,窗口要強迫刷新。
這些通過define定義的標識,可以在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 ;//指定窗口的處理函數為WndProc,WndProc將處理windows消息。
wndclass.cbClsExtra = 0;//窗口類無擴展
wndclass.cbWndExtra = 0;//窗口實例無擴展
wndclass.hInstance = hInstance;//指定當前應用程序實例句柄,也就是程序當前的標識號。
wndclass.hIcon = LoadIcon (NULL,IDI_APPLICATION);

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

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

/**//*
通過GetStockObject函數設置應用程序窗口的背景顏色。
HGDIOBJ GetStockObject(int fnObject);
函數返回HCURSOR類型的GDI對象句柄,為了程序能夠正確執行,必須把HGDIOBJ類型強制轉換成
HBRUSH畫刷句柄。
參數表示當前使用的畫刷顏色。
這些常量的定義可以在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);

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

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

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

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

/**//*
UpdateWindow這個函數的作用是用于重繪顯示區域。
因為如果ShowWindow函數的iCmdShow從WinMain獲得的參數是SW——
SHOWNORMAL,那么窗口的顯示區域就會被背景畫刷覆蓋,
調用UpdateWindow函數會通過發送給窗口消息處理函數WndProc一個WM_PAINT消息,
通過這個消息完成重繪顯示區域的工作。
*/
//-----------------------------------------------------------------------------------------
//---------------------------- 消息循
環 -------------------------------------------------

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

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

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

{

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

/**//*
把當前的消息發送到窗口消息處理函數中去處理,在這里為WndProc。
當DispatchMessage調用結束后,循環再次重復,重新回到
GetMessage處,接著獲取消息。
如果消息循環接收到WM_QUIT消息則跳出消息循環。
*/
}
//----------------------------------------------------------------------------------------
return msg.wParam;//返回消息結構中的wParam成員信息。

/**//*
MSG結構的wParam成員的值是傳遞給PostQuitMessage函數參數,通常是0。
因為PostQuitMessage函數是在結束消息循環必須調用的函數。
系統其實是執行了return 0;結束了WinMain函數退出了程序,很想控制臺應用程序main結束
的時候的return 0;,所以直接寫return 0;也不會導致程序錯誤。
*/
}

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

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


{
HDC hdc;//創建設備描述句柄對象
PAINTSTRUCT ps;//創建繪制結構對象

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

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

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

/**//*
當窗口剛開始建立的時候,整個顯示區域都是無效的,因為程序還沒有在窗口上繪制任何東
西。
第一條WM_PAINT消息通常發生在調用UpdateWindows函數的時候,告
訴窗口消息處理函數在顯示區域繪制一些東西。
事實上當用戶把wndclass.style設置成
CS_HREDRAW | CS_VREDRAW后,一旦用戶改變窗口大小,就會把顯示區域當作無效,這時候就會收到WM_PAINT消息。
*/

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

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

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

/**//*
處理WM_DESTROY消息必須調用PostQuitMessage函數,該函數向
消息隊列中發送WM_QUIT消息,讓程序退出消息循環。
應用程序可以在響應這個消息的同時做一些其它結束的工作。
*/
return 0;
}
return DefWindowProc (hwnd, message, wParam, lParam);//處理不于處理的消息
}