You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1568 lines
65 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <graphics.h>
#include <conio.h>
#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include <windows.h>
#include <tchar.h>
using namespace std;
// 全局常量定义
#define WIN_WIDTH 800
#define WIN_HEIGHT 600
#define FONT_SIZE 16
#define COLOR_BG RGB(245, 245, 245) // 背景色
#define COLOR_MENU RGB(60, 179, 113) // 菜单底色
#define COLOR_TEXT RGB(255, 255, 255) // 文字白色
#define COLOR_BLACK RGB(0, 0, 0) // 黑色
#define COLOR_RED RGB(255, 0, 0) // 红色
#define COLOR_BLUE RGB(0, 0, 255) // 蓝色
#define COLOR_GRAY RGB(200, 200, 200) // 灰色
// 输入焦点枚举(统一管理所有输入框焦点)
enum InputFocusType {
FOCUS_NONE, // 无焦点
FOCUS_LOGIN_PWD, // 登录密码框
FOCUS_COURSE_NUM, // 课程编号(添加/修改)
FOCUS_COURSE_NAME, // 课程名称
FOCUS_COURSE_CREDIT,// 课程学分
FOCUS_COURSE_TEACHER,// 授课教师
FOCUS_DEL_COURSE_NUM,// 删除课程编号
FOCUS_EDIT_COURSE_NUM,// 修改课程-查询编号
FOCUS_STU_NUM, // 学生学号
FOCUS_STU_NAME, // 学生姓名
FOCUS_STU_SEX, // 学生性别
FOCUS_STU_GRADE, // 学生年级
FOCUS_STU_SELECT_STU_NUM,// 选课-学生学号
FOCUS_STU_SELECT_COURSE_NUM,// 选课-课程编号
FOCUS_CHANGE_PWD_OLD, // 修改密码-旧密码
FOCUS_CHANGE_PWD_NEW1, // 修改密码-新密码
FOCUS_CHANGE_PWD_NEW2, // 修改密码-确认密码
FOCUS_DEL_STU_NUM // 删除学生学号
};
// 全局变量
string adminPwd = "1234"; // 管理员密码
bool isLogin = false; // 登录状态
string inputBuffer = ""; // 通用输入缓冲区
string tempStr1 = ""; // 临时输入1
string tempStr2 = ""; // 临时输入2
string tempStr3 = ""; // 临时输入3
int currentMenu = 0; // 当前菜单0-登录 1-主菜单 2-课程管理 3-学生管理 4-修改密码
InputFocusType currentFocus = FOCUS_NONE; // 当前输入焦点
DWORD lastCursorTime = 0; // 光标闪烁计时
bool showCursor = true; // 光标显示状态
// 键盘输入防抖标记
bool keyBackPressed = false;
bool keyEnterPressed = false;
bool charKeysPressed[95] = { false }; // 32-126可打印字符防抖
bool ctrlPressed = false; // Ctrl键状态用于粘贴功能
bool vPressed = false; // V键状态用于粘贴功能
// 信息基类
class info {
protected:
long number; // 编号
string name; // 名称
public:
info() {}
info(long num, string name) : number(num), name(name) {}
long getNumber() { return number; }
string getName() { return name; }
void setName(string n) { name = n; }
};
// 课程类
class course : public info {
private:
int credit; // 学分
string teachername; // 授课教师
public:
course() {}
course(long num, string name, int cre, string tea) : info(num, name) {
credit = cre;
teachername = tea;
}
int getCredit() { return credit; }
string getTeacher() { return teachername; }
void setCredit(int c) { credit = c; }
void setTeacher(string t) { teachername = t; }
// 静态方法声明
static void addCourse(long num, string name, int cre, string tea);
static void delCourse(long num);
static void editCourse(long num, string name, int cre, string tea);
static bool isHave(long num);
static course* getCourse(long num);
static vector<course>& getCourseList();
};
// 学生类
class student : public info {
private:
string sex; // 性别
string grade; // 年级
long scredit; // 总学分
vector<course> havec;// 已选课程
public:
student() {}
student(long num, string name, string se, string gra, long scr = 0) : info(num, name) {
sex = se;
grade = gra;
scredit = scr;
}
string getSex() { return sex; }
string getGrade() { return grade; }
long getSCredit() { return scredit; }
vector<course>& getHaveC() { return havec; }
void setSex(string s) { sex = s; }
void setGrade(string g) { grade = g; }
void setSCredit(long sc) { scredit = sc; }
// 静态方法声明
static void addStudent(long num, string name, string se, string gra);
static void delStudent(long num);
static void editStudent(long num, string name, string se, string gra);
static bool isHave(long num);
static student* getStudent(long num);
static vector<student>& getStudentList();
static void addCourseToStudent(long stuNum, long courseNum);
static void delCourseFromStudent(long stuNum, long courseNum);
};
// 全局容器
vector<course> courseList;
vector<student> studentList;
// 课程类静态方法实现
vector<course>& course::getCourseList() { return courseList; }
void course::addCourse(long num, string name, int cre, string tea) {
courseList.push_back(course(num, name, cre, tea));
}
void course::delCourse(long num) {
for (auto it = courseList.begin(); it != courseList.end(); it++) {
if (it->getNumber() == num) {
courseList.erase(it);
break;
}
}
}
void course::editCourse(long num, string name, int cre, string tea) {
for (auto& c : courseList) {
if (c.getNumber() == num) {
if (!name.empty()) c.setName(name);
if (cre > 0) c.setCredit(cre);
if (!tea.empty()) c.setTeacher(tea);
break;
}
}
}
bool course::isHave(long num) {
for (auto& c : courseList) {
if (c.getNumber() == num) return true;
}
return false;
}
course* course::getCourse(long num) {
for (auto& c : courseList) {
if (c.getNumber() == num) return &c;
}
return nullptr;
}
// 学生类静态方法实现
vector<student>& student::getStudentList() { return studentList; }
void student::addStudent(long num, string name, string se, string gra) {
studentList.push_back(student(num, name, se, gra));
}
void student::delStudent(long num) {
for (auto it = studentList.begin(); it != studentList.end(); it++) {
if (it->getNumber() == num) {
studentList.erase(it);
break;
}
}
}
void student::editStudent(long num, string name, string se, string gra) {
for (auto& s : studentList) {
if (s.getNumber() == num) {
if (!name.empty()) s.setName(name);
if (!se.empty()) s.setSex(se);
if (!gra.empty()) s.setGrade(gra);
break;
}
}
}
bool student::isHave(long num) {
for (auto& s : studentList) {
if (s.getNumber() == num) return true;
}
return false;
}
student* student::getStudent(long num) {
for (auto& s : studentList) {
if (s.getNumber() == num) return &s;
}
return nullptr;
}
void student::addCourseToStudent(long stuNum, long courseNum) {
student* stu = getStudent(stuNum);
course* crs = course::getCourse(courseNum);
if (stu && crs) {
// 检查是否已选
for (auto& c : stu->getHaveC()) {
if (c.getNumber() == courseNum) return;
}
stu->getHaveC().push_back(*crs);
}
}
void student::delCourseFromStudent(long stuNum, long courseNum) {
student* stu = getStudent(stuNum);
if (stu) {
for (auto it = stu->getHaveC().begin(); it != stu->getHaveC().end(); it++) {
if (it->getNumber() == courseNum) {
stu->getHaveC().erase(it);
break;
}
}
}
}
// 工具函数:绘制按钮
void drawButton(int x, int y, int w, int h, const TCHAR* text, COLORREF bgColor, COLORREF textColor) {
setfillcolor(bgColor);
solidroundrect(x, y, x + w, y + h, 10, 10);
settextcolor(textColor);
setbkmode(TRANSPARENT);
settextstyle(FONT_SIZE, 0, _T("微软雅黑"));
outtextxy(x + w / 2 - textwidth(text) / 2, y + h / 2 - textheight(text) / 2, text);
}
// 工具函数:检查鼠标是否点击按钮/输入框
bool isClickArea(int x, int y, int w, int h, int mouseX, int mouseY) {
return (mouseX >= x && mouseX <= x + w && mouseY >= y && mouseY <= y + h);
}
// 工具函数:数字转字符串
string num2str(long num) {
stringstream ss;
ss << num;
return ss.str();
}
// 工具函数:字符串转数字
long str2num(string str) {
if (str.empty()) return 0;
long num;
stringstream ss(str);
ss >> num;
return num;
}
// 工具函数:更新光标闪烁状态
void updateCursor() {
DWORD currentTime = GetTickCount();
if (currentTime - lastCursorTime > 500) { // 500ms闪烁一次
showCursor = !showCursor;
lastCursorTime = currentTime;
}
}
// 工具函数:绘制输入框(带焦点和光标)
void drawInputBox(int x, int y, int w, int h, const TCHAR* hint, string& inputStr, bool isFocused, bool isPassword = false) {
// 绘制输入框边框
setlinecolor(COLOR_BLACK);
rectangle(x, y, x + w, y + h);
// 绘制提示文字/输入内容
settextcolor(isFocused ? COLOR_BLACK : RGB(160, 160, 160));
settextstyle(FONT_SIZE, 0, _T("微软雅黑"));
TCHAR showBuf[256] = { 0 };
if (inputStr.empty()) {
outtextxy(x + 10, y + h / 2 - textheight(hint) / 2, hint);
}
else {
if (isPassword) {
// 密码框显示星号
string pwdStars(inputStr.length(), '*');
MultiByteToWideChar(CP_ACP, 0, pwdStars.c_str(), -1, showBuf, 256);
}
else {
MultiByteToWideChar(CP_ACP, 0, inputStr.c_str(), -1, showBuf, 256);
}
outtextxy(x + 10, y + h / 2 - textheight(showBuf) / 2, showBuf);
}
// 绘制闪烁光标(仅焦点时)
if (isFocused && showCursor) {
int cursorX = x + 10 + (inputStr.empty() ? 0 : textwidth(showBuf)) + 2;
setlinecolor(COLOR_BLACK);
line(cursorX, y + 5, cursorX, y + h - 5);
}
}
// 工具函数:创建支持中文输入的输入框
string createInputBox(const string& title, const string& hint, bool showCurrentValue = false, string currentValue = "") {
TCHAR tTitle[256], tHint[256], tResult[1024] = { 0 };
// 转换字符串为TCHAR
MultiByteToWideChar(CP_ACP, 0, title.c_str(), -1, tTitle, 256);
MultiByteToWideChar(CP_ACP, 0, hint.c_str(), -1, tHint, 256);
// 如果显示当前值,设置到结果中
if (showCurrentValue && !currentValue.empty()) {
MultiByteToWideChar(CP_ACP, 0, currentValue.c_str(), -1, tResult, 1024);
}
// 显示输入框(支持中文输入)
int ret = InputBox(tResult, 1024, tTitle, tHint);
if (ret == IDOK) {
// 转换结果回string
char buf[1024];
WideCharToMultiByte(CP_ACP, 0, tResult, -1, buf, 1024, NULL, NULL);
return string(buf);
}
return "";
}
// 工具函数:重置所有键盘防抖标记
void resetKeyFlags() {
keyBackPressed = false;
keyEnterPressed = false;
memset(charKeysPressed, 0, sizeof(charKeysPressed));
}
// 工具函数:统一处理键盘输入(适配所有输入框)
void handleKeyboardInput() {
// 处理退格键(所有焦点通用)- 防抖处理
if ((GetAsyncKeyState(VK_BACK) & 0x8000) && !keyBackPressed) {
keyBackPressed = true;
switch (currentFocus) {
case FOCUS_LOGIN_PWD: if (!inputBuffer.empty()) inputBuffer.pop_back(); break;
case FOCUS_CHANGE_PWD_OLD: if (!inputBuffer.empty()) inputBuffer.pop_back(); break;
case FOCUS_CHANGE_PWD_NEW1: if (!tempStr1.empty()) tempStr1.pop_back(); break;
case FOCUS_CHANGE_PWD_NEW2: if (!tempStr2.empty()) tempStr2.pop_back(); break;
case FOCUS_COURSE_NUM: if (!inputBuffer.empty()) inputBuffer.pop_back(); break;
case FOCUS_COURSE_CREDIT: if (!tempStr2.empty()) tempStr2.pop_back(); break;
case FOCUS_DEL_COURSE_NUM: if (!inputBuffer.empty()) inputBuffer.pop_back(); break;
case FOCUS_EDIT_COURSE_NUM: if (!inputBuffer.empty()) inputBuffer.pop_back(); break;
case FOCUS_STU_NUM: if (!inputBuffer.empty()) inputBuffer.pop_back(); break;
case FOCUS_STU_SELECT_STU_NUM: if (!inputBuffer.empty()) inputBuffer.pop_back(); break;
case FOCUS_STU_SELECT_COURSE_NUM: if (!tempStr1.empty()) tempStr1.pop_back(); break;
case FOCUS_DEL_STU_NUM: if (!inputBuffer.empty()) inputBuffer.pop_back(); break;
default: break;
}
}
else if (!(GetAsyncKeyState(VK_BACK) & 0x8000)) {
keyBackPressed = false;
}
// 仅处理可打印字符32-126- 防抖处理(仅限不需要中文输入的字段)
for (int i = 0; i < 95; i++) {
char c = 32 + i;
if ((GetAsyncKeyState(c) & 0x8000) && !charKeysPressed[i]) {
charKeysPressed[i] = true;
// 根据焦点过滤字符类型
switch (currentFocus) {
// 仅允许数字
case FOCUS_COURSE_NUM:
case FOCUS_DEL_COURSE_NUM:
case FOCUS_EDIT_COURSE_NUM:
case FOCUS_STU_NUM:
case FOCUS_STU_SELECT_STU_NUM:
case FOCUS_STU_SELECT_COURSE_NUM:
case FOCUS_COURSE_CREDIT:
case FOCUS_DEL_STU_NUM:
if (c >= '0' && c <= '9') {
if (currentFocus == FOCUS_COURSE_CREDIT) tempStr2 += c;
else inputBuffer += c;
}
break;
// 允许所有字符(密码框)
case FOCUS_LOGIN_PWD: inputBuffer += c; break;
case FOCUS_CHANGE_PWD_OLD: inputBuffer += c; break;
case FOCUS_CHANGE_PWD_NEW1: tempStr1 += c; break;
case FOCUS_CHANGE_PWD_NEW2: tempStr2 += c; break;
default: break;
}
}
else if (!(GetAsyncKeyState(c) & 0x8000)) {
charKeysPressed[i] = false;
}
}
}
// 登录界面(包含退出系统按钮)
void drawLogin() {
BeginBatchDraw();
cleardevice();
setbkcolor(COLOR_BG);
// 绘制标题
settextcolor(COLOR_MENU);
settextstyle(30, 0, _T("微软雅黑"));
const TCHAR* title = _T("学生选课管理系统-管理员端");
outtextxy(WIN_WIDTH / 2 - textwidth(title) / 2, 100, title);
// 绘制密码输入框
int inputX = WIN_WIDTH / 2 - 150;
int inputY = 200;
int inputW = 300;
int inputH = 40;
drawInputBox(inputX, inputY, inputW, inputH, _T("请输入管理员密码"), inputBuffer, currentFocus == FOCUS_LOGIN_PWD, true);
// 绘制登录按钮
drawButton(WIN_WIDTH / 2 - 80, 280, 160, 40, _T("登录"), COLOR_MENU, COLOR_TEXT);
// 绘制退出系统按钮
drawButton(WIN_WIDTH / 2 - 80, 340, 160, 40, _T("退出系统"), RGB(220, 100, 100), COLOR_TEXT);
// 处理鼠标事件
if (MouseHit()) {
MOUSEMSG msg = GetMouseMsg();
if (msg.uMsg == WM_LBUTTONDOWN) {
resetKeyFlags();
if (isClickArea(WIN_WIDTH / 2 - 80, 280, 160, 40, msg.x, msg.y)) {
if (inputBuffer == adminPwd) {
isLogin = true;
currentMenu = 1;
inputBuffer = "";
currentFocus = FOCUS_NONE;
}
else {
settextcolor(COLOR_RED);
const TCHAR* err = _T("密码错误请输入1234");
outtextxy(WIN_WIDTH / 2 - textwidth(err) / 2, 410, err);
inputBuffer = "";
}
Sleep(200);
}
else if (isClickArea(WIN_WIDTH / 2 - 80, 340, 160, 40, msg.x, msg.y)) {
closegraph();
exit(0);
}
else if (isClickArea(inputX, inputY, inputW, inputH, msg.x, msg.y)) {
currentFocus = FOCUS_LOGIN_PWD;
lastCursorTime = GetTickCount();
}
else {
currentFocus = FOCUS_NONE;
}
}
}
// 处理键盘输入
if (currentFocus == FOCUS_LOGIN_PWD) {
handleKeyboardInput();
if ((GetAsyncKeyState(VK_RETURN) & 0x8000) && !keyEnterPressed) {
keyEnterPressed = true;
if (inputBuffer == adminPwd) {
isLogin = true;
currentMenu = 1;
inputBuffer = "";
currentFocus = FOCUS_NONE;
}
else {
settextcolor(COLOR_RED);
const TCHAR* err = _T("密码错误请输入1234");
outtextxy(WIN_WIDTH / 2 - textwidth(err) / 2, 410, err);
inputBuffer = "";
}
Sleep(200);
}
else if (!(GetAsyncKeyState(VK_RETURN) & 0x8000)) {
keyEnterPressed = false;
}
}
FlushBatchDraw();
EndBatchDraw();
Sleep(10);
}
// 修改密码界面
void drawChangePassword() {
BeginBatchDraw();
cleardevice();
setbkcolor(COLOR_BG);
// 标题
settextcolor(COLOR_MENU);
settextstyle(30, 0, _T("微软雅黑"));
const TCHAR* title = _T("修改密码");
outtextxy(WIN_WIDTH / 2 - textwidth(title) / 2, 50, title);
// 返回按钮
drawButton(20, 20, 80, 30, _T("返回"), COLOR_GRAY, COLOR_BLACK);
// 输入框位置
int inputX = WIN_WIDTH / 2 - 150;
int inputW = 300;
int inputH = 40;
// 旧密码
settextcolor(COLOR_BLACK);
settextstyle(FONT_SIZE, 0, _T("微软雅黑"));
outtextxy(inputX, 130, _T("旧密码:"));
drawInputBox(inputX, 150, inputW, inputH, _T("请输入当前密码"), inputBuffer, currentFocus == FOCUS_CHANGE_PWD_OLD, true);
// 新密码
outtextxy(inputX, 210, _T("新密码:"));
drawInputBox(inputX, 230, inputW, inputH, _T("请输入新密码"), tempStr1, currentFocus == FOCUS_CHANGE_PWD_NEW1, true);
// 确认新密码
outtextxy(inputX, 290, _T("确认新密码:"));
drawInputBox(inputX, 310, inputW, inputH, _T("请再次输入新密码"), tempStr2, currentFocus == FOCUS_CHANGE_PWD_NEW2, true);
// 操作按钮
drawButton(inputX, 380, 140, 40, _T("确认修改"), COLOR_MENU, COLOR_TEXT);
drawButton(inputX + 170, 380, 140, 40, _T("取消"), COLOR_GRAY, COLOR_BLACK);
// 处理鼠标事件
if (MouseHit()) {
MOUSEMSG msg = GetMouseMsg();
if (msg.uMsg == WM_LBUTTONDOWN) {
resetKeyFlags();
// 返回按钮
if (isClickArea(20, 20, 80, 30, msg.x, msg.y)) {
currentMenu = 1;
inputBuffer = tempStr1 = tempStr2 = "";
currentFocus = FOCUS_NONE;
}
// 输入框焦点
else if (isClickArea(inputX, 150, inputW, inputH, msg.x, msg.y)) {
currentFocus = FOCUS_CHANGE_PWD_OLD;
lastCursorTime = GetTickCount();
}
else if (isClickArea(inputX, 230, inputW, inputH, msg.x, msg.y)) {
currentFocus = FOCUS_CHANGE_PWD_NEW1;
lastCursorTime = GetTickCount();
}
else if (isClickArea(inputX, 310, inputW, inputH, msg.x, msg.y)) {
currentFocus = FOCUS_CHANGE_PWD_NEW2;
lastCursorTime = GetTickCount();
}
// 确认修改按钮
else if (isClickArea(inputX, 380, 140, 40, msg.x, msg.y)) {
if (inputBuffer.empty() || tempStr1.empty() || tempStr2.empty()) {
settextcolor(COLOR_RED);
outtextxy(inputX, 480, _T("所有密码字段都不能为空!"));
}
else if (inputBuffer != adminPwd) {
settextcolor(COLOR_RED);
outtextxy(inputX, 480, _T("旧密码错误!"));
}
else if (tempStr1 != tempStr2) {
settextcolor(COLOR_RED);
outtextxy(inputX, 480, _T("两次输入的新密码不一致!"));
}
else if (tempStr1.length() < 4) {
settextcolor(COLOR_RED);
outtextxy(inputX, 480, _T("新密码长度不能少于4位"));
}
else {
adminPwd = tempStr1;
settextcolor(COLOR_MENU);
outtextxy(inputX, 480, _T("密码修改成功!"));
FlushBatchDraw();
Sleep(1000);
currentMenu = 1;
inputBuffer = tempStr1 = tempStr2 = "";
currentFocus = FOCUS_NONE;
return;
}
FlushBatchDraw();
Sleep(1000);
}
// 取消按钮
else if (isClickArea(inputX + 170, 380, 140, 40, msg.x, msg.y)) {
currentMenu = 1;
inputBuffer = tempStr1 = tempStr2 = "";
currentFocus = FOCUS_NONE;
}
}
}
// 处理键盘输入
handleKeyboardInput();
// 回车键提交
if ((GetAsyncKeyState(VK_RETURN) & 0x8000) && !keyEnterPressed) {
keyEnterPressed = true;
if (!inputBuffer.empty() && !tempStr1.empty() && !tempStr2.empty()) {
if (inputBuffer != adminPwd) {
settextcolor(COLOR_RED);
outtextxy(inputX, 480, _T("旧密码错误!"));
FlushBatchDraw();
Sleep(1000);
}
else if (tempStr1 != tempStr2) {
settextcolor(COLOR_RED);
outtextxy(inputX, 480, _T("两次输入的新密码不一致!"));
FlushBatchDraw();
Sleep(1000);
}
else if (tempStr1.length() < 4) {
settextcolor(COLOR_RED);
outtextxy(inputX, 480, _T("新密码长度不能少于4位"));
FlushBatchDraw();
Sleep(1000);
}
else {
adminPwd = tempStr1;
settextcolor(COLOR_MENU);
outtextxy(inputX, 480, _T("密码修改成功!"));
FlushBatchDraw();
Sleep(1000);
currentMenu = 1;
inputBuffer = tempStr1 = tempStr2 = "";
currentFocus = FOCUS_NONE;
}
}
}
else if (!(GetAsyncKeyState(VK_RETURN) & 0x8000)) {
keyEnterPressed = false;
}
FlushBatchDraw();
EndBatchDraw();
Sleep(10);
}
// 主菜单(现在包含退出登录)
void drawMainMenu() {
BeginBatchDraw();
cleardevice();
setbkcolor(COLOR_BG);
// 标题
settextcolor(COLOR_MENU);
settextstyle(30, 0, _T("微软雅黑"));
const TCHAR* title = _T("主菜单");
outtextxy(WIN_WIDTH / 2 - textwidth(title) / 2, 50, title);
// 功能按钮
drawButton(WIN_WIDTH / 2 - 100, 150, 200, 50, _T("课程信息管理"), COLOR_MENU, COLOR_TEXT);
drawButton(WIN_WIDTH / 2 - 100, 230, 200, 50, _T("学生信息管理"), COLOR_MENU, COLOR_TEXT);
drawButton(WIN_WIDTH / 2 - 100, 310, 200, 50, _T("修改密码"), COLOR_MENU, COLOR_TEXT);
drawButton(WIN_WIDTH / 2 - 100, 390, 200, 50, _T("退出登录"), RGB(220, 100, 100), COLOR_TEXT);
// 处理鼠标事件
if (MouseHit()) {
MOUSEMSG msg = GetMouseMsg();
if (msg.uMsg == WM_LBUTTONDOWN) {
resetKeyFlags();
currentFocus = FOCUS_NONE;
if (isClickArea(WIN_WIDTH / 2 - 100, 150, 200, 50, msg.x, msg.y)) {
currentMenu = 2;
inputBuffer = tempStr1 = tempStr2 = tempStr3 = "";
}
else if (isClickArea(WIN_WIDTH / 2 - 100, 230, 200, 50, msg.x, msg.y)) {
currentMenu = 3;
inputBuffer = tempStr1 = tempStr2 = tempStr3 = "";
}
else if (isClickArea(WIN_WIDTH / 2 - 100, 310, 200, 50, msg.x, msg.y)) {
currentMenu = 4;
inputBuffer = tempStr1 = tempStr2 = "";
currentFocus = FOCUS_NONE;
}
else if (isClickArea(WIN_WIDTH / 2 - 100, 390, 200, 50, msg.x, msg.y)) {
isLogin = false;
currentMenu = 0;
inputBuffer = "";
}
}
}
FlushBatchDraw();
EndBatchDraw();
Sleep(10);
}
// 课程管理界面
void drawCourseMenu() {
BeginBatchDraw();
cleardevice();
setbkcolor(COLOR_BG);
// 标题与返回按钮
settextcolor(COLOR_MENU);
settextstyle(30, 0, _T("微软雅黑"));
const TCHAR* title = _T("课程信息管理");
outtextxy(WIN_WIDTH / 2 - textwidth(title) / 2, 30, title);
drawButton(20, 20, 80, 30, _T("返回"), COLOR_GRAY, COLOR_BLACK);
// 功能按钮
drawButton(50, 100, 120, 40, _T("添加课程"), COLOR_MENU, COLOR_TEXT);
drawButton(200, 100, 120, 40, _T("删除课程"), COLOR_MENU, COLOR_TEXT);
drawButton(350, 100, 120, 40, _T("修改课程"), COLOR_MENU, COLOR_TEXT);
drawButton(500, 100, 120, 40, _T("查看所有课程"), COLOR_MENU, COLOR_TEXT);
// 处理鼠标事件
if (MouseHit()) {
MOUSEMSG msg = GetMouseMsg();
if (msg.uMsg == WM_LBUTTONDOWN) {
resetKeyFlags();
currentFocus = FOCUS_NONE;
if (isClickArea(20, 20, 80, 30, msg.x, msg.y)) {
currentMenu = 1;
inputBuffer = tempStr1 = tempStr2 = tempStr3 = "";
return;
}
// 添加课程
else if (isClickArea(50, 100, 120, 40, msg.x, msg.y)) {
inputBuffer = tempStr1 = tempStr2 = tempStr3 = "";
bool waitInput = true;
while (waitInput) {
BeginBatchDraw();
cleardevice();
settextcolor(COLOR_BLACK);
int numX = 150, numY = 95;
int nameX = 150, nameY = 155;
int creditX = 150, creditY = 215;
int teacherX = 150, teacherY = 275;
int inputW = 200, inputH = 40;
outtextxy(50, 50, _T("添加课程"));
outtextxy(50, 100, _T("课程编号:"));
drawInputBox(numX, numY, inputW, inputH, _T("数字编号"), inputBuffer, currentFocus == FOCUS_COURSE_NUM);
outtextxy(50, 160, _T("课程名称:"));
// 显示当前课程名称(如果有)
TCHAR nameDisplay[256] = { 0 };
if (!tempStr1.empty()) {
MultiByteToWideChar(CP_ACP, 0, tempStr1.c_str(), -1, nameDisplay, 256);
}
setlinecolor(COLOR_BLACK);
rectangle(nameX, nameY, nameX + inputW, nameY + inputH);
if (tempStr1.empty()) {
settextcolor(RGB(160, 160, 160));
outtextxy(nameX + 10, nameY + inputH / 2 - textheight(_T("点击输入课程名称")) / 2, _T("点击输入课程名称"));
}
else {
settextcolor(COLOR_BLACK);
outtextxy(nameX + 10, nameY + inputH / 2 - textheight(nameDisplay) / 2, nameDisplay);
}
outtextxy(50, 220, _T("课程学分:"));
drawInputBox(creditX, creditY, inputW, inputH, _T("数字"), tempStr2, currentFocus == FOCUS_COURSE_CREDIT);
outtextxy(50, 280, _T("授课教师:"));
// 显示当前授课教师(如果有)
TCHAR teacherDisplay[256] = { 0 };
if (!tempStr3.empty()) {
MultiByteToWideChar(CP_ACP, 0, tempStr3.c_str(), -1, teacherDisplay, 256);
}
rectangle(teacherX, teacherY, teacherX + inputW, teacherY + inputH);
if (tempStr3.empty()) {
settextcolor(RGB(160, 160, 160));
outtextxy(teacherX + 10, teacherY + inputH / 2 - textheight(_T("点击输入授课教师")) / 2, _T("点击输入授课教师"));
}
else {
settextcolor(COLOR_BLACK);
outtextxy(teacherX + 10, teacherY + inputH / 2 - textheight(teacherDisplay) / 2, teacherDisplay);
}
// 中文输入提示
settextcolor(COLOR_BLUE);
outtextxy(50, 330, _T("提示:点击课程名称或授课教师输入框可弹出中文输入窗口"));
settextcolor(COLOR_BLACK);
drawButton(150, 370, 100, 40, _T("确认添加"), COLOR_MENU, COLOR_TEXT);
drawButton(270, 370, 100, 40, _T("取消"), COLOR_GRAY, COLOR_BLACK);
FlushBatchDraw();
EndBatchDraw();
if (MouseHit()) {
MOUSEMSG msg2 = GetMouseMsg();
if (msg2.uMsg == WM_LBUTTONDOWN) {
resetKeyFlags();
if (isClickArea(numX, numY, inputW, inputH, msg2.x, msg2.y)) {
currentFocus = FOCUS_COURSE_NUM;
lastCursorTime = GetTickCount();
}
else if (isClickArea(nameX, nameY, inputW, inputH, msg2.x, msg2.y)) {
currentFocus = FOCUS_NONE;
string result = createInputBox("输入课程名称", "请输入课程名称(如:数据结构):");
if (!result.empty()) {
tempStr1 = result;
}
}
else if (isClickArea(creditX, creditY, inputW, inputH, msg2.x, msg2.y)) {
currentFocus = FOCUS_COURSE_CREDIT;
lastCursorTime = GetTickCount();
}
else if (isClickArea(teacherX, teacherY, inputW, inputH, msg2.x, msg2.y)) {
currentFocus = FOCUS_NONE;
string result = createInputBox("输入授课教师", "请输入授课教师姓名:");
if (!result.empty()) {
tempStr3 = result;
}
}
else if (isClickArea(150, 370, 100, 40, msg2.x, msg2.y)) {
long num = str2num(inputBuffer);
int credit = str2num(tempStr2);
if (!course::isHave(num) && !inputBuffer.empty() && !tempStr1.empty() && !tempStr2.empty()) {
course::addCourse(num, tempStr1, credit, tempStr3);
MessageBox(GetHWnd(), _T("课程添加成功!"), _T("提示"), MB_OK | MB_ICONINFORMATION);
waitInput = false;
currentMenu = 2;
currentFocus = FOCUS_NONE;
}
else {
MessageBox(GetHWnd(), _T("编号重复或信息不完整!"), _T("错误"), MB_OK | MB_ICONWARNING);
}
}
else if (isClickArea(270, 370, 100, 40, msg2.x, msg2.y)) {
waitInput = false;
currentMenu = 2;
currentFocus = FOCUS_NONE;
}
}
}
handleKeyboardInput();
updateCursor();
Sleep(10);
}
}
// 删除课程
else if (isClickArea(200, 100, 120, 40, msg.x, msg.y)) {
inputBuffer = "";
bool waitInput = true;
while (waitInput) {
BeginBatchDraw();
cleardevice();
settextcolor(COLOR_BLACK);
int numX = 150, numY = 95;
int inputW = 200, inputH = 40;
outtextxy(50, 50, _T("删除课程"));
outtextxy(50, 100, _T("课程编号:"));
drawInputBox(numX, numY, inputW, inputH, _T("输入要删除的编号"), inputBuffer, currentFocus == FOCUS_DEL_COURSE_NUM);
drawButton(150, 180, 100, 40, _T("确认删除"), COLOR_MENU, COLOR_TEXT);
drawButton(270, 180, 100, 40, _T("取消"), COLOR_GRAY, COLOR_BLACK);
FlushBatchDraw();
EndBatchDraw();
if (MouseHit()) {
MOUSEMSG msg2 = GetMouseMsg();
if (msg2.uMsg == WM_LBUTTONDOWN) {
resetKeyFlags();
if (isClickArea(numX, numY, inputW, inputH, msg2.x, msg2.y)) {
currentFocus = FOCUS_DEL_COURSE_NUM;
lastCursorTime = GetTickCount();
}
else if (isClickArea(150, 180, 100, 40, msg2.x, msg2.y)) {
long num = str2num(inputBuffer);
if (course::isHave(num)) {
course::delCourse(num);
MessageBox(GetHWnd(), _T("课程删除成功!"), _T("提示"), MB_OK | MB_ICONINFORMATION);
waitInput = false;
currentMenu = 2;
currentFocus = FOCUS_NONE;
}
else {
MessageBox(GetHWnd(), _T("课程不存在!"), _T("错误"), MB_OK | MB_ICONWARNING);
}
}
else if (isClickArea(270, 180, 100, 40, msg2.x, msg2.y)) {
waitInput = false;
currentMenu = 2;
currentFocus = FOCUS_NONE;
}
}
}
handleKeyboardInput();
updateCursor();
Sleep(10);
}
}
// 修改课程
else if (isClickArea(350, 100, 120, 40, msg.x, msg.y)) {
inputBuffer = tempStr1 = tempStr2 = tempStr3 = "";
bool waitInput = true;
bool isEditMode = false; // 是否进入编辑模式
course* targetCourse = nullptr;
while (waitInput) {
BeginBatchDraw();
cleardevice();
settextcolor(COLOR_BLACK);
if (!isEditMode) {
// 第一步:输入要修改的课程编号
int numX = 150, numY = 95;
int inputW = 200, inputH = 40;
outtextxy(50, 50, _T("修改课程-查询"));
outtextxy(50, 100, _T("课程编号:"));
drawInputBox(numX, numY, inputW, inputH, _T("输入要修改的编号"), inputBuffer, currentFocus == FOCUS_EDIT_COURSE_NUM);
drawButton(150, 180, 100, 40, _T("查询"), COLOR_MENU, COLOR_TEXT);
drawButton(270, 180, 100, 40, _T("取消"), COLOR_GRAY, COLOR_BLACK);
// 显示提示
if (!inputBuffer.empty() && !course::isHave(str2num(inputBuffer))) {
settextcolor(COLOR_RED);
outtextxy(150, 240, _T("课程编号不存在!"));
}
}
else {
// 第二步:编辑课程信息
outtextxy(50, 50, _T("修改课程-编辑"));
// 显示当前课程信息
// 显示当前课程信息
settextstyle(16, 0, _T("微软雅黑"));
int infoY = 100;
outtextxy(50, infoY, _T("当前课程信息:"));
infoY += 40;
// 输出编号
TCHAR numText[100];
swprintf_s(numText, _T("编号:%ld"), targetCourse->getNumber());
outtextxy(50, infoY, numText);
infoY += 30;
// 输出名称
TCHAR nameText[100];
swprintf_s(nameText, _T("名称:"));
outtextxy(50, infoY, nameText);
// 转换课程名称
TCHAR courseName[100];
MultiByteToWideChar(CP_ACP, 0, targetCourse->getName().c_str(), -1, courseName, 100);
outtextxy(150, infoY, courseName);
infoY += 30;
// 输出学分
TCHAR creditText[100];
swprintf_s(creditText, _T("学分:%d"), targetCourse->getCredit());
outtextxy(50, infoY, creditText);
infoY += 30;
// 输出教师
TCHAR teacherText[100];
swprintf_s(teacherText, _T("教师:"));
outtextxy(50, infoY, teacherText);
// 转换教师名称
TCHAR teacherName[100];
MultiByteToWideChar(CP_ACP, 0, targetCourse->getTeacher().c_str(), -1, teacherName, 100);
outtextxy(150, infoY, teacherName);
infoY += 30;
// 修改按钮
drawButton(50, 250, 120, 40, _T("修改名称"), COLOR_MENU, COLOR_TEXT);
drawButton(200, 250, 120, 40, _T("修改学分"), COLOR_MENU, COLOR_TEXT);
drawButton(350, 250, 120, 40, _T("修改教师"), COLOR_MENU, COLOR_TEXT);
drawButton(500, 250, 120, 40, _T("完成"), COLOR_GRAY, COLOR_BLACK);
drawButton(500, 300, 120, 40, _T("取消"), COLOR_RED, COLOR_TEXT);
// 提示信息
settextcolor(COLOR_BLUE);
outtextxy(50, 320, _T("提示:点击相应按钮可修改对应信息"));
settextcolor(COLOR_BLACK);
}
FlushBatchDraw();
EndBatchDraw();
if (MouseHit()) {
MOUSEMSG msg2 = GetMouseMsg();
if (msg2.uMsg == WM_LBUTTONDOWN) {
resetKeyFlags();
if (!isEditMode) {
// 查询阶段
int numX = 150, numY = 95, inputW = 200, inputH = 40;
if (isClickArea(numX, numY, inputW, inputH, msg2.x, msg2.y)) {
currentFocus = FOCUS_EDIT_COURSE_NUM;
lastCursorTime = GetTickCount();
}
else if (isClickArea(150, 180, 100, 40, msg2.x, msg2.y)) {
long num = str2num(inputBuffer);
if (course::isHave(num)) {
targetCourse = course::getCourse(num);
isEditMode = true;
currentFocus = FOCUS_NONE;
// 初始化临时变量
tempStr1 = targetCourse->getName();
tempStr2 = num2str(targetCourse->getCredit());
tempStr3 = targetCourse->getTeacher();
}
}
else if (isClickArea(270, 180, 100, 40, msg2.x, msg2.y)) {
waitInput = false;
currentMenu = 2;
currentFocus = FOCUS_NONE;
}
}
else {
// 编辑阶段
if (isClickArea(50, 250, 120, 40, msg2.x, msg2.y)) {
// 修改课程名称
string newName = createInputBox("修改课程名称", "请输入新的课程名称:", true, targetCourse->getName());
if (!newName.empty()) {
tempStr1 = newName;
course::editCourse(targetCourse->getNumber(), newName, -1, "");
}
}
else if (isClickArea(200, 250, 120, 40, msg2.x, msg2.y)) {
// 修改课程学分
string newCredit = createInputBox("修改课程学分", "请输入新的学分:", true, num2str(targetCourse->getCredit()));
if (!newCredit.empty()) {
int credit = str2num(newCredit);
if (credit > 0) {
tempStr2 = newCredit;
course::editCourse(targetCourse->getNumber(), "", credit, "");
}
}
}
else if (isClickArea(350, 250, 120, 40, msg2.x, msg2.y)) {
// 修改授课教师
string newTeacher = createInputBox("修改授课教师", "请输入新的教师姓名:", true, targetCourse->getTeacher());
if (!newTeacher.empty()) {
tempStr3 = newTeacher;
course::editCourse(targetCourse->getNumber(), "", -1, newTeacher);
}
}
else if (isClickArea(500, 250, 120, 40, msg2.x, msg2.y)) {
// 完成
MessageBox(GetHWnd(), _T("课程修改完成!"), _T("提示"), MB_OK | MB_ICONINFORMATION);
waitInput = false;
currentMenu = 2;
currentFocus = FOCUS_NONE;
}
else if (isClickArea(500, 300, 120, 40, msg2.x, msg2.y)) {
// 取消
waitInput = false;
currentMenu = 2;
currentFocus = FOCUS_NONE;
}
}
}
}
handleKeyboardInput();
updateCursor();
Sleep(10);
}
}
// 查看所有课程
else if (isClickArea(500, 100, 120, 40, msg.x, msg.y)) {
bool showList = true;
while (showList) {
BeginBatchDraw();
cleardevice();
settextcolor(COLOR_BLACK);
outtextxy(50, 50, _T("所有课程信息"));
// 绘制表头
int y = 100;
settextstyle(16, 0, _T("微软雅黑"));
outtextxy(50, y, _T("编号"));
outtextxy(150, y, _T("名称"));
outtextxy(280, y, _T("学分"));
outtextxy(350, y, _T("授课教师"));
y += 30;
// 绘制课程列表
settextstyle(14, 0, _T("微软雅黑"));
if (courseList.empty()) {
outtextxy(50, y, _T("暂无课程数据!"));
}
else {
for (auto& c : course::getCourseList()) {
if (y > WIN_HEIGHT - 80) break; // 防止超出界面
TCHAR numBuf[32] = { 0 };
MultiByteToWideChar(CP_ACP, 0, num2str(c.getNumber()).c_str(), -1, numBuf, 32);
outtextxy(50, y, numBuf);
TCHAR nameBuf[64] = { 0 };
MultiByteToWideChar(CP_ACP, 0, c.getName().c_str(), -1, nameBuf, 64);
outtextxy(150, y, nameBuf);
TCHAR creditBuf[32] = { 0 };
MultiByteToWideChar(CP_ACP, 0, num2str(c.getCredit()).c_str(), -1, creditBuf, 32);
outtextxy(280, y, creditBuf);
TCHAR teacherBuf[64] = { 0 };
MultiByteToWideChar(CP_ACP, 0, c.getTeacher().c_str(), -1, teacherBuf, 64);
outtextxy(350, y, teacherBuf);
y += 25;
}
}
// 绘制返回按钮(固定在底部)
drawButton(50, WIN_HEIGHT - 60, 80, 30, _T("返回"), COLOR_GRAY, COLOR_BLACK);
FlushBatchDraw();
EndBatchDraw();
// 持续监听返回按钮点击
if (MouseHit()) {
MOUSEMSG msg2 = GetMouseMsg();
if (msg2.uMsg == WM_LBUTTONDOWN && isClickArea(50, WIN_HEIGHT - 60, 80, 30, msg2.x, msg2.y)) {
showList = false;
currentMenu = 2;
currentFocus = FOCUS_NONE;
}
}
Sleep(10); // 降低CPU占用
}
}
}
}
FlushBatchDraw();
EndBatchDraw();
Sleep(10);
}
// 学生管理界面(已修复删除学生功能)
void drawStudentMenu() {
BeginBatchDraw();
cleardevice();
setbkcolor(COLOR_BG);
// 标题与返回按钮
settextcolor(COLOR_MENU);
settextstyle(30, 0, _T("微软雅黑"));
const TCHAR* title = _T("学生信息管理");
outtextxy(WIN_WIDTH / 2 - textwidth(title) / 2, 30, title);
drawButton(20, 20, 80, 30, _T("返回"), COLOR_GRAY, COLOR_BLACK);
// 功能按钮
drawButton(50, 100, 120, 40, _T("添加学生"), COLOR_MENU, COLOR_TEXT);
drawButton(200, 100, 120, 40, _T("删除学生"), COLOR_MENU, COLOR_TEXT);
drawButton(350, 100, 120, 40, _T("学生选课"), COLOR_MENU, COLOR_TEXT);
drawButton(500, 100, 120, 40, _T("查看所有学生"), COLOR_MENU, COLOR_TEXT);
// 处理鼠标事件
if (MouseHit()) {
MOUSEMSG msg = GetMouseMsg();
if (msg.uMsg == WM_LBUTTONDOWN) {
resetKeyFlags();
currentFocus = FOCUS_NONE;
if (isClickArea(20, 20, 80, 30, msg.x, msg.y)) {
currentMenu = 1;
inputBuffer = tempStr1 = tempStr2 = tempStr3 = "";
return;
}
// 添加学生
else if (isClickArea(50, 100, 120, 40, msg.x, msg.y)) {
inputBuffer = tempStr1 = tempStr2 = tempStr3 = "";
bool waitInput = true;
while (waitInput) {
BeginBatchDraw();
cleardevice();
settextcolor(COLOR_BLACK);
int numX = 150, numY = 95;
int nameX = 150, nameY = 155;
int sexX = 150, sexY = 215;
int gradeX = 150, gradeY = 275;
int inputW = 200, inputH = 40;
outtextxy(50, 50, _T("添加学生"));
outtextxy(50, 100, _T("学生学号:"));
drawInputBox(numX, numY, inputW, inputH, _T("数字学号"), inputBuffer, currentFocus == FOCUS_STU_NUM);
outtextxy(50, 160, _T("学生姓名:"));
// 显示当前学生姓名(如果有)
TCHAR nameDisplay[256] = { 0 };
if (!tempStr1.empty()) {
MultiByteToWideChar(CP_ACP, 0, tempStr1.c_str(), -1, nameDisplay, 256);
}
setlinecolor(COLOR_BLACK);
rectangle(nameX, nameY, nameX + inputW, nameY + inputH);
if (tempStr1.empty()) {
settextcolor(RGB(160, 160, 160));
outtextxy(nameX + 10, nameY + inputH / 2 - textheight(_T("点击输入学生姓名")) / 2, _T("点击输入学生姓名"));
}
else {
settextcolor(COLOR_BLACK);
outtextxy(nameX + 10, nameY + inputH / 2 - textheight(nameDisplay) / 2, nameDisplay);
}
outtextxy(50, 220, _T("学生性别:"));
// 显示当前学生性别(如果有)
TCHAR sexDisplay[256] = { 0 };
if (!tempStr2.empty()) {
MultiByteToWideChar(CP_ACP, 0, tempStr2.c_str(), -1, sexDisplay, 256);
}
rectangle(sexX, sexY, sexX + inputW, sexY + inputH);
if (tempStr2.empty()) {
settextcolor(RGB(160, 160, 160));
outtextxy(sexX + 10, sexY + inputH / 2 - textheight(_T("点击输入学生性别")) / 2, _T("点击输入学生性别"));
}
else {
settextcolor(COLOR_BLACK);
outtextxy(sexX + 10, sexY + inputH / 2 - textheight(sexDisplay) / 2, sexDisplay);
}
outtextxy(50, 280, _T("学生年级:"));
// 显示当前学生年级(如果有)
TCHAR gradeDisplay[256] = { 0 };
if (!tempStr3.empty()) {
MultiByteToWideChar(CP_ACP, 0, tempStr3.c_str(), -1, gradeDisplay, 256);
}
rectangle(gradeX, gradeY, gradeX + inputW, gradeY + inputH);
if (tempStr3.empty()) {
settextcolor(RGB(160, 160, 160));
outtextxy(gradeX + 10, gradeY + inputH / 2 - textheight(_T("点击输入学生年级")) / 2, _T("点击输入学生年级"));
}
else {
settextcolor(COLOR_BLACK);
outtextxy(gradeX + 10, gradeY + inputH / 2 - textheight(gradeDisplay) / 2, gradeDisplay);
}
// 中文输入提示
settextcolor(COLOR_BLUE);
outtextxy(50, 330, _T("提示:点击学生姓名、性别或年级输入框可弹出中文输入窗口"));
settextcolor(COLOR_BLACK);
drawButton(150, 370, 100, 40, _T("确认添加"), COLOR_MENU, COLOR_TEXT);
drawButton(270, 370, 100, 40, _T("取消"), COLOR_GRAY, COLOR_BLACK);
FlushBatchDraw();
EndBatchDraw();
if (MouseHit()) {
MOUSEMSG msg2 = GetMouseMsg();
if (msg2.uMsg == WM_LBUTTONDOWN) {
resetKeyFlags();
if (isClickArea(numX, numY, inputW, inputH, msg2.x, msg2.y)) {
currentFocus = FOCUS_STU_NUM;
lastCursorTime = GetTickCount();
}
else if (isClickArea(nameX, nameY, inputW, inputH, msg2.x, msg2.y)) {
currentFocus = FOCUS_NONE;
string result = createInputBox("输入学生姓名", "请输入学生姓名:");
if (!result.empty()) {
tempStr1 = result;
}
}
else if (isClickArea(sexX, sexY, inputW, inputH, msg2.x, msg2.y)) {
currentFocus = FOCUS_NONE;
string result = createInputBox("输入学生性别", "请输入学生性别(男/女):");
if (!result.empty()) {
tempStr2 = result;
}
}
else if (isClickArea(gradeX, gradeY, inputW, inputH, msg2.x, msg2.y)) {
currentFocus = FOCUS_NONE;
string result = createInputBox("输入学生年级", "请输入学生年级2023级:");
if (!result.empty()) {
tempStr3 = result;
}
}
else if (isClickArea(150, 370, 100, 40, msg2.x, msg2.y)) {
long num = str2num(inputBuffer);
if (!student::isHave(num) && !inputBuffer.empty() && !tempStr1.empty() && !tempStr2.empty() && !tempStr3.empty()) {
student::addStudent(num, tempStr1, tempStr2, tempStr3);
MessageBox(GetHWnd(), _T("学生添加成功!"), _T("提示"), MB_OK | MB_ICONINFORMATION);
waitInput = false;
currentMenu = 3;
currentFocus = FOCUS_NONE;
}
else {
MessageBox(GetHWnd(), _T("学号重复或信息不完整!"), _T("错误"), MB_OK | MB_ICONWARNING);
}
}
else if (isClickArea(270, 370, 100, 40, msg2.x, msg2.y)) {
waitInput = false;
currentMenu = 3;
currentFocus = FOCUS_NONE;
}
}
}
handleKeyboardInput();
updateCursor();
Sleep(10);
}
}
// 删除学生(已修复的功能)
else if (isClickArea(200, 100, 120, 40, msg.x, msg.y)) {
inputBuffer = "";
bool waitInput = true;
while (waitInput) {
BeginBatchDraw();
cleardevice();
settextcolor(COLOR_BLACK);
int numX = 150, numY = 95;
int inputW = 200, inputH = 40;
outtextxy(50, 50, _T("删除学生"));
outtextxy(50, 100, _T("学生学号:"));
drawInputBox(numX, numY, inputW, inputH, _T("输入要删除的学号"), inputBuffer, currentFocus == FOCUS_DEL_STU_NUM);
drawButton(150, 180, 100, 40, _T("确认删除"), COLOR_MENU, COLOR_TEXT);
drawButton(270, 180, 100, 40, _T("取消"), COLOR_GRAY, COLOR_BLACK);
FlushBatchDraw();
EndBatchDraw();
if (MouseHit()) {
MOUSEMSG msg2 = GetMouseMsg();
if (msg2.uMsg == WM_LBUTTONDOWN) {
resetKeyFlags();
if (isClickArea(numX, numY, inputW, inputH, msg2.x, msg2.y)) {
currentFocus = FOCUS_DEL_STU_NUM;
lastCursorTime = GetTickCount();
}
else if (isClickArea(150, 180, 100, 40, msg2.x, msg2.y)) {
long num = str2num(inputBuffer);
if (student::isHave(num)) {
student::delStudent(num);
MessageBox(GetHWnd(), _T("学生删除成功!"), _T("提示"), MB_OK | MB_ICONINFORMATION);
waitInput = false;
currentMenu = 3;
currentFocus = FOCUS_NONE;
}
else {
MessageBox(GetHWnd(), _T("学生不存在!"), _T("错误"), MB_OK | MB_ICONWARNING);
}
}
else if (isClickArea(270, 180, 100, 40, msg2.x, msg2.y)) {
waitInput = false;
currentMenu = 3;
currentFocus = FOCUS_NONE;
}
}
}
// 处理键盘输入
if (currentFocus == FOCUS_DEL_STU_NUM) {
handleKeyboardInput();
// 回车键提交
if ((GetAsyncKeyState(VK_RETURN) & 0x8000) && !keyEnterPressed) {
keyEnterPressed = true;
long num = str2num(inputBuffer);
if (student::isHave(num)) {
student::delStudent(num);
MessageBox(GetHWnd(), _T("学生删除成功!"), _T("提示"), MB_OK | MB_ICONINFORMATION);
waitInput = false;
currentMenu = 3;
currentFocus = FOCUS_NONE;
}
else {
MessageBox(GetHWnd(), _T("学生不存在!"), _T("错误"), MB_OK | MB_ICONWARNING);
}
}
else if (!(GetAsyncKeyState(VK_RETURN) & 0x8000)) {
keyEnterPressed = false;
}
}
updateCursor();
Sleep(10);
}
}
// 学生选课
else if (isClickArea(350, 100, 120, 40, msg.x, msg.y)) {
inputBuffer = tempStr1 = "";
bool waitInput = true;
while (waitInput) {
BeginBatchDraw();
cleardevice();
settextcolor(COLOR_BLACK);
int stuX = 150, stuY = 95;
int courseX = 150, courseY = 155;
int inputW = 200, inputH = 40;
outtextxy(50, 50, _T("学生选课"));
outtextxy(50, 100, _T("学生学号:"));
drawInputBox(stuX, stuY, inputW, inputH, _T("输入学号"), inputBuffer, currentFocus == FOCUS_STU_SELECT_STU_NUM);
outtextxy(50, 160, _T("课程编号:"));
drawInputBox(courseX, courseY, inputW, inputH, _T("输入课程编号"), tempStr1, currentFocus == FOCUS_STU_SELECT_COURSE_NUM);
drawButton(150, 220, 100, 40, _T("确认选课"), COLOR_MENU, COLOR_TEXT);
drawButton(270, 220, 100, 40, _T("取消"), COLOR_GRAY, COLOR_BLACK);
FlushBatchDraw();
EndBatchDraw();
if (MouseHit()) {
MOUSEMSG msg2 = GetMouseMsg();
if (msg2.uMsg == WM_LBUTTONDOWN) {
resetKeyFlags();
if (isClickArea(stuX, stuY, inputW, inputH, msg2.x, msg2.y)) {
currentFocus = FOCUS_STU_SELECT_STU_NUM;
lastCursorTime = GetTickCount();
}
else if (isClickArea(courseX, courseY, inputW, inputH, msg2.x, msg2.y)) {
currentFocus = FOCUS_STU_SELECT_COURSE_NUM;
lastCursorTime = GetTickCount();
}
else if (isClickArea(150, 220, 100, 40, msg2.x, msg2.y)) {
long stuNum = str2num(inputBuffer);
long courseNum = str2num(tempStr1);
if (student::isHave(stuNum) && course::isHave(courseNum)) {
student::addCourseToStudent(stuNum, courseNum);
MessageBox(GetHWnd(), _T("选课成功!"), _T("提示"), MB_OK | MB_ICONINFORMATION);
waitInput = false;
currentMenu = 3;
currentFocus = FOCUS_NONE;
}
else {
MessageBox(GetHWnd(), _T("学生或课程不存在!"), _T("错误"), MB_OK | MB_ICONWARNING);
}
}
else if (isClickArea(270, 220, 100, 40, msg2.x, msg2.y)) {
waitInput = false;
currentMenu = 3;
currentFocus = FOCUS_NONE;
}
}
}
handleKeyboardInput();
updateCursor();
Sleep(10);
}
}
// 查看所有学生
else if (isClickArea(500, 100, 120, 40, msg.x, msg.y)) {
bool showList = true;
while (showList) {
BeginBatchDraw();
cleardevice();
settextcolor(COLOR_BLACK);
outtextxy(50, 50, _T("所有学生信息"));
// 绘制表头
int y = 100;
settextstyle(16, 0, _T("微软雅黑"));
outtextxy(50, y, _T("学号"));
outtextxy(150, y, _T("姓名"));
outtextxy(250, y, _T("性别"));
outtextxy(300, y, _T("年级"));
outtextxy(400, y, _T("已选课程数"));
y += 30;
// 绘制学生列表
settextstyle(14, 0, _T("微软雅黑"));
if (studentList.empty()) {
outtextxy(50, y, _T("暂无学生数据!"));
}
else {
for (auto& s : student::getStudentList()) {
if (y > WIN_HEIGHT - 80) break; // 防止超出界面
TCHAR numBuf[32] = { 0 };
MultiByteToWideChar(CP_ACP, 0, num2str(s.getNumber()).c_str(), -1, numBuf, 32);
outtextxy(50, y, numBuf);
TCHAR nameBuf[64] = { 0 };
MultiByteToWideChar(CP_ACP, 0, s.getName().c_str(), -1, nameBuf, 64);
outtextxy(150, y, nameBuf);
TCHAR sexBuf[32] = { 0 };
MultiByteToWideChar(CP_ACP, 0, s.getSex().c_str(), -1, sexBuf, 32);
outtextxy(250, y, sexBuf);
TCHAR gradeBuf[32] = { 0 };
MultiByteToWideChar(CP_ACP, 0, s.getGrade().c_str(), -1, gradeBuf, 32);
outtextxy(300, y, gradeBuf);
TCHAR courseCntBuf[32] = { 0 };
MultiByteToWideChar(CP_ACP, 0, num2str(s.getHaveC().size()).c_str(), -1, courseCntBuf, 32);
outtextxy(400, y, courseCntBuf);
y += 25;
}
}
// 绘制返回按钮(固定在底部)
drawButton(50, WIN_HEIGHT - 60, 80, 30, _T("返回"), COLOR_GRAY, COLOR_BLACK);
FlushBatchDraw();
EndBatchDraw();
// 持续监听返回按钮点击
if (MouseHit()) {
MOUSEMSG msg2 = GetMouseMsg();
if (msg2.uMsg == WM_LBUTTONDOWN && isClickArea(50, WIN_HEIGHT - 60, 80, 30, msg2.x, msg2.y)) {
showList = false;
currentMenu = 3;
currentFocus = FOCUS_NONE;
}
}
Sleep(10);
}
}
}
}
FlushBatchDraw();
EndBatchDraw();
Sleep(10);
}
// 主函数
int main() {
initgraph(WIN_WIDTH, WIN_HEIGHT);
setbkcolor(COLOR_BG);
cleardevice();
lastCursorTime = GetTickCount();
resetKeyFlags();
// 添加使用说明提示
HWND hwnd = GetHWnd();
MessageBox(hwnd,
_T("学生选课管理系统\n\n")
_T("使用说明:\n")
_T("1. 默认管理员密码1234\n")
_T("2. 中文输入方法:\n")
_T(" - 点击课程名称、授课教师、学生姓名等输入框\n")
_T(" - 会自动弹出中文输入窗口\n")
_T(" - 在输入窗口中直接输入中文\n\n")
_T("点击确定开始使用"),
_T("学生选课管理系统"),
MB_OK | MB_ICONINFORMATION);
while (true) {
updateCursor();
if (!isLogin) {
drawLogin();
}
else {
switch (currentMenu) {
case 1: drawMainMenu(); break;
case 2: drawCourseMenu(); break;
case 3: drawStudentMenu(); break;
case 4: drawChangePassword(); break;
default: currentMenu = 1; break;
}
}
}
closegraph();
return 0;
}