在 Dev-C++中编译运行GUI 程序介绍(二)示例:祝福程序

在 Dev-C++中编译运行GUI 程序介绍(二)示例:祝福程序

前期见:

在 Dev-C++中编译运行GUI 程序介绍(一)基础 https://blog.csdn.net/cnds123/article/details/147019078

示例1、祝福程序

本文中的这个祝福程序是一个使用 Windows API 编写的简单 GUI 应用程序,比较简单,可在 Dev-C++中编译运行,主要用于显示祝福语。

运行效果

【编译设置

在 Dev-C++ 中,找到 "工具" 菜单并选择 "编译选项"。

在 "编译器" 选项卡中,将以下内容添加到 "链接器" 中:

-luser32 -lgdi32

-lgdi32 -lcrypt32

运行时,是否可以不显示cmd黑窗口?

在 Dev-C++ 中隐藏命令提示符窗口条件:确保您创建的是一个 Windows GUI 应用程序,而不是控制台应用程序。在 "链接器" 部分,添加 -mwindows 参数。这个参数告诉编译器链接为 Windows 应用程序,而不是控制台应用程序。

详见签约博文。】

源码(参考自网路)如下

#include <windows.h>
#include <iostream>  //string greetings[]用 
 
using namespace std;

//一个字符串数组,包含了祝福语。  
string greetings[] = {
        "祝你每天如意吉祥!",
        "祝你家庭幸福美满!",
        "愿你合家欢乐,幸福美满,好运连连!",
        "祝你事业顺利,万事如意,梦想成真!",
        "祝你幸福快乐每一天!",
        "祝你万事如意,笑容如花,事业有成,家庭美满!"
};
 
int win_w,win_h;  //用于存储窗口的宽度和高度。
 
HWND label,wish;  //HWND 类型的句柄,分别用于窗口中的标签和祝福文本。
 
//该函数会从 greetings 数组中随机选择一条祝福语,并将其设置为窗口中显示的文本。 
void get_rand() {
    int index = rand() % (sizeof(greetings) / sizeof(greetings[0]));
    SetWindowText(wish, greetings[index].c_str());
}

