在 Dev-C++中編譯運行GUI程序介紹(三)有趣示例一組
前期見
在 Dev-C++中編譯運行GUI 程序介紹(一)基礎 https://blog.csdn.net/cnds123/article/details/147019078
在 Dev-C++中編譯運行GUI 程序介紹(二)示例:祝福程序 https://blog.csdn.net/cnds123/article/details/147019350
本文給出一組可以在 Dev-C++中編譯運行的GUI 應用程序。
示例2、簡單的猜數字游戲
下面是一個簡單的猜數字游戲源碼,您可以在 Dev-C++ 中編譯和運行它。這個程序創建了一個基本的 GUI 界面,用戶可以通過輸入數字來進行猜測,程序會提示用戶猜的數字是太高、太低還是猜對了。并有猜中計數和“重玩”按鈕功能。
運行效果:
源碼如下:
#include <windows.h>
#include <string>
#include <cstdlib>
#include <ctime>using namespace std;// 全局變量
HWND hwndInput, hwndButton, hwndOutput, hwndCountLabel;
int randomNumber;
int guessCount = 0; // 猜中計數// 生成隨機數
void generateRandomNumber() {randomNumber = rand() % 100 + 1; // 生成 1 到 100 之間的隨機數guessCount = 0; // 重置猜中計數
}// 消息處理函數
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {switch (msg) {case WM_CREATE: {// 創建說明標簽CreateWindow("STATIC", "請輸入1到100之間的數字:", WS_CHILD | WS_VISIBLE,50, 20, 200, 25, hwnd, NULL, NULL, NULL);// 創建輸入框hwndInput = CreateWindow("EDIT", "", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_NUMBER,50, 50, 100, 25, hwnd, NULL, NULL, NULL);// 創建猜測按鈕hwndButton = CreateWindow("BUTTON", "猜測", WS_CHILD | WS_VISIBLE,50, 100, 100, 30, hwnd, (HMENU)1, NULL, NULL);// 創建重玩按鈕CreateWindow("BUTTON", "重玩", WS_CHILD | WS_VISIBLE,160, 100, 100, 30, hwnd, (HMENU)2, NULL, NULL);// 創建輸出框hwndOutput = CreateWindow("STATIC", "", WS_CHILD | WS_VISIBLE,50, 150, 200, 25, hwnd, NULL, NULL, NULL);// 創建猜中計數標簽hwndCountLabel = CreateWindow("STATIC", "猜測次數: 0", WS_CHILD | WS_VISIBLE,50, 180, 200, 25, hwnd, NULL, NULL, NULL);generateRandomNumber(); // 生成第一個隨機數// 設置光標焦點到輸入框SetFocus(hwndInput);break;}case WM_COMMAND: {if (LOWORD(wParam) == 1) { // 按鈕被點擊char buffer[10];GetWindowText(hwndInput, buffer, sizeof(buffer)); // 獲取輸入的文本int guess = atoi(buffer); // 將字符串轉換為整數// 進行猜測判斷string message;guessCount++; // 增加猜測次數if (guess < randomNumber) {message = "太低了!";} else if (guess > randomNumber) {message = "太高了!";} else {message = "恭喜你,猜對了!";// 不重置猜測次數,直到用戶選擇“重玩”}// 更新輸出框和猜中計數標簽SetWindowText(hwndOutput, message.c_str());SetWindowText(hwndCountLabel, ("猜測次數: " + to_string(guessCount)).c_str());// 設置光標焦點到輸入框SetFocus(hwndInput);}else if (LOWORD(wParam) == 2) { // 重玩按鈕被點擊generateRandomNumber(); // 生成新的隨機數SetWindowText(hwndOutput, ""); // 清空輸出框SetWindowText(hwndCountLabel, "猜測次數: 0"); // 重置猜中計數SetWindowText(hwndInput, ""); // 清空輸入框SetFocus(hwndInput); // 設置光標焦點到輸入框}break;}case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;
}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {srand(static_cast<unsigned int>(time(0))); // 設置隨機種子// 注冊窗口類const char CLASS_NAME[] = "GuessNumberWindow";WNDCLASS wc = {};wc.lpfnWndProc = WndProc;wc.hInstance = hInstance;wc.lpszClassName = CLASS_NAME;RegisterClass(&wc);// 創建窗口HWND hwnd = CreateWindowEx(0, CLASS_NAME, "猜數字游戲", WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, NULL, NULL, hInstance, NULL);ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// 消息循環MSG msg;while (GetMessage(&msg, NULL, 0, 0)) {TranslateMessage(&msg);DispatchMessage(&msg);}return 0;
}
示例3、剪子、包袱、錘游戲
剪子、包袱、錘(又稱石頭剪刀布)游戲規則
勝負關系:
剪子 勝 包袱(剪刀剪開布)。
包袱 勝 錘(布包裹石頭)。
錘 勝 剪子(石頭砸壞剪刀)。
手勢相同:平局,重新對決。
界面如下
源碼如下:
//剪子、包袱、錘游戲
#include <windows.h>
#include <string>
#include <cstdlib>
#include <ctime>
#include <sstream>using namespace std;// 全局變量
HWND hwndOutput, hwndComputerChoice;
int computerChoice;// 生成計算機的選擇
void generateComputerChoice() {computerChoice = rand() % 3; // 0 = 剪子, 1 = 包袱, 2 = 錘
}// 消息處理函數
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {switch (msg) {case WM_CREATE: {// 創建剪子按鈕CreateWindow("BUTTON", "剪子 (X)", WS_CHILD | WS_VISIBLE,50, 50, 100, 30, hwnd, (HMENU)1, NULL, NULL);// 創建包袱按鈕CreateWindow("BUTTON", "包袱 (Q)", WS_CHILD | WS_VISIBLE,50, 100, 100, 30, hwnd, (HMENU)2, NULL, NULL);// 創建錘按鈕CreateWindow("BUTTON", "錘 (P)", WS_CHILD | WS_VISIBLE,50, 150, 100, 30, hwnd, (HMENU)3, NULL, NULL);// 創建新局按鈕CreateWindow("BUTTON", "新局", WS_CHILD | WS_VISIBLE,50, 200, 100, 30, hwnd, (HMENU)4, NULL, NULL);// 創建輸出框hwndOutput = CreateWindow("STATIC", "", WS_CHILD | WS_VISIBLE,200, 50, 200, 100, hwnd, NULL, NULL, NULL);// 創建計算機選擇顯示框hwndComputerChoice = CreateWindow("STATIC", "", WS_CHILD | WS_VISIBLE,200, 150, 200, 25, hwnd, NULL, NULL, NULL);// 設置隨機種子srand(static_cast<unsigned int>(time(0)));break;}case WM_COMMAND: {if (LOWORD(wParam) >= 1 && LOWORD(wParam) <= 3) { // 剪子、包袱或錘按鈕被點擊int userChoice = LOWORD(wParam) - 1; // 0 = 剪子, 1 = 包袱, 2 = 錘generateComputerChoice(); // 生成計算機選擇// 計算機選擇對應的輸出來顯示string computerChoiceStr;if (computerChoice == 0) computerChoiceStr = "剪子 (X)";else if (computerChoice == 1) computerChoiceStr = "包袱 (Q)";else if (computerChoice == 2) computerChoiceStr = "錘 (P)";// 判斷輸贏string result;if (userChoice == computerChoice) {result = "平局!";} else if ((userChoice == 0 && computerChoice == 1) || (userChoice == 1 && computerChoice == 2) || (userChoice == 2 && computerChoice == 0)) {result = "你輸了!";} else {result = "你贏了!";}// 更新輸出框和計算機選擇框SetWindowText(hwndOutput, result.c_str());SetWindowText(hwndComputerChoice, ("計算機選擇: " + computerChoiceStr).c_str());} else if (LOWORD(wParam) == 4) { // 新局按鈕被點擊SetWindowText(hwndOutput, ""); // 清空輸出框SetWindowText(hwndComputerChoice, ""); // 清空計算機選擇框}break;}case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;
}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {// 注冊窗口類const char CLASS_NAME[] = "RockPaperScissorsWindow";WNDCLASS wc = {};wc.lpfnWndProc = WndProc;wc.hInstance = hInstance;wc.lpszClassName = CLASS_NAME;RegisterClass(&wc);// 創建窗口HWND hwnd = CreateWindowEx(0, CLASS_NAME, "剪子、包袱、錘游戲", WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 420, 300, NULL, NULL, hInstance, NULL);ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// 消息循環MSG msg;while (GetMessage(&msg, NULL, 0, 0)) {TranslateMessage(&msg);DispatchMessage(&msg);}return 0;
}
示例4、簡單計算器
可以在 Dev-C++ 中編譯和運行簡單計算器(通過計算機鍵盤輸入數)。
界面如下:
代碼如下:
#include <windows.h>
#include <string>
#include <sstream>using namespace std;// 全局變量
HWND hwndInput1, hwndInput2, hwndOutput, hwndButtonAdd, hwndButtonSub, hwndButtonMul, hwndButtonDiv;// 計算結果并顯示
void Calculate(char operation) {char buffer1[100], buffer2[100];GetWindowText(hwndInput1, buffer1, sizeof(buffer1)); // 獲取第一個輸入框的文本GetWindowText(hwndInput2, buffer2, sizeof(buffer2)); // 獲取第二個輸入框的文本double num1 = atof(buffer1); // 轉換為 doubledouble num2 = atof(buffer2); // 轉換為 doubledouble result = 0.0;// 根據操作符進行計算switch (operation) {case '+': result = num1 + num2; break;case '-': result = num1 - num2; break;case '*': result = num1 * num2; break;case '/':if (num2 != 0) {result = num1 / num2;} else {SetWindowText(hwndOutput, "錯誤:除以零");return;}break;}// 顯示結果stringstream ss;ss << result;SetWindowText(hwndOutput, ss.str().c_str());
}// 消息處理函數
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {switch (msg) {case WM_CREATE: {// 創建輸入框1hwndInput1 = CreateWindow("EDIT", "", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_NUMBER,50, 20, 100, 30, hwnd, NULL, NULL, NULL);// 創建輸入框2hwndInput2 = CreateWindow("EDIT", "", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_NUMBER,50, 60, 100, 30, hwnd, NULL, NULL, NULL);// 創建輸出框hwndOutput = CreateWindow("STATIC", "", WS_CHILD | WS_VISIBLE,50, 100, 200, 30, hwnd, NULL, NULL, NULL);// 創建加法按鈕hwndButtonAdd = CreateWindow("BUTTON", "+", WS_CHILD | WS_VISIBLE,200, 20, 30, 30, hwnd, (HMENU)1, NULL, NULL);// 創建減法按鈕hwndButtonSub = CreateWindow("BUTTON", "-", WS_CHILD | WS_VISIBLE,200, 60, 30, 30, hwnd, (HMENU)2, NULL, NULL);// 創建乘法按鈕hwndButtonMul = CreateWindow("BUTTON", "*", WS_CHILD | WS_VISIBLE,250, 20, 30, 30, hwnd, (HMENU)3, NULL, NULL);// 創建除法按鈕hwndButtonDiv = CreateWindow("BUTTON", "/", WS_CHILD | WS_VISIBLE,250, 60, 30, 30, hwnd, (HMENU)4, NULL, NULL);break;}case WM_COMMAND: {if (LOWORD(wParam) == 1) { // 加法按鈕被點擊Calculate('+');} else if (LOWORD(wParam) == 2) { // 減法按鈕被點擊Calculate('-');} else if (LOWORD(wParam) == 3) { // 乘法按鈕被點擊Calculate('*');} else if (LOWORD(wParam) == 4) { // 除法按鈕被點擊Calculate('/');}break;}case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;
}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {// 注冊窗口類const char CLASS_NAME[] = "SimpleCalculator";WNDCLASS wc = {};wc.lpfnWndProc = WndProc;wc.hInstance = hInstance;wc.lpszClassName = CLASS_NAME;RegisterClass(&wc);// 創建窗口HWND hwnd = CreateWindowEx(0, CLASS_NAME, "簡單計算器", WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 400, 200, NULL, NULL, hInstance, NULL);ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// 消息循環MSG msg;while (GetMessage(&msg, NULL, 0, 0)) {TranslateMessage(&msg);DispatchMessage(&msg);}return 0;
}
示例5、改進版的簡單計算器
下面是一個改進版的簡單計算器,界面上包含數字按鍵(0-9)和基本的運算按鍵(加、減、乘、除)。用戶可以通過點擊數字按鍵和運算符按鍵來輸入數字和運算,然后按下“=”按鈕來計算結果。
界面如下:
代碼如下:
#include <windows.h>
#include <string>
#include <cstdlib>
#include <sstream>using namespace std;// 全局變量
HWND hwndDisplay;
string currentInput = ""; // 當前輸入// 更新顯示框
void UpdateDisplay() {SetWindowText(hwndDisplay, currentInput.c_str());
}// 處理數字和操作符的按鈕點擊
void ButtonClick(char value) {currentInput += value; // 追加輸入UpdateDisplay();
}// 計算結果并顯示
void Calculate() {double num1 = 0.0, num2 = 0.0;char operation = '+';size_t pos = 0;// 解析輸入for (char c : currentInput) {if (c == '+' || c == '-' || c == '*' || c == '/') {num1 = atof(currentInput.substr(0, pos).c_str());operation = c;pos++;break;}pos++;}if (pos < currentInput.length()) {num2 = atof(currentInput.substr(pos).c_str());} else {return; // 沒有足夠的輸入進行計算}double result = 0.0;// 根據操作符進行計算switch (operation) {case '+': result = num1 + num2; break;case '-': result = num1 - num2; break;case '*': result = num1 * num2; break;case '/':if (num2 != 0) {result = num1 / num2;} else {currentInput = "錯誤:除以零";UpdateDisplay();return;}break;}// 顯示結果stringstream ss;ss << result;currentInput = ss.str(); // 更新為結果UpdateDisplay();
}// 消息處理函數
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {switch (msg) {case WM_CREATE: {// 創建顯示框hwndDisplay = CreateWindow("EDIT", "", WS_CHILD | WS_VISIBLE | ES_RIGHT | ES_READONLY,10, 10, 280, 30, hwnd, NULL, NULL, NULL);// 創建按鈕const char* buttons[] = {"7", "8", "9", "+","4", "5", "6", "-","1", "2", "3", "*","0", ".", "=", "/"};int x = 10, y = 50;for (int i = 0; i < 16; ++i) {CreateWindow("BUTTON", buttons[i], WS_CHILD | WS_VISIBLE,x, y, 65, 40, hwnd, (HMENU)(INT_PTR)(i + 1), NULL, NULL);x += 70;if ((i + 1) % 4 == 0) {x = 10;y += 45;}}// 創建"清空"按鈕CreateWindow("BUTTON", "清空", WS_CHILD | WS_VISIBLE,10, 230, 280, 30, hwnd, (HMENU)17, NULL, NULL);break;}case WM_COMMAND: {int id = LOWORD(wParam);if (id >= 1 && id <= 16) {const char* buttonValues[] = {"7", "8", "9", "+","4", "5", "6", "-","1", "2", "3", "*","0", ".", "=", "/"};if (buttonValues[id - 1][0] == '=') {Calculate();} else {ButtonClick(buttonValues[id - 1][0]);}} else if (id == 17) { // 清空按鈕currentInput = "";UpdateDisplay();}break;}case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;
}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {// 注冊窗口類const char CLASS_NAME[] = "SimpleCalculator";WNDCLASS wc = {};wc.lpfnWndProc = WndProc;wc.hInstance = hInstance;wc.lpszClassName = CLASS_NAME;RegisterClass(&wc);// 創建窗口HWND hwnd = CreateWindowEx(0, CLASS_NAME, "手持計算器", WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 315, 310, NULL, NULL, hInstance, NULL);if (hwnd == NULL) {return 0;}ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// 消息循環MSG msg = {};while (GetMessage(&msg, NULL, 0, 0)) {TranslateMessage(&msg);DispatchMessage(&msg);}return 0;
}
示例6、繪制直線、圓和三角形
Windows API中的GDI(Graphics Device Interface,圖形設備接口)是一個用于處理圖形和圖像輸出的子系統。它允許程序與各種輸出設備(如顯示器、打印機等設備無關性)進行交互,繪制圖形、文本和圖像。
GDI的作用
- 繪制圖形:GDI提供了一系列函數,用于繪制基本形狀(如線條、矩形、圓形、多邊形等)。程序員可以使用這些函數在窗口上繪制想要的圖形。
- 文本處理:GDI也可以用于繪制文本。它支持多種字體和文本格式,程序員可以選擇字體、大小和顏色來顯示文本。
- 圖像處理:GDI能夠加載并顯示位圖(BMP)、圖標等圖像格式。程序員可以將圖像繪制到窗口或打印機上。
- 設備無關性:GDI使得程序可以不依賴于特定的硬件設備。無論是在顯示器上繪制,還是在打印機上輸出,GDI提供的接口都是一致的。這意味著,程序可以在不同的輸出設備上運行,而不需要進行太多修改。
- 設備上下文(DC):在GDI中,設備上下文是一種數據結構,表示繪圖設備的狀態。程序在繪圖時需要獲取設備上下文,以便使用它來進行繪圖操作。
GDI的基本操作
- 創建窗口:在窗口上繪制圖形的第一步是創建一個窗口。這可以通過Windows API中的函數來實現。
- 獲取設備上下文:在繪制之前,程序需要獲取窗口的設備上下文(HDC),這樣才能在窗口上進行繪制。
- 繪制操作:
- 使用GDI函數繪制圖形(如MoveToEx和LineTo繪制直線)。
- 使用TextOut函數繪制文本。
- 使用BitBlt函數復制圖像。
- 釋放資源:繪制完成后,程序需要釋放獲取的設備上下文,以避免資源泄露。
先看效果圖:
源碼如下:
#include <windows.h>LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {switch (msg) {case WM_PAINT: {PAINTSTRUCT ps;HDC hdc = BeginPaint(hwnd, &ps);// 設置顏色HPEN hPen = CreatePen(PS_SOLID, 2, RGB(0, 0, 255)); // 藍色SelectObject(hdc, hPen);// 畫直線MoveToEx(hdc, 50, 50, NULL); // 起點LineTo(hdc, 200, 50); // 終點// 畫圓Ellipse(hdc, 50, 70, 150, 170); // x1, y1, x2, y2// 畫三角形POINT vertices[] = { {200, 70}, {250, 170}, {150, 170} };Polygon(hdc, vertices, 3);// 釋放資源DeleteObject(hPen);EndPaint(hwnd, &ps);break;}case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;
}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {const char CLASS_NAME[] = "SampleWindowClass";WNDCLASS wc = {};wc.lpfnWndProc = WndProc; // 設置窗口過程wc.hInstance = hInstance;wc.lpszClassName = CLASS_NAME;RegisterClass(&wc);// 創建窗口HWND hwnd = CreateWindowEx(0, CLASS_NAME, "繪圖示例", WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 400, 400, NULL, NULL, hInstance, NULL);if (hwnd == NULL) {return 0;}ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// 消息循環MSG msg;while (GetMessage(&msg, NULL, 0, 0)) {TranslateMessage(&msg);DispatchMessage(&msg);}return 0;
}
示例7、繪制紅五角星
使用Windows API中的GDI (圖形設備接口)。
先看效果圖:
源碼如下:
#include <windows.h>
#include <math.h>#define M_PI 3.14159265358979323846 // 定義π(如未定義)// 計算五角星頂點的函數
void DrawStar(HDC hdc, int centerX, int centerY, int size) {POINT points[10];double angle;int i;// 計算五角星的頂點for (i = 0; i < 10; i++) {angle = (i * 36.0) * (M_PI / 180.0); // 角度轉換為弧度// 外部頂點if (i % 2 == 0) {points[i].x = centerX + (int)(size * cos(angle));points[i].y = centerY - (int)(size * sin(angle));}// 內部頂點else {points[i].x = centerX + (int)(size * 0.5 * cos(angle));points[i].y = centerY - (int)(size * 0.5 * sin(angle));}}// 繪制五角星HPEN hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0)); // 紅色SelectObject(hdc, hPen);SelectObject(hdc, GetStockObject(NULL_BRUSH)); // 無填充Polygon(hdc, points, 10); // 繪制五角星// 釋放資源DeleteObject(hPen);
}// 消息處理函數
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {switch (msg) {case WM_PAINT: {PAINTSTRUCT ps;HDC hdc = BeginPaint(hwnd, &ps);// 設置背景顏色FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));// 繪制紅五角星DrawStar(hdc, 200, 150, 100);EndPaint(hwnd, &ps);break;}case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;
}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {const char CLASS_NAME[] = "StarDrawingWindow";WNDCLASS wc = {};wc.lpfnWndProc = WndProc; // 設置窗口過程wc.hInstance = hInstance;wc.lpszClassName = CLASS_NAME;RegisterClass(&wc);// 創建窗口HWND hwnd = CreateWindowEx(0, CLASS_NAME, "繪制紅五角星", WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, NULL, NULL, hInstance, NULL);if (hwnd == NULL) {return 0;}ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// 消息循環MSG msg;while (GetMessage(&msg, NULL, 0, 0)) {TranslateMessage(&msg);DispatchMessage(&msg);}return 0;
}