0

我在 XE5 中创建了两个用户组件。第一个是 TCustomPanel 的后代,它的目的是成为第二个组件的容器,它是 TCustomLabel 的后代。

容器。

class PACKAGE TMenuPanel : public TCustomPanel
{
private:
protected:
public:
    __fastcall TMenuPanel(TComponent* Owner);
__published:
    __property Align;
    __property Caption;
};

static inline void ValidCtrCheck(TMenuPanel *)
{
    new TMenuPanel(NULL);
}
//---------------------------------------------------------------------------
__fastcall TMenuPanel::TMenuPanel(TComponent* Owner)
    : TCustomPanel(Owner)
{
}
//---------------------------------------------------------------------------
namespace Menupanel
{
    void __fastcall PACKAGE Register()
    {
        TComponentClass classes[1] = {__classid(TMenuPanel)};
        RegisterComponents(L"Isis", classes, 0);
    }
}

所包含的。

//---------------------------------------------------------------------------
class PACKAGE TMenuLabel : public TCustomLabel
{
private:
    UnicodeString   FOption;
    int             FIndex;
    bool            FHighlighted;
protected:
    UnicodeString   __fastcall GetOption();
    void            __fastcall SetOption(UnicodeString Option);
    int             __fastcall GetIndex();
    void            __fastcall SetIndex(int Index);
    void            __fastcall SetHighlighted(bool Flag);
    void            __fastcall RecaptionLabel();
public:
    __fastcall TMenuLabel(TComponent* Owner);
__published:

  __property int            Index = {read=GetIndex, write=SetIndex, nodefault};
  __property UnicodeString  Option = {read=GetOption, write=SetOption, nodefault};
  __property bool           Highlighted = {read=FHighlighted, write=SetHighlighted, nodefault};
};

static inline void ValidCtrCheck(TMenuLabel *)
{
    new TMenuLabel(NULL);
}
//---------------------------------------------------------------------------
__fastcall TMenuLabel::TMenuLabel(TComponent* Owner)
    : TCustomLabel(Owner)
{
    if (!Name.IsEmpty()) {
        FOption = L"Option"+Name;
    } else {
        FOption = L"Option";
    }
    FHighlighted = false;
}

到目前为止一切顺利,组件已安装,它们出现在调色板中,它们的属性出现在检查器中。但...

如果MenuPanel 放在窗体上,MenuLabels 就放在里面。如果它放置在窗体中的面板上,则菜单标签将放置在面板中。有趣的是,如果将放置在表单中的 MenuPanel 剪切并粘贴到面板上,则 MenuLabels 位于 MenuPanel 中。

菜单面板中的菜单标签

我知道这与设置 MenuPanel 的父属性有关,但构造函数采用 TComponent *Owner 参数,即 Form。然而,面板可以放置在面板内,面板内,标签将放置在右侧。

有没有人遇到过同样的问题?

4

2 回答 2

0

当您在表单设计器中放置一个组件时,它Parent会成为当前聚焦的组件(如果它ControlStyle包含csAcceptsControls,否则将Parent使用它,依此类推,直到csAcceptsControls找到)。因此,请确保您的 MenuPanel 组件csAcceptsControls在其构造函数中启用了标志,并且在删除 MenuLabel 对象时在表单设计器中选择了您的 MenuPanel。

于 2014-06-25T15:18:11.207 回答
0

我需要对父组件的引用,因为它具有特定子组件字体颜色的值。ParentFont 提供 FontName、Size、Styles,但容器为特定的 TStaticText 派生组件定义字体颜色属性。

容器定义:

MESSAGE void __fastcall MPIntHandler(TMyIntMessage &Msg);
BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(IC_GETCOLOR, TMyIntMessage, MPIntHandler);
END_MESSAGE_MAP(TComponent)


//---------------------------------------------------------------------------
void __fastcall TMenuPanel::MPIntHandler(TMyIntMessage &Msg)
{
    WPARAM WP = *Msg.wparam;
    WORD lWord = LOWORD(WP);
    if (lWord == CLR_LABEL) {
        OutputDebugStringA("Returning FLabelColor");
        Msg.Result = (long)FLabelColor;
    } else {
        OutputDebugStringA("lWord != CLR_LABEL");
        Msg.Result = (long)clRed;
    }
}

孩子覆盖 CreateParams:

//---------------------------------------------------------------------------

    void __fastcall TMenuLabel::CreateParams(TCreateParams &Params)
    {
    int wParam = MAKEWPARAM(CLR_LABEL,0);
    int lParam = 0;

        OutputDebugStringA("CreateParams");
        TStaticText::CreateParams(Params);
        if (Params.WndParent != NULL) {
            hwndParent = Params.WndParent;
            LRESULT lRes = SendGetIntMessage(hwndParent,IC_GETCOLOR,wParam,lParam);
            Font->Color = (TColor)lRes;
        }
    }

这在设计和运行时都有效。

于 2014-06-30T13:06:01.893 回答