我做了一个游戏,有一关是需要关闭了画布才能通过关卡,可我不知道如何检测当前画布是否关闭,要关闭了就打开计算器(先这么写,到时候我改),谢谢各位大佬🧍♂️!
我不使用MFC,所以尽量用win32控制台,谢谢🙏。
我希望关闭时获得处理,以便阻止关闭
我做了一个游戏,有一关是需要关闭了画布才能通过关卡,可我不知道如何检测当前画布是否关闭,要关闭了就打开计算器(先这么写,到时候我改),谢谢各位大佬🧍♂️!
我不使用MFC,所以尽量用win32控制台,谢谢🙏。
我希望关闭时获得处理,以便阻止关闭
可以通过截获关闭的消息来阻止窗口关闭。
需要注意:由于消息处理函数是一个独立的线程,所以任何多线程同时访问的变量,都要注意同步。
以下是个完整的例子,在 7 秒钟内无法关闭窗口,7 秒钟后可以关闭窗口:
// 编译环境:VC6 ~ VC2019,EasyX_20210224,32 位编译
// 如需 64 位编译,请修改 GWL_WNDPROC 为 GWLP_WNDPROC
#include <graphics.h>
#include <conio.h>
// 全局变量
WNDPROC g_OriginWndProc = NULL; // 原有的窗口消息处理函数
// 注意:消息处理函数是一个新的线程。多线程访问同一个变量,需要注意同步。
int g_i = 7; // 多个线程访问的变量
CRITICAL_SECTION g_cs; // 临界区对象
LRESULT CALLBACK NewWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
bool b;
switch (uMsg)
{
case WM_CLOSE:
b = false;
EnterCriticalSection(&g_cs); // 进入临界区
if (g_i == 0)
b = true;
LeaveCriticalSection(&g_cs); // 离开临界区
if (b) exit(0); // 如果 g_i 减到 0,会将 b 赋值为 true,退出程序
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam); // 执行默认的消息处理函数
}
return 0;
}
// 主函数
int main()
{
InitializeCriticalSection(&g_cs); // 初始化临界区对象
// 创建绘图窗口,并设定新的消息处理函数
HWND wnd = initgraph(640, 480); // 初始化图形窗口,并返回窗口句柄
g_OriginWndProc = (WNDPROC)GetWindowLong(wnd, GWL_WNDPROC); // 保存旧的消息处理函数
SetWindowLong(wnd, GWL_WNDPROC, (LONG)NewWndProc); // 设置新的消息处理函数
while (true)
{
EnterCriticalSection(&g_cs); // 进入临界区
if (g_i != 0)
{
outtextxy(100, 180, '0' + g_i--);
outtextxy(100, 200, _T("现在不能关闭窗口"));
}
else
{
outtextxy(100, 180, '0' + g_i);
outtextxy(100, 200, _T("现在可以关闭窗口"));
}
LeaveCriticalSection(&g_cs); // 离开临界区
Sleep(1000);
}
_getch();
closegraph();
DeleteCriticalSection(&g_cs); // 删除临界区对象
return 0;
}
提供一种用 HiEasyX 实现的简易方法,需要在项目中加入 HiEasyX 库,详情请见 https://codebus.cn/huidong/hieasyx 。
1. 判断窗口是否仍然存在
EasyX 的用户可能早已习惯不判断绘图窗口是否还存在,因为在 EasyX 中,窗口一旦被关闭,将自动退出程序,但是 HiEasyX 提供更多的选择。
方式一:使用 initgraph 创建窗口
所有窗口被关闭后,程序将自动退出。
方式二:使用 hiex::initgraph_win32 或 hiex::Window 创建窗口
所有窗口被关闭后,不会自动退出程序(若创建窗口后调用 hiex::AutoExit(),则会自动退出程序)。
您可以随时使用 hiex::IsAnyWindow() 检测是否还存在任何窗口。
也可以使用 hiex::IsAliveWindow() 或 hiex::Window::IsAlive() 检测某一窗口是否存在。
特别注意!以此方式创建窗口,如果不判断窗口是否关闭,则窗口被关闭后程序会一直在后台运行。
2. 拦截窗口关闭消息
如果你需要拦截窗口关闭消息,则需要自定义窗口过程函数,这部分详情参见 https://github.com/zouhuidong/HiEasyX/blob/main/Tutorial/wnd_proc.md。
暂时无法获得关闭时的消息,但是你可以设置禁用窗口关闭按钮:
initgraph(x, y, EX_NOCLOSE);
然后在界面上画出来一个按钮,点击后可以进行相应的处理,再决定是否关闭。
我认为可以考虑接收窗口关闭消息。
具体实现可以参考贴吧这篇文章,他将EasyX的窗口过程函数修改到了自定义函数来处理缩放消息,同理你可以添加窗口关闭消息,进而作后续的处理。
https://tieba.baidu.com/p/6014139638