Динамически создаваемый TFrame вызывает утечку пользовательского объекта Windows

В тестовом проекте C++ Builder 6 я пытаюсь понять связь между TWinControl классы пользовательских объектов VCL и Windows, потому что я ищу утечку пользовательских объектов в моем исходном приложении, где я использую несколько уровней вложенных фреймов, периодически создаваемых во время выполнения, что приводит к сбою приложения через несколько дней.

В тестовом проекте я наблюдаю странное поведение. Когда я добавляю динамически созданный TFrame Для объекта на панели число пользовательских объектов увеличивается на 2. Если я удаляю фрейм путем удаления, количество пользовательских объектов уменьшается на 1. Если я добавляю его снова, приращение равно 1. Если я добавляю более 1 кадра, приращение составляет 2 после превышения последнего максимального значения кадров. Это код для воспроизведения этого:

MainForm.cpp

#include <vcl.h>
#pragma hdrstop

#include "MainFrm.h"

#pragma resource "*.dfm"
TMainForm *MainForm;

int UserObjectCount() {
    return GetGuiResources(GetCurrentProcess(), 1);
}

__fastcall TMainForm::TMainForm(TComponent* Owner)
    : TForm(Owner)
{
}

void __fastcall TMainForm::AddButtonClick(TObject *Sender)
{
    String msg = "add: "+IntToStr(UserObjectCount())+",";
    (new TFrame(static_cast<TComponent*>(NULL)))->Parent = FramesPanel;
    trace(msg+IntToStr(UserObjectCount()));
}

void __fastcall TMainForm::RemoveButtonClick(TObject *Sender)
{
    if (!FramesPanel->ControlCount) return;
    String msg = "rem: "+IntToStr(UserObjectCount())+",";
    FramesPanel->Controls[0]->Free();
    trace(msg+IntToStr(UserObjectCount()));
}

void TMainForm::trace(const String& msg)
{
    TraceMemo->Lines->Add(msg);
}

Это похоже на своего рода кеширование. Смотрите (сгруппированный) фрагмент трассы (формат действия: до, после):

add: 28,30
rem: 30,29

add: 29,30
add: 30,32
rem: 32,31
rem: 31,30

add: 30,31
add: 31,32
add: 32,34
rem: 34,33
rem: 33,32
rem: 32,31

Еще одно наблюдение: если я использую TPanel вместо TFrame Поведение тривиально.

Чтобы понять, является ли это функцией Windows, я создал другое тестовое приложение с Lazarus (Google не помог). Здесь поведение подсчета объектов пользователя неудивительно: увеличение и уменьшение компенсируют друг друга.

Чем объясняется это поведение, похожее на кеширование? Как вернуться к начальному количеству пользовательских объектов?

Прошу прощения за то, что подтолкнул вас назад в старые времена BCB6.

0 ответов

Другие вопросы по тегам