MFC CComboBoxEx GDI-Ressourcenleck

 C Programming >> C-Programmierung >  >> Tags >> MFC
MFC CComboBoxEx GDI-Ressourcenleck


Ich habe einen sehr einfachen MFC-Dialog mit einem einzigen CComboBoxEx Kontrolle.


.rc


IDD_MFCAPPLICATION1_DIALOG DIALOGEX 0, 0, 160, 200
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "MFCApplication1"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
CONTROL "", IDC_COMBO1, "ComboBoxEx32", CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP, 10, 20, 140, 250
END

c++ Quellcode


class CMFCApplication1Dlg : public CDialogEx
{
public:
CMFCApplication1Dlg(CWnd* pParent = NULL);
virtual void DoDataExchange( CDataExchange* pDX );
CComboBoxEx m_ctrlComboEx1;
virtual BOOL OnInitDialog();
DECLARE_MESSAGE_MAP()
};

CMFCApplication1Dlg::CMFCApplication1Dlg(CWnd* pParent)
: CDialogEx(IDD_MFCAPPLICATION1_DIALOG, pParent)
{}
void CMFCApplication1Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_COMBO1, m_ctrlComboEx1);
}
BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx)
END_MESSAGE_MAP()
BOOL CMFCApplication1Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
for (int i = 0; i<24; i++) // add useless junk text strings
{
COMBOBOXEXITEM cbei; memset(&cbei, 0, sizeof(cbei));
cbei.mask = CBEIF_TEXT;
cbei.iItem = i;
cbei.pszText = L"useless junk text string 4 handle leaks";
cbei.iImage = 0;
cbei.iSelectedImage = 0;
m_ctrlComboEx1.InsertItem(&cbei);
}
return TRUE;
}

Beim Scrollen der Einträge des Listenfelds steigen die GDI-Ressourcen der Anwendung schnell an und werden nie freigegeben.


Sehen Sie sich das Bild an, das den Effekt und die zunehmende Anzahl von GDI-Objekten im Task-Manager zeigt:



Es scheint, dass dies mit der blauen "Hervorhebung" der Textelemente zusammenhängt.


Windows-Spezifikation


Edition                    Windows 10 Home
Version 1809
Installed on 19.12.2018
Operating System Build 17763.253

Geröllskala 100 %


Bauen



  • Microsoft Visual Studio-Version 15.9.5

  • Windows SDK-Version 10.0.17763.0

  • Visual Studio 2017 (v141)

  • MFC in gemeinsam genutzter DLL

  • Unicode


Das Problem tritt sowohl in der x64-Debug- als auch in der Release-Konfiguration auf, daher scheint es nicht mit den Debug- oder Optimierungseinstellungen zusammenzuhängen.


Ist dies ein Fehler in meiner winzigen Anwendung oder ist dies ein (möglicherweise bekannter) Windows-Systemfehler?

Wenn dies ein Windows-Bug ist, gibt es dann einen Workaround?



GitHub-Repository mit dem vollständigen Projekt:MFC-CComboBoxEx-Resource-Issue



Hinweis:


GDI-Ressourcenlecks sind mit der folgenden Windows 10-Vorschauversion immer noch nicht behoben:



Einige Code-Antworten


