国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

如何創建一個最簡單的Windows桌面應用程序 (C++)

2019-11-11 02:08:41
字體:
來源:轉載
供稿:網友

如何創建一個最簡單的Windows桌面應用程序 (C++)

     最近剛開始學習C/C++開發Windows應用程序,這里將會以零基礎的視角把學習過程完全記錄下來。如果你也剛剛起步,那本文一定非常適合你。

     進入正題,本文討論如何使用Visual Studio生成一個最簡單的C窗體應用程序,并向用戶顯示Hello~

     下面我們一步步來介紹,對于涉及代碼的地方,我們只介紹大體的框架,完整的代碼會在文章最后給出。   

     創建基于 Win32 的項目

     1.在文件菜單上,單擊新建,然后單擊項目。

     2.在“新建項目”對話框的左窗格中,依次單擊“已安裝模板”和“Visual C++”,然后選擇“Win32”。在中間窗格中,選擇“Win32 項目”。在“名稱”框中,鍵入項目名稱,例如HelloApp。單擊“確定”。

     3.在“Win32 應用程序向導”的歡迎頁面中,單擊“下一步”。在“應用程序設置”頁的“應用程序類型”下,選擇“Windows 應用程序”。 在“附加選項”下,選擇“空項目”。 單擊“完成”以創建項目。

     4.在“解決方案資源管理器”中,右鍵單擊 HelloApp項目,然后依次單擊“添加”和“新建項”。 在“添加新項”對話框中選擇“C++ 文件(.cpp)”。 在“名稱”框中,鍵入文件名,例如GT_HelloWorldWin32.cpp。單擊“添加”。

     添加引用

     我們的應用程序需要使用許多現有定義才能完成所需功能,針對我們的需求,添加引用如下(其中前兩個是必須的):

#include <windows.h> #include <stdlib.h> #include <string.h> #include <tchar.h> 

     WinMain函數     

     正如每個 C/C++控制臺應用程序在起始點必須具有 main 函數,每個基于 Win32 的應用程序的函數也必須具有 WinMain 函數。WinMain就相當于是入口函數,并且具有固定的語法:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPRevInstance, LPSTR lpCmdLine, int nCmdShow); 

     實現WinMain函數時內部邏輯大體相同,主要有以下幾部分:

     1.創建描述窗體信息的窗口類結構WNDCLASSEX 

     如何創建一個 WNDCLASSEX 類型的窗口類結構?下面的代碼演示了一個典型的窗口類結構WNDCLASSEX 的定義:

//創建 WNDCLASSEX 類型的窗口類結構。 此結構包含關于窗口的信息	//例如應用程序圖標、窗口背景色、標題欄中顯示的名稱、窗口過程函數的名稱等。	WNDCLASSEX wcex; 	wcex.cbSize = sizeof(WNDCLASSEX); 	wcex.style          = CS_HREDRAW | CS_VREDRAW; 	wcex.lpfnWndProc    = WndProc; 	wcex.cbClsExtra     = 0; 	wcex.cbWndExtra     = 0; 	wcex.hInstance      = hInstance; 	wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_application)); 	wcex.hCursor        = LoadCursor(NULL, IDC_ARROW); 	wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1); 	wcex.lpszMenuName   = NULL; 	wcex.lpszClassName  = szWindowClass; 	wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); 

     對于初學者,我們不用過分糾結代碼的細節,暫時從宏觀上把控。我們需要知道,此結構包含關于窗口的信息,例如應用程序圖標、窗口背景色、標題欄中顯示的名稱、窗口過程函數的名稱等。     2.對窗口類進行注冊

     現在已創建了窗口類,必須進行注冊。

     使用 RegisterClassEx 函數,并將窗口類結構作為參數傳遞。

   RegisterClassEx(&wcex);

     3.創建并顯示窗口

     現在需要使用CreateWindow函數創建窗口

     使用ShowWindow函數顯示窗口

     這部分也很好理解,詳見文末的代碼

     4.偵聽消息

     添加用于偵聽操作系統所發送消息的消息循環。

     當應用程序收到一條消息時,此循環將該消息調度到 WndProc 函數。WndProc 函數用于對接收的消息進行處理,我們下面會介紹到。 

     該消息循環類似于以下代碼:

