CResourceException Warning: Uncaught exception in WindowProc (returning 0).

本文探讨了GDI对象泄漏导致的CResourceException异常,分析了GDI对象的使用限制及异常产生的原因,并提供了诊断GDI泄漏的方法。
部署运行你感兴趣的模型镜像
Warning: Uncaught exception in WindowProc (returning 0).
ElectronicFence.exe 中的 0x762ec42d 处最可能的异常: Microsoft C++ 异常: 内存位置 0x0015f134 处的 CResourceException。
Warning: Uncaught exception in WindowProc (returning 0).
ElectronicFence.exe 中的 0x762ec42d 处最可能的异常: Microsoft C++ 异常: 内存位置 0x0015f134 处的 CResourceException。
Warning: Uncaught exception in WindowProc (returning 0).

 GDI泄漏会弹出CResourceException异常,一个过程的GDI上线是10000,若是跨越这个值法度就会down掉。若是在视频处理惩罚函数存在gdi泄漏,会很轻易达到这个上限值。一个简单的办法可以断定gdi是否存在泄漏,就是应用Windows任务管理器中进程(【查看】-》【选择列】选上【GDI对象】)看里面的该过程的GDI对象是否一向在增长。


使用资源的对象和对象使用资源的方式。

1.使用资源的对象可分为两类 局部和全局
2.使用资源的方式也分为两类 拷贝和指针

结合你的代码,CreateCaret创建提示符 虽然没有明确使用资源的是什么对象 但是去MSDN上就可以知道了 实际上使用提示符的是CTextView这个窗口
,是一个全局的对象。但是它使用资源的方式却可以认为是指针式的 即它在使用bitmap作为提示符时 其实并没有把bitmap拷贝一份 而是“寄希望于”它一直存在。这样 当你的bitmap是局部变量的时候 它就找不到这个资源了 也就没法显示提示符了。

但是当CDC* pDC; 使用CBrush,CPen,CFont时,pDC所指向的CDC是全局的 但是它使用资源的方式可以认为是拷贝式的 也就是当我们建立一个CPen pen; 并执行pDC->SelectObject(&pen);后,实际上相当于将pen拷贝了一份给CDC。这样 就算是pen是局部变量 在以后的使用过程中也会保持pen所代表的画笔。

既然如此 我想如果使用资源的对象是局部的话,也很容易解释了,就不多说了。
我对这个方面没有更深的理解了,上面也只是我自己按照自己的想法说的,楼主要找更加确切的东西,再问问高人 或者到MSDN上去找几个资源使用的例子 自己总结一下。
另外去参考一下:http://dev.21tx.com/2004/02/14/17312.html
上面这个文章当中提到了一个CGdiObject类的“虚拟析构函数”不知道是不是因为跟这个虚拟构造函数有关系(可能是基类没有实现这个析构函数)
另外 GDI的很多麻烦在GDI+中有很多已经没有了。GDI+中很多以前GDI中需要清理内存的地方都没有了。 GDI+是GDI的升级 学习方向应该向GDI+偏移。

您可能感兴趣的与本文相关的镜像

ComfyUI

ComfyUI

AI应用
ComfyUI

ComfyUI是一款易于上手的工作流设计工具,具有以下特点:基于工作流节点设计,可视化工作流搭建,快速切换工作流,对显存占用小,速度快,支持多种插件,如ADetailer、Controlnet和AnimateDIFF等

