Delphi Markup Label throws "Control 'MDLabel1' has no parent window."

392 views Asked by At

Searching for a Delphi label component with basic format/markup support I came across Delphi Markup Label (MDLabel). As a bonus it supports links. Unfortunately I can't get it working. The component is provided as a single MD_Label.pas file. I've created a component package for it and installed it. I can now select it from the components list, but adding it to a form throws an error:

Control 'MDLabel1' has no parent window."

I traced it down to the call CreateWnd and found some topics for similar problems, but still wasn't able to solve this. Did I do something wrong or is this something that needs to be adjusted because the initial code was written for Delphi 2007 and I'm using XE?

The component is to large to post the whole source code here, but you can download it from the link above. Here's the creation part:

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;

Full source: http://pastebin.com/sxYvpqTy

As a side note: If you feel that there's a better component that supports formating text within labels, please feel free to share as a comment (TJvHTLabel and TJvMarkupLabel are not good).

1

There are 1 answers

1
Remy Lebeau On

This error is a very common one for component authors who don't understand how the VCL works internally.

The fact that the error occurs while dropping the component on the Form at design-time means that the component's constructor is doing something it should not be. One of the operations requires the component's Handle to have an allocated HWND, but that is not possible at the time of the error because the component's Parent property has not been assigned yet, or the Parent.Handle does not have an allocated HWND of its own. The Parent is not assigned until after the constructor exits.

So, you need to debug the code and find the offending constructor code that relies on the component's Handle property, and move it out of the constructor. Depending on which code it is, it either belongs in Loaded() or CreateWnd(), or even SetParent(), or it may even need to be disabled completely at design-time (sometimes run-time code should not be executed at design-time or during DFM streaming at all).