Visual C++它大概可以分成三個主要的部分:
3. Platform SDK。這才是Visual C++和整個Visual Studio的精華和靈魂,雖然我們很少能直接接觸到它。大致說來,Platform SDK是以Microsoft C/C++編譯器為核心(不是Visual C++,看清楚了),配合MASM,輔以其他一些工具和文檔資料。上面說到Developer Studio沒有編譯程序的功能,那么這項工作是由誰來完成的呢?是CL,是NMAKE,和其他許許多多命令行程序,這些我們看不到的程序才是構成Visual Studio的基石。
2. MFC。從理論上來講,MFC也不是專用於Visual C++,Borland C++,C++Builder和Symantec C++同樣可以處理MFC。同時,用Visual C++編寫代碼也並不意味着一定要用MFC,只要願意,用Visual C++來編寫SDK程序,或者使用STL,ATL,一樣沒有限制。不過,Visual C++本來就是為MFC打造的,Visual C++中的許多特征和語言擴展也是為MFC而設計的,所以用Visual C++而不用MFC就等於拋棄了Visual C++中很大的一部分功能。但是,Visual C++也不等於MFC。
1. Developer Studio,這是一個集成開發環境,我們日常工作的99%都是在它上面完成的,再加上它的標題赫然寫着“Microsoft Visual C++”,所以很多人理所當然的認為,那就是Visual C++了。其實不然,雖然Developer Studio提供了一個很好的編輯器和很多Wizard,但實際上它沒有任何編譯和鏈接程序的功能,真正完成這些工作的幕后英雄后面會介紹。我們也知道,Developer Studio並不是專門用於VC的,它也同樣用於VB,VJ,VID等Visual Studio家族的其他同胞兄弟。所以不要把Developer Studio當成Visual C++, 它充其量只是Visual C++的一個殼子而已。這一點請切記!
Visual C++6.0不僅是一個C++ 編譯器,而且是一個基於Windows操作系統的可視化集成開發環境(integrated development environment,IDE)。Visual C++6.0由許多組件組成,包括編輯器、調試器以及程序向導AppWizard、類向導Class Wizard等開發工具。 這些組件通過一個名為Developer Studio的組件集成為和諧的開發環境。
Visual C++ 6.0,簡稱VC或者VC6.0,是微軟推出的一款C++編譯器,將“高級語言”翻譯為“機器語言(低級語言)”的程序。Visual C++是一個功能強大的可視化軟件開發工具。自1993年Microsoft公司推出Visual C++1.0后,隨着其新版本的不斷問世,Visual C++已成為專業程序員進行軟件開發的首選工具。雖然微軟公司推出了 Visual C++.NET(Visual C++7.0),但它的應用的很大的局限性,只適用於Windows 2000、Windows XP和Windows NT4.0。所以實際中,更多的是以Visual C++6.0為平台。
1.使用VC++6.0編譯C語言文件(.c)
#include <stdio.h>
int main(int argc, char** argv)
{
printf("Hello World!");
getch();
return 0;
}




2.使用VC++6.0創建MFC對話框程序





