到目前为止我被这个难住了。那里有 MFC 专家吗?
我有一个工作的 C++ MFC 应用程序。它应该只是调出一个对话,然后做其他事情。
我的应用程序有一个显示在对话框中的位图(在“logo.bmp”中)。 我想更新它显示的内容,因此,在 IDE 未运行的情况下,我将现有文件重命名为“old-logo.bmp”,在该“res”文件夹中复制了一个名为“new-logo.bmp”的新文件, 并复制新图像并将其命名为“logo.bmp”。
我没有很仔细地确保DPI、宽度和高度与原始文件相同;回想起来,我发现位深度相同但尺寸不同(旧:445x106,新:445x123)。
我启动了 IDE(Visual Studio 2022 Community,版本 17.5),应用程序编译没有任何错误,也没有任何新警告。
我以为我没事。我在调试器中启动它并立即得到一个异常:
mywindow.exe 中的 0x727C8B96 (comctl32.dll) 抛出异常:0xC0000005:访问冲突写入位置 0x00BA4114.
我发现调用栈是这样的:
CMyWindowApp::InitInstance() ->
CMyDialog::DoModal() ->
// ... windows stuff ...
CMyDialog::OnInitDialog() -> CPropertySheet::OnInitDialog()
在最后一次通话中我得到了例外。
这里有些奇怪:如果我点击继续,那么应用程序会正常启动 - 除了它在对话框的预期区域根本不显示任何位图。
我尝试将“res”文件夹恢复到它之前的文件集:我仍然遇到同样的异常。
我从以前的文件创建了一个新的工作区,但我仍然遇到同样的错误!
我将 VS2022 回滚到以前的版本(我有最新版本,我认为是 17.5.5 - 我将它回滚到 17.5.0) - 仍然是同样的错误。
我不明白。应用程序甚至在调用它的 OnPaint() 或 ResizeSheet() 成员函数之前都不会加载图像(这两个函数都没有被调用——我在它们上面设置了断点)。
我想知道是否有一些集中存储的 VS2022 缓存,我通过手动切换 .bmp 文件搞砸了(我永远不会,再也不会那样做!),我可能会破坏它以便重建.
我难住了。伙计们,有什么想法吗?
相关代码
在 MyWindow.cpp 中:
// MyWindow.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "afxvisualmanager.h" // to clean up instance allocated by others
#include "MyWindow.h"
#include "MyDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
const COleDateTime CExporterApp::m_StarterCard(2037, 12, 31, 0, 0, 0);
// CMyWindowApp
BEGIN_MESSAGE_MAP(CMyWindowApp, CWinApp)
// ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CMyWindowApp construction
CMyWindowApp::CMyWindowApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
CMyWindowApp::~CMyWindowApp()
{
// To make sure base class destructor is getting called.
}
// The one and only CMyWindowApp object
CMyWindowApp theApp;
BOOL CMyWindowApp::InitInstance()
{
// InitCommonControlsEx() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
if (!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
CMyDialog sht;
INT_PTR nResponse = sht.DoModal();
// stuff we never get to...
}
在 MyDialog.cpp 中:
// MyDialog.cpp : implementation file
//
#include "stdafx.h"
#include "MyWindow.h"
#include "MyDialog.h"
#include "bitmap.h"
// ... some other application-specific includes ...
// CMyDialog
const COLORREF CMyDialog::m_dwBkColor = RGB(246, 243, 234);
IMPLEMENT_DYNAMIC(CMyDialog, CPropertySheet)
CMyDialog::CMyDialog()
:CPropertySheet()
{
EnableStackedTabs(FALSE);
m_wndbkBrush.CreateSolidBrush(m_dwBkColor); // background brush.
m_Page1.SetBackgroundColor(m_dwBkColor);
AddPage(&m_Page1);
}
CMyDialog::CMyDialog(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
:CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{
}
CMyDialog::CMyDialog(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
:CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{
}
CMyDialog::~CMyDialog()
{
m_wndbkBrush.DeleteObject(); // Unload background brush.
}
void CMyDialog::OnDestroy()
{
CPropertySheet::OnDestroy();
m_TabCtrl.UnsubclassWindow();
}
BEGIN_MESSAGE_MAP(CMyDialog, CPropertySheet)
//{{AFX_MSG_MAP(CMyDialog)
//}}AFX_MSG_MAP
//ON_COMMAND(ID_APPLY_NOW, OnApplyNow)
ON_WM_PAINT()
ON_WM_CTLCOLOR()
ON_WM_ERASEBKGND()
ON_BN_CLICKED(IDOK, OnOK)
ON_BN_CLICKED(IDCANCEL, OnCancel)
ON_WM_DESTROY()
ON_MESSAGE(WM_DEVICECHANGE, OnDeviceChange)
ON_MESSAGE(WM_SETACTIVEPAGE, OnSetActivePage)
ON_WM_SYSCOMMAND()
END_MESSAGE_MAP()
// CMyDialog message handlers
BOOL CMyDialog::OnInitDialog()
{
BOOL bResult = CPropertySheet::OnInitDialog();
// other stuff we don't reach - we hit the exception in the call above...
)
// other stuff