<think>我们正在理MFC异常理中的类型不匹配问题,特别是在使用CATCH_ALL和END_CATCH_ALL宏时,同时涉及AfxProcessWndProcException函数的使用。根据引用内容,MFC异常理使用宏来捕获异常,这些宏会捕获指向CException或其子类的指针。问题描述:在CATCH_ALL和END_CATCH_ALL块中,捕获的异常类型不匹配。可能的原因是我们试图捕获非MFC异常(如C++标准异常)或者异常理宏使用不当。解决方案:1.确保只使用MFC异常宏(TRY,CATCH,CATCH_ALL,END_CATCH,END_CATCH_ALL)来捕获MFC异常(即从CException派生的异常)。2.如果代码中同时存在C++标准异常和MFC异常,需要分别理。MFC异常宏不能捕获C++标准异常,反之亦然。3.在窗口过程(WindowProcedure)中,如果希望MFC能够理未捕获的异常,可以使用AfxProcessWndProcException函数。该函数用于理窗口消息理函数(如WindowProc)中未被捕获的异常。具体步骤:情况1:使用MFC异常宏捕获MFC异常如果代码中抛出的异常是MFC异常(通过AfxThrow...函数抛出),则可以使用CATCH_ALL宏捕获所有MFC异常(即CException*类型)。示例代码:```cppTRY{//可能抛出MFC异常的代码AfxThrowFileException(CFileException::fileNotFound);}CATCH_ALL(e){//理异常,e是指向CException的指针TCHARszCause[255];e->GetErrorMessage(szCause,255);AfxMessageBox(szCause);e->Delete();//删除异常对象}END_CATCH_ALL```情况2:混合异常理(MFC异常和C++标准异常)如果代码中可能同时抛出两种异常,需要分别捕获:```cpptry{//可能抛出MFC异常或C++标准异常的代码}catch(CException*e){//理MFC异常e->Delete();}catch(conststd::exception&e){//理标准异常AfxMessageBox(CString(e.what()));}catch(...){//理其他未知异常}```情况3:在窗口过程(WindowProc)中使用AfxProcessWndProcException当在窗口消息理函数中发生异常且未被捕获时,可以调用AfxProcessWndProcException。通常,MFC的消息映射机制已经理了异常,但如果你自己理窗口过程,则可能需要手动调用。示例:```cppLRESULTCALLBACKMyWndProc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAMlParam){try{//消息理代码}catch(CException*e){//调用MFC的异常理函数AfxProcessWndProcException(e,message,wParam,lParam);e->Delete();return0;}catch(...){//理其他异常return0;}returnDefWindowProc(hWnd,message,wParam,lParam);}```注意:AfxProcessWndProcException函数会理异常,例如显示错误消息,然后返回一个适当的消息理结果(通常返回0)。该函数只能理CException*类型的异常。关于类型不匹配问题:使用CATCH_ALL宏时,它捕获的是CException*类型的异常。因此,在CATCH_ALL块中,变量e的类型是CException*。如果你试图将e用于非CException*类型,或者代码抛出了非MFC异常,则会导致类型不匹配。建议:1.检查抛出的异常类型,确保在MFC异常宏中只抛出MFC异常。2.如果确实需要捕获所有类型的异常(包括非MFC异常),则应该使用C++标准的try/catch块,并在其中分别捕获MFC异常(CException*)和其他异常。引用说明:根据引用[4],MFC异常理捕获的是异常对象的指针,并且在使用后需要手动删除(调用e->Delete()或deletee)。同时,引用[5]指出MFC支持两种异常理方式,但不要混用。因此,类型不匹配的解决方案是确保异常类型与捕获方式匹配。相关问题:1.MFC中如何理C++标准异常?2.如何将C++标准异常转换为MFC异常?3.AfxProcessWndProcException函数在哪些情况下应该被调用?4.MFC异常宏(TRY/CATCH)和C++标准异常(try/catch)能否嵌套使用?5.如何自定义MFC异常类?</think>### 解决 MFC 中 `CATCH_ALL` 和 `END_CATCH_ALL` 类型不匹配问题 在 MFC 异常理中,`CATCH_ALL` 和 `END_CATCH_ALL` 宏用于捕获所有类型的异常(派生自 `CException` 的指针),但使用时需注意类型一致性。以下是常见问题及解决方案: #### 问题场景 当使用 `CATCH_ALL` 捕获异常后,在异常理块中调用需要特定异常类型的方法(如 `AfxProcessWndProcException`)时,可能出现类型不匹配错误: ```cpp TRY { // 可能抛出异常的代码 } CATCH_ALL(e) { AfxProcessWndProcException(e, ...); // 类型不匹配错误! e->Delete(); } END_CATCH_ALL ``` #### 解决方案 1. **显式类型转换** `AfxProcessWndProcException` 需要 `CException*` 类型参数,需强制转换: ```cpp CATCH_ALL(e) { // 显式转换为 CException* AfxProcessWndProcException(static_cast<CException*>(e), msg, wParam, lParam); e->Delete(); // 必须手动删除异常对象 } END_CATCH_ALL ``` 2. **使用动态类型检查** 若需理特定子类异常(如 `CFileException`): ```cpp CATCH_ALL(e) { if (e->IsKindOf(RUNTIME_CLASS(CFileException))) { auto* pFileEx = dynamic_cast<CFileException*>(e); // 理文件异常... } e->Delete(); } END_CATCH_ALL ``` 3. **混合异常理模式** 同时理 MFC 异常和 C++ 标准异常: ```cpp try { TRY { // MFC 代码 } CATCH_ALL(e) { throw e; // 将 MFC 异常转抛给外层 } END_CATCH_ALL } catch (CException* e) { AfxProcessWndProcException(e, ...); e->Delete(); } catch (...) { // 理标准异常 } ``` #### 关键注意事项 1. **异常对象生命周期** `CATCH_ALL` 捕获的是 `CException*` 指针,必须调用 `e->Delete()` 释放资源[^4]。 2. **`AfxProcessWndProcException` 作用** 该函数专门理窗口消息过程中的异常: ```cpp // 参数说明: // e: CException* 类型异常 // msg: 触发异常的窗口消息 // wParam/lParam: 消息参数 BOOL AfxProcessWndProcException( CException* e, const MSG* msg, WPARAM wParam, LPARAM lParam ); ``` 3. **避免宏混用** MFC 异常宏(`TRY/CATCH_ALL`)与 C++ 标准 `try/catch` 不能直接嵌套,需通过转抛异常实现交互[^5]。 #### 完整示例 ```cpp LRESULT MyWindowProc(UINT msg, WPARAM wParam, LPARAM lParam) { MSG curMsg = { m_hWnd, msg, wParam, lParam }; TRY { // 窗口消息理代码... } CATCH_ALL(e) { // 理异常并转换类型 if (AfxProcessWndProcException(static_cast<CException*>(e), &curMsg)) { e->Delete(); return TRUE; // 异常已理 } e->Delete(); } END_CATCH_ALL return DefWindowProc(msg, wParam, lParam); } ``` > **根本原因**:`CATCH_ALL` 捕获的 `e` 本质是 `CException*`,但编译器可能推断为模糊类型。显式转换可消除歧义[^4][^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值