3.使用API創建Win32窗口簡單講解
int APIENTRY WinMain(HINSTANCE hInstance, // 本模塊的實例句柄
HINSTANCE hPrevInstance, // Win16 留下的廢物,現在已經不用了
LPSTR lpCmdLine, // 命令行參數
int nCmdShow) // 主窗口初始化時的顯示方式
{ // 下面這行代碼是我添加的,用於彈出一個小對話框
::MessageBox(NULL, "Hello, Win32 Application", "04Win32AppDemo", MB_OK);
return 0;
}
APIENTRY是__stdcall
的宏定義,說明 WinMain 函數采用的是 Windows 標准調用方式。
hInstance 指定了當前模塊的實例句柄。其實在 Win32 下,模塊的實例句柄和模塊句
柄是一樣的,只是說法不同,所以可以通過以下語句獲得當前可執行模塊的實例句柄。
hInstance = ( HINSTANCE )GetModuleHandle(NULL); // 取得應用程序的實例句柄(即模塊句柄)
GetModuleHandle 函數的惟一參數是模塊的名稱,函數會返回這個模塊的句柄。模塊句柄
的值就是該模塊在內存中的首地址。如果為 GetModuleHandle 傳遞 NULL 的話,函數返回的
是可執行文件所在模塊的模塊句柄,而不管是在哪個模塊中做這個調用的。
lpCmdLine 是命令行參數。其值由 CreateProcess 函數的第二個參數指定。通常應用程
序在初始化時檢查這個參數,以決定是否打開特定文檔。
nCmdShow 指定了窗口初始化時的顯示方式。這個值也是由 CreateProcess 函數傳遞
的。一般以這個值為參數調用 ShowWindow 就可以了,此函數用於設置窗口的顯示狀態,
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
CALLBACK 宏是__stdcall 的意思,說明采用 Windows 標准方式傳遞參數。hWnd 參數標
識了消息到達的窗口;uMsg 參數是一個被命名的常量(消息 ID 號),它指定了所發的消息,
當窗口函數接受到消息時,它使用消息 ID 號來決定如何處理這個消息;wParam 和 lParam 是
消息的兩個參數,其值取決於 uMsg。
// 窗口函數的函數原形
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{ char szClassName[] = "MainWClass";
WNDCLASSEX wndclass;
// 用描述主窗口的參數填充 WNDCLASSEX 結構
wndclass.cbSize = sizeof(wndclass); // 結構的大小
wndclass.style = CS_HREDRAW|CS_VREDRAW; // 指定如果大小改變就重畫
wndclass.lpfnWndProc = MainWndProc; // 窗口函數指針
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 = szClassName ; // 窗口類的名稱
wndclass.hIconSm = NULL; // 沒有類的小圖標
// 注冊這個窗口類
::RegisterClassEx(&wndclass);
// 創建主窗口
HWND hwnd = ::CreateWindowEx(
0, // dwExStyle,擴展樣式
szClassName, // lpClassName,類名
"My first Window!", // lpWindowName,標題
WS_OVERLAPPEDWINDOW, // dwStyle,窗口風格
CW_USEDEFAULT, // X,初始 X 坐標
CW_USEDEFAULT, // Y,初始 Y 坐標
CW_USEDEFAULT, // nWidth,寬度
CW_USEDEFAULT, // nHeight,高度
NULL, // hWndParent,父窗口句柄
NULL, // hMenu,菜單句柄
hInstance, // hlnstance,程序實例句柄
NULL) ; // lpParam,用戶數據
if(hwnd == NULL)
{ ::MessageBox(NULL, "創建窗口出錯!", "error", MB_OK);
return -1;
}
// 顯示窗口,刷新窗口客戶區
::ShowWindow(hwnd, nCmdShow);
::UpdateWindow(hwnd);
// 從消息隊列中取出消息,交給窗口函數處理,直到 GetMessage 返回 FALSE,結束消息循環
MSG msg;
while(::GetMessage(&msg, NULL, 0, 0))
{ // 轉化鍵盤消息
::TranslateMessage(&msg);
// 將消息發送到相應的窗口函數
::DispatchMessage(&msg);
}
// 當 GetMessage 返回 FALSE 時程序結束
return msg.wParam;
}
LRESULT CALLBACK MainWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{ char szText[] = "最簡單的窗口程序!";
switch (message)
{
case WM_PAINT: // 窗口客戶區需要重畫
{ HDC hdc;
PAINTSTRUCT ps;
// 使無效的客戶區變的有效,並取得設備環境句柄
hdc = ::BeginPaint (hwnd, &ps) ;
// 顯示文字
::TextOut(hdc, 10, 10, szText, strlen(szText));
::EndPaint(hwnd, &ps);
return 0;
}
case WM_DESTROY: // 正在銷毀窗口
// 向消息隊列投遞一個 WM_QUIT 消息,促使 GetMessage 函數返回 0,結束消息循環
::PostQuitMessage(0) ;
return 0 ;
}
// 將我們不處理的消息交給系統做默認處理
return ::DefWindowProc(hwnd, message, wParam, lParam);
}
分析以上程序,可以得出在桌面上顯示一個窗口的具體步驟,這就是主程序的結構流程。
(1)注冊窗口類(RegisterClassEx)
(2)創建窗口(CreateWindowEx)
(3)在桌面顯示窗口(ShowWindow)
(4)更新窗口客戶區(UpdateWindow)
(5)進入無限的消息獲取和處理的循環。首先是獲取消息(GetMessage),如果有消息到
達,則將消息分派到回調函數處理(DispatchMessage),如果消息是 WM_QUIT,則 GetMessage
函數返回 FALSE,整個消息循環結束。消息具體的處理過程是在 MainWndProc 函數中進行的。
1.注冊窗口類
typedef struct _WNDCLASSEX {
UINT cbSize; // WNDCLASSEX 結構的大小
UINT style; // 從這個窗口類派生的窗口具有的風格
WNDPROC lpfnWndProc; // 即 window procedure, 窗口消息處理函數指針
int cbClsExtra; // 指定緊跟在窗口類結構后的附加字節數
int cbWndExtra; // 指定緊跟在窗口事例后的附加字節數
HANDLE hInstance; // 本模塊的實例句柄
HICON hIcon; // 窗口左上角圖標的句柄
HCURSOR hCursor; // 光標的句柄
HBRUSH hbrBackground; // 背景畫刷的句柄
LPCTSTR lpszMenuName; // 菜單名
LPCTSTR lpszClassName; // 該窗口類的名稱
HICON hIconSm; // 小圖標句柄
} WNDCLASSEX;
2.創建窗口
HWND hwnd = ::CreateWindowEx(
0, // dwExStyle,擴展樣式
szClassName, // lpClassName,類名
"My first Window!", // lpWindowName,標題
WS_OVERLAPPEDWINDOW, // dwStyle,窗口風格
CW_USEDEFAULT, // X,初始 X 坐標
CW_USEDEFAULT, // Y,初始 Y 坐標
CW_USEDEFAULT, // nWidth,寬度
CW_USEDEFAULT, // nHeight,高度
NULL, // hWndParent,父窗口句柄
NULL, // hMenu,菜單句柄
hInstance, // hlnstance,程序實例句柄
NULL) ; // lpParam,用戶數據
下面列出了一些常見風格的定義,它們是以 WS(Windows Style 的縮寫)為前綴的預定
義的值:
WS_BORDER 創建一個單邊框的窗口
WS_CAPTION 創建一個有標題框的窗口(包括 WS_BODER 風格)
WS_CHIlD 創建一個子窗口。這個風格不能與 WS_POPVP 風格合用
WS_DISABLED 創建一個初始狀態為禁止的子窗口。一個禁止狀態的窗日不能接受來自用戶
的輸人信息
WS_DLGFRAME 創建一個帶對話框邊框風格的窗口。這種風格的窗口不能帶標題條
WS_HSCROLL 創建一個有水平滾動條的窗口
WS_VSCROLL 創建一個有垂直滾動條的窗口
WS_ICONIC 創建一個初始狀態為最小化狀態的窗口。與 WS_MINIMIZE 風格相同
WS_MAXIMIZE 創建一個具有最大化按鈕的窗口。該風格不能和 WS_EX_CONTEXTHELP 風
格同時出現,同時必須指定 WS_SYSMENU 風格
WS_OVERLAPPED 產生一個層疊的窗口。一個層疊的窗口有一個標題條和一個邊框。與
WS_TILED 風格相同
WS_OVERLAPPEDWINDOW 創建一個具有 WS_OVERLAPPED,WS_CAPTION,
WS_SYSMENU ,WS_THICKFRAME,WS_MINIMIZEBOX,
WS_MAXMIZEBOX 風格的層疊窗口
WS_POPUP 創建一個彈出式窗口。該風格不能與 WS_CHLD 風格同時使用
WS_POPUPWINDOW 創建一個具有 WS_BORDER,WS_POPUP,WS_SYSMENU 風格的
窗口,WS_CAPTION 和 WS_POPUPWINDOW 必須同時設定才能
使窗口某單可見
WS_SIZEBOX 創建一個可調邊框的窗口,與 WS_THICKFRAME 風格相同
WS_SYSMENU 創建一個在標題條上帶有窗口菜單的窗口,必須同時設定
WS_CAPTION 風格
WS_THICKFRAME 創建一個具有可調邊框的窗口,與 WS_SIZEBOX 風格相同
WS_VISIBLE 創建一個初始狀態為可見的窗口
typedef struct tagMSG {
HWND hwnd; // 消息要發向的窗口句柄
UINT message; // 消息標識符,以 WM_ 開頭的預定義值(意為 Window Message)
WPARAM wParam; // 消息的參數之一
LPARAM lParam; // 消息的參數之二
DWORD time; // 消息放入消息隊列的時間
POINT pt; // 這是一個 POINT 數據結構,表示消息放入消息隊列時的鼠標位置
} MSG, *PMSG ;