Compare commits

..

4 Commits

@ -0,0 +1,55 @@
# Project: ÏîÄ¿1
# Makefile created by Dev-C++ 5.11
CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
OBJ = UserManager.o User.o QuestionGenerator.o Question.o LoginWindow.o RegisterWindow.o QuestionWindow.o main.o EmailSender.o SelectionWindow.o
LINKOBJ = UserManager.o User.o QuestionGenerator.o Question.o LoginWindow.o RegisterWindow.o QuestionWindow.o main.o EmailSender.o SelectionWindow.o
LIBS = -L"D:/³ÌÐòÉè¼Æ/Dev-Cpp/MinGW64/lib" -L"D:/³ÌÐòÉè¼Æ/Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib" -static-libgcc -mwindows -lws2_32 -lwininet
INCS = -I"D:/³ÌÐòÉè¼Æ/Dev-Cpp/MinGW64/include" -I"D:/³ÌÐòÉè¼Æ/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"D:/³ÌÐòÉè¼Æ/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include"
CXXINCS = -I"D:/³ÌÐòÉè¼Æ/Dev-Cpp/MinGW64/include" -I"D:/³ÌÐòÉè¼Æ/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"D:/³ÌÐòÉè¼Æ/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -I"D:/³ÌÐòÉè¼Æ/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++"
BIN = test3.exe
CXXFLAGS = $(CXXINCS)
CFLAGS = $(INCS)
RM = rm.exe -f
.PHONY: all all-before all-after clean clean-custom
all: all-before $(BIN) all-after
clean: clean-custom
${RM} $(OBJ) $(BIN)
$(BIN): $(OBJ)
$(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)
UserManager.o: UserManager.cpp
$(CPP) -c UserManager.cpp -o UserManager.o $(CXXFLAGS)
User.o: User.cpp
$(CPP) -c User.cpp -o User.o $(CXXFLAGS)
QuestionGenerator.o: QuestionGenerator.cpp
$(CPP) -c QuestionGenerator.cpp -o QuestionGenerator.o $(CXXFLAGS)
Question.o: Question.cpp
$(CPP) -c Question.cpp -o Question.o $(CXXFLAGS)
LoginWindow.o: LoginWindow.cpp
$(CPP) -c LoginWindow.cpp -o LoginWindow.o $(CXXFLAGS)
RegisterWindow.o: RegisterWindow.cpp
$(CPP) -c RegisterWindow.cpp -o RegisterWindow.o $(CXXFLAGS)
QuestionWindow.o: QuestionWindow.cpp
$(CPP) -c QuestionWindow.cpp -o QuestionWindow.o $(CXXFLAGS)
main.o: main.cpp
$(CPP) -c main.cpp -o main.o $(CXXFLAGS)
EmailSender.o: EmailSender.cpp
$(CPP) -c EmailSender.cpp -o EmailSender.o $(CXXFLAGS)
SelectionWindow.o: SelectionWindow.cpp
$(CPP) -c SelectionWindow.cpp -o SelectionWindow.o $(CXXFLAGS)

@ -0,0 +1,27 @@
#include "Question.h"
Question::Question(const std::string& text, const std::vector<std::string>& options, int correctAnswer)
: text(text), options(options), correctAnswer(correctAnswer) {}
std::string Question::getText() const {
return text;
}
std::vector<std::string> Question::getOptions() const {
return options;
}
int Question::getCorrectAnswer() const {
return correctAnswer;
}
bool Question::checkAnswer(int userAnswer) const {
return userAnswer == correctAnswer;
}
std::string Question::getCorrectOptionText() const {
if (correctAnswer >= 0 && correctAnswer < (int)options.size()) {
return options[correctAnswer];
}
return "ÎÞÕýÈ·´ð°¸";
}

@ -0,0 +1,25 @@
#ifndef QUESTION_H
#define QUESTION_H
#include <string>
#include <vector>
class Question {
public:
Question(const std::string& text, const std::vector<std::string>& options, int correctAnswer);
std::string getText() const;
std::vector<std::string> getOptions() const;
int getCorrectAnswer() const;
bool checkAnswer(int userAnswer) const;
// Ìí¼Óµ÷ÊÔ·½·¨
std::string getCorrectOptionText() const;
private:
std::string text;
std::vector<std::string> options;
int correctAnswer;
};
#endif

