C语言写一个弹窗

教育   2024-11-20 22:25   宁夏  

背景

前面一期《孔明棋》写的内容有点多,但是里面的函数功能都没有详细说明,这一期就分解一下前一期中的一些函数功能,讲解一下完成一个弹窗需要哪些函数。

如果我们只是需要一个简简单单的弹窗

只需要一行代码就能实现

MessageBox(NULL, _T("这是一个弹窗"), _T("My Message Box"), MB_YESNO | MB_ICONINFORMATION);

但是如果我们想要一个动态的按钮。

就需要很多行代码

源码

///////////////////////////////////////////////////// 程序名称:弹窗// 编译环境:Mictosoft Visual Studio 2022, EasyX_20200315(beta)// 作  者:luoyh <2864292458@qq.com>// 公 众 号:C语言研究// 最后修改:2024-11-20//
#include<graphics.h>#include<conio.h>int rW = GetSystemMetrics(SM_CXSCREEN); // 屏幕宽度 像素int rH = GetSystemMetrics(SM_CYSCREEN); // 屏幕高度 像素
struct Button{ int X1; // 左上角 int Y1; int X2; // 右下角 int Y2; int size; // 字体大小 LPCTSTR str; // 对应文本};
void Full_Screen(); // 全屏bool WINDOWS(LPCTSTR str, LPCTSTR str1, LPCTSTR str2); // 弹窗void DrawButtonT(Button button, COLORREF color, LOGFONT f); // 绘制按钮// 渐变色void GradientFill(int left, int top, int right, int bottom, COLORREF startColor, COLORREF endColor);
int main(){ Full_Screen(); // 全屏 WINDOWS(_T("这是一个弹窗"), _T("确定"), _T("取消")); // 弹窗 return 0;}
void Full_Screen() // 全屏{ HWND hwnd = initgraph(rW, rH); // 初始化绘图窗口并获取窗口句柄(以 EasyX 为例) LONG l_WinStyle = GetWindowLong(hwnd, GWL_STYLE); // 获取窗口信息 // 设置窗口信息 最大化 取消标题栏及边框 SetWindowLong(hwnd, GWL_STYLE, (l_WinStyle | WS_POPUP | WS_MAXIMIZE) & ~WS_CAPTION & ~WS_THICKFRAME & ~WS_BORDER);// 直接修改窗口样式 SetWindowPos(hwnd, HWND_TOP, 0, 0, rW, rH, 0); setbkcolor(BLACK); cleardevice(); // 设置背景颜色为黑色}
void DrawButtonT(Button button, COLORREF color, LOGFONT f) // 绘制按钮{ setbkmode(TRANSPARENT); RECT r = { button.X1, button.Y1, button.X2, button.Y2 }; settextcolor(color); if (color == WHITE) { setfillcolor(RGB(30, 30, 30)); setlinecolor(RGB(20, 20, 20)); fillrectangle(button.X1, button.Y1, button.X2, button.Y2); } else { GradientFill(button.X1, button.Y1, button.X2, button.Y2, WHITE, BLACK); } settextstyle(&f); // 设置字体样式 drawtext(button.str, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);}
bool WINDOWS(LPCTSTR str, LPCTSTR str1, LPCTSTR str2){ LOGFONT f; gettextstyle(&f); // 获取当前字体设置 f.lfHeight = 40; // 设置字体高度为 _tcscpy_s(f.lfFaceName, _T("楷体")); // 设置字体为“黑体”(高版本 VC 推荐使用 _tcscpy_s 函数) f.lfQuality = ANTIALIASED_QUALITY; // 设置输出效果为抗锯齿 settextstyle(&f); // 设置字体样式 // 弹窗长 int TC = 1000; // 弹窗高 int TH = 300; int TX1 = (rW - TC) / 2; int TX2 = TX1 + TC; int TY1 = (rH - TH) / 2; int TY2 = TY1 + TH; RECT r = { TX1,TY1,TX2,TY2 }; int TXZ = TX1 + TC / 2; Button button4 = { TX1, TY2, TXZ, TY2 + 65, 40, str1 }; Button button5 = { TXZ, TY2, TX2, TY2 + 65, 40,str2 }; ExMessage msg; BeginBatchDraw(); bool T = true; // 控制循环 bool R = true; // 控制返回值 int NUMS = 0; // 游戏的主循环 while (T) { FlushBatchDraw(); cleardevice(); setfillcolor(RGB(20, 20, 20)); solidrectangle(TX1, TY1, TX2, TY2); drawtext(str, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE); DrawButtonT(button4, WHITE, f); DrawButtonT(button5, WHITE, f); while (peekmessage(&msg, EX_MOUSE)) // 如果获取到了消息就执行 { switch (msg.message) { case WM_MOUSEMOVE: if (msg.x > button4.X1 && msg.x<button4.X2 && msg.y>button4.Y1 && msg.y < button4.Y2) { NUMS = 1; } if (msg.x > button5.X1 && msg.x<button5.X2 && msg.y>button5.Y1 && msg.y < button5.Y2) { NUMS = 2; } break; case WM_LBUTTONDOWN: if (msg.x > button4.X1 && msg.x<button4.X2 && msg.y>button4.Y1 && msg.y < button4.Y2) { NUMS = 3; } if (msg.x > button5.X1 && msg.x<button5.X2 && msg.y>button5.Y1 && msg.y < button5.Y2) { NUMS = 4; } break; } }
switch (NUMS) { case 0:break; case 1: DrawButtonT(button4, BLACK, f); DrawButtonT(button5, WHITE, f); break; case 2: DrawButtonT(button5, BLACK, f); DrawButtonT(button4, WHITE, f); break; case 3: T = false; R = false; // 确定退出 break; case 4: T = false; R = true; break; // 开始游戏 } } EndBatchDraw(); return R;}
void GradientFill(int left, int top, int right, int bottom, COLORREF startColor, COLORREF endColor){ // 计算水平和垂直方向上的颜色变化量 double dx = right - left; double dy = bottom - top; double redStep = (GetRValue(endColor) - GetRValue(startColor)) / dx; double greenStep = (GetGValue(endColor) - GetGValue(startColor)) / dx; double blueStep = (GetBValue(endColor) - GetBValue(startColor)) / dx; // 遍历每个像素点,并设置其颜色 for (int x = left; x <= right; x++) { COLORREF currentColor = RGB(GetRValue(startColor) + (x - left) * redStep, GetGValue(startColor) + (x - left) * greenStep, GetBValue(startColor) + (x - left) * blueStep); setfillcolor(currentColor); solidrectangle(x, top, x, bottom); // 填充当前列的颜色 }}

介绍

实现以上整个功能看起来很复杂,其实总共使用了四个函数。

第一个函数

把界面设置为全屏。

void Full_Screen();

 这个函数能够让我们界面为全屏,能够提高程序的观赏性。一般如果想写一个完美的程序,离不开这个功能。

第二个函数

一个渐变色的色条

void GradientFill(int left, int top, int right, int bottom, COLORREF startColor, COLORREF endColor)

这个函数是绘制按钮的组成部分。渐变色就是一个矩形框,然后赋予它起始色,再定义一个终止色。这个函数前面我有一篇文章介绍过可以点击查看,渐变色条

第三个函数

绘制按钮

void DrawButtonT(Button button, COLORREF color, LOGFONT f);    // 绘制按钮

绘制这个按钮还需要一个结构体

struct Button{  int X1;        // 左上角  int Y1;  int X2;        // 右下角  int Y2;  int size;      // 字体大小  LPCTSTR str;    // 对应文本};

第四个函数

绘制弹窗

bool WINDOWS(LPCTSTR str, LPCTSTR str1, LPCTSTR str2);      // 弹窗

前三个函数都是为了绘制弹窗服务。

如果要了解更多细节,建议放到编译器中运行,然后自己动手修改一下参数就知道每一个函数的具体意义了,这是学习的最好方法。

C语言研究
写给自己的笔记,时常写写,时常看看,仅此而已。