当前位置: 首页 > 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++教程

相关文章:

  • 【论文】云原生事件驱动架构在智能风控系统中的实践与思考
  • 抖音图文带货和短视频带货有什么区别
  • 玄机抽奖Spring Web项目
  • 9. 回文数
  • linux网络编程socket套接字
  • 与 AI 聊天更顺畅:cat_code.py
  • MySQL5.7和8.0 破解root密码
  • C++ STL ——string的使用讲解及其底层实现
  • react-嵌套路由 二级路由
  • 128K 长文本处理实战:腾讯混元 + 云函数 SCF 构建 PDF 摘要生成器
  • Spring Cloud Config动态刷新实战指南
  • CyberGlove触觉反馈手套遥操作机器人灵巧手解决方案
  • java中的anyMatch和allMatch方法
  • [3D-portfolio] 版块包装高阶组件(封装到HOC) | Email表单逻辑 | 链式调用
  • 【Electron】electron+react的插件@electron/remote用法,在渲染进程直接调用主进程的API
  • 码蹄集:MT2045斐波那契,但是是字符串
  • Java设计模式->责任链模式的介绍
  • Java 编程之备忘录模式
  • SQL学习笔记3
  • LeetCode--37.解数独