In a C++ Builder 6 test project, I try to understand the relation between the TWinControl
classes of the VCL and Windows user objects, because I'm hunting a leak of user objects in my original application where I use some levels of nested frames, created periodically at runtime, that causes my application to crash after some days.
In the test project I observe a strange behaviour. When I add a dynamically created TFrame
object to a panel, the count of user objects increases by 2. If I remove a frame by deletion, the user object count is decreased by 1. If I add it again, the increment is 1. If I add more than 1 frame, the increment is 2 after exceeding the last maximum value of frames. This is the code to reproduce this:
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);
}
It looks like a kind of caching. See the (grouped) excerpt of the trace (format action: before,after):
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
Another observation: If I use TPanel
instead of TFrame
, the behaviour is is trivial.
As to understand whether this is a Windows feature, I built another test application with Lazarus (Google didn't help). Here the user object count behaviour is unsurprising: increment and decrement compensate each other.
What is the explanation of this caching-like behaviour? How to get back to the initial count of user objects?
I'm sorry for pushing you back into the old times of BCB6.