Binary file not shown.

@ -0,0 +1,442 @@
#include "QuestionGenerator.h"
#include "Question.h"
#include <cstdlib>
#include <ctime>
#include <sstream>
#include <cmath>
#include <windows.h>
#include <algorithm>
#include <vector>
#include <iostream>
#include <stack>
// C++98兼容的数字转字符串函数
std::string intToString(int value) {
std::stringstream ss;
ss << value;
return ss.str();
}
// 浮点数转字符串保留2位小数
std::string doubleToString(double value) {
std::stringstream ss;
ss.precision(2);
ss << std::fixed << value;
return ss.str();
}
QuestionGenerator::QuestionGenerator(const std::string& userType) : userType(userType) {
srand(static_cast<unsigned int>(time(NULL)));
}
std::vector<Question> QuestionGenerator::generateQuestions(int count) {
std::vector<Question> questions;
for (int i = 0; i < count; ++i) {
Question question("", std::vector<std::string>(), 0);
if (userType == "elementary") {
question = generateElementaryQuestion();
} else if (userType == "middle") {
question = generateMiddleSchoolQuestion();
} else if (userType == "high") {
question = generateHighSchoolQuestion();
}
if (question.getText() != "" && question.getOptions().size() == 4) {
questions.push_back(question);
} else {
// 如果生成失败,重新生成
i--;
}
}
return questions;
}
// 获取操作符的优先级
int getOperatorPriority(char op) {
if (op == '*' || op == '/') return 2;
if (op == '+' || op == '-') return 1;
return 0;
}
// 计算两个数的运算结果
int calculate(int a, int b, char op) {
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/':
if (b != 0 && a % b == 0) return a / b;
return a; // 如果除不尽,返回原值(应该不会发生)
default: return a;
}
}
// 使用栈计算表达式结果(正确考虑运算优先级)
int calculateWithPriority(const std::vector<int>& numbers, const std::vector<char>& operators) {
if (numbers.size() != operators.size() + 1) {
return numbers[0]; // 错误情况,返回第一个数
}
std::stack<int> numStack;
std::stack<char> opStack;
numStack.push(numbers[0]);
for (size_t i = 0; i < operators.size(); ++i) {
char currentOp = operators[i];
int currentNum = numbers[i + 1];
// 处理操作符优先级
while (!opStack.empty() && getOperatorPriority(opStack.top()) >= getOperatorPriority(currentOp)) {
int num2 = numStack.top(); numStack.pop();
int num1 = numStack.top(); numStack.pop();
char op = opStack.top(); opStack.pop();
numStack.push(calculate(num1, num2, op));
}
opStack.push(currentOp);
numStack.push(currentNum);
}
// 处理剩余的操作
while (!opStack.empty()) {
int num2 = numStack.top(); numStack.pop();
int num1 = numStack.top(); numStack.pop();
char op = opStack.top(); opStack.pop();
numStack.push(calculate(num1, num2, op));
}
return numStack.top();
}
// 生成表达式字符串(带括号显示优先级)
std::string generateExpressionString(const std::vector<int>& numbers, const std::vector<char>& operators) {
std::string expression = intToString(numbers[0]);
for (size_t i = 0; i < operators.size(); ++i) {
expression += " ";
expression += operators[i];
expression += " ";
expression += intToString(numbers[i + 1]);
}
return expression;
}
Question QuestionGenerator::generateElementaryQuestion() {
int operandCount = 2 + rand() % 2; // 2-3个操作数
std::vector<int> numbers;
std::vector<char> operators;
// 生成第一个数字
numbers.push_back(1 + rand() % 20);
// 生成操作符和数字
for (int i = 0; i < operandCount; ++i) {
char op;
int num = 1 + rand() % 15;
// 根据情况选择操作符
if (i == 0) {
// 第一个操作符随机选择
op = "+-*/"[rand() % 4];
} else {
// 后续操作符避免复杂组合
if (operators[i-1] == '*' || operators[i-1] == '/') {
op = "+-"[rand() % 2]; // 乘除后接加减
} else {
op = "+-*/"[rand() % 4];
}
}
// 特殊处理
if (op == '/') {
// 确保能整除
if (num == 0) num = 1;
// 调整被除数确保整除
numbers[i] = numbers[i] * num;
} else if (op == '-') {
// 确保减法结果不为负
// 先计算当前值
int currentValue = calculateWithPriority(numbers, operators);
if (currentValue - num < 0) {
num = rand() % currentValue + 1;
}
} else if (op == '*') {
// 避免结果过大
if (numbers[i] * num > 100) {
num = 2;
}
}
operators.push_back(op);
numbers.push_back(num);
}
// 计算正确结果
int result = calculateWithPriority(numbers, operators);
// 确保结果合理
if (result <= 0 || result > 200) {
return generateElementaryQuestion(); // 重新生成
}
// 生成表达式
std::string expression = generateExpressionString(numbers, operators);
std::string questionText = expression + " = ?";
if (isDuplicate(questionText)) {
return generateElementaryQuestion();
}
addToHistory(questionText);
// 生成选项
std::vector<std::string> options;
int correctIndex = rand() % 4;
// 生成3个错误答案
std::vector<int> wrongAnswers;
for (int i = 0; i < 3; ++i) {
int wrongAnswer;
int attempts = 0;
do {
attempts++;
if (attempts > 10) {
wrongAnswer = result + (i + 1) * 3;
break;
}
int offset = (rand() % 10) + 2;
if (rand() % 2 == 0) {
wrongAnswer = result + offset;
} else {
wrongAnswer = result - offset;
if (wrongAnswer < 1) wrongAnswer = result + offset;
}
} while (wrongAnswer == result ||
std::find(wrongAnswers.begin(), wrongAnswers.end(), wrongAnswer) != wrongAnswers.end());
wrongAnswers.push_back(wrongAnswer);
}
// 构建选项
for (int i = 0; i < 4; ++i) {
if (i == correctIndex) {
options.push_back(intToString(result));
} else {
options.push_back(intToString(wrongAnswers[i > correctIndex ? i-1 : i]));
}
}
// 调试输出
std::cout << "小学题目: " << questionText << std::endl;
std::cout << "计算顺序: ";
for (size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers[i];
if (i < operators.size()) {
std::cout << " " << operators[i] << " ";
}
}
std::cout << " = " << result << std::endl;
std::cout << "正确答案: " << result << std::endl;
std::cout << "------------------------" << std::endl;
return Question(questionText, options, correctIndex);
}
// 辅助函数:找到一个数的约数
int QuestionGenerator::findDivisor(int number) {
if (number <= 1) return 1;
for (int i = 2; i <= 10; ++i) {
if (number % i == 0) {
return i;
}
}
return 1;
}
Question QuestionGenerator::generateMiddleSchoolQuestion() {
int type = rand() % 2; // 0: 平方题, 1: 开方题
if (type == 0) {
// 平方题
int base = 2 + rand() % 15; // 2-16
int coefficient = 1 + rand() % 5;
int result = coefficient * base * base;
std::string questionText;
if (coefficient == 1) {
// 方案1: 使用Unicode上标
// questionText = intToString(base) + "2 = ?";
// 方案2: 使用文本描述
questionText = intToString(base) + "的平方 = ?";
} else {
// questionText = intToString(coefficient) + " × " + intToString(base) + "2 = ?";
questionText = intToString(coefficient) + " × " + intToString(base) + "的平方 = ?";
}
if (isDuplicate(questionText)) {
return generateMiddleSchoolQuestion();
}
addToHistory(questionText);
// 生成选项
std::vector<std::string> options;
int correctIndex = rand() % 4;
std::vector<int> wrongAnswers;
for (int i = 0; i < 3; ++i) {
int wrongAnswer;
do {
int offset = (rand() % 20) + 5;
if (rand() % 2 == 0) {
wrongAnswer = result + offset;
} else {
wrongAnswer = result - offset;
if (wrongAnswer <= 0) wrongAnswer = result + offset;
}
} while (wrongAnswer == result ||
std::find(wrongAnswers.begin(), wrongAnswers.end(), wrongAnswer) != wrongAnswers.end());
wrongAnswers.push_back(wrongAnswer);
}
for (int i = 0; i < 4; ++i) {
if (i == correctIndex) {
options.push_back(intToString(result));
} else {
options.push_back(intToString(wrongAnswers[i > correctIndex ? i-1 : i]));
}
}
return Question(questionText, options, correctIndex);
} else {
// 开方题
int base = 2 + rand() % 12; // 2-13
int squared = base * base;
// 方案1: 使用Unicode平方根符号
// std::string questionText = "√(" + intToString(squared) + ") = ?";
// 方案2: 使用文本描述
std::string questionText = "根号" + intToString(squared) + " = ?";
if (isDuplicate(questionText)) {
return generateMiddleSchoolQuestion();
}
addToHistory(questionText);
// 生成选项
std::vector<std::string> options;
int correctIndex = rand() % 4;
std::vector<int> wrongAnswers;
for (int i = 0; i < 3; ++i) {
int wrongAnswer;
do {
wrongAnswer = base + (rand() % 5) - 2; // -2到+2的偏移
if (wrongAnswer <= 0) wrongAnswer = 1;
} while (wrongAnswer == base ||
std::find(wrongAnswers.begin(), wrongAnswers.end(), wrongAnswer) != wrongAnswers.end());
wrongAnswers.push_back(wrongAnswer);
}
for (int i = 0; i < 4; ++i) {
if (i == correctIndex) {
options.push_back(intToString(base));
} else {
options.push_back(intToString(wrongAnswers[i > correctIndex ? i-1 : i]));
}
}
return Question(questionText, options, correctIndex);
}
}
Question QuestionGenerator::generateHighSchoolQuestion() {
const char* trigFunctions[] = {"sin", "cos", "tan"};
const char* currentFunc = trigFunctions[rand() % 3];
int angle = 0;
double result = 0.0;
int commonAngles[] = {0, 30, 45, 60, 90};
angle = commonAngles[rand() % 5];
double radian = angle * 3.14159 / 180.0;
if (std::string(currentFunc) == "sin") {
result = sin(radian);
} else if (std::string(currentFunc) == "cos") {
result = cos(radian);
} else {
if (angle == 90) angle = 45;
radian = angle * 3.14159 / 180.0;
result = tan(radian);
}
result = round(result * 100) / 100.0;
std::string questionText = std::string(currentFunc) + "(" + intToString(angle) + "°) = ?";
if (isDuplicate(questionText)) {
return generateHighSchoolQuestion();
}
addToHistory(questionText);
std::vector<std::string> options;
int correctIndex = rand() % 4;
std::vector<double> wrongAnswers;
for (int i = 0; i < 3; ++i) {
double wrongAnswer;
do {
double offset = (rand() % 20 + 5) / 100.0;
if (rand() % 2 == 0) {
wrongAnswer = result + offset;
} else {
wrongAnswer = result - offset;
if (wrongAnswer < -1.0) wrongAnswer = result + offset;
}
wrongAnswer = round(wrongAnswer * 100) / 100.0;
} while (wrongAnswer == result ||
std::find(wrongAnswers.begin(), wrongAnswers.end(), wrongAnswer) != wrongAnswers.end());
wrongAnswers.push_back(wrongAnswer);
}
for (int i = 0; i < 4; ++i) {
if (i == correctIndex) {
options.push_back(doubleToString(result));
} else {
options.push_back(doubleToString(wrongAnswers[i > correctIndex ? i-1 : i]));
}
}
return Question(questionText, options, correctIndex);
}
bool QuestionGenerator::isDuplicate(const std::string& questionText) {
for (std::set<std::string>::iterator it = questionHistory.begin(); it != questionHistory.end(); ++it) {
if (*it == questionText) {
return true;
}
}
return false;
}
void QuestionGenerator::addToHistory(const std::string& questionText) {
questionHistory.insert(questionText);
}
void QuestionGenerator::clearHistory() {
questionHistory.clear();
}

