1

在 C++ Builder 6 测试项目中,我尝试了解TWinControlVCL 和 Windows 用户对象的类之间的关系,因为我在我的原始应用程序中寻找用户对象的泄漏,我使用了一些级别的嵌套框架,定期创建在运行时,这会导致我的应用程序在几天后崩溃。

在测试项目中,我观察到一个奇怪的行为。当我将动态创建的TFrame对象添加到面板时,用户对象的计数增加 2。如果我通过删除删除一帧,则用户对象计数减少 1。如果我再次添加它,则增量为 1。如果我添加超过1帧,超过最后一个最大值后增加2帧。这是重现此代码的代码:

主窗体.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 构建了另一个测试应用程序(谷歌没有帮助)。这里的用户对象计数行为并不令人惊讶:递增和递减相互补偿。

这种类似缓存的行为的解释是什么?如何回到用户对象的初始计数?

很抱歉把你推回到 BCB6 的旧时代。

4

0 回答 0