Perdita di risorse GDI MFC CComboBoxEx

 C Programming >> Programmazione C >  >> Tags >> MFC
Perdita di risorse GDI MFC CComboBoxEx


Ho una finestra di dialogo MFC molto semplice, con un singolo CComboBoxEx controllo.


.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

codice sorgente c++


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;
}

Durante lo scorrimento degli elementi della casella di riepilogo, le risorse GDI dell'applicazione aumentano rapidamente e non vengono mai rilasciate.


Guarda l'immagine, che mostra l'effetto e il numero crescente di oggetti GDI nel task manager:



Sembra che ciò sia correlato all'"evidenziazione" blu degli elementi di testo.


Specifiche di Windows


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

Scala del ghiaione 100%


Costruisci



  • Microsoft Visual Studio versione 15.9.5

  • Windows SDK versione 10.0.17763.0

  • Visual Studio 2017 (v141)

  • MFC nella DLL condivisa

  • Unicode


Il problema è presente sia nella configurazione di debug x64 che in quella di rilascio, quindi sembra non essere correlato alle impostazioni di debug o ottimizzazione.


È un bug nella mia piccola applicazione o è un bug del sistema Windows (forse noto)?

Se si tratta di un bug di Windows, esiste una soluzione alternativa?



Repository GitHub con il progetto completo:MFC-CComboBoxEx-Resource-Issue



Nota:


Perdite di risorse GDI non ancora risolte con la seguente versione di anteprima di Windows 10:



Alcune risposte al codice


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] ---