| 導購 | 订阅 | 在线投稿
分享
 
 
 

Visual C++ 入門精解

來源:互聯網  2008-06-01 02:06:55  評論

程序作者:管甯個人網站: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程序的具體分析。

更多內容請看C/C++技術學堂 C/C++技術專題 Solaris基礎知識入門專題,或

第一部分

匈牙利命名法規則

一般情況下,變量的取名方式爲:

<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.

更多內容請看C/C++技術學堂 C/C++技術專題 Solaris基礎知識入門專題,或

第二部分

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通過調用此函數進行消息處理。

更多內容請看C/C++技術學堂 C/C++技術專題 Solaris基礎知識入門專題,或

第三部分

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_FILENAMESND_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_SINGLELINEDT_CENTERDT_VCENTER);//繪制文字在窗口顯示區域中

/*

DT_SINGLELINEDT_CENTERDT_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);//處理不于處理的消息

}

  程序作者:管甯 個人網站: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程序的具體分析。 更多內容請看C/C++技術學堂 C/C++技術專題 Solaris基礎知識入門專題,或 第一部分 匈牙利命名法規則   一般情況下,變量的取名方式爲: <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. 更多內容請看C/C++技術學堂 C/C++技術專題 Solaris基礎知識入門專題,或 第二部分 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通過調用此函數進行消息處理。 更多內容請看C/C++技術學堂 C/C++技術專題 Solaris基礎知識入門專題,或 第三部分 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_FILENAMESND_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_SINGLELINEDT_CENTERDT_VCENTER);//繪制文字在窗口顯示區域中 /* DT_SINGLELINEDT_CENTERDT_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);//處理不于處理的消息 }
󰈣󰈤
王朝萬家燈火計劃
期待原創作者加盟
 
 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有