1

我正在使用 C++ Builder XE,并且 TCheckBox 的“显示”属性有问题。

我有一个TForm(ChannelConfigForm),其中有一个TGroupBox(AlarmsGroupBox),其中有一个TCheckBox(A4_en_Xbox)。

有时,我看不到表单上的某些控件。

根据帮助文档:“如果组件的 Visible 属性及其父层次结构中的所有父级都为 true,则 Showing 保证为 true。如果包含该控件的父级之一的 Visible 属性值为 false,则 Showing 可能是真或假。显示是一个只读属性。

为了找出发生了什么,我编写了以下函数来调试程序:(注意:此函数中的 debugf 只是我编写的调试语句,其工作方式类似于 printf,它将调试内容写入表单)

void ShowParentTree(TControl *Control)
{
  wchar_t Name[32];
  static int level=0;
  TWinControl *wc;

  level++;
  if (level==1)
    debugf(L"Parents of control \"%s\" (%s) :",
                       Control->Name.c_str(),
                       Control->ClassName().c_str());

  // Display what Control has as parents and if they're visible and showing
  debugf(L"level %d : %s->Visible  = %s",level,
                       Control->Name.c_str(),
                       Control->Visible?L"true":L"false");
  wc=(TWinControl *)Control;
  debugf(L"level %d : %s->Showing  = %s",level,
                       wc->Name.c_str(),
                       wc->Showing?L"true":L"false");

  if (Control->Parent)
    ShowParentTree((TControl *)Control->Parent);

  level--;
}

有时当我显示 ChannelConfigForm 时,我会得到以下信息:

Parents of control "A4_en_Xbox" (TCheckBox) :
level 1 : A4_en_Xbox->Visible  = true
level 1 : A4_en_Xbox->Showing  = false
level 2 : AlarmsGroupBox->Visible  = true
level 2 : AlarmsGroupBox->Showing  = true
level 3 : ChannelConfigForm->Visible  = true
level 3 : ChannelConfigForm->Showing  = true

我理解这意味着 A4_en_Xbox->Showing 属性在我认为应该为真时为假。

4

1 回答 1

0

检查A4_en_Xbox->HandleAllocated()返回的内容。 Showing如果HandleAllocated()返回 false,则为 false。VCL 不保证 TWinControl 派生的组件始终始终具有HWND分配。有时它会HWND在内部释放 s 并在需要时重新创建它们。

此外,您的代码中有一个小的逻辑错误。并非所有TControl后代都派生自TWinControl,但您的代码假定输入TControl始终是TWinControl后代。您需要检查这一点,这样您就可以避免访问ShowingTWinControl控件的属性。您也可以完全取消递归,只需使用简单的循环即可:

void ShowParentTree(TControl *Control)
{
    if (!Control)
        return;

    int level = 0;
    TWinControl *wc = dynamic_cast<TWinControl*>(Control);

    debugf(L"Parents of control \"%s\" (%s) :",
                         Control->Name.c_str(),
                         Control->ClassName().c_str());

    // Display what Control has as parents and if they're visible and showing
    do
    {
        level++;

        if (wc)
        {
            debugf(L"level %d : %s Visible = %s, Showing = %s, HandleAllocated = %s",
                level,
                Control->Name.c_str(),
                Control->Visible ? L"true" : L"false",
                wc->Showing ? L"true" : L"false",
                wc->HandleAllocated() ? L"true" : L"false");

        }
        else
        {
            debugf(L"level %d : %s Visible = %s",
                level,
                Control->Name.c_str(),
                Control->Visible ? L"true" : L"false");
        }

        wc = Control->Parent;
        Control = wc;
    }
    while (Control);
}
于 2012-10-31T18:10:47.217 回答