Search code examples
c++c++buildervcl

Creating TCanvas to measure text width


I want to measure text width of a TButton so that I can resize it when the text changes. If the button uses ParentFont, I can use the form Canvas to get the width:

int GetButtonTextWidth(TForm* form, TButton* btn)
{
    const int base = form->Canvas->TextWidth(btn->Caption);
    const int margin = 16;
    return base + margin;
}

If the button has different font, for example it is bold, this is not accurate. I tried to create a new TCanvas:

int GetButtonTextWidth(TForm* form, TButton* btn)
{
    std::unique_ptr<TCanvas> canvas(new TCanvas);
    canvas->Font = btn->Font;
    const int base = canvas->TextWidth(btn->Caption);
    const int margin = 16;
    return base + margin;
}

This gives exception: "Canvas does not allow drawing". How do I create a TCanvas that allows measuring text width and gives accurate results?


Solution

  • The VCL has a TControlCanvas class for associating a Canvas with a UI control.

    int GetButtonTextWidth(TButton* btn)
    {
        std::unique_ptr<TControlCanvas> canvas(new TControlCanvas);
        canvas->Control = btn;
        canvas->Font = btn->Font;
        const int base = canvas->TextWidth(btn->Caption);
        const int margin = 16;
        return base + margin;
    }