I am trying to write a multi-window text editor. I have a Page Control containing 20 pages, and each page (tab sheet) contains an instance of my editor. Which works mostly ok, except I sometimes get weird results when painting my editor window. The attached code is a greatly cut-down version (which isn't a text editor any more, just a TWinControl that paints a single line of text) to illustrate the problem. Sometimes the message text is displayed correctly, and sometimes (i.e. for some tabs) either the message doesn't show at all or it appears in the wrong place or in a different font.
The code is:

__fastcall Tmixala::Tmixala(TComponent* Owner) : TForm(Owner)
{
    int i, h, w;

    PCmain = new TPageControl(this);
    PCmain->Style = tsTabs;
    PCmain->TabWidth = 60;
    PCmain->MultiLine = false;
    PCmain->Parent = this;
    PCmain->Width = ClientWidth-10;
    PCmain->Height = ClientHeight-10;

    h = PCmain->Height - 30;
    w = PCmain->Width - 10;

    for (i=0; i<20; i++)
    {
        tabs[i] = new TTabSheet(this);
        tabs[i]->Left = 4;
        tabs[i]->Top = 4;
        tabs[i]->Tag = i;
        tabs[i]->PageControl = PCmain;
        tabs[i]->TabVisible = true;
        tabs[i]->Caption = "Tab " + IntToStr(i);

        eds[i] = new editor(this);
        eds[i]->Parent = tabs[i];
        eds[i]->setCanvas();
        eds[i]->resizeWindow(w, h);
    }
}

__fastcall editor::editor(TComponent* Owner) : TCustomControl(Owner)
{
    Color = clGreen;
    Left = 0;
    Top = 0;
    Height = 100;
    Width = 120;

    Canvas = new TCanvas;
}

void __fastcall editor::setCanvas()
{
    HWND dummy;
    Canvas->Handle = GetDeviceContext(dummy);
}

void __fastcall editor::Paint()
{
    char msg[12];

    sprintf(msg, "Message: %d", ((TWinControl*)Parent)->Tag);
    Canvas->TextOut(20, 20, msg);
}

void __fastcall editor::resizeWindow(int width, int height)
{
    Width = width - Left - 1;
    Height = height - Top - 1;
}

and the header file is

#include <stdio.h>

class Tmixala : public TForm
{
__published:

public:
    __fastcall Tmixala(TComponent* Owner);
    TPageControl *PCmain;
    TTabSheet *tabs[20];
    class editor *eds[20];
};

class editor : public TCustomControl
{
public:
    __fastcall editor(TComponent* Owner);
    void __fastcall Paint();
    void __fastcall resizeWindow(int width, int height);
    void __fastcall setCanvas();

    TCanvas *Canvas;
};

Can anyone tell me please what I've missed. All sensible comments will be considered.

I haven't tried whichever GUI SDK you're using, but I'm concerned about the lack of information provided to the Canvas object. How does -it- know which font to use? Does the same tab always display the same way (whether correctly or incorrectly), or will it display one way, and then if you go to another tab and come back to the first one, it displays differently from how it did before?

Thanks for replying.

I have added

Canvas->Font->Name = "Fixedsys";
Canvas->Font->Size = 9;

into my setCanvas method which seems to have addressed the font problem.

I have just run the program and tabs 6, 11, 16, 17, 18, 19 display correctly, and all the others don't. They just show a green window with no text.
I have also found that for the tabs with no text, the canvas ClipRect contains zeros in the Paint method.
Sometimes a tab that displays the text correctly will revert to a blank window the next time it is selected.

Hmmm, I just noticed you included the keyword 'class' at line 11 of your header file above. Instead I think what you need to do is "forward declare" your editor class by adding a single line before line 3:

class editor;

and then remove the word "class" in front of "editor" inside your Tmixala class.

Meanwhile, I looked up "TForm" to see that you're using the Delphi GUI SDK. Again, I haven't programmed in it myself, so I don't really know much about how it's supposed to work. In your editor class, when you get a resizeWindow() callback, you recompute member variables Width and Height, but how does the TCanvas instance find out about its new size?

I have made the forward declaration change you suggested.
TCanvas does not seem to have any size. At least, there are no properties that suggest they might contain the size.
I was a bit premature when I said that naming and sizing the canvas's font had fixed it: the second and subsequent times a tab is selected the text size, and colour may change even though the canvas object itself still reports them as being correct. There is something screwy going on.
Thankyou for your continuing help.

This article has been dead for over six months. Start a new discussion instead.