@ -0,0 +1,29 @@
#ifndef QUESTIONGENERATOR_H
#define QUESTIONGENERATOR_H
#include "Question.h"
#include <vector>
#include <string>
#include <set>
class QuestionGenerator {
public:
QuestionGenerator(const std::string& userType);
std::vector<Question> generateQuestions(int count);
void clearHistory();
private:
std::string userType;
std::set<std::string> questionHistory;
Question generateElementaryQuestion();
Question generateMiddleSchoolQuestion();
Question generateHighSchoolQuestion();
int findDivisor(int number);
bool isDuplicate(const std::string& questionText);
void addToHistory(const std::string& questionText);
};
#endif

Binary file not shown.

@ -0,0 +1,195 @@
#include "QuestionWindow.h"
#include "QuestionGenerator.h"
#include "SelectionWindow.h"
#include <string>
#include <sstream>
#include <windows.h>
#include <iostream> // 添加iostream用于调试输出
HWND QuestionWindow::hwnd = NULL;
HWND QuestionWindow::hQuestionText = NULL;
HWND QuestionWindow::hOptions[4] = {NULL, NULL, NULL, NULL};
HWND QuestionWindow::hNextButton = NULL;
HWND QuestionWindow::hProgress = NULL;
std::vector<Question> QuestionWindow::questions;
int QuestionWindow::currentQuestion = 0;
int QuestionWindow::score = 0;
void QuestionWindow::Show(const std::string& userType, int questionCount) {
// 如果窗口已存在,先销毁
if (hwnd != NULL) {
DestroyWindow(hwnd);
hwnd = NULL;
}
// 生成题目 - 使用传入的题目数量
QuestionGenerator generator(userType);
questions = generator.generateQuestions(questionCount);
currentQuestion = 0;
score = 0;
WNDCLASSEX wc;
memset(&wc, 0, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = GetModuleHandle(NULL);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = "QuestionWindow";
RegisterClassEx(&wc);
hwnd = CreateWindowEx(0, "QuestionWindow", "数学学习软件 - 答题",
WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, 500, 400,
NULL, NULL, GetModuleHandle(NULL), NULL);
if (!hwnd) {
MessageBox(NULL, "创建答题窗口失败", "错误", MB_OK | MB_ICONERROR);
return;
}
CreateControls();
LoadQuestion();
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
}
void QuestionWindow::CreateControls() {
// 进度显示
hProgress = CreateWindow("STATIC", "", WS_VISIBLE | WS_CHILD | SS_LEFT,
10, 10, 200, 25, hwnd, NULL, GetModuleHandle(NULL), NULL);
// 题目文本
hQuestionText = CreateWindow("STATIC", "", WS_VISIBLE | WS_CHILD | SS_LEFT | WS_BORDER,
10, 50, 460, 60, hwnd, NULL, GetModuleHandle(NULL), NULL);
// 选项按钮
for (int i = 0; i < 4; i++) {
hOptions[i] = CreateWindow("BUTTON", "", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON,
10, 120 + i * 40, 460, 30, hwnd, (HMENU)(10 + i),
GetModuleHandle(NULL), NULL);
}
// 下一题按钮
hNextButton = CreateWindow("BUTTON", "下一题", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
200, 300, 100, 30, hwnd, (HMENU)20, GetModuleHandle(NULL), NULL);
}
LRESULT CALLBACK QuestionWindow::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_COMMAND: {
int cmd = LOWORD(wParam);
if (cmd == 20) { // 下一题按钮
OnNextQuestion();
}
break;
}
case WM_CLOSE:
DestroyWindow(hwnd);
SelectionWindow::Show(); // 关闭时返回选择界面
break;
case WM_DESTROY:
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
void QuestionWindow::LoadQuestion() {
if (currentQuestion >= (int)questions.size()) {
ShowResult();
return;
}
Question& question = questions[currentQuestion];
// 更新进度
std::stringstream progress;
progress << "进度: " << (currentQuestion + 1) << "/" << questions.size();
SetWindowText(hProgress, progress.str().c_str());
// 设置题目文本
SetWindowText(hQuestionText, question.getText().c_str());
// 设置选项
std::vector<std::string> options = question.getOptions();
// 调试输出:显示正确答案(在控制台)
std::cout << "题目 " << (currentQuestion + 1) << ": " << question.getText() << std::endl;
std::cout << "正确答案: 选项" << (question.getCorrectAnswer() + 1)
<< " - " << options[question.getCorrectAnswer()] << std::endl;
std::cout << "所有选项: ";
for (int i = 0; i < 4; i++) {
std::cout << "[" << (i+1) << "]" << options[i] << " ";
}
std::cout << std::endl << std::endl;
for (int i = 0; i < 4; i++) {
if (i < (int)options.size()) {
SetWindowText(hOptions[i], options[i].c_str());
}
SendMessage(hOptions[i], BM_SETCHECK, BST_UNCHECKED, 0);
}
if (currentQuestion == (int)questions.size() - 1) {
SetWindowText(hNextButton, "提交");
}
}
void QuestionWindow::OnNextQuestion() {
// 检查当前选择的答案
int selectedAnswer = -1;
for (int i = 0; i < 4; i++) {
if (SendMessage(hOptions[i], BM_GETCHECK, 0, 0) == BST_CHECKED) {
selectedAnswer = i;
break;
}
}
if (selectedAnswer == -1) {
MessageBox(hwnd, "请选择一个答案", "提示", MB_OK | MB_ICONINFORMATION);
return;
}
// 检查答案
if (questions[currentQuestion].checkAnswer(selectedAnswer)) {
score++;
std::cout << "" << (currentQuestion + 1) << "题回答正确!" << std::endl;
} else {
std::cout << "" << (currentQuestion + 1) << "题回答错误!" << std::endl;
}
currentQuestion++;
LoadQuestion();
}
void QuestionWindow::ShowResult() {
std::stringstream result;
int total = questions.size();
int percentage = (total > 0) ? (score * 100 / total) : 0;
result << "答题完成!\n得分: " << score << "/" << total
<< "\n正确率: " << percentage << "%\n\n"
<< "请选择:\n"
<< "是 - 返回选择界面\n"
<< "否 - 结束程序";
// 显示带有选项的消息框
int choice = MessageBox(hwnd, result.str().c_str(), "答题结果",
MB_YESNO | MB_ICONINFORMATION | MB_DEFBUTTON1);
DestroyWindow(hwnd);
hwnd = NULL;
if (choice == IDYES) {
// 用户选择"是" - 继续做题,返回选择界面
SelectionWindow::Show();
} else {
// 用户选择"否" - 退出程序
PostQuitMessage(0);
}
}

@ -0,0 +1,32 @@
#ifndef QUESTIONWINDOW_H
#define QUESTIONWINDOW_H
#include <windows.h>
#include <vector>
#include <string>
#include "Question.h"
class QuestionWindow {
public:
static void Show(const std::string& userType, int questionCount);
static HWND GetHandle() { return hwnd; }
private:
static HWND hwnd;
static HWND hQuestionText;
static HWND hOptions[4];
static HWND hNextButton;
static HWND hProgress;
static std::vector<Question> questions;
static int currentQuestion;
static int score;
static void CreateControls();
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
static void LoadQuestion();
static void OnNextQuestion();
static void ShowResult();
};
#endif

Binary file not shown.

@ -0,0 +1,161 @@
#include "SelectionWindow.h"
#include "QuestionWindow.h"
#include "LoginWindow.h"
#include "UserManager.h"
#include <string>
HWND SelectionWindow::hwnd = NULL;
HWND SelectionWindow::hQuestionCount = NULL;
void SelectionWindow::Show() {
// 如果窗口已存在,先销毁
if (hwnd != NULL) {
DestroyWindow(hwnd);
hwnd = NULL;
}
WNDCLASSEX wc;
memset(&wc, 0, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = GetModuleHandle(NULL);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = "SelectionWindow";
RegisterClassEx(&wc);
hwnd = CreateWindowEx(0, "SelectionWindow", "数学学习软件 - 选择难度",
WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 350,
NULL, NULL, GetModuleHandle(NULL), NULL);
if (!hwnd) {
MessageBox(NULL, "创建选择窗口失败", "错误", MB_OK | MB_ICONERROR);
return;
}
CreateControls();
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
}
void SelectionWindow::CreateControls() {
// 标题
CreateWindow("STATIC", "请选择题目难度", WS_VISIBLE | WS_CHILD | SS_CENTER,
10, 20, 360, 30, hwnd, NULL, GetModuleHandle(NULL), NULL);
// 题目数量输入
CreateWindow("STATIC", "题目数量 (10-30):", WS_VISIBLE | WS_CHILD,
50, 60, 120, 25, hwnd, NULL, GetModuleHandle(NULL), NULL);
hQuestionCount = CreateWindow("EDIT", "10", WS_VISIBLE | WS_CHILD | WS_BORDER,
180, 60, 60, 25, hwnd, NULL, GetModuleHandle(NULL), NULL);
// 小学按钮
CreateWindow("BUTTON", "小学题目", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
100, 100, 200, 40, hwnd, (HMENU)1, GetModuleHandle(NULL), NULL);
// 初中按钮
CreateWindow("BUTTON", "初中题目", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
100, 150, 200, 40, hwnd, (HMENU)2, GetModuleHandle(NULL), NULL);
// 高中按钮
CreateWindow("BUTTON", "高中题目", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
100, 200, 200, 40, hwnd, (HMENU)3, GetModuleHandle(NULL), NULL);
// 退出登录按钮
CreateWindow("BUTTON", "退出登录", WS_VISIBLE | WS_CHILD,
150, 260, 100, 30, hwnd, (HMENU)4, GetModuleHandle(NULL), NULL);
}
LRESULT CALLBACK SelectionWindow::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_COMMAND: {
int cmd = LOWORD(wParam);
if (cmd == 1) { // 小学题目
OnElementarySelected();
} else if (cmd == 2) { // 初中题目
OnMiddleSchoolSelected();
} else if (cmd == 3) { // 高中题目
OnHighSchoolSelected();
} else if (cmd == 4) { // 退出登录
OnLogout();
}
break;
}
case WM_CLOSE:
DestroyWindow(hwnd);
LoginWindow::Show(); // 关闭选择窗口时返回登录界面
break;
case WM_DESTROY:
// 不在WM_DESTROY中调用PostQuitMessage
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
bool SelectionWindow::validateQuestionCount() {
int count = getQuestionCount();
if (count < 10 || count > 30) {
MessageBox(hwnd, "题目数量必须在10-30之间", "输入错误", MB_OK | MB_ICONWARNING);
SetFocus(hQuestionCount);
return false;
}
return true;
}
int SelectionWindow::getQuestionCount() {
char countText[10];
GetWindowText(hQuestionCount, countText, sizeof(countText));
// 转换为整数
int count = atoi(countText);
if (count <= 0) {
count = 10; // 默认值
}
return count;
}
void SelectionWindow::OnElementarySelected() {
if (!validateQuestionCount()) {
return;
}
int questionCount = getQuestionCount();
DestroyWindow(hwnd);
hwnd = NULL;
QuestionWindow::Show("elementary", questionCount);
}
void SelectionWindow::OnMiddleSchoolSelected() {
if (!validateQuestionCount()) {
return;
}
int questionCount = getQuestionCount();
DestroyWindow(hwnd);
hwnd = NULL;
QuestionWindow::Show("middle", questionCount);
}
void SelectionWindow::OnHighSchoolSelected() {
if (!validateQuestionCount()) {
return;
}
int questionCount = getQuestionCount();
DestroyWindow(hwnd);
hwnd = NULL;
QuestionWindow::Show("high", questionCount);
}
void SelectionWindow::OnLogout() {
UserManager::getInstance().logout();
DestroyWindow(hwnd);
hwnd = NULL;
LoginWindow::Show();
}

@ -0,0 +1,25 @@
#ifndef SELECTIONWINDOW_H
#define SELECTIONWINDOW_H
#include <windows.h>
class SelectionWindow {
public:
static void Show();
static HWND GetHandle() { return hwnd; }
private:
static HWND hwnd;
static HWND hQuestionCount;
static void CreateControls();
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
static void OnElementarySelected();
static void OnMiddleSchoolSelected();
static void OnHighSchoolSelected();
static void OnLogout();
static bool validateQuestionCount();
static int getQuestionCount();
};
#endif

Binary file not shown.

@ -0,0 +1,2 @@
1853439381@qq.com,Temp123,elementary
2470975401@qq.com,123456QWe,elementary

@ -0,0 +1,27 @@
#include <windows.h>
#include <cstdlib>
#include <ctime>
#include "LoginWindow.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
// 初始化随机数种子
srand(static_cast<unsigned int>(time(NULL)));
// 显示登录窗口
LoginWindow::Show();
// 主消息循环
MSG msg;
BOOL bRet;
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
if (bRet == -1) {
// 错误处理
break;
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}

Binary file not shown.

@ -0,0 +1,242 @@
[Project]
FileName=test3.dev
Name=ÏîÄ¿1
Type=0
Ver=2
ObjFiles=
Includes=
Libs=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=
CppCompiler=
Linker=-lws2_32 -lwininet_@@_
IsCpp=1
Icon=
ExeOutput=
ObjectOutput=
LogOutput=
LogOutputEnabled=0
OverrideOutput=0
OverrideOutputName=test3.exe
HostApplication=
UseCustomMakefile=0
CustomMakefile=
CommandLine=
Folders=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000000000000000000000
UnitCount=19
[VersionInfo]
Major=1
Minor=0
Release=0
Build=0
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=1.0.0.0
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
AutoIncBuildNr=0
SyncProduct=1
[Unit9]
FileName=User.h
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit1]
FileName=Question.h
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit2]
FileName=UserManager.h
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit3]
FileName=UserManager.cpp
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit4]
FileName=User.cpp
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit5]
FileName=QuestionGenerator.h
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit6]
FileName=QuestionGenerator.cpp
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit7]
FileName=Question.cpp
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit8]
FileName=LoginWindow.h
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit10]
FileName=LoginWindow.cpp
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit11]
FileName=RegisterWindow.h
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit12]
FileName=RegisterWindow.cpp
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit13]
FileName=QuestionWindow.h
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit14]
FileName=QuestionWindow.cpp
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit15]
FileName=main.cpp
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit17]
FileName=EmailSender.h
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit16]
FileName=EmailSender.cpp
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit19]
FileName=SelectionWindow.h
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit18]
FileName=SelectionWindow.cpp
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=

