Visual c++ 使用AFX_IDB_CHECKLISTBOX_95调试MFC应用程序生成时出错
我在运行应用程序时突然开始遇到错误。我在有问题的行上放置断点:Visual c++ 使用AFX_IDB_CHECKLISTBOX_95调试MFC应用程序生成时出错,visual-c++,mfc,Visual C++,Mfc,我在运行应用程序时突然开始遇到错误。我在有问题的行上放置断点: m_lbWeeks.SetCheck(iIndex, BST_CHECKED); 列表框的类型为CMyCheckListBox,它源自CCheckListBox: #pragma once #include <afxwin.h> class CMyCheckListBox : public CCheckListBox { public: virtual void DrawItem(LPD
m_lbWeeks.SetCheck(iIndex, BST_CHECKED);
列表框的类型为CMyCheckListBox
,它源自CCheckListBox
:
#pragma once
#include <afxwin.h>
class CMyCheckListBox :
public CCheckListBox
{
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// set item height once:
if ((GetStyle() & (LBS_OWNERDRAWFIXED | LBS_HASSTRINGS)) ==
(LBS_OWNERDRAWFIXED | LBS_HASSTRINGS) && m_cyText == 0)
{
SetItemHeight(0, CalcMinimumItemHeight() + 2);
}
// add some space between box and string:
lpDrawItemStruct->rcItem.left += 2;
CCheckListBox::DrawItem(lpDrawItemStruct);
}
};
验证
行。我以前从未遇到过这个问题,尽管最近我将VisualStudio更新为最新版本
此错误:
30996
),位于afxres.h
中。但是资源本身似乎没有加载。即使我们点击忽略它时仍然显示一个复选框。组合设置为“有字符串”,所有者绘制为“固定”
我现在真的很困惑 如果运行名为appTranslator的第三方应用程序,创建新项目并选择EXE的调试版本,我可以在参考资料中看到30996位图。但是当我选择exe的发布版本时,这个位图不会显示!都疯了
深入研究Visual Studio中的核心RC文件,我在afxres.RC中看到:
#ifndef _AFX_INTL_RESOURCES
/////////////////////////////////////////////////////////////////////////////
// CMiniFrameWnd Bitmap
AFX_IDB_MINIFRAME_MENU BITMAP DISCARDABLE "res\\minifwnd.bmp"
/////////////////////////////////////////////////////////////////////////////
// CCheckListBox Bitmaps
AFX_IDB_CHECKLISTBOX_95 BITMAP DISCARDABLE "res\\95check.bmp"
/////////////////////////////////////////////////////////////////////////////
#endif // _AFX_INTL_RESOURCES
因此,仅当未定义\u AFX\u INTL\u RESOURCES
时,才包括资源。我现在不能再往前走了。头痛
更新 我决定将自己的代码添加到我的主对话框
OnInitDialog
中,以查看发生了什么:
CBitmap bmp;
if (!bmp.LoadBitmap(AFX_IDB_CHECKLISTBOX_95))
{
AfxMessageBox(_T("1. Bitmap was not loaded"));
}
else
{
AfxMessageBox(_T("1. Bitmap was loaded"));
bmp.Detach();
}
LPCTSTR lpszResourceName = MAKEINTRESOURCE(AFX_IDB_CHECKLISTBOX_95);
HINSTANCE hinstRes = AfxFindResourceHandle(lpszResourceName, RT_BITMAP);
if (hinstRes != nullptr)
{
HBITMAP hbmp = (HBITMAP) ::LoadImage(hinstRes, lpszResourceName, IMAGE_BITMAP, 0, 0, 0);
if (hbmp != nullptr)
{
bmp.Attach(hbmp);
AfxMessageBox(_T("2. Bitmap was loaded"));
}
else
AfxMessageBox(_T("2. Bitmap was not loaded"));
}
如果我在任何语言的版本中编译并运行我的应用程序(使用卫星DLL文件),两个实例都会返回位图已加载。事实上,这是一个好消息
如果我用英语64位调试编译并运行我的软件,它也会找到资源并加载位图。只有当我尝试在非英语的Debug中运行软件时,才会出现问题。我一直在使用“发布”卫星DLL文件,这似乎是不可接受的。如果我试图为调试可执行文件构建DLL文件,appTranslator似乎无法正常工作。由于appTranslator不再维护,我想我必须承认这在技术上对我来说不是问题,因为我不会发布调试版本。“只在调试模式下发生。”-当然,宏就是这样工作的:“在MFC的发行版中,VERIFY会计算表达式,但不会打印或中断程序。”发行版配置可能也会失败,但不会报告失败。核心问题可能与(非标准)有关您实现多语言支持的方式。@IInspectable我有一个复选框。它是功能性的。appTranslator会创建我正确加载的mfc附属dll文件。
CCheckListBox
有两个不同的实现来呈现复选框的视觉效果,具体取决于返回的是TRUE
还是FALSE
。如果使用视觉样式如果控件处于活动状态,则该控件将使用UXTheme API呈现复选框控件,否则它将使用位图资源(请参阅winctrl3.cpp中的predrawItem主题化
和PreDrawItemNonThemed
),则CCheckListBox
控件将不需要位图资源。这并不是说您可以忽略失败的调试断言。这很可能是模块状态管理出错的结果。解释了状态管理为什么重要以及需要如何实现。位图资源需要在启用之前加载能够确定视觉样式是否处于活动状态。这是\u AFX\u CHECKLIST\u STATE
的构造函数中的注释。这是一个体系结构约束,而不是一个bug。不过,更重要的是,我明确地试图说服您,忽略故障是不安全的。如果代码找不到编译到模块中的资源,那么您将被忽略可能处理模块状态管理是任性的。现在忽略这一点会让您花费数小时、数天、数周的时间调试难以诊断的故障。
CBitmap bmp;
if (!bmp.LoadBitmap(AFX_IDB_CHECKLISTBOX_95))
{
AfxMessageBox(_T("1. Bitmap was not loaded"));
}
else
{
AfxMessageBox(_T("1. Bitmap was loaded"));
bmp.Detach();
}
LPCTSTR lpszResourceName = MAKEINTRESOURCE(AFX_IDB_CHECKLISTBOX_95);
HINSTANCE hinstRes = AfxFindResourceHandle(lpszResourceName, RT_BITMAP);
if (hinstRes != nullptr)
{
HBITMAP hbmp = (HBITMAP) ::LoadImage(hinstRes, lpszResourceName, IMAGE_BITMAP, 0, 0, 0);
if (hbmp != nullptr)
{
bmp.Attach(hbmp);
AfxMessageBox(_T("2. Bitmap was loaded"));
}
else
AfxMessageBox(_T("2. Bitmap was not loaded"));
}