|
|
#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) // 蓝色
|
|
|
|
|
|
// 输入焦点枚举(统一管理所有输入框焦点)
|
|
|
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_PWD1, // 修改密码-新密码
|
|
|
FOCUS_CHANGE_PWD2 // 修改密码-确认密码
|
|
|
};
|
|
|
|
|
|
// 全局变量
|
|
|
string adminPwd = "1234"; // 管理员密码
|
|
|
bool isLogin = false; // 登录状态
|
|
|
string inputBuffer = ""; // 通用输入缓冲区
|
|
|
string tempStr1 = ""; // 临时输入1(课程名称/学生姓名等)
|
|
|
string tempStr2 = ""; // 临时输入2(学分/性别等)
|
|
|
string tempStr3 = ""; // 临时输入3(教师/年级等)
|
|
|
int currentMenu = 0; // 当前菜单:0-登录 1-主菜单 2-课程管理 3-学生管理
|
|
|
InputFocusType currentFocus = FOCUS_NONE; // 当前输入焦点
|
|
|
DWORD lastCursorTime = 0; // 光标闪烁计时
|
|
|
bool showCursor = true; // 光标显示状态
|
|
|
// 键盘输入防抖标记
|
|
|
bool keyBackPressed = false;
|
|
|
bool keyEnterPressed = false;
|
|
|
bool charKeysPressed[95] = { false }; // 32-126可打印字符防抖
|
|
|
|
|
|
// 信息基类
|
|
|
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() ? textwidth(hint) : textwidth(showBuf)) + 2;
|
|
|
line(cursorX, y + 5, cursorX, y + h - 5);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 工具函数:重置所有键盘防抖标记
|
|
|
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_COURSE_NUM: if (!inputBuffer.empty()) inputBuffer.pop_back(); break;
|
|
|
case FOCUS_COURSE_NAME: if (!tempStr1.empty()) tempStr1.pop_back(); break;
|
|
|
case FOCUS_COURSE_CREDIT: if (!tempStr2.empty()) tempStr2.pop_back(); break;
|
|
|
case FOCUS_COURSE_TEACHER: if (!tempStr3.empty()) tempStr3.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_NAME: if (!tempStr1.empty()) tempStr1.pop_back(); break;
|
|
|
case FOCUS_STU_SEX: if (!tempStr2.empty()) tempStr2.pop_back(); break;
|
|
|
case FOCUS_STU_GRADE: if (!tempStr3.empty()) tempStr3.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_CHANGE_PWD1: if (!inputBuffer.empty()) inputBuffer.pop_back(); break;
|
|
|
case FOCUS_CHANGE_PWD2: if (!tempStr1.empty()) tempStr1.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:
|
|
|
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_COURSE_NAME: tempStr1 += c; break;
|
|
|
case FOCUS_COURSE_TEACHER: tempStr3 += c; break;
|
|
|
case FOCUS_STU_NAME: tempStr1 += c; break;
|
|
|
case FOCUS_STU_SEX: tempStr2 += c; break;
|
|
|
case FOCUS_STU_GRADE: tempStr3 += c; break;
|
|
|
case FOCUS_CHANGE_PWD1: inputBuffer += c; break;
|
|
|
case FOCUS_CHANGE_PWD2: tempStr1 += c; break;
|
|
|
default: break;
|
|
|
}
|
|
|
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);
|
|
|
|
|
|
// 处理鼠标事件
|
|
|
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, 350, err);
|
|
|
inputBuffer = "";
|
|
|
}
|
|
|
Sleep(200);
|
|
|
}
|
|
|
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, 350, err);
|
|
|
inputBuffer = "";
|
|
|
}
|
|
|
Sleep(200);
|
|
|
}
|
|
|
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("退出系统"), COLOR_MENU, 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)) {
|
|
|
// 修改密码逻辑
|
|
|
inputBuffer = tempStr1 = "";
|
|
|
bool waitInput = true;
|
|
|
while (waitInput) {
|
|
|
BeginBatchDraw();
|
|
|
cleardevice();
|
|
|
settextcolor(COLOR_BLACK);
|
|
|
|
|
|
int pwd1X = 100, pwd1Y = 130;
|
|
|
int pwd2X = 100, pwd2Y = 220;
|
|
|
int pwdW = 200, pwdH = 40;
|
|
|
|
|
|
outtextxy(100, 100, _T("请输入新密码:"));
|
|
|
drawInputBox(pwd1X, pwd1Y, pwdW, pwdH, _T("新密码"), inputBuffer, currentFocus == FOCUS_CHANGE_PWD1, true);
|
|
|
|
|
|
outtextxy(100, 190, _T("请确认新密码:"));
|
|
|
drawInputBox(pwd2X, pwd2Y, pwdW, pwdH, _T("确认密码"), tempStr1, currentFocus == FOCUS_CHANGE_PWD2, true);
|
|
|
|
|
|
drawButton(100, 280, 100, 40, _T("确认"), COLOR_MENU, COLOR_TEXT);
|
|
|
drawButton(220, 280, 100, 40, _T("取消"), RGB(200, 200, 200), COLOR_BLACK);
|
|
|
|
|
|
FlushBatchDraw();
|
|
|
EndBatchDraw();
|
|
|
|
|
|
if (MouseHit()) {
|
|
|
MOUSEMSG msg2 = GetMouseMsg();
|
|
|
if (msg2.uMsg == WM_LBUTTONDOWN) {
|
|
|
resetKeyFlags();
|
|
|
if (isClickArea(pwd1X, pwd1Y, pwdW, pwdH, msg2.x, msg2.y)) {
|
|
|
currentFocus = FOCUS_CHANGE_PWD1;
|
|
|
lastCursorTime = GetTickCount();
|
|
|
}
|
|
|
else if (isClickArea(pwd2X, pwd2Y, pwdW, pwdH, msg2.x, msg2.y)) {
|
|
|
currentFocus = FOCUS_CHANGE_PWD2;
|
|
|
lastCursorTime = GetTickCount();
|
|
|
}
|
|
|
else if (isClickArea(100, 280, 100, 40, msg2.x, msg2.y)) {
|
|
|
if (inputBuffer == tempStr1 && !inputBuffer.empty()) {
|
|
|
adminPwd = inputBuffer;
|
|
|
cleardevice();
|
|
|
outtextxy(100, 350, _T("密码修改成功!"));
|
|
|
FlushBatchDraw();
|
|
|
}
|
|
|
else {
|
|
|
cleardevice();
|
|
|
outtextxy(100, 350, _T("两次密码不一致!"));
|
|
|
FlushBatchDraw();
|
|
|
}
|
|
|
Sleep(1000);
|
|
|
waitInput = false;
|
|
|
currentMenu = 1;
|
|
|
currentFocus = FOCUS_NONE;
|
|
|
}
|
|
|
else if (isClickArea(220, 280, 100, 40, msg2.x, msg2.y)) {
|
|
|
waitInput = false;
|
|
|
currentMenu = 1;
|
|
|
currentFocus = FOCUS_NONE;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
handleKeyboardInput();
|
|
|
updateCursor();
|
|
|
Sleep(10);
|
|
|
}
|
|
|
}
|
|
|
else if (isClickArea(WIN_WIDTH / 2 - 100, 390, 200, 50, msg.x, msg.y)) {
|
|
|
closegraph();
|
|
|
exit(0);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
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("返回"), RGB(200, 200, 200), 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("课程名称:"));
|
|
|
drawInputBox(nameX, nameY, inputW, inputH, _T("如:数据结构"), tempStr1, currentFocus == FOCUS_COURSE_NAME);
|
|
|
|
|
|
outtextxy(50, 220, _T("课程学分:"));
|
|
|
drawInputBox(creditX, creditY, inputW, inputH, _T("数字"), tempStr2, currentFocus == FOCUS_COURSE_CREDIT);
|
|
|
|
|
|
outtextxy(50, 280, _T("授课教师:"));
|
|
|
drawInputBox(teacherX, teacherY, inputW, inputH, _T("教师姓名"), tempStr3, currentFocus == FOCUS_COURSE_TEACHER);
|
|
|
|
|
|
drawButton(150, 350, 100, 40, _T("确认添加"), COLOR_MENU, COLOR_TEXT);
|
|
|
drawButton(270, 350, 100, 40, _T("取消"), RGB(200, 200, 200), 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_COURSE_NAME;
|
|
|
lastCursorTime = GetTickCount();
|
|
|
}
|
|
|
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_COURSE_TEACHER;
|
|
|
lastCursorTime = GetTickCount();
|
|
|
}
|
|
|
else if (isClickArea(150, 350, 100, 40, msg2.x, msg2.y)) {
|
|
|
long num = str2num(inputBuffer);
|
|
|
int credit = str2num(tempStr2);
|
|
|
if (!course::isHave(num) && !inputBuffer.empty() && !tempStr1.empty()) {
|
|
|
course::addCourse(num, tempStr1, credit, tempStr3);
|
|
|
cleardevice();
|
|
|
outtextxy(50, 420, _T("课程添加成功!"));
|
|
|
}
|
|
|
else {
|
|
|
cleardevice();
|
|
|
outtextxy(50, 420, _T("编号重复或信息为空!"));
|
|
|
}
|
|
|
FlushBatchDraw();
|
|
|
Sleep(1000);
|
|
|
waitInput = false;
|
|
|
currentMenu = 2;
|
|
|
currentFocus = FOCUS_NONE;
|
|
|
}
|
|
|
else if (isClickArea(270, 350, 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("取消"), RGB(200, 200, 200), 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);
|
|
|
cleardevice();
|
|
|
outtextxy(50, 250, _T("课程删除成功!"));
|
|
|
}
|
|
|
else {
|
|
|
cleardevice();
|
|
|
outtextxy(50, 250, _T("课程不存在!"));
|
|
|
}
|
|
|
FlushBatchDraw();
|
|
|
Sleep(1000);
|
|
|
waitInput = false;
|
|
|
currentMenu = 2;
|
|
|
currentFocus = FOCUS_NONE;
|
|
|
}
|
|
|
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("取消"), RGB(200, 200, 200), COLOR_BLACK);
|
|
|
|
|
|
// 显示提示
|
|
|
if (!inputBuffer.empty() && !course::isHave(str2num(inputBuffer))) {
|
|
|
settextcolor(COLOR_RED);
|
|
|
outtextxy(150, 240, _T("课程编号不存在!"));
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
// 第二步:编辑课程信息(回显原有数据)
|
|
|
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("课程编号:"));
|
|
|
// 编号不可修改,仅显示
|
|
|
TCHAR numBuf[32] = { 0 };
|
|
|
MultiByteToWideChar(CP_ACP, 0, num2str(targetCourse->getNumber()).c_str(), -1, numBuf, 32);
|
|
|
rectangle(numX, numY, numX + inputW, numY + inputH);
|
|
|
outtextxy(numX + 10, numY + inputH / 2 - textheight(numBuf) / 2, numBuf);
|
|
|
|
|
|
outtextxy(50, 160, _T("课程名称:"));
|
|
|
// 回显原有名称
|
|
|
if (tempStr1.empty()) tempStr1 = targetCourse->getName();
|
|
|
drawInputBox(nameX, nameY, inputW, inputH, _T("如:数据结构"), tempStr1, currentFocus == FOCUS_COURSE_NAME);
|
|
|
|
|
|
outtextxy(50, 220, _T("课程学分:"));
|
|
|
// 回显原有学分
|
|
|
if (tempStr2.empty()) tempStr2 = num2str(targetCourse->getCredit());
|
|
|
drawInputBox(creditX, creditY, inputW, inputH, _T("数字"), tempStr2, currentFocus == FOCUS_COURSE_CREDIT);
|
|
|
|
|
|
outtextxy(50, 280, _T("授课教师:"));
|
|
|
// 回显原有教师
|
|
|
if (tempStr3.empty()) tempStr3 = targetCourse->getTeacher();
|
|
|
drawInputBox(teacherX, teacherY, inputW, inputH, _T("教师姓名"), tempStr3, currentFocus == FOCUS_COURSE_TEACHER);
|
|
|
|
|
|
drawButton(150, 350, 100, 40, _T("确认修改"), COLOR_MENU, COLOR_TEXT);
|
|
|
drawButton(270, 350, 100, 40, _T("取消"), RGB(200, 200, 200), 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;
|
|
|
}
|
|
|
}
|
|
|
else if (isClickArea(270, 180, 100, 40, msg2.x, msg2.y)) {
|
|
|
waitInput = false;
|
|
|
currentMenu = 2;
|
|
|
currentFocus = FOCUS_NONE;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
// 编辑阶段
|
|
|
int nameX = 150, nameY = 155;
|
|
|
int creditX = 150, creditY = 215;
|
|
|
int teacherX = 150, teacherY = 275;
|
|
|
int inputW = 200, inputH = 40;
|
|
|
|
|
|
if (isClickArea(nameX, nameY, inputW, inputH, msg2.x, msg2.y)) {
|
|
|
currentFocus = FOCUS_COURSE_NAME;
|
|
|
lastCursorTime = GetTickCount();
|
|
|
}
|
|
|
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_COURSE_TEACHER;
|
|
|
lastCursorTime = GetTickCount();
|
|
|
}
|
|
|
else if (isClickArea(150, 350, 100, 40, msg2.x, msg2.y)) {
|
|
|
// 确认修改
|
|
|
int credit = str2num(tempStr2);
|
|
|
course::editCourse(targetCourse->getNumber(), tempStr1, credit, tempStr3);
|
|
|
cleardevice();
|
|
|
outtextxy(50, 420, _T("课程修改成功!"));
|
|
|
FlushBatchDraw();
|
|
|
Sleep(1000);
|
|
|
waitInput = false;
|
|
|
currentMenu = 2;
|
|
|
currentFocus = FOCUS_NONE;
|
|
|
}
|
|
|
else if (isClickArea(270, 350, 100, 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("返回"), RGB(200, 200, 200), 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("返回"), RGB(200, 200, 200), 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("学生姓名:"));
|
|
|
drawInputBox(nameX, nameY, inputW, inputH, _T("姓名"), tempStr1, currentFocus == FOCUS_STU_NAME);
|
|
|
|
|
|
outtextxy(50, 220, _T("学生性别:"));
|
|
|
drawInputBox(sexX, sexY, inputW, inputH, _T("男/女"), tempStr2, currentFocus == FOCUS_STU_SEX);
|
|
|
|
|
|
outtextxy(50, 280, _T("学生年级:"));
|
|
|
drawInputBox(gradeX, gradeY, inputW, inputH, _T("如:2023级"), tempStr3, currentFocus == FOCUS_STU_GRADE);
|
|
|
|
|
|
drawButton(150, 350, 100, 40, _T("确认添加"), COLOR_MENU, COLOR_TEXT);
|
|
|
drawButton(270, 350, 100, 40, _T("取消"), RGB(200, 200, 200), 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_STU_NAME;
|
|
|
lastCursorTime = GetTickCount();
|
|
|
}
|
|
|
else if (isClickArea(sexX, sexY, inputW, inputH, msg2.x, msg2.y)) {
|
|
|
currentFocus = FOCUS_STU_SEX;
|
|
|
lastCursorTime = GetTickCount();
|
|
|
}
|
|
|
else if (isClickArea(gradeX, gradeY, inputW, inputH, msg2.x, msg2.y)) {
|
|
|
currentFocus = FOCUS_STU_GRADE;
|
|
|
lastCursorTime = GetTickCount();
|
|
|
}
|
|
|
else if (isClickArea(150, 350, 100, 40, msg2.x, msg2.y)) {
|
|
|
long num = str2num(inputBuffer);
|
|
|
if (!student::isHave(num) && !inputBuffer.empty() && !tempStr1.empty()) {
|
|
|
student::addStudent(num, tempStr1, tempStr2, tempStr3);
|
|
|
cleardevice();
|
|
|
outtextxy(50, 420, _T("学生添加成功!"));
|
|
|
}
|
|
|
else {
|
|
|
cleardevice();
|
|
|
outtextxy(50, 420, _T("学号重复或信息为空!"));
|
|
|
}
|
|
|
FlushBatchDraw();
|
|
|
Sleep(1000);
|
|
|
waitInput = false;
|
|
|
currentMenu = 3;
|
|
|
currentFocus = FOCUS_NONE;
|
|
|
}
|
|
|
else if (isClickArea(270, 350, 100, 40, msg2.x, msg2.y)) {
|
|
|
waitInput = false;
|
|
|
currentMenu = 3;
|
|
|
currentFocus = FOCUS_NONE;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
handleKeyboardInput();
|
|
|
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("取消"), RGB(200, 200, 200), 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);
|
|
|
cleardevice();
|
|
|
outtextxy(50, 290, _T("选课成功!"));
|
|
|
}
|
|
|
else {
|
|
|
cleardevice();
|
|
|
outtextxy(50, 290, _T("学生或课程不存在!"));
|
|
|
}
|
|
|
FlushBatchDraw();
|
|
|
Sleep(1000);
|
|
|
waitInput = false;
|
|
|
currentMenu = 3;
|
|
|
currentFocus = FOCUS_NONE;
|
|
|
}
|
|
|
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("返回"), RGB(200, 200, 200), 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();
|
|
|
|
|
|
while (true) {
|
|
|
updateCursor();
|
|
|
if (!isLogin) {
|
|
|
drawLogin();
|
|
|
}
|
|
|
else {
|
|
|
switch (currentMenu) {
|
|
|
case 1: drawMainMenu(); break;
|
|
|
case 2: drawCourseMenu(); break;
|
|
|
case 3: drawStudentMenu(); break;
|
|
|
default: currentMenu = 1; break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
closegraph();
|
|
|
return 0;
|
|
|
} |