Code date creation的开发技术介绍
C++图形化数据生成器 Code date creation 开发技术笔记
作者:starryfast
本文基于源码 v7.0.0(Exceed 正式版),记录开发过程中的技术选型、架构设计与核心实现,供技术同行参考。
1. 技术选型与工程配置
1.1 开发环境
- 语言标准:C++(兼容 C++11)
- 集成开发环境:Visual Studio Code
- 编译器:MinGW-w64(g++),内置版本仅支持 C++11,同时支持用户指定系统 g++ 路径
- 目标平台:Windows(x86_64),独立 exe,无需额外运行时
1.2 关键宏定义
#define_CRT_SECURE_NO_WARNINGS#defineWIN32_LEAN_AND_MEAN#define_WIN32_WINNT0x0603// 支持 Windows 8.1 及以上 APIWIN32_LEAN_AND_MEAN精简 Windows 头文件,减少编译时间。_WIN32_WINNT = 0x0603启用 Windows 8.1 及以上的 API 特性(如DwmSetWindowAttribute圆角窗口)。
1.3 链接库与清单
#pragmacomment(lib,"comctl32.lib")#pragmacomment(lib,"comdlg32.lib")#pragmacomment(lib,"advapi32.lib")#pragmacomment(lib,"shell32.lib")#pragmacomment(lib,"gdi32.lib")#pragmacomment(lib,"gdiplus.lib")#pragmacomment(lib,"uxtheme.lib")#pragmacomment(lib,"dwmapi.lib")依赖库说明:
- comctl32:通用控件(
InitCommonControlsEx) - comdlg32:通用对话框(
GetOpenFileName、ChooseColor) - advapi32:注册表操作(
RegCreateKeyEx、RegSetValueEx) - gdiplus:图片加载与渐变绘制
- uxtheme/dwmapi:主题支持与窗口圆角
清单依赖声明了 Common Controls 6.0.0.0,启用视觉样式(XP 风格及以上)。
1.4 GDI+ 初始化
GdiplusStartupInput gdi;GdiplusStartup(&g_gdiplusToken,&gdi,NULL);GdiplusStartup初始化 GDI+,返回 token 用于GdiplusShutdown。所有 GDI+ 对象(Image、Graphics、LinearGradientBrush)依赖此初始化。
2. 图形界面架构
2.1 窗口过程与消息循环
采用经典 Win32 消息驱动模型:
while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}WndProc处理的核心消息包括:
WM_CREATE:创建所有子控件、加载配置、初始化 GDI+WM_COMMAND:按钮点击、下拉选择、复选框切换WM_SIZE:更新滚动条范围和页面大小WM_VSCROLL/WM_MOUSEWHEEL:滚动响应WM_ERASEBKGND:绘制背景(渐变或图片)WM_CTLCOLORSTATIC/WM_CTLCOLOREDIT/WM_CTLCOLORBTN:自定义控件颜色
2.2 滚动机制
与常见的一体化滚动不同,本工具采用子控件整体偏移的方式实现滚动:
voidScrollToPosition(HWND hWnd,intnewPos){intdeltaY=lastPos-newPos;// 遍历所有子控件,逐个调整其 Y 坐标child=GetWindow(hWnd,GW_CHILD);while(child){SetWindowPos(child,NULL,pt.x,pt.y+deltaY,...);child=GetNextWindow(child,GW_HWNDNEXT);}InvalidateRect(hWnd,NULL,FALSE);}这种方式的优势是所有子控件的相对位置关系保持不变,只整体平移。适用于控件数量较多、布局复杂的窗口。
滚动范围g_totalContentHeight在WM_CREATE中根据所有控件位置计算得出,WM_SIZE中动态更新滚动条信息。
2.3 窗口圆角
BOOL immersive=TRUE;DwmSetWindowAttribute(hWnd,DWMWA_WINDOW_CORNER_PREFERENCE,&immersive,sizeof(immersive));利用dwmapi实现窗口圆角,仅 Windows 11 有效。
3. 控件系统
3.1 四种模式切换
工具通过单选框切换四种工作模式:
| 模式 ID | 名称 | 功能 |
|---|---|---|
| 0 | 随机生成 | 配置参数,批量生成.in文件 |
| 1 | 自编译 | 提供 AC 代码,自动生成.out |
| 2 | 打包 ZIP | 将已生成文件打包为.zip |
| 3 | 实用工具 | 110+ 系统小工具 |
SwitchMode函数实现模式切换,通过ShowWindow(SW_HIDE/SW_SHOW)控制不同控件组的显隐。每个模式对应一组控件 ID 数组。
3.2 字体
两种字体:
g_hFontNormal:Microsoft YaHei UI,-20pt,用于普通控件g_hFontLog:Cascadia Code,-16pt,用于日志和预览编辑框(等宽字体)
创建后通过WM_SETFONT发送给所有子控件。
3.3 自定义颜色控件
通过WM_CTLCOLORSTATIC/WM_CTLCOLOREDIT消息实现:
caseWM_CTLCOLORSTATIC:{SetTextColor(hdc,g_textColor);SetBkMode(hdc,TRANSPARENT);return(LRESULT)g_hBrushBg;}caseWM_CTLCOLOREDIT:{SetTextColor(hdc,g_textColor);SetBkColor(hdc,g_bgColor);return(LRESULT)g_hBrushEdit;}g_hBrushBg和g_hBrushEdit在颜色变化时重建,并通过ApplyColorSettings刷新全窗口。
4. 随机数据生成引擎
4.1 随机数实现
随机数生成采用rand()+ 手动扩展:
intrandomInt(intmin,intmax){returnmin+rand()%(max-min+1);}longlongrandomBetween(longlonga,longlongb){if(a>b)swap(a,b);unsignedlonglongrange=(unsignedlonglong)(b-a)+1;unsignedlonglongr=((unsignedlonglong)rand()<<30)|((unsignedlonglong)rand()<<15)|(unsignedlonglong)rand();returna+(longlong)(r%range);}种子在wWinMain中初始化:srand((unsigned)time(NULL))。
4.2 数据类型
下拉框支持七种数据类型:
| 索引 | 类型 | 参数配置 |
|---|---|---|
| 0 | 整数(随机) | 值域范围,可重复 |
| 1 | 整数(不重复) | 值域范围,使用std::set去重 |
| 2 | 字符串(小写) | 长度 |
| 3 | 字符串(大写) | 长度 |
| 4 | 字符串(混合) | 长度 |
| 5 | 浮点数(随机) | 值域范围,double输出 |
| 6 | 日期时间 | 年份/月/日/时/分/秒随机 |
类型切换时动态显示/隐藏对应的参数控件(IDC_EDIT_RANGE1/2或IDC_EDIT_STRLEN)。
4.3 生成函数
GenerateInputFiles是核心生成函数,参数包括:
start/end:文件编号范围(如 1~10 生成 10 个.in)dataType:数据类型(1~7)range1/range2:值域strLen:字符串长度countPerFile:每文件元素个数writeCount:是否在文件首行写入元素个数vars:额外变量(键值对,在数据前输出)customCharset:自定义字符集
额外变量解析:
vector<ExtraVar>ParseExtraVars(HWND hEdit){// 支持两种格式:// 1. name=value// 2. name value(空格分隔)}生成的.in文件格式示例:
n 10 a b c 1 2 3 4 5 6 7 8 9 104.4 特殊类型生成
浮点数生成:
doubleval=(double)rand()/RAND_MAX*200.0-100.0;fwprintf(fp,L"%.6f ",val);日期时间生成:
inty=randomInt(2000,2030);intm=randomInt(1,12);intd=randomInt(1,28);fwprintf(fp,L"%04d-%02d-%02d %02d:%02d:%02d ",y,m,d,h,min,s);5. 自编译模式
5.1 编译执行流程
CompileAndRunBatch和CompileAndRunSingle实现自编译:
- 调用
CreateProcess执行g++编译命令 - 编译成功后,对每个
.in文件运行生成的可执行文件 - 通过输入重定向读取
.in,输出重定向写入.out
5.2 进程创建
SECURITY_ATTRIBUTES sa={sizeof(sa),NULL,TRUE};CreatePipe(&hRead,&hWrite,&sa,0);HANDLE hNull=CreateFileW(L"NUL",GENERIC_READ,...);STARTUPINFOW si={sizeof(si)};si.dwFlags=STARTF_USESTDHANDLES;si.hStdOutput=hWrite;si.hStdError=hWrite;si.hStdInput=hNull;CreateProcessW(NULL,cmd,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi);编译命令示例:
"g++.exe" "source.cpp" -o "temp_ac.exe"运行命令示例:
cd /d "outdir" && "temp_ac.exe" < "1.in" > "1.out"5.3 管道与重定向
编译时使用管道捕获stdout/stderr,运行时不捕获(直接重定向到文件)。CreatePipe创建匿名管道,hWrite传给子进程作为标准输出,父进程通过hRead读取编译信息。
运行子进程时使用_wsystem而非CreateProcess,简化命令构造(支持cd /d和重定向符号)。
6. ZIP 打包模块
6.1 自主实现的 ZIP 格式
工具没有使用第三方压缩库,而是手写 ZIP 文件格式:
#pragmapack(push,1)structZipLocal{uint32_tsig;// 0x04034b50uint16_tvn,fl,mt;uint16_tmt2,md;uint32_tcrc;uint32_tcs,us;uint16_tnl,el;};structZipCentral{...};structZipEOCD{...};#pragmapack(pop)PackRecordedFilesToZip函数按 ZIP 规范写入:
- 对每个文件计算 CRC32
- 写入 Local File Header
- 写入文件名(UTF-8 编码)
- 写入文件数据
- 最后写入 Central Directory 和 End of Central Directory
6.2 CRC32 实现
staticuint32_tcrc32_table[256];staticvoidinit_crc32(){for(uint32_ti=0;i<256;++i){uint32_tc=i;for(intj=0;j<8;++j)c=(c>>1)^((c&1)?0xEDB88320:0);crc32_table[i]=c;}}staticuint32_tcalc_crc32(constvoid*d,size_t len){uint32_tc=0xFFFFFFFF;for(size_t i=0;i<len;++i)c=(c>>8)^crc32_table[(c^((uint8_t*)d)[i])&0xFF];returnc^0xFFFFFFFF;}标准 CRC32 算法,与 ZIP 格式要求的校验值一致。
6.3 文件命名
打包时从完整路径中提取文件名:src.substr(src.find_last_of(L"\\/") + 1)。文件名转换为 UTF-8 编码写入 ZIP。
7. 主题与颜色系统
7.1 颜色存储
颜色值存储在全局变量g_textColor和g_bgColor中,通过注册表持久化:
voidSaveColorSettings(){RegSetValueExW(hKey,L"TextColor",0,REG_DWORD,(BYTE*)&g_textColor,sizeof(COLORREF));RegSetValueExW(hKey,L"BgColor",0,REG_DWORD,(BYTE*)&g_bgColor,sizeof(COLORREF));}7.2 预设主题
十个预设主题按钮(经典白底、暗夜灰底、护眼绿底、柔和米色、深蓝科技、黄昏橙紫、森林暗绿、极简灰白、粉彩樱花、黑金奢华):
caseIDC_THEME_WHITE:SetPresetTheme(RGB(0,0,0),RGB(255,255,255));break;caseIDC_THEME_DARK:SetPresetTheme(RGB(230,230,230),RGB(50,50,50));break;// ...7.3 颜色选择器
ShowColorDialog调用系统ChooseColor对话框,依次选择文字颜色和背景颜色。
7.4 渐变背景
g_gradColors存储多个颜色值,DrawBackground使用LinearGradientBrush绘制水平渐变:
if(g_gradColors.size()>=2){vector<Gdiplus::Color>colors;vector<REAL>positions;for(inti=0;i<count;++i){colors.push_back(Color(GetRValue(c),GetGValue(c),GetBValue(c)));positions.push_back((REAL)i/(count-1));}LinearGradientBrushbrush(Rect(0,0,w,h),Color::White,Color::Black,LinearGradientModeHorizontal);brush.SetInterpolationColors(colors.data(),positions.data(),count);g.FillRectangle(&brush,0,0,w,h);}ShowGradientDialog允许用户通过多次ChooseColor选择多个颜色,保存到注册表。
8. 背景图片
8.1 图片加载
使用 GDI+ 的Image::FromFile加载图片:
g_pBgImage=Image::FromFile(path.c_str());if(g_pBgImage&&g_pBgImage->GetLastStatus()==Ok){// 保存路径到注册表}支持格式:JPG、PNG、BMP(通过文件对话框过滤)。
8.2 图片绘制
DrawBackground中保持宽高比缩放:
intiw=g_pBgImage->GetWidth(),ih=g_pBgImage->GetHeight();floatscale=max((float)w/iw,(float)h/ih);intdw=(int)(iw*scale),dh=(int)(ih*scale);g.DrawImage(g_pBgImage,(w-dw)/2,(h-dh)/2,dw,dh);居中显示,超出部分裁剪。
8.3 图片缓存
g_hBGBitmap缓存绘制后的位图,避免每次WM_ERASEBKGND重新绘制渐变或缩放图片:
voidUpdateBGCache(HWND hWnd){// 仅在窗口尺寸变化时重建位图if(g_hBGBitmap&&g_bgCacheSize.cx==w&&g_bgCacheSize.cy==h)return;// 创建兼容位图,绘制背景,缓存}WM_ERASEBKGND直接使用BitBlt将缓存位图复制到窗口 DC,大幅提升绘制性能。
9. g++ 编译器管理
9.1 自动检测
AutoFindGpp按以下顺序搜索:
- 程序自身目录及
../mingw64/bin/ PATH环境变量(跳过 RedPanda)- 常见安装路径(MinGW、TDM-GCC、CodeBlocks、Dev-Cpp)
- 遍历所有固定/可移动磁盘根目录(深度限制 6 层,跳过 Windows、System32、WinSxS 等系统目录)
9.2 路径存储
注册表路径:HKEY_CURRENT_USER\Software\TestDataGenerator\GppPath
voidSaveGppPath(constwstring&path){RegSetValueExW(hKey,L"GppPath",0,REG_SZ,(BYTE*)path.c_str(),...);}工具启动时自动加载保存的路径。
10. 实用工具集成
10.1 系统工具调用
110+ 工具按钮通过ShellExecuteW调用系统命令:
voidOpenCalculator(HWND hWnd){ShellExecuteW(NULL,L"open",L"calc.exe",NULL,NULL,SW_SHOWNORMAL);}voidOpenRegEdit(HWND hWnd){ShellExecuteW(NULL,L"open",L"regedit.exe",NULL,NULL,SW_SHOWNORMAL);}10.2 网络工具
- 百度搜索:构造 URL
https://www.baidu.com/s?wd=+ 关键词 - 二维码生成:调用
https://api.qrserver.com/v1/create-qr-code/ - IP 查询:打开
ip.cn - 天气查询:打开
tianqi.qq.com
10.3 交互式工具
部分工具通过自定义InputBox函数获取用户输入:
BOOLInputBox(HWND hWnd,constwchar_t*title,constwchar_t*prompt,wchar_t*out,intmaxLen);例如定时关机、打开网址、密码生成等均使用此对话框。
11. 数据持久化
11.1 注册表键值
路径:HKEY_CURRENT_USER\Software\TestDataGenerator
存储项:
TextColor/BgColor:颜色设置GppPath:g++ 路径BackgroundImage:背景图片路径GradColorCount+GradColor0..N:渐变色列表
11.2 配置文件
SaveConfig/LoadConfig通过WritePrivateProfileString和GetPrivateProfileString读写.ini文件:
WritePrivateProfileStringW(L"Settings",L"Start",start,file);GetPrivateProfileStringW(L"Settings",L"Start",L"1",buf,32,file);支持保存和加载生成参数(起始 ID、结束 ID、数据类型、范围、长度、个数等)。
12. 版本迭代技术记录
| 版本 | 日期 | 技术变化 |
|---|---|---|
| 5.0.0 | 2026-06-12 | 首个版本,完成 Win32 GUI 框架、基础数据类型生成、主题切换 |
| 6.0.0 | 2026-06-19 | 新增 ZIP 打包模块(手写 ZIP 格式),自编译模式,注册表持久化 |
| PRO 1.0.0 | 2026-06-20 | 稳定性修复,参数校验增强 |
| Future | 2026-06-21 | 集成 110+ 工具,图片加载优化,g++ 自动检测增强 |
| Exceed 7.0.0 | 2026-07-12 | 渐变色支持,图片缓存优化,DWM 圆角窗口,自定义 InputBox |
13. 总结
本文基于源码 v7.0.0 记录了 Code date creation 的核心技术实现:
- 纯 Win32 API + GDI+构建图形界面,无第三方 GUI 框架依赖
- 手写 ZIP 格式实现文件打包,无压缩库依赖
- 自定义 InputBox实现轻量级用户输入对话框
- 注册表 + INI 文件实现配置持久化
- 背景图片缓存 + 渐变实现灵活的主题系统
- 自编译模式通过
CreateProcess调用 g++,支持批量生成
整个工具在 Windows 原生 API 上构建,依赖少、体积小,所有功能均为自主实现。
本文基于源码实际内容撰写,所有技术细节均可从代码中验证。