//这是 Windows 应用程序的核心功能,处理所有发送到窗口的消息 
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
        switch(Message) {
                case WM_CREATE: {
                	    //界面元素的创建
                        static HFONT hFont = CreateFont(40,0,0,0,0,FALSE,FALSE,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"微软雅黑");//创建字体
                        // label
                        label = CreateWindow("static", TEXT("祝福语言"), WS_CHILD | WS_VISIBLE | SS_CENTER, 0, 0, win_w, 45, hwnd,
                        (HMENU)1,((LPCREATESTRUCT)lParam)->hInstance,NULL);
                        SendMessage(label,WM_SETFONT,(WPARAM)hFont,TRUE);
                         
                        // wish
                        static HFONT hFont2 = CreateFont(25,0,0,0,0,FALSE,FALSE,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"微软雅黑");//创建字体
                        wish = CreateWindow("static", TEXT(""), WS_CHILD | WS_VISIBLE | SS_CENTER, 0, 50, win_w, 45, hwnd,
                        (HMENU)1,((LPCREATESTRUCT)lParam)->hInstance,NULL);
                        SendMessage(wish,WM_SETFONT,(WPARAM)hFont2,TRUE);
                         
                        CreateWindow("button", TEXT("随机"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON , 100, 150, 100, 45, hwnd,
                        (HMENU)1001,((LPCREATESTRUCT)lParam)->hInstance,NULL);
                         
                        CreateWindow("button", TEXT("退出"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON , 300, 150, 100, 45, hwnd,
                        (HMENU)1002,((LPCREATESTRUCT)lParam)->hInstance,NULL);
                                 
                        LONG style = GetWindowLong(hwnd, GWL_STYLE);        
                        style &= ~(WS_MAXIMIZEBOX|WS_SIZEBOX|WS_MINIMIZE);        
                        SetWindowLong(hwnd, GWL_STYLE, style);        
                        get_rand();
                        break;
                }
                case WM_COMMAND: {
                        if(LOWORD(wParam)==1001){
                                get_rand();
                        } 
                        else if (LOWORD(wParam)==1002) {
                                DestroyWindow(hwnd);
                        }
                    break; 
                }
                case WM_DESTROY: {
                        PostQuitMessage(0);
                        break;
                }
                default:
                        return DefWindowProc(hwnd, Message, wParam, lParam);
        }
        return 0;
}

//这是 Windows 应用程序的入口点。 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
        WNDCLASSEX wc;
        HWND hwnd;
        MSG Msg;
 
        memset(&wc,0,sizeof(wc));
        wc.cbSize                 = sizeof(WNDCLASSEX);
        wc.lpfnWndProc         = WndProc; /* insert window procedure function here */
        wc.hInstance         = hInstance;
        wc.hCursor                 = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
        wc.lpszClassName = "WindowClass";
        wc.hIcon                 = LoadIcon(NULL, IDI_APPLICATION); /* use "A" as icon name when you want to use the project icon */
        wc.hIconSm                 = LoadIcon(NULL, IDI_APPLICATION); /* as above */
 
        if(!RegisterClassEx(&wc)) {
                MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
                return 0;
        }
         
        win_h = 240;
        win_w = 640;
 
        hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","祝福",WS_VISIBLE|WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,win_w,win_h,NULL,NULL,hInstance,NULL);
        if(hwnd == NULL) {
                MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
                return 0;
        }
 
        while(GetMessage(&Msg, NULL, 0, 0) > 0) {
                TranslateMessage(&Msg);
                DispatchMessage(&Msg);
        }
        return Msg.wParam;
}

说明

windows.h:包含 Windows API 的所有功能,允许进行窗口创建、消息处理等。

iostream:用于输入输出操作。

窗口过程函数

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { ... }

这是 Windows 应用程序的核心功能,处理所有发送到窗口的消息,包括:

  • WM_CREATE:窗口创建时调用,创建界面元素(标签和按钮)并初始化文本。
  • WM_COMMAND:处理按钮点击事件。如果点击“随机”按钮,就调用 get_rand() 函数;如果点击“退出”按钮,就销毁窗口。
  • WM_DESTROY:窗口被销毁时,发送退出消息。
  • 其他消息则调用默认窗口处理过程。

WinMain 函数

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { ... }

这是 Windows 应用程序的入口点。主要步骤包括:

  • 定义窗口类,并设置其属性(如窗口过程、光标、背景等)。
  • 注册窗口类。
  • 创建窗口并显示。
  • 进入消息循环,等待和处理窗口消息。

在 WinMain 函数中,调用 CreateWindowEx 创建窗口,并通过 ShowWindow 和 UpdateWindow 显示窗口。

祝福程序改进版

这个改进版本,将祝福语放到“祝福语.txt”(编码UTF-8)文本文件中。Dev-Cpp 5.11版本较老对UTF-8支持不是太好(Dev-C++ 环境在处理 Unicode 字符串时遇到问题,对较早ANSI 编码支持较好,多次尝试后,变通绕过困难),下面的代码在读取 UTF-8 编码的文件时,将内容临时转换为 ANSI 编码显示,但不改变原始文件——绕过编码处理困难。

并显示一幅小图片:图片最好是适合显示区域的大小(约200x150像素),图片格式bmp(本代码只支持Windows原生支持的位图格式)。

将名为“祝福语.txt”文本文件和一张名为“祝福图片.bmp”的图片放在与程序可执行文件相同的目录下。

运行效果:

源码如下:

#include <windows.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <ctime>

using namespace std;

vector<string> greetings;

int win_w, win_h;
HWND label, wish, pictureBox;  // 添加图片控件句柄
HBITMAP hBitmap = NULL;        // 位图句柄

