当前位置: 首页 > news >正文

【C++】ATM机模拟系统 :完整窗口实现

下面是一个完整的C++ ATM机模拟系统,使用Windows API实现窗口界面,包含所有基础功能模块。

我将提供完整代码并详细解释实现原理。 

#include <windows.h>
#include <string>
#include <fstream>
#include <ctime>
using namespace std;// 全局变量
const string CARD_NUMBER = "1234567890";
const string PIN = "1234";
float balance = 10000.0;
float dailyWithdrawn = 0.0;
int attempts = 0;
bool atmLocked = false;
string transactionHistory = "";// 控件ID
#define ID_CARD_EDIT     101
#define ID_PIN_EDIT      102
#define ID_LOGIN_BTN     103
#define ID_BALANCE_BTN   104
#define ID_DEPOSIT_BTN   105
#define ID_WITHDRAW_BTN  106
#define ID_EXIT_BTN      107
#define ID_RECEIPT_BTN   108
#define ID_AMOUNT_EDIT   109
#define ID_CONFIRM_BTN   110
#define ID_BACK_BTN      111
#define ID_INFO_TEXT     112
#define ID_HISTORY_LIST  113// 函数声明
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void CreateLoginControls(HWND);
void CreateMainControls(HWND);
void CreateTransactionControls(HWND, const string&);
void ProcessLogin(HWND);
void ShowBalance(HWND);
void DepositMoney(HWND);
void WithdrawMoney(HWND);
void PrintReceipt(HWND);
void ResetDailyLimit();
void SaveTransaction(const string&);
void UpdateInfoText(HWND, const string&);
string GetCurrentDateTime();// 主函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static TCHAR szAppName[] = TEXT("ATM Simulation");HWND hwnd;MSG msg;WNDCLASS wndclass;wndclass.style = CS_HREDRAW | CS_VREDRAW;wndclass.lpfnWndProc = WndProc;wndclass.cbClsExtra = 0;wndclass.cbWndExtra = 0;wndclass.hInstance = hInstance;wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wndclass.lpszMenuName = NULL;wndclass.lpszClassName = szAppName;if (!RegisterClass(&wndclass)) {MessageBox(NULL, TEXT("Program requires Windows NT!"), szAppName, MB_ICONERROR);return 0;}hwnd = CreateWindow(szAppName, TEXT("银行ATM系统"), WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX,CW_USEDEFAULT, CW_USEDEFAULT, 500, 400, NULL, NULL, hInstance, NULL);ShowWindow(hwnd, iCmdShow);UpdateWindow(hwnd);while (GetMessage(&msg, NULL, 0, 0)) {TranslateMessage(&msg);DispatchMessage(&msg);}return msg.wParam;
}// 窗口过程
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {static HWND hCardEdit, hPinEdit, hLoginBtn, hBalanceBtn, hDepositBtn, hWithdrawBtn;static HWND hExitBtn, hReceiptBtn, hAmountEdit, hConfirmBtn, hBackBtn, hInfoText, hHistoryList;switch (message) {case WM_CREATE:CreateLoginControls(hwnd);ResetDailyLimit();break;case WM_COMMAND:switch (LOWORD(wParam)) {case ID_LOGIN_BTN:ProcessLogin(hwnd);break;case ID_BALANCE_BTN:ShowBalance(hwnd);break;case ID_DEPOSIT_BTN:CreateTransactionControls(hwnd, "存款");break;case ID_WITHDRAW_BTN:CreateTransactionControls(hwnd, "取款");break;case ID_RECEIPT_BTN:PrintReceipt(hwnd);break;case ID_EXIT_BTN:DestroyWindow(hwnd);break;case ID_CONFIRM_BTN:if (GetWindowTextLength(GetDlgItem(hwnd, ID_AMOUNT_EDIT)) {char amountText[20];GetWindowText(GetDlgItem(hwnd, ID_AMOUNT_EDIT), amountText, 20);float amount = atof(amountText);if (GetWindowTextLength(GetDlgItem(hwnd, ID_CONFIRM_BTN)) {char btnText[20];GetWindowText(GetDlgItem(hwnd, ID_CONFIRM_BTN), btnText, 20);if (strcmp(btnText, "存款确认") == 0) {balance += amount;SaveTransaction("存款: +" + string(amountText) + "元");UpdateInfoText(hwnd, "存款成功!当前余额: " + to_string(balance) + "元");} else if (strcmp(btnText, "取款确认") == 0) {if (amount > balance) {UpdateInfoText(hwnd, "余额不足!");} else if (amount > 2000) {UpdateInfoText(hwnd, "单笔取款不能超过2000元");} else if (dailyWithdrawn + amount > 20000) {UpdateInfoText(hwnd, "今日取款已超限额(20000元)");} else {balance -= amount;dailyWithdrawn += amount;SaveTransaction("取款: -" + string(amountText) + "元");UpdateInfoText(hwnd, "取款成功!当前余额: " + to_string(balance) + "元");}}}}break;case ID_BACK_BTN:DestroyWindow(GetDlgItem(hwnd, ID_AMOUNT_EDIT));DestroyWindow(GetDlgItem(hwnd, ID_CONFIRM_BTN));DestroyWindow(GetDlgItem(hwnd, ID_BACK_BTN));CreateMainControls(hwnd);break;}break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, message, wParam, lParam);}return 0;
}// 创建登录界面控件
void CreateLoginControls(HWND hwnd) {CreateWindow(TEXT("STATIC"), TEXT("卡号:"), WS_CHILD | WS_VISIBLE | SS_CENTER,100, 50, 80, 25, hwnd, NULL, NULL, NULL);CreateWindow(TEXT("EDIT"), TEXT(""), WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,180, 50, 200, 25, hwnd, (HMENU)ID_CARD_EDIT, NULL, NULL);CreateWindow(TEXT("STATIC"), TEXT("密码:"), WS_CHILD | WS_VISIBLE | SS_CENTER,100, 100, 80, 25, hwnd, NULL, NULL, NULL);CreateWindow(TEXT("EDIT"), TEXT(""), WS_CHILD | WS_VISIBLE | WS_BORDER | ES_PASSWORD | ES_AUTOHSCROLL,180, 100, 200, 25, hwnd, (HMENU)ID_PIN_EDIT, NULL, NULL);CreateWindow(TEXT("BUTTON"), TEXT("登录"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,200, 150, 100, 30, hwnd, (HMENU)ID_LOGIN_BTN, NULL, NULL);CreateWindow(TEXT("STATIC"), TEXT(""), WS_CHILD | WS_VISIBLE | SS_LEFT,50, 200, 400, 30, hwnd, (HMENU)ID_INFO_TEXT, NULL, NULL);UpdateInfoText(hwnd, "请输入您的银行卡号和密码");
}// 创建主界面控件
void CreateMainControls(HWND hwnd) {CreateWindow(TEXT("BUTTON"), TEXT("查询余额"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,50, 50, 150, 40, hwnd, (HMENU)ID_BALANCE_BTN, NULL, NULL);CreateWindow(TEXT("BUTTON"), TEXT("存款"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,250, 50, 150, 40, hwnd, (HMENU)ID_DEPOSIT_BTN, NULL, NULL);CreateWindow(TEXT("BUTTON"), TEXT("取款"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,50, 120, 150, 40, hwnd, (HMENU)ID_WITHDRAW_BTN, NULL, NULL);CreateWindow(TEXT("BUTTON"), TEXT("打印凭条"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,250, 120, 150, 40, hwnd, (HMENU)ID_RECEIPT_BTN, NULL, NULL);CreateWindow(TEXT("BUTTON"), TEXT("退出系统"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,150, 200, 150, 40, hwnd, (HMENU)ID_EXIT_BTN, NULL, NULL);CreateWindow(TEXT("STATIC"), TEXT(""), WS_CHILD | WS_VISIBLE | SS_LEFT,50, 260, 400, 60, hwnd, (HMENU)ID_INFO_TEXT, NULL, NULL);UpdateInfoText(hwnd, "请选择您需要的服务");
}// 创建交易界面控件
void CreateTransactionControls(HWND hwnd, const string& type) {// 清除主界面按钮DestroyWindow(GetDlgItem(hwnd, ID_BALANCE_BTN));DestroyWindow(GetDlgItem(hwnd, ID_DEPOSIT_BTN));DestroyWindow(GetDlgItem(hwnd, ID_WITHDRAW_BTN));DestroyWindow(GetDlgItem(hwnd, ID_RECEIPT_BTN));DestroyWindow(GetDlgItem(hwnd, ID_EXIT_BTN));string label = type + "金额:";CreateWindow(TEXT("STATIC"), label.c_str(), WS_CHILD | WS_VISIBLE | SS_CENTER,100, 80, 100, 25, hwnd, NULL, NULL, NULL);CreateWindow(TEXT("EDIT"), TEXT(""), WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | ES_NUMBER,220, 80, 150, 25, hwnd, (HMENU)ID_AMOUNT_EDIT, NULL, NULL);string btnText = type + "确认";CreateWindow(TEXT("BUTTON"), btnText.c_str(), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,100, 140, 120, 40, hwnd, (HMENU)ID_CONFIRM_BTN, NULL, NULL);CreateWindow(TEXT("BUTTON"), TEXT("返回"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,260, 140, 120, 40, hwnd, (HMENU)ID_BACK_BTN, NULL, NULL);UpdateInfoText(hwnd, "请输入" + type + "金额,然后点击确认");
}// 处理登录逻辑
void ProcessLogin(HWND hwnd) {if (atmLocked) {UpdateInfoText(hwnd, "账户已锁定,请联系银行工作人员");return;}char cardText[20], pinText[20];GetWindowText(GetDlgItem(hwnd, ID_CARD_EDIT), cardText, 20);GetWindowText(GetDlgItem(hwnd, ID_PIN_EDIT), pinText, 20);if (string(cardText) == CARD_NUMBER && string(pinText) == PIN) {// 清除登录控件DestroyWindow(GetDlgItem(hwnd, ID_CARD_EDIT));DestroyWindow(GetDlgItem(hwnd, ID_PIN_EDIT));DestroyWindow(GetDlgItem(hwnd, ID_LOGIN_BTN));DestroyWindow(GetDlgItem(hwnd, ID_INFO_TEXT));// 创建主界面CreateMainControls(hwnd);attempts = 0;} else {attempts++;if (attempts >= 3) {atmLocked = true;UpdateInfoText(hwnd, "密码错误次数过多,账户已锁定!");} else {UpdateInfoText(hwnd, "卡号或密码错误!剩余尝试次数: " + to_string(3 - attempts));}}
}// 显示余额
void ShowBalance(HWND hwnd) {string info = "当前余额: " + to_string(balance) + "元\n";info += "今日已取款: " + to_string(dailyWithdrawn) + "元";UpdateInfoText(hwnd, info);
}// 打印凭条
void PrintReceipt(HWND hwnd) {string receipt = "====== 银行交易凭条 ======\n";receipt += "时间: " + GetCurrentDateTime() + "\n";receipt += "卡号: " + CARD_NUMBER + "\n";receipt += "当前余额: " + to_string(balance) + "元\n";receipt += "今日已取款: " + to_string(dailyWithdrawn) + "元\n";receipt += "交易历史:\n" + transactionHistory;receipt += "==========================";UpdateInfoText(hwnd, receipt);
}// 更新信息文本
void UpdateInfoText(HWND hwnd, const string& text) {HWND hInfo = GetDlgItem(hwnd, ID_INFO_TEXT);SetWindowText(hInfo, text.c_str());
}// 保存交易记录
void SaveTransaction(const string& transaction) {transactionHistory += GetCurrentDateTime() + " - " + transaction + "\n";
}// 获取当前日期时间
string GetCurrentDateTime() {time_t now = time(0);tm* ltm = localtime(&now);char buffer[80];strftime(buffer, 80, "%Y-%m-%d %H:%M:%S", ltm);return string(buffer);
}// 重置每日限额
void ResetDailyLimit() {time_t now = time(0);tm* ltm = localtime(&now);static int lastResetDay = ltm->tm_mday;if (ltm->tm_mday != lastResetDay) {dailyWithdrawn = 0.0;lastResetDay = ltm->tm_mday;}
}

功能模块详解

1. 系统架构

  • Windows API编程​:使用Windows原生API创建窗口应用程序
  • 面向过程设计​:采用函数模块化设计,每个功能独立实现
  • 安全机制​:密码错误锁定、取款限额等安全措施

2. 核心功能实现

用户认证模块
void ProcessLogin(HWND hwnd) {if (atmLocked) {UpdateInfoText(hwnd, "账户已锁定,请联系银行工作人员");return;}// 获取输入GetWindowText(GetDlgItem(hwnd, ID_CARD_EDIT), cardText, 20);GetWindowText(GetDlgItem(hwnd, ID_PIN_EDIT), pinText, 20);// 验证信息if (string(cardText) == CARD_NUMBER && string(pinText) == PIN) {// 登录成功处理CreateMainControls(hwnd);} else {attempts++;if (attempts >= 3) {atmLocked = true; // 锁定账户}}
}
交易处理模块
// 存款处理
balance += amount;
SaveTransaction("存款: +" + string(amountText) + "元");// 取款处理(含限额检查)
if (amount > balance) {// 余额不足
} 
else if (amount > 2000) {// 单笔超限
} 
else if (dailyWithdrawn + amount > 20000) {// 日累计超限
} 
else {balance -= amount;dailyWithdrawn += amount;SaveTransaction("取款: -" + string(amountText) + "元");
}
凭条打印模块
void PrintReceipt(HWND hwnd) {string receipt = "====== 银行交易凭条 ======\n";receipt += "时间: " + GetCurrentDateTime() + "\n";receipt += "卡号: " + CARD_NUMBER + "\n";receipt += "当前余额: " + to_string(balance) + "元\n";receipt += "今日已取款: " + to_string(dailyWithdrawn) + "元\n";receipt += "交易历史:\n" + transactionHistory;// ...
}

3. 界面设计

  • 分层界面​:登录界面 → 主菜单 → 交易界面
  • 控件管理​:动态创建/销毁控件实现界面切换
  • 信息反馈​:实时更新信息区域提供操作反馈

4. 安全机制

  1. 密码保护​:三次错误尝试锁定账户
  2. 取款限额​:
    • 单笔 ≤ 2000元
    • 每日累计 ≤ 20000元
  3. 交易记录​:完整记录所有操作供审计
  4. 日限额重置​:每日自动重置取款额度
void ResetDailyLimit() {time_t now = time(0);tm* ltm = localtime(&now);static int lastResetDay = ltm->tm_mday;if (ltm->tm_mday != lastResetDay) {dailyWithdrawn = 0.0; // 重置日取款额}
}

编译与运行说明

 1.​开发环境​: 

  • Windows系统
  • 支持Windows API的编译器(如MinGW、Visual Studio)

 ​2.编译命令​(g++): 

g++ atm.cpp -o atm.exe -luser32 -lgdi32 -lcomctl32

  3.运行​: 

  • 直接执行生成的atm.exe
  • 测试账号:1234567890
  • 测试密码:1234

扩展建议

  1. 数据库集成​:使用SQLite存储多用户账户信息
  2. 文件存储​:交易记录保存到文件
  3. 界面美化​:添加图标、背景图片
  4. 网络功能​:连接银行服务器验证账户
  5. 语音提示​:增加操作语音提示

本ATM模拟系统完整实现了银行自动柜员机的基本功能,代码结构清晰,模块划分明确,适合学习Windows API编程和金融系统原理。

通过添加异常处理和文件存储,可以进一步增强系统健壮性和实用性

复习要点

  1. Windows API窗口创建流程
  2. 消息循环处理机制
  3. 控件动态管理技术
  4. 金融系统安全设计原则
  5. 交易事务处理逻辑
  6. 时间处理与限额重置机制

如需进一步扩展功能,可以考虑添加转账、修改密码等功能模块

资源推荐:

C/C++学习交流君羊 << 点击加入

C/C++教程

http://www.lqws.cn/news/530533.html

相关文章:

  • 机器学习15-规则学习-知识加强
  • MySQL-主从复制分库分表
  • WebSocket 与 HTTP 的区别及 Spring Boot 实战应用
  • 如何将视频从 iPhone 发送到 Android 设备
  • Midscene.js:使用 LLMs.txt 快速生成 AI 自动化测试用例「喂饭教程」
  • pyhton自动化采集数据脚本
  • 实现Taro小程序+nut-ui左滑删除效果
  • Go 语言中的指针
  • Java+Vue开发的SRM企业招采管理系统,一站式管理招采,助力企业高效运营
  • VC formal document and examples
  • 先考 HCIA 还是直接考 HCIP?网络工程师认证选择指南
  • 深入剖析Nginx架构及其不同使用场景下的配置
  • 蜂鸟代理IP+云手机:跨境电商多账号运营的“隐形风控引擎”
  • 手机控车一键启动汽车智能钥匙
  • Java Lambda表达式
  • CMake实践:安装与配置
  • 基于vue3+ByteMD快速搭建自己的Markdown文档编辑器
  • MySQL 中的锁机制详解:原理、实现方式与实战解析!
  • MySQL多表关系
  • Nordic 电源管理nPM1300 EK评估板介绍
  • 大模型在慢性病毒性肝炎预测及诊疗方案制定中的应用研究
  • 频宽是什么: 0.35/Tr、0.5/Tr?
  • 第七章---软件实现与编码
  • 关于 ARM64 汇编:调用流程与栈帧结构解析
  • 酒店智能门锁系统常见问题解决方法——东方仙盟
  • zookeeper总是重启失败
  • Golang是什么
  • AI代码编程工具:开启智能编程新时代
  • uniapp微信小程序:editor组件placeholder字体样式修改
  • Spring Boot 中使用 Jackson 实现全局时间格式处理(支持多格式反序列化)