Binary file not shown.

@ -0,0 +1,98 @@
[Editor_0]
CursorCol=7
CursorRow=25
TopLine=1
LeftChar=1
[Editors]
Order=8,0,1,2,3,4,5,6,7,9,10,11,12,13,14,15,16,17,18
Focused=13
[Editor_1]
CursorCol=7
CursorRow=36
TopLine=1
LeftChar=1
[Editor_2]
CursorCol=2
CursorRow=164
TopLine=122
LeftChar=1
[Editor_3]
CursorCol=2
CursorRow=24
TopLine=1
LeftChar=1
[Editor_4]
CursorCol=7
CursorRow=29
TopLine=1
LeftChar=1
[Editor_5]
CursorCol=2
CursorRow=364
TopLine=326
LeftChar=1
[Editor_6]
CursorCol=2
CursorRow=27
TopLine=1
LeftChar=1
[Editor_7]
CursorCol=7
CursorRow=23
TopLine=1
LeftChar=1
[Editor_8]
CursorCol=7
CursorRow=23
TopLine=1
LeftChar=1
[Editor_9]
CursorCol=2
CursorRow=135
TopLine=1
LeftChar=1
[Editor_10]
CursorCol=7
CursorRow=30
TopLine=1
LeftChar=1
[Editor_11]
CursorCol=2
CursorRow=225
TopLine=131
LeftChar=1
[Editor_12]
CursorCol=7
CursorRow=32
TopLine=1
LeftChar=1
[Editor_13]
CursorCol=18
CursorRow=179
TopLine=150
LeftChar=1
[Editor_14]
CursorCol=2
CursorRow=27
TopLine=1
LeftChar=1
[Editor_15]
CursorCol=56
CursorRow=32
TopLine=1
LeftChar=1
[Editor_16]
CursorCol=7
CursorRow=16
TopLine=1
LeftChar=1
[Editor_17]
CursorCol=2
CursorRow=161
TopLine=1
LeftChar=1
[Editor_18]
CursorCol=7
CursorRow=25
TopLine=1
LeftChar=1
Loading…
Cancel
Save