我在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被剪切并粘贴在面板上,则MenuLabel位于MenuPanel中。
我知道这与设置MenuPanel的父属性有关,但构造函数采用TComponent * Owner参数,即Form。然而,小组可以放在小组内,小组内,标签将放在右边。
是否有人遇到同样的问题?
答案 0 :(得分:0)
当您在表单设计器中删除组件时,其Parent
将成为当前关注的组件(如果其ControlStyle
包含csAcceptsControls
,否则将使用其Parent
,依此类推,直到找到csAcceptsControls
。因此,请确保您的MenuPanel组件在其构造函数中启用了csAcceptsControls
标记,并且在删除MenuLabel对象时在窗体设计器中选择了MenuPanel。
答案 1 :(得分: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;
}
}
这在设计和运行时都有效。