2017-01-07 10 views
-2

Поиск компонента метки Delphi с базовым форматом/поддержкой разметки. Я столкнулся с Delphi Markup Label (MDLabel). В качестве бонуса он поддерживает ссылки. К сожалению, я не могу заставить его работать. Компонент предоставляется как один файл MD_Label.pas. Я создал для него компонентный пакет и установил его. Теперь я могу выбрать его из списка компонентов, но при добавлении его в форму выдает ошибку:Delphi Markup Label throws «Control« MDLabel1 »не имеет родительского окна».

Control 'MDLabel1' has no parent window."

Я проследил его до вызова 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 не хорошо).

+0

Я никогда не пользовался ярлыками JV. Но, по-видимому, они работают. Почему они были «не хороши», тогда как тот, который нельзя даже отбросить на форму? –

+0

Проблема не в CreateWnd. Проблема в том, что у элемента управления нет родителя. –

+0

Я не собираюсь DL компонент. Но то, что, вероятно, будет важно для понимания проблемы, - это иерархия компонента. Затем проверьте всю иерархию, если и как «SetParent» переопределен. Следите за любым кодом, который может вызывать исключения. –

ответ

1

Эта ошибка является очень распространенной для авторов компонентов, которые не понимают, как VCL работает внутренне.

Тот факт, что ошибка возникает при отбрасывании компонента в форме во время разработки, означает, что конструктор компонента делает то, чего не должно быть. Одна из операций требует, чтобы компонент Handle имел выделенный HWND, но это невозможно во время ошибки, поскольку свойство Parent компонента еще не назначено, или Parent.Handle не имеет выделенного HWND. Parent не назначается после завершения работы конструктора.

Итак, вам нужно отладить код и найти код конструктора-нарушителя, который опирается на свойство компонента Handle и вывести его из конструктора. В зависимости от того, какой код он есть, он либо принадлежит Loaded(), либо CreateWnd(), или даже SetParent(), либо его даже может быть необходимо отключить полностью во время разработки (иногда код времени выполнения не должен выполняться во время разработки или во время потоковой передачи DFM вообще).

+0

Благодарим вас за дополнительные сведения к обсуждению в комментариях.Я сократил код за куском и выяснил, что метод 'ParseText' называется косвенно в процессе создания. Чтобы не изменять слишком много исходного кода, я просто добавил 'if not Assigned (Parent), а затем exit;' в начале метода, который решил проблему. – CodeX