// 将UTF-8编码的字符串转换为当前系统的ANSI编码
string UTF8ToANSI(const string& utf8Str) {
    if (utf8Str.empty()) return "";
    
    // 先将UTF-8转换为UTF-16 (宽字符)
    int wideLen = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, NULL, 0);
    if (wideLen == 0) return "";
    
    vector<wchar_t> wideStr(wideLen);
    MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, &wideStr[0], wideLen);
    
    // 再将UTF-16转换为ANSI
    int ansiLen = WideCharToMultiByte(CP_ACP, 0, &wideStr[0], -1, NULL, 0, NULL, NULL);
    if (ansiLen == 0) return "";
    
    vector<char> ansiStr(ansiLen);
    WideCharToMultiByte(CP_ACP, 0, &wideStr[0], -1, &ansiStr[0], ansiLen, NULL, NULL);
    
    return string(&ansiStr[0]);
}

// 加载图片函数
HBITMAP LoadImageFile(const char* filename) {
    return (HBITMAP)LoadImageA(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
}

bool loadGreetingsFromFile(const string& filename) {
    // 以二进制模式打开UTF-8编码的文件
    ifstream file(filename.c_str(), ios::binary);
    if (!file.is_open()) {
        MessageBoxA(NULL, "无法打开祝福语文件!", "错误", MB_ICONERROR | MB_OK);
        return false;
    }

    string line;
    while (getline(file, line)) {
        if (!line.empty()) {
            // 将UTF-8编码的行转换为ANSI编码
            string ansiLine = UTF8ToANSI(line);
            greetings.push_back(ansiLine);
        }
    }
    file.close();

    if (greetings.empty()) {
        MessageBoxA(NULL, "祝福语文件为空!", "错误", MB_ICONERROR | MB_OK);
        return false;
    }

    return true;
}

void get_rand() {
    if (greetings.empty()) return;
    
    int index = rand() % greetings.size();
    SetWindowTextA(wish, greetings[index].c_str());
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
    switch(Message) {
        case WM_CREATE: {
            HFONT hFont = CreateFontA(40, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, 
                                      ANSI_CHARSET, OUT_DEFAULT_PRECIS, 
                                      CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, 
                                      DEFAULT_PITCH | FF_DONTCARE, "宋体");
            
            label = CreateWindowA("static", "祝福语言", WS_CHILD | WS_VISIBLE | SS_CENTER, 
                                  0, 0, win_w, 45, hwnd, (HMENU)1, 
                                  ((LPCREATESTRUCT)lParam)->hInstance, NULL);
            SendMessageA(label, WM_SETFONT, (WPARAM)hFont, TRUE);
             
            HFONT hFont2 = CreateFontA(25, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, 
                                       ANSI_CHARSET, OUT_DEFAULT_PRECIS, 
                                       CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, 
                                       DEFAULT_PITCH | FF_DONTCARE, "宋体");
            wish = CreateWindowA("static", "", WS_CHILD | WS_VISIBLE | SS_CENTER, 
                                 0, 50, win_w, 45, hwnd, (HMENU)2, 
                                 ((LPCREATESTRUCT)lParam)->hInstance, NULL);
            SendMessageA(wish, WM_SETFONT, (WPARAM)hFont2, TRUE);
            
            // 创建图片控件
            pictureBox = CreateWindowA("static", "", WS_CHILD | WS_VISIBLE | SS_BITMAP | SS_CENTERIMAGE, 
                                      win_w/2 - 100, 100, 200, 150, hwnd, (HMENU)3, 
                                      ((LPCREATESTRUCT)lParam)->hInstance, NULL);
            
            // 加载图片
            hBitmap = LoadImageFile("祝福图片.bmp");
            if (hBitmap) {
                SendMessageA(pictureBox, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap);
            } else {
                MessageBoxA(NULL, "无法加载图片!", "警告", MB_ICONWARNING | MB_OK);
            }
             
            // 调整按钮位置,放在图片下方
            CreateWindowA("button", "随机", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 
                          win_w/2 - 150, 260, 100, 45, hwnd, (HMENU)1001, 
                          ((LPCREATESTRUCT)lParam)->hInstance, NULL);
             
            CreateWindowA("button", "退出", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 
                          win_w/2 + 50, 260, 100, 45, hwnd, (HMENU)1002, 
                          ((LPCREATESTRUCT)lParam)->hInstance, NULL);
                     
            LONG style = GetWindowLong(hwnd, GWL_STYLE);        
            style &= ~(WS_MAXIMIZEBOX | WS_SIZEBOX | WS_MINIMIZE);        
            SetWindowLong(hwnd, GWL_STYLE, style);
            
            get_rand();
            break;
        }
        case WM_COMMAND: {
            if(LOWORD(wParam) == 1001) {
                get_rand();
            } 
            else if (LOWORD(wParam) == 1002) {
                DestroyWindow(hwnd);
            }
            break; 
        }
        case WM_DESTROY: {
            // 释放位图资源
            if (hBitmap) {
                DeleteObject(hBitmap);
            }
            PostQuitMessage(0);
            break;
        }
        default:
            return DefWindowProc(hwnd, Message, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    srand((unsigned int)time(NULL));
    
    if (!loadGreetingsFromFile("祝福语.txt")) {
        return 0;
    }
    
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    memset(&wc, 0, sizeof(wc));
    wc.cbSize         = sizeof(WNDCLASSEX);
    wc.lpfnWndProc    = WndProc;
    wc.hInstance      = hInstance;
    wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszClassName  = "WindowClass";
    wc.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
    wc.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc)) {
        MessageBoxA(NULL, "窗口注册失败!", "错误!", MB_ICONEXCLAMATION|MB_OK);
        return 0;
    }
     
    win_h = 350;  // 增加窗口高度以容纳图片
    win_w = 640;

    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "WindowClass", "祝福", 
                          WS_VISIBLE|WS_OVERLAPPEDWINDOW, 
                          CW_USEDEFAULT, CW_USEDEFAULT, win_w, win_h, 
                          NULL, NULL, hInstance, NULL);
    if(hwnd == NULL) {
        MessageBoxA(NULL, "窗口创建失败!", "错误!", MB_ICONEXCLAMATION|MB_OK);
        return 0;
    }

    while(GetMessage(&Msg, NULL, 0, 0) > 0) {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}

特别提示

需要注意的是,Windows API 开发应用程序并不一定都是图形用户界面(GUI)的。Windows API(应用程序编程接口)是一个功能丰富的库,支持多种类型的应用程序开发,包括命令行工具、后台服务、驱动程序以及传统的 GUI 应用程序。

一个简单的 Windows API 控制台应用程序示例源码:

#include <windows.h>
#include <stdio.h>

int main() {
    SYSTEM_INFO sysInfo;
    GetSystemInfo(&sysInfo);

    printf("处理器数量: %d\n", sysInfo.dwNumberOfProcessors);
    printf("页面大小: %d bytes\n", sysInfo.dwPageSize);

    MEMORYSTATUSEX memInfo;
    memInfo.dwLength = sizeof(MEMORYSTATUSEX);
    GlobalMemoryStatusEx(&memInfo);

    printf("总物理内存: %lld MB\n", memInfo.ullTotalPhys / (1024 * 1024));
    printf("可用物理内存: %lld MB\n", memInfo.ullAvailPhys / (1024 * 1024));

    return 0;
}

运行效果:

通过灵活使用 Windows API,你可以开发出适应各种场景的高效应用程序! 

我们这个系列主题,重点关注的是用户交互界面(窗口)的GUI 应用程序。

开发简单的小项目或游戏来应用所学知识,参考其他人的例子是一种好方法。后面还将给出我收集的更多的例子。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习&认知实践爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值