IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ 通过DestroyWindow或SendMessage关闭视窗时候出现问题 -> 正文阅读

[C++知识库]C++ 通过DestroyWindow或SendMessage关闭视窗时候出现问题


问题概览

近期在完成一个连接多台相机,并实时显示每一个相机窗口的程序过程中,在程序的最后会涉及对显示窗口的关闭。但是期间尝试采用DestroyWindowSendMessage来关闭时都出现了无法关闭或异常中断的问题。详细问题如下

  1. 在主线程中使用DestroyWindow无法关闭生成的子视窗,返回值为false;
  2. 在主线程中使用SendMessage(g_hwnd[i], WM_CLOSE, 0, 0)依次关闭多个视窗时,异常中断。

一.DestroyWindow无法关闭视窗问题

1.问题现象

在主线程中使用DestroyWindow(hwnd)时无法关闭销毁视窗,该函数返回值为false

bool flag = DestroyWindow(g_hwnd[0]);

在这里插入图片描述

2.排查思路

由于该函数并不会返回报错码,故采用GetLastError()来查看实际的错误原因。将上述代码修改为如下后,再通过断点调试查到的错误码即可获取实际的错误原因。

bool flag = DestroyWindow(g_hwnd[0]);
DWORD err = GetLastError();

在这里插入图片描述

3.问题原因及解决办法

通过查看错误对照码,可以看到错误码5对应的是“拒绝访问”,这意味着造成该问题的原因很有可能是所操作的对象权限不够导致,该判断的论据可参考在子线程用调用::DestroyWindow无效,GetlastError为5—拒绝访问

由于我的程序窗口对象的创建是在其他线程中创建的,而我从主线程对其他线程创建的窗口对象进行销毁的时候,自然就会产生“拒绝访问,无法销毁”这样的问题了。

解决办法:

  1. 将窗口对象的创建从其他线程移至该线程中来进行。
  2. 通过给窗口发关闭消息来关闭窗口,窗口消息函数书写如下:
// 窗口消息函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		hWnd = NULL;
		break;
	case WM_CLOSE:
		DestroyWindow(hWnd);
		break;
	}

	return DefWindowProc(hWnd, msg, wParam, lParam);
}

二.用SendMessage关闭多个视窗时,异常中断

1.问题现象

为处理上一个问题,我决定采用给窗口发消息的方式来关闭窗口,但是采用SendMessage(g_hwnd[i], WM_CLOSE, 0, 0)来依次关闭多个窗口时,程序总是会异常中断。中断的报错信息基本形式长这样:

0x00007FFADC4A547C (msctf.dll)处(位于 test.exe 中)引发的异常: 0xC0000005

2.排查思路

为解决这一问题,我采用过将轮询方式改为单独销毁,或者在两次发消息期间加等待时间(最大2s),均没有效果,但是发现只发送单窗口的时候并不会中断。从这篇向窗口发送消息SendMessage帖子中受到启发,怀疑还是消息阻塞导致的问题。

3.问题原因及解决办法

问题原因:
SendMessage这个函数发送消息会等待窗口程序处理完消息再返回,如果是给多个窗口发消息,那很有可能造成消息的阻塞。(但我加了等待时间还是没用这点,希望有大佬可以指导说明)

SendMessageW或SendMessageA,这两个函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。而和函数PostMessage不同,PostMessage是将一个消息寄送到一个线程的消息队列后就立即返回

解决办法:
采用PostMessage来发送关闭窗口的消息即可。

PostMessage(g_hwnd[i], WM_CLOSE, 0, 0);

参考引用

  1. C++ :用GetLastError()查找错误原因;
  2. 在子线程用调用::DestroyWindow无效,GetlastError为5—拒绝访问
  3. 向窗口发送消息SendMessage
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-16 11:05:17  更:2021-07-16 11:06:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/28 5:09:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码