win32 wstring <-> string

本文提供了两个实用的函数:一个用于将宽字符串(wchar_t)转换为多字节字符串(char),另一个用于相反的转换。通过具体的C++代码示例,展示了如何在不同字符集之间进行高效转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

static std::string w2c(std::wstring str)
	{
		int nlength = str.length();
		int nbytes = WideCharToMultiByte(0,0,str.c_str(),nlength,NULL,0,NULL,NULL);
		if(nbytes == 0) return "";

		char*buff = new char[nbytes+1];
		WideCharToMultiByte(0,0,str.c_str(),nlength,buff,nbytes,NULL,NULL);
		buff[nbytes] = '\0';
		std::string ret_str = std::string(buff);
		delete [] buff;
		return ret_str;		
	}

static std::wstring c2w(std::string str)
	{
		if(str.length() == 0) return std::wstring();

		int nu = str.length();
		size_t n =(size_t)MultiByteToWideChar(CP_ACP,0,str.c_str(),nu,NULL,0);
		wchar_t*wbuff = new wchar_t[n+1];
		MultiByteToWideChar(CP_ACP,0,str.c_str(),(int)nu,wbuff,(int)n);
		wbuff[n] = 0;

		std::wstring wstr_ret = std::wstring(wbuff);
		delete []wbuff;
		return wstr_ret;
	}



转载于:https://my.oschina.net/lyr/blog/375799

