Download

Creating custom Rich Text Block decorators

Hi there!

I’ve been trying to create my own custom RichTextBlockDecorator in C++, and I’ve run into a problem which has me stumped. Whenever I try to compile code that uses a class that subclasses the FRichTextDecorator class, I get a linker error:


CompilerResultsLog: Error:   MyRichTextBlockDecorator.cpp.obj : error LNK2019: unresolved external symbol "public: __cdecl FRichTextDecorator::FRichTextDecorator(class URichTextBlock *)" (??0FRichTextDecorator@@QEAA@PEAVURichTextBlock@@@Z) referenced in function "public: virtual class TSharedPtr<class ITextDecorator,0> __cdecl UMyRichTextBlockDecorator::Crea
teDecorator(class URichTextBlock *)" (?CreateDecorator@UMyRichTextBlockDecorator@@UEAA?AV?$TSharedPtr@VITextDecorator@@$0A@@@PEAVURichTextBlock@@@Z)
CompilerResultsLog: Error:   MyRichTextBlockDecorator.cpp.obj : error LNK2001: unresolved external symbol "public: virtual class TSharedRef<class ISlateRun,0> __cdecl FRichTextDecorator::Create(class TSharedRef<class FTextLayout,0> const &,struct FTextRunParseResults const &,class FString const &,class TSharedRef<class FString,0> const &,class ISlateStyle co
nst *)" (?Create@FRichTextDecorator@@UEAA?AV?$TSharedRef@VISlateRun@@$0A@@@AEBV?$TSharedRef@VFTextLayout@@$0A@@@AEBUFTextRunParseResults@@AEBVFString@@AEBV?$TSharedRef@VFString@@$0A@@@PEBVISlateStyle@@@Z)
CompilerResultsLog: Error:   MyRichTextBlockDecorator.cpp.obj : error LNK2001: unresolved external symbol "protected: virtual class TSharedPtr<class SWidget,0> __cdecl FRichTextDecorator::CreateDecoratorWidget(struct FTextRunInfo const &,struct FTextBlockStyle const &)const " (?CreateDecoratorWidget@FRichTextDecorator@@MEBA?AV?$TSharedPtr@VSWidget@@$0A@@@AEB
UFTextRunInfo@@AEBUFTextBlockStyle@@@Z)

The code compiles just fine, it’s the linking part thats failing. Visual Studio shows no linter errors. I am including the


#include "Components/RichTextBlockDecorator.h"

component in my header file.

I’m not the best at parsing C++ linker errors but it seems to me that it fails to find the FRichTextDecorator class?

This is how my subclass of FRichTextDecorator looks like - stripped to the wire just to get something to compile…

This class is just defined in my c++ file.


class FRichInlineScaledImage : public FRichTextDecorator
{
public:
    FRichInlineScaledImage(URichTextBlock* InOwner, UMyRichTextBlockDecorator* InDecorator)
        : FRichTextDecorator(InOwner)
        , Decorator(InDecorator)
    {
    }

    virtual bool Supports(const FTextRunParseResults& RunParseResult, const FString& Text) const override
    {
        return false;
    }

protected:
    virtual TSharedPtr<SWidget> CreateDecoratorWidget(const FTextRunInfo& RunInfo, const FTextBlockStyle& TextStyle) const override
    {
        return NULL;
    }

private:
    UMyRichTextBlockDecorator* Decorator;
};

Please - does anyone have any idea what’s wrong?

Try adding “UMG” to your Build.cs “PublicDependencyModuleNames”

Tried that, but it doesnt seem to help…

I even tried removing my Build and Intermediate folders and do a full rebuild - no dice!

This is how my Projects Build.cs file looks:


// Fill out your copyright notice in the Description page of Project Settings.

using UnrealBuildTool;

public class MyProject : ModuleRules
{
    public MyProject(ReadOnlyTargetRules Target) : base(Target)
    {
        PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

        PublicDependencyModuleNames.AddRange(new string] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });

        PrivateDependencyModuleNames.AddRange(new string] {  });

        // Uncomment if you are using Slate UI
        PrivateDependencyModuleNames.AddRange(new string] { "Slate", "SlateCore" });

        // Uncomment if you are using online features
        // PrivateDependencyModuleNames.Add("OnlineSubsystem");

        // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
    }
}


In addition, the code compiles and links without a problem as long as I do not invoke the FRichTextDecorator constructor. E.g. code that uses Slate / UMG works fine, it’s seemingly just the FRichTextDecorator that gives me a problem…

I’m running into similar problems here, no clue why it works for their example (RichTextImageDecorator) but not for me.

Would sure be nice if Epic could get their act together and provide useable documentation and actually complete features.

The best documentation is the engine source. If you haven’t done it, download the entire engine source, generate the engine solution, and open it up. You can always find an example of some other module doing what you’re trying to do and simply work backwards from that.

Unfortunately FRichTextDecorator is not an exported class. It should have the UMG_API macro but doesn’t for some reason, so you’ll get linker errors. It’s an incredibly frustrating oversight that basically makes it impossible to create your own decorators without modifying engine source.

EDIT: Has been fixed in Master:
https://github.com/EpicGames/UnrealE…ockDecorator.h

Oh dear, thanks for clarifying!