IDD_MFCAPPLICATION1_DIALOG DIALOGEX 0, 0, 160, 200 STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME EXSTYLE WS_EX_APPWINDOW CAPTION "MFCApplication1" FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN
CONTROL "", IDC_COMBO1, "ComboBoxEx32", CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP, 10, 20, 140, 250 END
class CMFCApplication1Dlg : public CDialogEx { public:
CMFCApplication1Dlg(CWnd* pParent = NULL);
virtual void DoDataExchange( CDataExchange* pDX );
CComboBoxEx m_ctrlComboEx1;
virtual BOOL OnInitDialog();
DECLARE_MESSAGE_MAP() };
CMFCApplication1Dlg::CMFCApplication1Dlg(CWnd* pParent)
: CDialogEx(IDD_MFCAPPLICATION1_DIALOG, pParent) {} void CMFCApplication1Dlg::DoDataExchange(CDataExchange* pDX) {
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_COMBO1, m_ctrlComboEx1);
} BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx) END_MESSAGE_MAP() BOOL CMFCApplication1Dlg::OnInitDialog() {
CDialogEx::OnInitDialog();
for (int i = 0;
i<24;
i++) // add useless junk text strings
{
COMBOBOXEXITEM cbei;
memset(&cbei, 0, sizeof(cbei));
cbei.mask = CBEIF_TEXT;
cbei.iItem = i;
cbei.pszText = L"useless junk text string 4 handle leaks";
cbei.iImage = 0;
cbei.iSelectedImage = 0;
m_ctrlComboEx1.InsertItem(&cbei);
}
return TRUE;
}
Edition
Windows 10 Home Version
1809 Installed on 19.12.2018 Operating System Build
17763.253
typedef struct {
PVOID pKernelAddress;
USHORT wProcessId;
USHORT wCount;
USHORT wUpper;
USHORT wType;
PVOID pUserAddress;
} GDICELL;
struct DemoDlg {
struct GH {
USHORT wType;
bool bPresent;
GH() : bPresent(true) {}
};
GDICELL* m_GdiSharedHandleTable;
SIZE_T m_nMaxHandleCount;
std::map<PVOID, GH>
m_hm;
BOOL InitGDICheck()
{
_PEB* peb = RtlGetCurrentPeb();
GDICELL* GdiSharedHandleTable = (GDICELL*)peb->GdiSharedHandleTable;
MEMORY_BASIC_INFORMATION mbi;
if (VirtualQuery(GdiSharedHandleTable, &mbi, sizeof(mbi)))
{ m_nMaxHandleCount = mbi.RegionSize / sizeof(GDICELL);
m_GdiSharedHandleTable = GdiSharedHandleTable;
return TRUE;
}
return FALSE;
}
SIZE_T CheckGdiLeaks()
{
GDICELL* GdiSharedHandleTable = m_GdiSharedHandleTable;
SIZE_T nHandleCount = m_nMaxHandleCount, n = 0;
USHORT wProcessId = (USHORT)GetCurrentProcessId();
do
{ if (GdiSharedHandleTable->wProcessId == wProcessId) {
n++;
GH&
p = m_hm[GdiSharedHandleTable->pKernelAddress];
if (p.bPresent)
{
p.wType = GdiSharedHandleTable->wType;
DbgPrint("++%p>%04x\n", GdiSharedHandleTable->pKernelAddress, p.wType);
}
p.bPresent = true;
}
} while (GdiSharedHandleTable++, --nHandleCount);
auto end = m_hm.end(), it = m_hm.begin();
if (it != end)
{ do {
GH&
p = it->second;
if (p.bPresent)
{
p.bPresent = false;
it++;
}
else
{
DbgPrint("--%p>%04x\n", it->first, p.wType);
it = m_hm.erase(it);
} } while (it != end);
}
return n;
}
static INT_PTR CALLBACK _DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_INITDIALOG)
{ SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
}
if (DemoDlg* p = reinterpret_cast<DemoDlg*>(GetWindowLongPtrW(hwndDlg, DWLP_USER)))
{ return p->DialogProc(hwndDlg, uMsg, wParam, lParam);
}
return 0;
}
INT_PTR DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM /*lParam*/)
{
switch (uMsg)
{
case WM_INITDIALOG: if (InitGDICheck()) {
COMBOBOXEXITEM cbei = { CBEIF_TEXT };
cbei.pszText = L"any text";
SendMessageW(GetDlgItem(hwndDlg, IDC_COMBOBOXEX1), CBEM_INSERTITEM, 0, (LPARAM)&cbei);
} else {
EndDialog(hwndDlg, 0);
} break;
case WM_COMMAND: switch (wParam) { case MAKEWPARAM(IDC_COMBOBOXEX1, CBN_DROPDOWN ):
DbgPrint("--- DROPDOWN [%x] --- \n", CheckGdiLeaks());
break;
case MAKEWPARAM(IDC_COMBOBOXEX1, CBN_CLOSEUP):
DbgPrint("--- CLOSEUP [%x] --- \n", CheckGdiLeaks());
break;
case MAKEWPARAM(IDCANCEL, BN_CLICKED):
EndDialog(hwndDlg, 1);
break;
} break;
}
return 0;
} };
{
DemoDlg dlg;
DialogBoxParamW((HINSTANCE)&__ImageBase,
MAKEINTRESOURCE(IDD_DIALOG1), HWND_DESKTOP, DemoDlg::_DialogProc, (LPARAM)&dlg);
}
++FFFFFFFFFF3C0DC0>0004 ++FFFFFFFFFF81171B>0004 ++FFFFFFFFFF06171F>0004 ++FFFFFFFFFFA61737>0005 ++FFFFFFFFFF8517D9>0001 --FFFFFFFFFF02171F>0004 --FFFFFFFFFF3A0DC0>0004 --FFFFFFFFFF80171B>0004 --FFFFFFFFFF8417D9>0005 --FFFFFFFFFFA51737>0001 --- DROPDOWN [a] ---  ++FFFFFFFFFF470DC0>0004 ++FFFFFFFFFF12171F>0004 ++FFFFFFFFFF8917D9>0001 --FFFFFFFFFF06171F>0004 --FFFFFFFFFF3C0DC0>0004 --FFFFFFFFFF8517D9>0001 --- CLOSEUP [a] ---  ++FFFFFFFFFF490DC0>0004 ++FFFFFFFFFF85171B>0004 ++FFFFFFFFFF13171F>0004 ++FFFFFFFFFFA71737>0001 ++FFFFFFFFFF8A17D9>0005 --FFFFFFFFFF12171F>0004 --FFFFFFFFFF470DC0>0004 --FFFFFFFFFF81171B>0004 --FFFFFFFFFF8917D9>0001 --FFFFFFFFFFA61737>0005 --- DROPDOWN [a] ---  ++FFFFFFFFFF540DC0>0004 ++FFFFFFFFFF91171B>0004 ++FFFFFFFFFFAB1737>0001 --FFFFFFFFFF490DC0>0004 --FFFFFFFFFF85171B>0004 --FFFFFFFFFFA71737>0001 --- CLOSEUP [a] --- 
++FFFFFFFFFF141043>0005 ++FFFFFFFFFF1015B8>0004 ++FFFFFFFFFF6B198C>0004 ++FFFFFFFFFF3319B6>0001 ++FFFFFFFFFFFB1A5E>0005 ++FFFFFFFFFF6A1AC4>0004 ++FFFFFFFFFF8C1B87>0001 ++FFFFFFFFFF0F1C31>0004 --FFFFFFFFFF0515B8>0004 --FFFFFFFFFF060ED2>0001 --FFFFFFFFFF1010FF>0005 --FFFFFFFFFF3E198C>0004 --FFFFFFFFFF5A1AC4>0004 --FFFFFFFFFFD812DD>0001 --FFFFFFFFFFE11C31>0004 --FFFFFFFFFFFA0CFB>0005 --- DROPDOWN [10] --- ++FFFFFFFFFFCB08DF>0010 ++FFFFFFFFFF1715B8>0004 ++FFFFFFFFFF7E198C>0004 ++FFFFFFFFFF3519B6>0001 ++FFFFFFFFFF8F1B87>0001 ++FFFFFFFFFF231C31>0004 --FFFFFFFFFF0F1C31>0004 --FFFFFFFFFF1015B8>0004 --FFFFFFFFFF3319B6>0001 --FFFFFFFFFF6B198C>0004 --FFFFFFFFFF8C1B87>0001 --- CLOSEUP [11] --- ++FFFFFFFFFF2615B8>0004 ++FFFFFFFFFF87198C>0004 ++FFFFFFFFFF3619B6>0001 ++FFFFFFFFFF901B87>0001 ++FFFFFFFFFF2C1C31>0004 --FFFFFFFFFF1715B8>0004 --FFFFFFFFFF231C31>0004 --FFFFFFFFFF3519B6>0001 --FFFFFFFFFF7E198C>0004 --FFFFFFFFFF8F1B87>0001 --- DROPDOWN [11] --- ++FFFFFFFFFF3A15B8>0004 ++FFFFFFFFFF8E198C>0004 ++FFFFFFFFFF3819B6>0001 ++FFFFFFFFFF931B87>0001 ++FFFFFFFFFF3F1C31>0004 ++FFFFFFFFFFA51C6F>0010 --FFFFFFFFFF2615B8>0004 --FFFFFFFFFF2C1C31>0004 --FFFFFFFFFF3619B6>0001 --FFFFFFFFFF87198C>0004 --FFFFFFFFFF901B87>0001 --- CLOSEUP [12] --- ++FFFFFFFFFF4115B8>0004 ++FFFFFFFFFF96198C>0004 ++FFFFFFFFFF6B1AC4>0004 ++FFFFFFFFFF4E1C31>0004 --FFFFFFFFFF141043>0005 --FFFFFFFFFF3819B6>0001 --FFFFFFFFFF3A15B8>0004 --FFFFFFFFFF3F1C31>0004 --FFFFFFFFFF6A1AC4>0004 --FFFFFFFFFF8E198C>0004 --FFFFFFFFFF931B87>0001 --FFFFFFFFFFFB1A5E>0005 --- DROPDOWN [e] --- ++FFFFFFFFFF161043>0005 ++FFFFFFFFFF4515B8>0004 ++FFFFFFFFFFA2198C>0004 ++FFFFFFFFFF5F19B6>0005 ++FFFFFFFFFF1B1A52>0010 ++FFFFFFFFFF281A5E>0001 ++FFFFFFFFFFBF1B87>0001 ++FFFFFFFFFF6C1C31>0004 --FFFFFFFFFF4115B8>0004 --FFFFFFFFFF4E1C31>0004 --FFFFFFFFFF96198C>0004 --- CLOSEUP [13] --- ++FFFFFFFFFF171043>0001 ++FFFFFFFFFF4615B8>0004 ++FFFFFFFFFFAA198C>0004 ++FFFFFFFFFF6019B6>0001 ++FFFFFFFFFF291A5E>0005 ++FFFFFFFFFF721AC4>0004 ++FFFFFFFFFFC01B87>0005 ++FFFFFFFFFF7B1C31>0004 --FFFFFFFFFF161043>0005 --FFFFFFFFFF281A5E>0001 --FFFFFFFFFF4515B8>0004 --FFFFFFFFFF5F19B6>0005 --FFFFFFFFFF6B1AC4>0004 --FFFFFFFFFF6C1C31>0004 --FFFFFFFFFFA2198C>0004 --FFFFFFFFFFBF1B87>0001 --- DROPDOWN [13] --- ++FFFFFFFFFF1A1043>0001 ++FFFFFFFFFF01112F>0010 ++FFFFFFFFFFB6198C>0004 ++FFFFFFFFFF6219B6>0001 ++FFFFFFFFFF761AC4>0004 ++FFFFFFFFFF991C31>0004 --FFFFFFFFFF171043>0001 --FFFFFFFFFF6019B6>0001 --FFFFFFFFFF721AC4>0004 --FFFFFFFFFF7B1C31>0004 --FFFFFFFFFFAA198C>0004 --- CLOSEUP [14] ---