Delphi Markup Label抛出“Control'MDLabel1'没有父窗口。”

时间:2017-01-07 12:18:51

标签: delphi delphi-xe

在搜索具有基本格式/标记支持的Delphi标签组件时,我遇到了Delphi Markup Label (MDLabel)。作为奖励,它支持链接。不幸的是,我无法让它发挥作用。该组件作为单个MD_Label.pas文件提供。我为它创建了一个组件包并安装它。我现在可以从组件列表中选择它,但将其添加到表单会引发错误:

  

控制'MDLabel1'没有父窗口。“

我将其追溯到调用CreateWnd并找到了类似问题的一些主题,但仍无法解决此问题。我做错了什么或是否需要调整,因为最初的代码是为Delphi 2007编写的,而我正在使用XE?

该组件很大,可以在此处发布完整的源代码,但您可以从上面的链接下载它。这是创作部分:

constructor TMDLabel.Create(AOwner: TComponent);
begin
  FInitialized := False; // required for runtime creation of MDLabel
  inherited;
  ControlStyle := [csOpaque, csCaptureMouse, csClickEvents, csSetCaption];

  FLinkFontNormal := TFont.Create;
  FLinkFontNormal.Assign(Font);
  FLinkFontNormal.Color := clBlue;
  FLinkFontNormal.Style := [];

  FLinkFontHover := TFont.Create;
  FLinkFontHover.Assign(Font);
  FLinkFontHover.Color := clRed;
  FLinkFontHover.Style := [fsUnderline];

  Width := 100;
  Height := 13;
  Cursor := crArrow;
  TabStop := False;
  DoubleBuffered := True;
  FTextHeight := 0;

  FAutoSizeWidth := True;
  FAutoSizeHeight := True;
  FTextAlignment := taLeftJustify;
  FCompressSpaces := False;
  FTabWidth := 8;
  FParsingText := False;
  FBuildingLines := False;
  FRebuildLines := False;
  FMaxWidth := 0;

  FLinkFontNormal.OnChange := DoFontChange;
  FLinkFontHover.OnChange := DoFontChange;

  FOnLinkClicked := nil;
  FOnPaintBackground := nil;
  FOnHeightChanged := nil;
  FOnWidthChanged := nil;

  FLines := TList.Create;
  FWords := TList.Create;
  FLinkRCs := TList.Create;

  FMouseDownMove := False;
  FMouseWasDown := False;
  FMouseDownIndex := - 1;
  FInitialized := True;
end;

procedure TMDLabel.CreateWnd;
begin
  inherited CreateWnd;
{$IFNDEF UNICODE}
  if (inherited Caption <> '') and (FCaptionUTF8 = '') then CaptionUTF8 := inherited Caption;
{$ENDIF}
end;

完整来源: http://pastebin.com/sxYvpqTy

作为旁注:如果您认为有更好的组件支持在标签内格式化文本,请随意分享作为评论(TJvHTLabel和TJvMarkupLabel 好)。

1 个答案:

答案 0 :(得分:2)

对于不了解VCL内部工作原理的组件作者来说,此错误非常常见。

在设计时将组件放在Form上时发生错误的事实意味着组件的构造函数正在做一些它不应该做的事情。其中一个操作要求组件的Handle具有已分配的HWND,但在发生错误时这是不可能的,因为组件的Parent属性尚未分配,或者Parent.Handle没有自己分配的HWND。直到构造函数退出后才会分配Parent

因此,您需要调试代码并找到依赖于组件的Handle属性的有问题的构造函数代码,并将其移出构造函数。根据它的代码,它可能属于Loaded()CreateWnd(),甚至属于SetParent(),或者甚至可能需要在设计时完全禁用(有时是运行时代码)不应该在设计时或在DFM流媒体中执行。