// 检查任务是否存在 bool TaskExists(const wchar_t* taskName) { HRESULT hr = S_OK; bool exists = false; CoInitializeEx(NULL, COINIT_MULTITHREADED); ITaskService* pService = NULL; hr = CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskService, (LPVOID*)&pService); if (SUCCEEDED(hr)) { hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()); if (SUCCEEDED(hr)) { ITaskFolder* pRootFolder = NULL; hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder); if (SUCCEEDED(hr)) { IRegisteredTask* pTask = NULL; hr = pRootFolder->GetTask(_bstr_t(taskName), &pTask); if (SUCCEEDED(hr)) { exists = true; pTask->Release(); } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { exists = false; } else { ShowError(L"获取任务信息失败", hr); } pRootFolder->Release(); } } pService->Release(); } CoUninitialize(); return exists; } // 修改参数类型为 char* 和 std::string // 修改参数类型为 char* 和 std::string bool CreateStartupTask(char* taskName, std::string appPath) { // 将输入参数转换为宽字符 std::wstring wTaskName = AnsiToWide(taskName); std::wstring wAppPath = StringToWide(appPath); // 首先检查任务是否存在 if (TaskExists(wTaskName.c_str())) { //MessageBoxW(NULL, L"任务已存在,无需创建", L"信息", MB_ICONINFORMATION); return true; } HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if (FAILED(hr)) { //ShowError(L"初始化COM库失败", hr); return false; } hr = CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL ); if (FAILED(hr) && hr != RPC_E_TOO_LATE) { //ShowError(L"初始化安全库失败", hr); CoUninitialize(); return false; } ITaskService* pService = NULL; hr = CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskService, (LPVOID*)&pService); if (FAILED(hr)) { //ShowError(L"创建任务计划服务实例失败", hr); CoUninitialize(); return false; } hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()); if (FAILED(hr)) { //ShowError(L"连接到任务计划服务失败", hr); pService->Release(); CoUninitialize(); return false; } ITaskFolder* pRootFolder = NULL; hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder); if (FAILED(hr)) { //ShowError(L"获取根文件夹失败", hr); pService->Release(); CoUninitialize(); return false; } // 删除已存在的任务 (虽然我们已经检查过,但还是做一次以防万一) hr = pRootFolder->DeleteTask(_bstr_t(wTaskName.c_str()), 0); if (FAILED(hr) && hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { //ShowError(L"删除现有任务失败", hr); } // 创建新任务 ITaskDefinition* pTask = NULL; hr = pService->NewTask(0, &pTask); if (FAILED(hr)) { //ShowError(L"创建新任务失败", hr); pRootFolder->Release(); pService->Release(); CoUninitialize(); return false; } // 设置任务注册信息 IRegistrationInfo* pRegInfo = NULL; hr = pTask->get_RegistrationInfo(&pRegInfo); if (SUCCEEDED(hr)) { pRegInfo->put_Author(_bstr_t(L"Your Company")); pRegInfo->Release(); } // 设置任务主体 ITaskSettings* pSettings = NULL; hr = pTask->get_Settings(&pSettings); if (SUCCEEDED(hr)) { pSettings->put_StartWhenAvailable(VARIANT_TRUE); pSettings->put_RunOnlyIfNetworkAvailable(VARIANT_FALSE); pSettings->put_DisallowStartIfOnBatteries(VARIANT_FALSE); pSettings->put_StopIfGoingOnBatteries(VARIANT_FALSE); pSettings->Release(); } // 创建登录触发器 ITriggerCollection* pTriggerCollection = NULL; hr = pTask->get_Triggers(&pTriggerCollection); if (SUCCEEDED(hr)) { ITrigger* pTrigger = NULL; hr = pTriggerCollection->Create(TASK_TRIGGER_LOGON, &pTrigger); if (SUCCEEDED(hr)) { ILogonTrigger* pLogonTrigger = NULL; hr = pTrigger->QueryInterface(IID_ILogonTrigger, (LPVOID*)&pLogonTrigger); if (SUCCEEDED(hr)) { pLogonTrigger->put_Id(_bstr_t(L"LogonTrigger")); pLogonTrigger->put_UserId(_bstr_t(L"")); // 当前用户 pLogonTrigger->Release(); } pTrigger->Release(); } pTriggerCollection->Release(); } // 创建操作 IActionCollection* pActionCollection = NULL; hr = pTask->get_Actions(&pActionCollection); if (SUCCEEDED(hr)) { IAction* pAction = NULL; hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction); if (SUCCEEDED(hr)) { IExecAction* pExecAction = NULL; hr = pAction->QueryInterface(IID_IExecAction, (LPVOID*)&pExecAction); if (SUCCEEDED(hr)) { pExecAction->put_Path(_bstr_t(wAppPath.c_str())); pExecAction->Release(); } pAction->Release(); } pActionCollection->Release(); } // 注册任务 IRegisteredTask* pRegisteredTask = NULL; hr = pRootFolder->RegisterTaskDefinition( _bstr_t(wTaskName.c_str()), pTask, TASK_CREATE_OR_UPDATE, _variant_t(), // 空用户名 = 当前用户 _variant_t(), // 空密码 = 当前用户 TASK_LOGON_INTERACTIVE_TOKEN, _variant_t(L""), &pRegisteredTask); if (FAILED(hr)) { //ShowError(L"注册任务失败", hr); } else { //MessageBoxW(NULL, L"成功创建登录启动任务", L"信息", MB_ICONINFORMATION); pRegisteredTask->Release(); } pTask->Release(); pRootFolder->Release(); pService->Release(); CoUninitialize(); return SUCCEEDED(hr); } 修改代码绕过QVM360检测 不要修改原有变量
07-11
#include <iostream> #include <vector> #include <string> #include <thread> #include <mutex> #include <filesystem> #include <sstream> #include <locale> #include <codecvt> #ifdef _WIN32 #include <windows.h> #include <shellapi.h> #define PATH_SEPARATOR L"\\" #define OS_WINDOWS #else #include <unistd.h> #define PATH_SEPARATOR L"/" #endif namespace fs = std::filesystem; // 字符串转换函数 std::wstring ConvertToWString(const std::string& str) { try { // 使用标准库转换工具 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; return converter.from_bytes(str); } catch (...) { // 转换失败时返回默认错误信息 return L"转换错误"; } } // 修复日志输出函数 void OutputLog(const std::wstring& msg) { #ifdef OS_WINDOWS // OutputDebugStringW(msg.c_str()); // 输出到调试器 // OutputDebugStringW(L"\n"); // wprintf(L"%S\n", msg.c_str()); #endif //std::wcout << msg << std::endl; std::wcerr << msg << std::endl; // 输出到控制台 } // 检查管理员权限(跨平台) bool CheckAdminPrivileges() { #ifdef OS_WINDOWS BOOL isAdmin = FALSE; SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; PSID AdministratorsGroup = nullptr; if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup)) { return false; } if (!CheckTokenMembership(nullptr, AdministratorsGroup, &isAdmin)) { FreeSid(AdministratorsGroup); return false; } FreeSid(AdministratorsGroup); return (isAdmin != FALSE); #else return (getuid() == 0); // Linux root检查 #endif } // 实际的文件夹监控函数(Win32 API实现) void MonitorDirectoryWin32(LPCWSTR path) { HANDLE hDir = CreateFileW( path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, nullptr ); if (hDir == INVALID_HANDLE_VALUE) { OutputLog(L"监控失败: " + std::wstring(path)); return; } BYTE buffer[4096]; DWORD bytesReturned; FILE_NOTIFY_INFORMATION* pNotify; while (ReadDirectoryChangesW( hDir, buffer, sizeof(buffer), TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME, &bytesReturned, nullptr, nullptr)) { pNotify = (FILE_NOTIFY_INFORMATION*)buffer; do { std::wstring filename(pNotify->FileName, pNotify->FileNameLength / sizeof(WCHAR)); switch (pNotify->Action) { case FILE_ACTION_ADDED: OutputLog(L"添加: " + filename); break; case FILE_ACTION_REMOVED: OutputLog(L"删除: " + filename); break; case FILE_ACTION_MODIFIED: OutputLog(L"修改: " + filename); break; case FILE_ACTION_RENAMED_OLD_NAME: OutputLog(L"重命名前: " + filename); break; case FILE_ACTION_RENAMED_NEW_NAME: OutputLog(L"重命名后: " + filename); break; } pNotify = pNotify->NextEntryOffset ? (FILE_NOTIFY_INFORMATION*)((BYTE*)pNotify + pNotify->NextEntryOffset) : nullptr; } while (pNotify); } CloseHandle(hDir); } // 递归监控实现(优化线程管理) void MonitorSubdirectories(const std::wstring& rootDir) { std::vector<std::thread> threads; std::mutex mtx; auto monitorFunc = [&mtx](const std::wstring & path) { OutputLog(L"开始监控: " + path); MonitorDirectoryWin32(path.c_str()); }; // 添加根目录 threads.emplace_back(monitorFunc, rootDir); // 递归添加子目录 try { for (const auto& entry : fs::recursive_directory_iterator(rootDir)) { if (entry.is_directory()) { std::lock_guard lock(mtx); threads.emplace_back(monitorFunc, entry.path().wstring()); } } } catch (const fs::filesystem_error& e) { // 使用转换函数处理异常消息 OutputLog(L"目录遍历错误: " + ConvertToWString(e.what())); } // 等待所有线程完成 for (auto& t : threads) { if (t.joinable()) t.join(); } } int main() { // 设置本地化支持 //setlocale(LC_ALL, "chs"); setlocale(LC_ALL, ".UTF-8"); SetConsoleCP(CP_UTF8); SetConsoleOutputCP(CP_UTF8); // 管理员权限检查 if (!CheckAdminPrivileges()) { OutputLog(L"⚠️ 需要管理员权限,正在尝试重启..."); #ifdef OS_WINDOWS WCHAR exePath[MAX_PATH]; GetModuleFileNameW(nullptr, exePath, MAX_PATH); SHELLEXECUTEINFOW sei = { sizeof(sei) }; sei.lpVerb = L"runas"; sei.lpFile = exePath; sei.nShow = SW_SHOWNORMAL; if (!ShellExecuteExW(&sei)) { OutputLog(L"重启失败,错误代码: " + std::to_wstring(GetLastError())); } #endif return 1; } const std::wstring targetDir = L"E:\\Toolshed\\RedPanda-CPP\\projects"; OutputLog(L"🔍 开始监控目录: " + targetDir); MonitorSubdirectories(targetDir); return 0; } 帮我完善代码使用GCC写个Win32UI窗口,列表框{序号,路径文件名,文件修改时间,变化状态},右键菜单{开启监听/停止监听,打开文件,定位文件},监听的变化输出到窗口的列表,
最新发布
08-10
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <windows.h> #include <graphics.h> #include <easyx.h> #include <mmsystem.h> #include <time.h> #include <functional> #include <string> #include <vector> #include <iostream> #include <conio.h> #include <io.h> #include <shlwapi.h> #include <algorithm> #pragma comment(lib, "winmm.lib") #pragma comment(lib, "shlwapi.lib") // 解决time_t格式化问题 #ifdef _WIN32 #define TIME_T_FMT "%lld" #else #define TIME_T_FMT "%ld" #endif // 座位状态常量 #define SEAT_AVAILABLE L"空闲" #define SEAT_RESERVED L"已预约" #define SEAT_OCCUPIED L"已占用" #define SEAT_MAINTAIN L"维护中" // 数据文件路径 #define SEAT_DATA_FILE L"seats.txt" #define USER_DATA_FILE L"users.txt" // 定义Button类,表示一个按钮 class Button { private: int x; int y; int width; int height; float scale; bool isMouseOver; std::wstring text; std::function<void()> onClick; public: Button(int x, int y, int width, int height, const std::wstring& text, const std::function<void()>& onClick) : x(x), y(y), width(width), height(height), text(text), onClick(onClick), scale(1.0f), isMouseOver(false) { } void checkMouseOver(int mouseX, int mouseY) { isMouseOver = (mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height); if (isMouseOver) { scale = 0.95f; } else { scale = 1.0f; } } bool checkClick(int mouseX, int mouseY) { if (mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height) { onClick(); isMouseOver = false; scale = 1.0f; return true; } return false; } void draw() { int scaledWidth = static_cast<int>(width * scale); int scaledHeight = static_cast<int>(height * scale); int scaledX = x + (width - scaledWidth) / 2; int scaledY = y + (height - scaledHeight) / 2; if (isMouseOver) { setlinecolor(RGB(0, 120, 215)); setfillcolor(RGB(229, 241, 251)); } else { setlinecolor(RGB(100, 149, 237)); setfillcolor(RGB(173, 216, 230)); } fillroundrect(scaledX, scaledY, scaledX + scaledWidth, scaledY + scaledHeight, 10, 10); settextcolor(BLACK); setbkmode(TRANSPARENT); settextstyle(static_cast<int>(20 * scale), 0, _T("微软雅黑")); int textX = scaledX + (scaledWidth - textwidth(text.c_str())) / 2; int textY = scaledY + (scaledHeight - textheight(_T("T"))) / 2; outtextxy(textX, textY, text.c_str()); } }; class Widget { public: // 将pages和buttons改为public std::vector<IMAGE*> pages; std::vector<std::vector<Button*>> buttons; private: int width; int height; int currentIndex; public: Widget(int width, int height) :width(width), height(height), currentIndex(-1) { } ~Widget() { clearPages(); } void clearPages() { for (auto page : pages) { delete page; } pages.clear(); for (auto& pageButtons : buttons) { for (auto button : pageButtons) { delete button; } pageButtons.clear(); } buttons.clear(); } void addPage(IMAGE* page) { pages.push_back(page); buttons.push_back({}); } void addButton(int index, Button* button) { if (index >= 0 && index < static_cast<int>(buttons.size())) { buttons[index].push_back(button); } } void setCurrentIndex(int index) { if (index >= 0 && index < static_cast<int>(pages.size())) { currentIndex = index; } } int getCurrentIndex() const { return currentIndex; } void init() { initgraph(width, height); } void run() { ExMessage msg; BeginBatchDraw(); while (true) { if (peekmessage(&msg)) { int mouseX = msg.x; int mouseY = msg.y; switch (msg.message) { case WM_LBUTTONDOWN: if (currentIndex >= 0 && currentIndex < static_cast<int>(buttons.size())) { for (Button* button : buttons[currentIndex]) { if (button->checkClick(mouseX, mouseY)) break; } } break; case WM_MOUSEMOVE: if (currentIndex >= 0 && currentIndex < static_cast<int>(buttons.size())) { for (Button* button : buttons[currentIndex]) { button->checkMouseOver(mouseX, mouseY); } } break; case WM_KEYDOWN: if (msg.vkcode == VK_ESCAPE) // 按ESC键退出 { return; } break; } } cleardevice(); if (currentIndex >= 0 && currentIndex < static_cast<int>(pages.size())) { putimage(0, 0, pages[currentIndex]); for (Button* button : buttons[currentIndex]) { button->draw(); } } // 添加页面标题 settextcolor(RGB(25, 25, 112)); settextstyle(32, 0, _T("微软雅黑")); switch (currentIndex) { case 0: outtextxy(220, 50, _T("湘潭大学图书馆座位预约系统")); break; case 1: outtextxy(300, 50, _T("用户功能菜单")); break; case 2: outtextxy(300, 50, _T("管理员功能菜单")); break; case 3: outtextxy(300, 50, _T("座位查询功能")); break; } // 添加操作提示 settextcolor(RGB(70, 70, 70)); settextstyle(16, 0, _T("微软雅黑")); outtextxy(20, height - 30, _T("提示: 鼠标悬停在按钮上可查看效果,ESC键退出系统")); FlushBatchDraw(); Sleep(10); } EndBatchDraw(); } void close() { closegraph(); } }; // 结构体定义 typedef struct Seats { wchar_t number[50]; wchar_t state[20]; int floor; struct Seats* next; struct Seats* prev; } Seat; typedef struct User { wchar_t studentId[20]; wchar_t password[20]; wchar_t reservedSeat[50]; time_t registerTime; struct User* next; } User; typedef struct SeatQueue { Seat* front; Seat* rear; int count; } SeatQueue; // 全局变量 SeatQueue* seatQueue = NULL; User* userList = NULL; User* currentUser = NULL; bool isAdmin = false; int musicPlaying = 0; Widget* globalWidget = nullptr; // 函数声明 SeatQueue* createQueue(); void destroyQueue(SeatQueue* queue); Seat* createSeat(const wchar_t* number, int floor, const wchar_t* state); void addSeat(SeatQueue* queue, Seat* seat); void removeSeat(SeatQueue* queue, Seat* seat); Seat* findSeatByNumber(SeatQueue* queue, const wchar_t* number); Seat* findSeatByFloor(SeatQueue* queue, int floor, Seat* startAfter); Seat* findSeatByState(SeatQueue* queue, const wchar_t* state, Seat* startAfter); Seat* findRandomAvailableSeat(SeatQueue* queue); void loadSeats(SeatQueue* queue, const wchar_t* filename); void saveSeats(SeatQueue* queue, const wchar_t* filename); int loginUser(User** user); void addUser(User** head, const wchar_t* id, const wchar_t* password); void loadUsers(User** head, const wchar_t* filename); void saveUsers(User* head, const wchar_t* filename); User* findUser(User* head, const wchar_t* id); void handleReserveSeat(User* user, const wchar_t* seatNumber); // 移除默认参数 void handleCancelReservation(User* user); void updateSeatState(Seat* seat, const wchar_t* state); void displayRandomAvailableSeat(); int adminLogin(); void initGlobalWidget(); void initMainMenuButtons(); void initUserMenuButtons(); void initAdminMenuButtons(); void initSeatQueryButtons(); void cleanup(); void displaySeatList(Seat* startSeat, const wchar_t* title, int maxCount, std::function<Seat* (Seat*)> getNextFunc, bool showReserveButtons = false); void displaySeatListPage(const wchar_t* title, std::function<Seat* (Seat*)> getFirstFunc, std::function<Seat* (Seat*)> getNextFunc, bool showReserveButtons = false); // 座位队列相关函数实现 SeatQueue* createQueue() { SeatQueue* queue = (SeatQueue*)malloc(sizeof(SeatQueue)); if (!queue) { MessageBox(NULL, L"内存分配失败", L"错误", MB_OK | MB_ICONERROR); exit(1); } queue->front = queue->rear = NULL; queue->count = 0; return queue; } void destroyQueue(SeatQueue* queue) { if (!queue) return; Seat* current = queue->front; while (current) { Seat* next = current->next; free(current); current = next; } free(queue); } Seat* createSeat(const wchar_t* number, int floor, const wchar_t* state) { Seat* seat = (Seat*)malloc(sizeof(Seat)); if (!seat) { MessageBox(NULL, L"内存分配失败", L"错误", MB_OK | MB_ICONERROR); exit(1); } wcscpy_s(seat->number, number); wcscpy_s(seat->state, state); seat->floor = floor; seat->next = seat->prev = NULL; return seat; } void addSeat(SeatQueue* queue, Seat* seat) { if (!queue || !seat) return; if (!queue->rear) { queue->front = queue->rear = seat; } else { queue->rear->next = seat; seat->prev = queue->rear; queue->rear = seat; } queue->count++; } void removeSeat(SeatQueue* queue, Seat* seat) { if (!queue || !seat) return; if (seat->prev) seat->prev->next = seat->next; else queue->front = seat->next; if (seat->next) seat->next->prev = seat->prev; else queue->rear = seat->prev; queue->count--; free(seat); } // 查找座位 Seat* findSeatByNumber(SeatQueue* queue, const wchar_t* number) { if (!queue || !number) return NULL; Seat* current = queue->front; while (current) { if (wcscmp(current->number, number) == 0) { return current; } current = current->next; } return NULL; } Seat* findSeatByFloor(SeatQueue* queue, int floor, Seat* startAfter) { if (!queue) return NULL; Seat* current = startAfter ? startAfter->next : queue->front; while (current) { if (current->floor == floor) { return current; } current = current->next; } return NULL; } Seat* findSeatByState(SeatQueue* queue, const wchar_t* state, Seat* startAfter) { if (!queue || !state) return NULL; Seat* current = startAfter ? startAfter->next : queue->front; while (current) { if (wcscmp(current->state, state) == 0) { return current; } current = current->next; } return NULL; } // 查找随机可用座位 Seat* findRandomAvailableSeat(SeatQueue* queue) { if (!queue) return NULL; // 统计可用座位数量 int availableCount = 0; Seat* current = queue->front; while (current) { if (wcscmp(current->state, SEAT_AVAILABLE) == 0) { availableCount++; } current = current->next; } if (availableCount == 0) return NULL; // 随机选择一个可用座位 srand(static_cast<unsigned int>(time(NULL))); int randomIndex = rand() % availableCount; int currentIndex = 0; current = queue->front; while (current) { if (wcscmp(current->state, SEAT_AVAILABLE) == 0) { if (currentIndex == randomIndex) { return current; } currentIndex++; } current = current->next; } return NULL; } // 文件操作函数 void loadSeats(SeatQueue* queue, const wchar_t* filename) { if (!queue) return; FILE* file = _wfopen(filename, L"r"); if (!file) { wprintf(L"座位数据文件不存在,创建默认数据...\n"); // 添加更多初始座位数据 addSeat(queue, createSeat(L"A101", 1, SEAT_AVAILABLE)); addSeat(queue, createSeat(L"A102", 1, SEAT_AVAILABLE)); addSeat(queue, createSeat(L"A103", 1, SEAT_RESERVED)); addSeat(queue, createSeat(L"A104", 1, SEAT_OCCUPIED)); addSeat(queue, createSeat(L"A105", 1, SEAT_MAINTAIN)); addSeat(queue, createSeat(L"A106", 1, SEAT_AVAILABLE)); addSeat(queue, createSeat(L"A107", 1, SEAT_AVAILABLE)); addSeat(queue, createSeat(L"A108", 1, SEAT_RESERVED)); addSeat(queue, createSeat(L"A109", 1, SEAT_AVAILABLE)); addSeat(queue, createSeat(L"A110", 1, SEAT_OCCUPIED)); addSeat(queue, createSeat(L"B201", 2, SEAT_AVAILABLE)); addSeat(queue, createSeat(L"B202", 2, SEAT_AVAILABLE)); addSeat(queue, createSeat(L"B203", 2, SEAT_AVAILABLE)); addSeat(queue, createSeat(L"B204", 2, SEAT_RESERVED)); addSeat(queue, createSeat(L"B205", 2, SEAT_OCCUPIED)); addSeat(queue, createSeat(L"B206", 2, SEAT_MAINTAIN)); addSeat(queue, createSeat(L"B207", 2, SEAT_AVAILABLE)); addSeat(queue, createSeat(L"B208", 2, SEAT_AVAILABLE)); addSeat(queue, createSeat(L"B209", 2, SEAT_RESERVED)); addSeat(queue, createSeat(L"B210", 2, SEAT_AVAILABLE)); addSeat(queue, createSeat(L"C301", 3, SEAT_AVAILABLE)); addSeat(queue, createSeat(L"C302", 3, SEAT_AVAILABLE)); addSeat(queue, createSeat(L"C303", 3, SEAT_RESERVED)); addSeat(queue, createSeat(L"C304", 3, SEAT_RESERVED)); addSeat(queue, createSeat(L"C305", 3, SEAT_MAINTAIN)); addSeat(queue, createSeat(L"C306", 3, SEAT_OCCUPIED)); addSeat(queue, createSeat(L"C307", 3, SEAT_AVAILABLE)); addSeat(queue, createSeat(L"C308", 3, SEAT_AVAILABLE)); addSeat(queue, createSeat(L"C309", 3, SEAT_RESERVED)); addSeat(queue, createSeat(L"C310", 3, SEAT_AVAILABLE)); // 保存初始数据到文件 saveSeats(queue, filename); return; } wchar_t number[50], state[20]; int floor; while (fwscanf(file, L"%49s %d %19s", number, &floor, state) != EOF) { addSeat(queue, createSeat(number, floor, state)); } fclose(file); } void saveSeats(SeatQueue* queue, const wchar_t* filename) { if (!queue) return; FILE* file = _wfopen(filename, L"w"); if (!file) { MessageBox(NULL, L"无法保存座位数据", L"错误", MB_OK | MB_ICONERROR); return; } Seat* current = queue->front; while (current) { fwprintf(file, L"%s %d %s\n", current->number, current->floor, current->state); current = current->next; } fclose(file); } // 用户管理函数 void loadUsers(User** head, const wchar_t* filename) { FILE* file = _wfopen(filename, L"r"); if (!file) { wprintf(L"用户数据文件不存在,创建默认用户...\n"); // 添加初始用户数据 addUser(head, L"20250001", L"123456"); addUser(head, L"20250002", L"654321"); addUser(head, L"20250003", L"123456"); // 为部分用户分配预约座位 User* user1 = findUser(*head, L"20250001"); if (user1) { wcscpy_s(user1->reservedSeat, L"A103"); saveUsers(*head, filename); } User* user2 = findUser(*head, L"20250002"); if (user2) { wcscpy_s(user2->reservedSeat, L"B204"); saveUsers(*head, filename); } return; } wchar_t id[20], password[20], seat[50]; time_t regTime; while (fwscanf(file, L"%19s %19s %49s " TIME_T_FMT, id, password, seat, &regTime) != EOF) { User* user = (User*)malloc(sizeof(User)); if (!user) { MessageBox(NULL, L"内存分配失败", L"错误", MB_OK | MB_ICONERROR); continue; } wcscpy_s(user->studentId, id); wcscpy_s(user->password, password); wcscpy_s(user->reservedSeat, seat); user->registerTime = regTime; user->next = *head; *head = user; } fclose(file); } void saveUsers(User* head, const wchar_t* filename) { FILE* file = _wfopen(filename, L"w"); if (!file) { MessageBox(NULL, L"无法保存用户数据", L"错误", MB_OK | MB_ICONERROR); return; } User* current = head; while (current) { fwprintf(file, L"%s %s %s " TIME_T_FMT L"\n", current->studentId, current->password, current->reservedSeat, current->registerTime); current = current->next; } fclose(file); } // 用户登录 int loginUser(User** user) { wchar_t id[20], password[20]; // 清空当前屏幕 cleardevice(); // 绘制登录界面 IMAGE loginBg; if (_waccess(_T("login_bg.jpg"), 0) != -1) { loadimage(&loginBg, _T("login_bg.jpg"), 800, 600, true); putimage(0, 0, &loginBg); } else { setbkcolor(RGB(240, 248, 255)); // 淡蓝色背景 cleardevice(); } // 绘制标题 settextstyle(30, 0, _T("微软雅黑")); settextcolor(RGB(25, 25, 112)); // 深蓝色 outtextxy(220, 50, _T("湘潭大学图书馆座位预约系统")); settextstyle(20, 0, _T("微软雅黑")); settextcolor(RGB(0, 0, 139)); // 深蓝色 outtextxy(350, 150, _T("用户登录")); // 添加操作提示 settextstyle(16, 0, _T("微软雅黑")); settextcolor(RGB(70, 70, 70)); outtextxy(250, 200, _T("请输入您的学号和密码登录系统")); outtextxy(250, 230, _T("默认用户: 20250001(123456), 20250002(654321)")); FlushBatchDraw(); // 输入学号 if (InputBox(id, sizeof(id) / sizeof(wchar_t), _T("请输入学号"), NULL, NULL, 0, FALSE) <= 0) { return 0; // 用户取消 } // 输入密码 if (InputBox(password, sizeof(password) / sizeof(wchar_t), _T("请输入密码"), NULL, NULL, 0, TRUE) <= 0) { return 0; // 用户取消 } if (wcscmp(id, L"20250001") == 0 && wcscmp(password, L"123456") == 0) { // 清空登录界面 cleardevice(); // 显示欢迎信息 settextstyle(30, 0, _T("微软雅黑")); settextcolor(RGB(25, 25, 112)); outtextxy(250, 200, L"登录成功,正在跳转..."); FlushBatchDraw(); Sleep(1500); return 1; } // 从文件验证用户 User* found = findUser(userList, id); if (found && wcscmp(found->password, password) == 0) { *user = found; // 清空登录界面 cleardevice(); // 显示欢迎信息 settextstyle(30, 0, _T("微软雅黑")); settextcolor(RGB(25, 25, 112)); outtextxy(250, 200, L"登录成功,正在跳转..."); FlushBatchDraw(); Sleep(1500); return 1; } MessageBox(NULL, _T("登录失败,请检查学号和密码"), _T("错误"), MB_OK | MB_ICONERROR); return 0; } // 添加用户 void addUser(User** head, const wchar_t* id, const wchar_t* password) { if (findUser(*head, id)) { MessageBox(NULL, _T("该用户已存在"), _T("错误"), MB_OK | MB_ICONERROR); return; } User* newUser = (User*)malloc(sizeof(User)); if (!newUser) { MessageBox(NULL, _T("内存分配失败"), _T("错误"), MB_OK | MB_ICONERROR); return; } wcscpy_s(newUser->studentId, id); wcscpy_s(newUser->password, password); newUser->reservedSeat[0] = L'\0'; newUser->registerTime = time(NULL); newUser->next = *head; *head = newUser; saveUsers(*head, USER_DATA_FILE); } // 查找用户 User* findUser(User* head, const wchar_t* id) { User* current = head; while (current) { if (wcscmp(current->studentId, id) == 0) { return current; } current = current->next; } return NULL; } // 处理座位预约 - 移除定义中的默认参数 void handleReserveSeat(User* user, const wchar_t* seatNumber) { if (!user) { MessageBox(NULL, _T("请先登录"), _T("错误"), MB_OK | MB_ICONERROR); return; } if (wcslen(user->reservedSeat) > 0) { MessageBox(NULL, _T("你已经预约了座位,不能重复预约"), _T("错误"), MB_OK | MB_ICONERROR); return; } wchar_t seatNum[50]; if (seatNumber) { wcscpy_s(seatNum, seatNumber); } else { if (InputBox(seatNum, sizeof(seatNum) / sizeof(wchar_t), _T("请输入要预约的座位编号(例如:A101)"), NULL, NULL, 0, FALSE) <= 0) { return; // 用户取消操作 } } Seat* seat = findSeatByNumber(seatQueue, seatNum); if (!seat) { MessageBox(NULL, _T("未找到该座位,请检查座位编号是否正确"), _T("错误"), MB_OK | MB_ICONERROR); return; } if (wcscmp(seat->state, SEAT_AVAILABLE) != 0) { wchar_t msg[100]; swprintf_s(msg, L"该座位不可预约,当前状态: %s", seat->state); MessageBox(NULL, msg, _T("错误"), MB_OK | MB_ICONERROR); return; } // 更新座位状态 updateSeatState(seat, SEAT_RESERVED); wcscpy_s(user->reservedSeat, seatNum); saveUsers(userList, USER_DATA_FILE); saveSeats(seatQueue, SEAT_DATA_FILE); wchar_t msg[100]; swprintf_s(msg, L"成功预约座位: %s", seatNum); MessageBox(NULL, msg, L"成功", MB_OK); } // 处理取消预约 void handleCancelReservation(User* user) { if (!user) { MessageBox(NULL, _T("请先登录"), _T("错误"), MB_OK | MB_ICONERROR); return; } if (wcslen(user->reservedSeat) == 0) { MessageBox(NULL, _T("你没有预约任何座位"), _T("提示"), MB_OK); return; } wchar_t msg[100]; swprintf_s(msg, L"确定要取消预约的座位 %s 吗?", user->reservedSeat); int confirm = MessageBox(NULL, msg, L"确认取消预约", MB_YESNO | MB_ICONQUESTION); if (confirm != IDYES) return; Seat* seat = findSeatByNumber(seatQueue, user->reservedSeat); if (!seat) { MessageBox(NULL, _T("未找到你预约的座位"), _T("错误"), MB_OK | MB_ICONERROR); user->reservedSeat[0] = L'\0'; saveUsers(userList, USER_DATA_FILE); return; } // 更新座位状态 updateSeatState(seat, SEAT_AVAILABLE); user->reservedSeat[0] = L'\0'; saveUsers(userList, USER_DATA_FILE); saveSeats(seatQueue, SEAT_DATA_FILE); MessageBox(NULL, _T("成功取消预约"), _T("提示"), MB_OK); } // 管理员登录 int adminLogin() { wchar_t id[20], password[20]; // 清空当前屏幕 cleardevice(); // 绘制登录界面 IMAGE loginBg; if (_waccess(_T("admin_login_bg.jpg"), 0) != -1) { loadimage(&loginBg, _T("admin_login_bg.jpg"), 800, 600, true); putimage(0, 0, &loginBg); } else { setbkcolor(RGB(240, 248, 255)); // 淡蓝色背景 cleardevice(); } // 绘制标题 settextstyle(30, 0, _T("微软雅黑")); settextcolor(RGB(25, 25, 112)); // 深蓝色 outtextxy(220, 50, _T("湘潭大学图书馆座位预约系统")); settextstyle(20, 0, _T("微软雅黑")); settextcolor(RGB(0, 0, 139)); // 深蓝色 outtextxy(350, 150, _T("管理员登录")); // 添加操作提示 settextstyle(16, 0, _T("微软雅黑")); settextcolor(RGB(70, 70, 70)); outtextxy(280, 200, _T("默认账号: admin, 密码: admin123")); FlushBatchDraw(); // 输入管理员账号 if (InputBox(id, sizeof(id) / sizeof(wchar_t), _T("请输入管理员账号"), NULL, NULL, 0, FALSE) <= 0) { return 0; // 用户取消 } // 输入密码 if (InputBox(password, sizeof(password) / sizeof(wchar_t), _T("请输入密码"), NULL, NULL, 0, TRUE) <= 0) { return 0; // 用户取消 } // 简单验证,实际应用中应从数据库或配置文件读取 if (wcscmp(id, L"admin") == 0 && wcscmp(password, L"admin123") == 0) { // 清空登录界面 cleardevice(); // 显示欢迎信息 settextstyle(30, 0, _T("微软雅黑")); settextcolor(RGB(25, 25, 112)); outtextxy(250, 200, L"管理员登录成功,正在跳转..."); FlushBatchDraw(); Sleep(1500); return 1; } MessageBox(NULL, L"登录失败,请检查账号和密码", L"错误", MB_OK | MB_ICONERROR); return 0; } // 显示随机可用座位 void displayRandomAvailableSeat() { Seat* randomSeat = findRandomAvailableSeat(seatQueue); if (!randomSeat) { MessageBox(NULL, _T("当前没有可用的座位"), _T("提示"), MB_OK); return; } wchar_t info[200]; swprintf_s(info, L"系统为您随机推荐一个可用座位:\n\n座位编号: %s\n楼层: %d层\n状态: %s\n\n是否预约该座位?", randomSeat->number, randomSeat->floor, randomSeat->state); int choice = MessageBox(NULL, info, L"随机推荐座位", MB_YESNO | MB_ICONQUESTION); if (choice == IDYES && currentUser) { // 更新座位状态 updateSeatState(randomSeat, SEAT_RESERVED); wcscpy_s(currentUser->reservedSeat, randomSeat->number); saveUsers(userList, USER_DATA_FILE); saveSeats(seatQueue, SEAT_DATA_FILE); wchar_t msg[100]; swprintf_s(msg, L"成功预约座位: %s", randomSeat->number); MessageBox(NULL, msg, L"成功", MB_OK); } } // 更新座位状态 void updateSeatState(Seat* seat, const wchar_t* state) { if (!seat || !state) return; wcscpy_s(seat->state, state); } // 初始化全局控件 void initGlobalWidget() { if (globalWidget) return; globalWidget = new Widget(800, 600); globalWidget->init(); // 创建页面0 - 主菜单 IMAGE* mainPage = new IMAGE(800, 600); if (_waccess(_T("main_bg.jpg"), 0) != -1) { loadimage(mainPage, _T("main_bg.jpg"), 800, 600, true); } else { mainPage->Resize(800, 600); DWORD* pBuf = GetImageBuffer(mainPage); for (int i = 0; i < 800 * 600; i++) { pBuf[i] = RGB(240, 248, 255); // 淡蓝色背景 } } globalWidget->addPage(mainPage); // 创建页面1 - 用户菜单 IMAGE* userPage = new IMAGE(800, 600); if (_waccess(_T("user_bg.jpg"), 0) != -1) { loadimage(userPage, _T("user_bg.jpg"), 800, 600, true); } else { userPage->Resize(800, 600); DWORD* pBuf = GetImageBuffer(userPage); for (int i = 0; i < 800 * 600; i++) { pBuf[i] = RGB(230, 240, 255); // 更浅的蓝色背景 } } globalWidget->addPage(userPage); // 创建页面2 - 管理员菜单 IMAGE* adminPage = new IMAGE(800, 600); if (_waccess(_T("admin_bg.jpg"), 0) != -1) { loadimage(adminPage, _T("admin_bg.jpg"), 800, 600, true); } else { adminPage->Resize(800, 600); DWORD* pBuf = GetImageBuffer(adminPage); for (int i = 0; i < 800 * 600; i++) { pBuf[i] = RGB(230, 240, 255); // 更浅的蓝色背景 } } globalWidget->addPage(adminPage); // 创建页面3 - 座位查询菜单 IMAGE* queryPage = new IMAGE(800, 600); if (_waccess(_T("query_bg.jpg"), 0) != -1) { loadimage(queryPage, _T("query_bg.jpg"), 800, 600, true); } else { queryPage->Resize(800, 600); DWORD* pBuf = GetImageBuffer(queryPage); for (int i = 0; i < 800 * 600; i++) { pBuf[i] = RGB(230, 240, 255); // 更浅的蓝色背景 } } globalWidget->addPage(queryPage); // 初始化所有按钮 initMainMenuButtons(); initUserMenuButtons(); initAdminMenuButtons(); initSeatQueryButtons(); } // 初始化主菜单按钮 void initMainMenuButtons() { // 用户登录按钮 globalWidget->addButton(0, new Button(300, 180, 200, 50, L"用户登录", []() { if (loginUser(&currentUser)) { globalWidget->setCurrentIndex(1); // 切换到用户菜单 } })); // 管理员登录按钮 globalWidget->addButton(0, new Button(300, 250, 200, 50, L"管理员登录", []() { if (adminLogin()) { isAdmin = true; globalWidget->setCurrentIndex(2); // 切换到管理员菜单 } })); // 退出系统按钮 globalWidget->addButton(0, new Button(300, 320, 200, 50, L"退出系统", []() { cleanup(); exit(0); })); // 添加系统说明 globalWidget->addButton(0, new Button(250, 400, 300, 30, L"系统说明", []() { MessageBox(NULL, L"欢迎使用湘潭大学图书馆座位预约系统\n\n" L"1. 用户功能:预约座位、取消预约、查询座位\n" L"2. 管理员功能:管理座位信息\n" L"3. 默认用户:20250001(123456), 20250002(654321)\n" L"4. 管理员账号:admin,密码:admin123\n\n" L"注意:所有操作会自动保存数据", L"系统说明", MB_OK | MB_ICONINFORMATION); })); } // 初始化用户菜单按钮 void initUserMenuButtons() { // 查看个人信息 globalWidget->addButton(1, new Button(300, 150, 200, 50, L"查看个人信息", []() { wchar_t info[200]; struct tm tm_info; wchar_t regTimeStr[26]; // 安全的时间格式化 if (localtime_s(&tm_info, &currentUser->registerTime) == 0) { wcsftime(regTimeStr, 26, L"%Y-%m-%d %H:%M:%S", &tm_info); } else { wcscpy_s(regTimeStr, L"未知时间"); } swprintf_s(info, L"学号: %s\n注册时间: %s\n已预约座位: %s", currentUser->studentId, regTimeStr, wcslen(currentUser->reservedSeat) > 0 ? currentUser->reservedSeat : L"无"); // 创建信息窗口 HWND hWnd = GetHWnd(); MessageBox(hWnd, info, L"个人信息", MB_OK); })); // 预约座位 globalWidget->addButton(1, new Button(300, 220, 200, 50, L"预约座位", []() { handleReserveSeat(currentUser, nullptr); // 显式传递nullptr })); // 取消预约 globalWidget->addButton(1, new Button(300, 290, 200, 50, L"取消预约", []() { handleCancelReservation(currentUser); })); // 座位查询 globalWidget->addButton(1, new Button(300, 360, 200, 50, L"座位查询", []() { globalWidget->setCurrentIndex(3); // 切换到查询页面 })); // 退出登录按钮 globalWidget->addButton(1, new Button(300, 430, 200, 50, L"退出登录", []() { currentUser = NULL; globalWidget->setCurrentIndex(0); // 返回主菜单 })); // 帮助按钮 globalWidget->addButton(1, new Button(300, 500, 200, 30, L"使用帮助", []() { MessageBox(NULL, L"用户功能使用指南:\n\n" L"1. 查看个人信息:查看您的预约信息\n" L"2. 预约座位:输入座位号预约可用座位\n" L"3. 取消预约:取消您当前的预约\n" L"4. 座位查询:按不同条件查询座位状态\n" L"5. 退出登录:返回主菜单\n\n" L"提示:在查询界面可以直接预约空闲座位", L"用户帮助", MB_OK | MB_ICONINFORMATION); })); } // 初始化管理员菜单按钮 void initAdminMenuButtons() { // 添加座位 globalWidget->addButton(2, new Button(300, 150, 200, 50, L"添加座位", []() { wchar_t number[50], state[20], floorStr[10]; int floor; if (InputBox(number, sizeof(number) / sizeof(wchar_t), _T("请输入座位编号(例如:A101)"), NULL, NULL, 0, FALSE) <= 0) { return; // 用户取消 } if (InputBox(floorStr, sizeof(floorStr) / sizeof(wchar_t), _T("请输入楼层(1-5)"), NULL, NULL, 0, FALSE) <= 0) { return; // 用户取消 } floor = _wtoi(floorStr); if (floor < 1 || floor > 5) { MessageBox(NULL, _T("楼层必须在1到5之间"), _T("错误"), MB_OK | MB_ICONERROR); return; } if (InputBox(state, sizeof(state) / sizeof(wchar_t), _T("请输入座位状态(空闲/已预约/已占用/维护中)"), NULL, NULL, 0, FALSE) <= 0) { return; // 用户取消 } Seat* newSeat = createSeat(number, floor, state); addSeat(seatQueue, newSeat); saveSeats(seatQueue, SEAT_DATA_FILE); wchar_t msg[100]; swprintf_s(msg, L"座位 %s 添加成功", number); MessageBox(NULL, msg, L"成功", MB_OK); })); // 删除座位 globalWidget->addButton(2, new Button(300, 220, 200, 50, L"删除座位", []() { wchar_t number[50]; if (InputBox(number, sizeof(number) / sizeof(wchar_t), _T("请输入要删除的座位编号"), NULL, NULL, 0, FALSE) <= 0) { return; // 用户取消 } Seat* seat = findSeatByNumber(seatQueue, number); if (!seat) { MessageBox(NULL, _T("未找到该座位"), _T("错误"), MB_OK | MB_ICONERROR); return; } wchar_t msg[100]; swprintf_s(msg, L"确定要删除座位 %s 吗?", number); int confirm = MessageBox(NULL, msg, L"确认删除", MB_YESNO | MB_ICONQUESTION); if (confirm != IDYES) return; removeSeat(seatQueue, seat); saveSeats(seatQueue, SEAT_DATA_FILE); swprintf_s(msg, L"座位 %s 删除成功", number); MessageBox(NULL, msg, L"成功", MB_OK); })); // 修改座位状态 globalWidget->addButton(2, new Button(300, 290, 200, 50, L"修改座位状态", []() { wchar_t number[50], state[20]; if (InputBox(number, sizeof(number) / sizeof(wchar_t), _T("请输入要修改的座位编号"), NULL, NULL, 0, FALSE) <= 0) { return; // 用户取消 } Seat* seat = findSeatByNumber(seatQueue, number); if (!seat) { MessageBox(NULL, _T("未找到该座位"), _T("错误"), MB_OK | MB_ICONERROR); return; } if (InputBox(state, sizeof(state) / sizeof(wchar_t), _T("请输入新的座位状态(空闲/已预约/已占用/维护中)"), NULL, NULL, 0, FALSE) <= 0) { return; // 用户取消 } updateSeatState(seat, state); saveSeats(seatQueue, SEAT_DATA_FILE); wchar_t msg[100]; swprintf_s(msg, L"座位 %s 状态已更新为 %s", number, state); MessageBox(NULL, msg, L"成功", MB_OK); })); // 查看所有座位 globalWidget->addButton(2, new Button(300, 360, 200, 50, L"查看所有座位", []() { displaySeatListPage(L"所有座位列表", [](Seat*) { return seatQueue->front; }, [](Seat* current) { return current->next; }); })); // 退出登录按钮 globalWidget->addButton(2, new Button(300, 430, 200, 50, L"退出登录", []() { isAdmin = false; globalWidget->setCurrentIndex(0); // 返回主菜单 })); // 帮助按钮 globalWidget->addButton(2, new Button(300, 500, 200, 30, L"使用帮助", []() { MessageBox(NULL, L"管理员功能使用指南:\n\n" L"1. 添加座位:添加新的座位信息\n" L"2. 删除座位:删除不再使用的座位\n" L"3. 修改座位状态:更新座位状态\n" L"4. 查看所有座位:浏览当前所有座位信息\n" L"5. 退出登录:返回主菜单\n\n" L"提示:所有更改会自动保存", L"管理员帮助", MB_OK | MB_ICONINFORMATION); })); } // 通用座位列表显示函数 void displaySeatList(Seat* startSeat, const wchar_t* title, int maxCount, std::function<Seat* (Seat*)> getNextFunc, bool showReserveButtons) { // 绘制标题 settextstyle(30, 0, _T("微软雅黑")); settextcolor(RGB(25, 25, 112)); outtextxy(300, 20, title); settextstyle(16, 0, _T("微软雅黑")); settextcolor(BLACK); int yPos = 80; outtextxy(100, yPos, _T("座位编号")); outtextxy(300, yPos, _T("楼层")); outtextxy(500, yPos, _T("状态")); if (showReserveButtons) { outtextxy(600, yPos, _T("操作")); } settextstyle(14, 0, _T("微软雅黑")); yPos += 40; Seat* seat = startSeat; int count = 0; while (seat && count < maxCount) { outtextxy(100, yPos, seat->number); wchar_t floorStr[10]; swprintf_s(floorStr, L"%d层", seat->floor); outtextxy(300, yPos, floorStr); // 根据座位状态设置不同颜色 if (wcscmp(seat->state, SEAT_AVAILABLE) == 0) { settextcolor(GREEN); } else if (wcscmp(seat->state, SEAT_RESERVED) == 0) { settextcolor(BLUE); } else if (wcscmp(seat->state, SEAT_OCCUPIED) == 0) { settextcolor(RED); } else { settextcolor(BLACK); } outtextxy(500, yPos, seat->state); settextcolor(BLACK); // 恢复默认颜色 yPos += 30; count++; seat = getNextFunc(seat); } // 显示统计信息 wchar_t countStr[100]; swprintf_s(countStr, L"显示 %d 个座位", count); settextstyle(16, 0, _T("微软雅黑")); outtextxy(300, 450, countStr); } // 创建并显示座位列表页面 void displaySeatListPage(const wchar_t* title, std::function<Seat* (Seat*)> getFirstFunc, std::function<Seat* (Seat*)> getNextFunc, bool showReserveButtons) { // 保存当前页面索引 int prevPage = globalWidget->getCurrentIndex(); // 创建一个新的临时页面用于显示座位 IMAGE* tempPage = new IMAGE(800, 600); if (_waccess(_T("result_bg.jpg"), 0) != -1) { loadimage(tempPage, _T("result_bg.jpg"), 800, 600, true); } else { tempPage->Resize(800, 600); DWORD* pBuf = GetImageBuffer(tempPage); for (int i = 0; i < 800 * 600; i++) { pBuf[i] = RGB(240, 248, 255); // 淡蓝色背景 } } globalWidget->pages.push_back(tempPage); int tempPageIndex = static_cast<int>(globalWidget->pages.size() - 1); globalWidget->buttons.push_back(std::vector<Button*>()); // 添加空按钮列表 globalWidget->setCurrentIndex(tempPageIndex); // 添加返回按钮 Button* backBtn = new Button(350, 520, 100, 40, L"返回", [prevPage]() { globalWidget->setCurrentIndex(prevPage); }); globalWidget->buttons[tempPageIndex].push_back(backBtn); // 添加预约按钮(如果需要) if (showReserveButtons && currentUser) { Seat* seat = getFirstFunc(nullptr); int yPos = 120; // 起始Y位置 while (seat) { if (wcscmp(seat->state, SEAT_AVAILABLE) == 0) { Button* reserveBtn = new Button(600, yPos - 5, 80, 25, L"预约", [seat]() { handleReserveSeat(currentUser, seat->number); // 传递座位号 }); globalWidget->buttons[tempPageIndex].push_back(reserveBtn); } yPos += 30; seat = getNextFunc(seat); } } // 进入子循环,等待用户点击返回按钮 ExMessage msg; bool exitLoop = false; while (!exitLoop) { if (peekmessage(&msg)) { if (msg.message == WM_LBUTTONDOWN) { bool clicked = false; for (Button* button : globalWidget->buttons[tempPageIndex]) { if (button->checkClick(msg.x, msg.y)) { if (button == backBtn) { exitLoop = true; // 点击返回按钮时退出循环 } clicked = true; break; } } } else if (msg.message == WM_MOUSEMOVE) { for (Button* button : globalWidget->buttons[tempPageIndex]) { button->checkMouseOver(msg.x, msg.y); } } } // 绘制 cleardevice(); putimage(0, 0, tempPage); // 绘制所有按钮 for (Button* button : globalWidget->buttons[tempPageIndex]) { button->draw(); } // 绘制座位列表 displaySeatList(getFirstFunc(nullptr), title, 10, getNextFunc, showReserveButtons); FlushBatchDraw(); Sleep(10); } // 退出子循环后,删除临时页面和按钮 for (Button* button : globalWidget->buttons[tempPageIndex]) { delete button; } globalWidget->buttons.erase(globalWidget->buttons.begin() + tempPageIndex); delete tempPage; globalWidget->pages.erase(globalWidget->pages.begin() + tempPageIndex); } // 初始化座位查询按钮 void initSeatQueryButtons() { // 按楼层查询 globalWidget->addButton(3, new Button(300, 150, 200, 50, L"按楼层查询", []() { wchar_t input[50]; if (InputBox(input, sizeof(input) / sizeof(wchar_t), _T("请输入楼层(1-5)"), NULL, NULL, 0, FALSE) <= 0) { return; // 用户取消 } int floor = _wtoi(input); if (floor <= 0 || floor > 5) { MessageBox(NULL, _T("楼层输入无效,请输入1-5之间的数字"), _T("错误"), MB_OK | MB_ICONERROR); return; } wchar_t title[100]; swprintf_s(title, L"%d楼座位列表", floor); displaySeatListPage(title, [floor](Seat*) { return findSeatByFloor(seatQueue, floor, nullptr); }, [floor](Seat* current) { return findSeatByFloor(seatQueue, floor, current); }, true); })); // 按编号查询 globalWidget->addButton(3, new Button(300, 220, 200, 50, L"按编号查询", []() { wchar_t input[50]; if (InputBox(input, sizeof(input) / sizeof(wchar_t), _T("请输入座位编号(例如:A101)"), NULL, NULL, 0, FALSE) <= 0) { return; // 用户取消 } Seat* seat = findSeatByNumber(seatQueue, input); if (!seat) { MessageBox(NULL, _T("未找到该座位,请检查座位编号是否正确"), _T("提示"), MB_OK); return; } wchar_t info[200]; swprintf_s(info, L"座位信息:\n\n编号: %s\n楼层: %d层\n状态: %s", seat->number, seat->floor, seat->state); // 如果是空闲座位且用户已登录,添加预约选项 if (currentUser && wcscmp(seat->state, SEAT_AVAILABLE) == 0) { wcscat_s(info, L"\n\n是否预约该座位?"); int choice = MessageBox(NULL, info, L"座位信息", MB_YESNO | MB_ICONQUESTION); if (choice == IDYES) { handleReserveSeat(currentUser, seat->number); // 传递座位号 } } else { MessageBox(NULL, info, L"座位信息", MB_OK); } })); // 按状态查询 globalWidget->addButton(3, new Button(300, 290, 200, 50, L"按状态查询", []() { wchar_t states[4][20] = { SEAT_AVAILABLE, SEAT_RESERVED, SEAT_OCCUPIED, SEAT_MAINTAIN }; // 清空屏幕 cleardevice(); IMAGE stateBg; if (_waccess(_T("state_bg.jpg"), 0) != -1) { loadimage(&stateBg, _T("state_bg.jpg"), 800, 600, true); putimage(0, 0, &stateBg); } else { setbkcolor(RGB(240, 248, 255)); // 淡蓝色背景 cleardevice(); } // 绘制标题 settextstyle(30, 0, _T("微软雅黑")); settextcolor(RGB(25, 25, 112)); outtextxy(250, 20, _T("按状态查询座位")); settextstyle(16, 0, _T("微软雅黑")); settextcolor(BLACK); outtextxy(300, 100, _T("请选择查询的状态:")); outtextxy(300, 150, _T("1. 空闲")); outtextxy(300, 200, _T("2. 已预约")); outtextxy(300, 250, _T("3. 已占用")); outtextxy(300, 300, _T("4. 维护中")); outtextxy(300, 350, _T("5. 返回")); FlushBatchDraw(); int stateChoice = _getch() - '0'; if (stateChoice < 1 || stateChoice > 4) return; wchar_t title[100]; swprintf_s(title, L"%s座位列表", states[stateChoice - 1]); displaySeatListPage(title, [stateChoice, states](Seat*) { return findSeatByState(seatQueue, states[stateChoice - 1], nullptr); }, [stateChoice, states](Seat* current) { return findSeatByState(seatQueue, states[stateChoice - 1], current); }, true); })); // 随机推荐可用座位 globalWidget->addButton(3, new Button(300, 360, 200, 50, L"随机推荐可用座位", []() { displayRandomAvailableSeat(); })); // 返回按钮 globalWidget->addButton(3, new Button(300, 430, 200, 50, L"返回", []() { if (currentUser) { globalWidget->setCurrentIndex(1); // 返回用户菜单 } else { globalWidget->setCurrentIndex(0); // 返回主菜单 } })); // 帮助按钮 globalWidget->addButton(3, new Button(300, 500, 200, 30, L"查询帮助", []() { MessageBox(NULL, L"座位查询功能指南:\n\n" L"1. 按楼层查询:显示指定楼层的座位\n" L"2. 按编号查询:查找特定编号的座位\n" L"3. 按状态查询:按座位状态筛选座位\n" L"4. 随机推荐:系统推荐可用座位\n" L"5. 返回:返回上一级菜单\n\n" L"提示:在查询结果中可以直接预约空闲座位", L"查询帮助", MB_OK | MB_ICONINFORMATION); })); } // 清理资源 void cleanup() { if (globalWidget) { globalWidget->close(); delete globalWidget; globalWidget = nullptr; } if (seatQueue) { destroyQueue(seatQueue); seatQueue = NULL; } // 释放用户链表 User* current = userList; while (current) { User* next = current->next; free(current); current = next; } userList = NULL; // 停止背景音乐 if (musicPlaying) { mciSendString(_T("stop bgm"), NULL, 0, NULL); mciSendString(_T("close bgm"), NULL, 0, NULL); musicPlaying = 0; } } // 设置工作目录到程序所在位置 void SetWorkingDirectoryToProgramPath() { wchar_t path[MAX_PATH]; GetModuleFileNameW(NULL, path, MAX_PATH); PathRemoveFileSpecW(path); SetCurrentDirectoryW(path); } // 主函数 int main() { // 设置工作目录 SetWorkingDirectoryToProgramPath(); // 初始化座位队列 seatQueue = createQueue(); loadSeats(seatQueue, SEAT_DATA_FILE); // 初始化用户列表 loadUsers(&userList, USER_DATA_FILE); // 初始化全局控件 initGlobalWidget(); // 设置初始页面 globalWidget->setCurrentIndex(0); // 播放背景音乐 if (_waccess(_T("background.mp3"), 0) != -1) { mciSendString(_T("open \"background.mp3\" alias bgm"), NULL, 0, NULL); mciSendString(_T("play bgm repeat"), NULL, 0, NULL); musicPlaying = 1; } // 运行主循环 globalWidget->run(); // 释放资源 cleanup(); return 0; }删掉按状态查询功能,还有删去显示全部座位这个功能
05-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值