// Main message loop: 	// 添加用于偵聽操作系統所發送消息的消息循環。 	// 當應用程序收到一條消息時,此循環將該消息調度到 WndProc 函數以進行處理。 	MSG msg; 	while (GetMessage(&msg, NULL, 0, 0)) { 		TranslateMessage(&msg); //翻譯消息		DispatchMessage(&msg);  //派遣消息	} 

     WndProc 函數

     WndProc 函數用以處理應用程序收到的消息。

     首先需要判斷收到的消息類型進而做出不同的處理,這需要使用 switch 語句。     系統提供了眾多的消息命令,例如 WM_PAINT 代表收到了繪圖消息,而收到鼠標點擊消息的標識是WM_LBUTTONDOWN...

     這里以處理 WM_PAINT 消息為例進行說明。

     要處理 WM_PAINT 消息,首先應調用 BeginPaint,然后處理所有的繪圖邏輯,例如在窗口中布局文本、按鈕和其他控件,然后調用 EndPaint。 

     對于此應用程序,開始調用和結束調用之間的邏輯是在窗口中顯示字符串 “Hello,World!”。 在以下代碼中,TextOut 函數用于顯示字符串。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { 	PAINTSTRUCT ps;	HDC hdc; 	TCHAR greeting[] = _T("Hello, World!"); 	switch (message) { 		case WM_PAINT: 			//要處理 WM_PAINT 消息,首先應調用 BeginPaint			//然后處理所有的邏輯以及在窗口中布局文本、按鈕和其他控件等			//然后調用 EndPaint。 			hdc = BeginPaint(hWnd, &ps); 			// -----------------在這段代碼對應用程序進行布局------------------------ 			// 對于此應用程序,開始調用和結束調用之間的邏輯是在窗口中顯示字符串 “Hello,World!”。			// 請注意 TextOut 函數用于顯示字符串。			TextOut(hdc, 50, 5, greeting, _tcslen(greeting)); 			// -----------------------布局模塊結束----------------------------------			EndPaint(hWnd, &ps);			break; 		case WM_DESTROY: 			PostQuitMessage(0); 			break;		default: 			//DefWindowProc缺省窗口處理函數			//這個函數是默認的窗口處理函數,我們可以把不關心的消息都丟給它來處理			return DefWindowProc(hWnd, message, wParam, lParam); 			break; 	} 	return 0; } 

     程序運行的結果為:

     完整代碼

     到此我已經理清了寫一個Windows應用程序的主要邏輯

     我是按照Microsoft官方文檔進行的學習,詳見創建Windows桌面應用程序

     對于更多的細節,代碼中給出了詳細注釋。

// GT_HelloWorldWin32.cpp // compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c // 這是一個最簡單的Win32程序,亦可作為開發桌面應用程序的模板#include <windows.h> #include <stdlib.h> #include <string.h> #include <tchar.h> // ------------------------Global variables---------------------------------// 主窗體類名static TCHAR szWindowClass[] = _T("win32app"); // 應用程序標題欄處出現的字符串static TCHAR szTitle[] = _T("Win32 Guided Tour Application"); //HINSTANCE 是Windows里的一中數據類型,是用于標示(記錄)一個程序的實例。//它與HMODULE是一樣的(通用的,這兩種類型最終就是32位無符號長整形)。//HINSTANCE,分開看就是 HANDLE(句柄) + INSTANCE(實例)//實例就是一個程序。用QQ來舉例:你可以開同時開2個qq號,但是你電腦里的qq軟件只有一份。//這2個qq號就是qq的2個實例HINSTANCE hInst; // -------------------------需要預定義的函數放置在此代碼塊種:---------------------------- //每個 Windows 桌面應用程序必須具有一個窗口過程函數//此函數處理應用程序從操作系統中接收的大量消息。 //例如,如果應用程序的對話框中有“確定”按鈕,那么用戶單擊該按鈕時,//操作系統會向應用程序發送一條消息,通知按鈕已被單擊。WndProc 負責對該事件作出響應。//在本例中,相應的響應可能是關閉對話框。LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //-------------------------------------正式內容-----------------------------------------//主窗體函數(入口過程)//每個基于 Win32 的應用程序的函數必須具有 WinMain 函數//正如每個 C 應用程序和 C++ 控制臺應用程序在起始點必須具有 main 函數int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { 	//創建 WNDCLASSEX 類型的窗口類結構。 此結構包含關于窗口的信息	//例如應用程序圖標、窗口背景色、標題欄中顯示的名稱、窗口過程函數的名稱等。	WNDCLASSEX wcex; 	wcex.cbSize = sizeof(WNDCLASSEX); 	wcex.style          = CS_HREDRAW | CS_VREDRAW; 	wcex.lpfnWndProc    = WndProc; 	wcex.cbClsExtra     = 0; 	wcex.cbWndExtra     = 0; 	wcex.hInstance      = hInstance; 	wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); 	wcex.hCursor        = LoadCursor(NULL, IDC_ARROW); 	wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1); 	wcex.lpszMenuName   = NULL; 	wcex.lpszClassName  = szWindowClass; 	wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); 		//對已創建的窗口類進行注冊。 使用 RegisterClassEx 函數,并將窗口類結構作為參數傳遞。	if (!RegisterClassEx(&wcex)) { 		MessageBox(NULL, _T("Call to RegisterClassEx failed!"), _T("Win32 Guided Tour"), NULL); 		return 1; 	} 	// Store instance handle in our global variable 	// 將句柄實例存儲于全局變量中	hInst = hInstance; 		// CreateWindow 函數的參數解釋: 	// szWindowClass: the name of the application 	// szTitle: the text that appears in the title bar 	// WS_OVERLAPPEDWINDOW: the type of window to create 	// CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y) 	// 500, 100: initial size (width, length) 	// NULL: the parent of this window 	// NULL: this application does not have a menu bar 	// hInstance: the first parameter from WinMain 	// NULL: not used in this application 	// 返回的HWND是一個窗口的句柄	HWND hWnd = CreateWindow( szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 100, NULL, NULL, hInstance, NULL ); 	if (!hWnd) { 		MessageBox(NULL, _T("Call to CreateWindow failed!"), _T("Win32 Guided Tour"), NULL); 		return 1; 	} 	// ShowWindow 函數的參數解釋: 	// hWnd: CreateWindow函數返回的窗口句柄 	// nCmdShow: the fourth parameter from WinMain 	ShowWindow(hWnd, nCmdShow);	// UpdateWindow函數用于更新窗口指定的區域	// 如果窗口更新的區域不為空,UpdateWindow函數就發送一個WM_PAINT消息來更新指定窗口的客戶區。	// 函數繞過應用程序的消息隊列,直接發送WM_PAINT消息給指定窗口的窗口過程	// 如果更新區域為空,則不發送消息。	UpdateWindow(hWnd); 	// Main message loop: 	// 添加用于偵聽操作系統所發送消息的消息循環。 	// 當應用程序收到一條消息時,此循環將該消息調度到 WndProc 函數以進行處理。 	MSG msg; 	while (GetMessage(&msg, NULL, 0, 0)) { 		TranslateMessage(&msg); //翻譯消息		DispatchMessage(&msg);  //派遣消息	} 	return (int) msg.wParam; } // //  函數: WndProc(HWND, UINT, WPARAM, LPARAM) // //  目標:  處理主窗體產生的信息// //  WM_PAINT消息代表繪制主窗體 // //  WM_DESTROY消息代表投遞一個退出消息并返回 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { 	PAINTSTRUCT ps;	HDC hdc; 	TCHAR greeting[] = _T("Hello, World!"); 	switch (message) { 		case WM_PAINT: 			//要處理 WM_PAINT 消息,首先應調用 BeginPaint			//然后處理所有的邏輯以及在窗口中布局文本、按鈕和其他控件等			//然后調用 EndPaint。 			hdc = BeginPaint(hWnd, &ps); 			// -----------------在這段代碼對應用程序進行布局------------------------ 			// 對于此應用程序,開始調用和結束調用之間的邏輯是在窗口中顯示字符串 “Hello,World!”。			// 請注意 TextOut 函數用于顯示字符串。			TextOut(hdc, 50, 5, greeting, _tcslen(greeting)); 			// -----------------------布局模塊結束----------------------------------			EndPaint(hWnd, &ps);			break; 		case WM_DESTROY: 			PostQuitMessage(0); 			break;		default: 			//DefWindowProc缺省窗口處理函數			//這個函數是默認的窗口處理函數,我們可以把不關心的消息都丟給它來處理			return DefWindowProc(hWnd, message, wParam, lParam); 			break; 	} 	return 0; } 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 晋宁县| 稷山县| 包头市| 张北县| 桃源县| 澜沧| 承德市| 尼勒克县| 绥芬河市| 阿尔山市| 翼城县| 松滋市| 安远县| 马尔康县| 曲松县| 惠水县| 渭南市| 普陀区| 大安市| 华宁县| 岳阳市| 北宁市| 许昌县| 阳原县| 化州市| 陈巴尔虎旗| 淮阳县| 大丰市| 遂昌县| 汤原县| 栾川县| 高要市| 原平市| 南宁市| 沂源县| 花莲市| 新沂市| 五寨县| 徐汇区| 金川县| 宝坻区|