Gmail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
About TCanvas, TControlCanvas, TextHeight
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  17 messages - Expand all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Vladimir Stefanovic  
View profile  
 More options Dec 2 2005, 10:59 am
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Vladimir Stefanovic" <antiv...@po.sbb.co.yu>
Date: Fri, 2 Dec 2005 16:59:19 +0100
Local: Fri, Dec 2 2005 10:59 am
Subject: About TCanvas, TControlCanvas, TextHeight
Hi,

I have a TForm and TRichEdit inside it (alClient, no borders).
I need to adjust the width & height of the TForm depending on
the TRichEdit contents.

Ok. I have the code which calculates the accurate WIDTH and
also gets into account the possibility of TRichEdit to have different
formating, like BOLD, etc.

But I made some overlook in the part which calculates the
HEIGHT...

In fact I used a *constant* 14, for Arial of size 8. (Yes, I know
that's a bad idea :) That worked fine untill I tried the program on
a PC on which some standard Windows view settings were changed.
I don't know what was exactly changed but I noticed HIGH screen
resolution with BIG caption bar, and BIG minimize, maximize, close
gadgets.

Can you please tell me:

1) What can I do to avoid that Windows settings affect my app?
(What is the property Scaled really for?)

2) Which of the three routines below should I use to calculate
the hight in my case, and why the Button1 & Button3 returns
the result of 14, and the Button2 the result of 13 (the both
TForm & TRichEdit hah the Arial size 10).

// 14
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   ShowMessage( Canvas->TextHeight( "Wg" ) );

}

// 13
void __fastcall TForm1::Button2Click(TObject *Sender)
{
   TControlCanvas *pCanvas = NULL;

   int result;
   try
   {
      pCanvas = new TControlCanvas();
      pCanvas->Control = RichEdit1;
      result = pCanvas->TextHeight( "Wg" );
   }
   catch ( const Exception &e )
   {
      // ...
   }

   if ( pCanvas )
      delete pCanvas;

   ShowMessage( result );

}

// 14
void __fastcall TForm1::Button3Click(TObject *Sender)
{
    HFONT OldFont;
    HDC  DC;
    TTextMetric* Tm = new TTextMetric;
    DC = GetDC( RichEdit1->Handle );
    OldFont = SelectObject( DC, RichEdit1->Font->Handle );
    GetTextMetrics( DC, Tm );
    int result = Tm->tmHeight;
    SelectObject( DC, OldFont );
    ReleaseDC( RichEdit1->Handle, DC );
    delete Tm;

    ShowMessage( result );

}

--
Best regards,
Vladimir Stefanovic

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vladimir Stefanovic  
View profile  
 More options Dec 2 2005, 12:17 pm
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Vladimir Stefanovic" <antiv...@po.sbb.co.yu>
Date: Fri, 2 Dec 2005 18:17:04 +0100
Local: Fri, Dec 2 2005 12:17 pm
Subject: Re: About TCanvas, TControlCanvas, TextHeight
New details:

> I don't know what was exactly changed but I noticed HIGH
> screen resolution with BIG caption bar, and BIG minimize,
> maximize, close gadgets.

The changed *thing* was DPI resolution, which was changed
from 96 to 120.

An now, I'm more confused than before:

When I change the resolution from 96 to 120, and reopen
my project, I can see that TRichEdit::Font::Size was changed in
my IDE from 8 to 7 (?!).

Then,  when I change the resolution again from 120 to 96, and
reopen my project, I can see that TRichEdit::Font::Size was changed
in my IDE from 7 to 8 (?!).

The  TRichEdit::Font::Height is the same: -11.

In the BCB Help, I was found this formula:
   Font.Size = - Font.Height * 72 / Font.PixelsPerInch
...which can explane how FontSize changed:

96 DPI: ( -11 * 72 ) / 96 = 8.25
120 DPI: ( -11 * 72 ) / 96 = 6.6

Does that mean i have to calculate the desired font height based
on DPI to fin the font size?

--
Best regards,
Vladimir Stefanovic


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vladimir Stefanovic  
View profile  
 More options Dec 2 2005, 12:19 pm
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Vladimir Stefanovic" <antiv...@po.sbb.co.yu>
Date: Fri, 2 Dec 2005 18:19:45 +0100
Local: Fri, Dec 2 2005 12:19 pm
Subject: Re: About TCanvas, TControlCanvas, TextHeight

> 120 DPI: ( -11 * 72 ) / 96 = 6.6

120 DPI: ( -11 * 72 ) / 120 = 6.6

--
Best regards,
Vladimir Stefanovic


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Remy Lebeau (TeamB)  
View profile  
 More options Dec 2 2005, 3:11 pm
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Remy Lebeau \(TeamB\)" <no.s...@no.spam.com>
Date: Fri, 2 Dec 2005 12:11:26 -0800
Local: Fri, Dec 2 2005 3:11 pm
Subject: Re: About TCanvas, TControlCanvas, TextHeight

"Vladimir Stefanovic" <antiv...@po.sbb.co.yu> wrote in message

news:43906f2a@newsgroups.borland.com...

> Ok. I have the code which calculates the accurate WIDTH
> and also gets into account the possibility of TRichEdit to have
> different formating, like BOLD, etc.

> But I made some overlook in the part which calculates the
> HEIGHT...

An alternative way to calculate the dimensions of the TRichEdit content is
to not involve any Canvas at all.  Use the EM_GETLINECOUNT, EM_LINEINDEX,
EM_LINELENGTH, and EM_POSFROMCHAR messages instead.  Given particular
character indexes, you can calculate absolute pixel offsets for any
character in the content, regardless of the font, style, dpi, etc.

For example (untested):

    int lines = RichEdit1->Perform(EM_GETLINECOUNT, 0, 0);
    if( lines > 0 )
    {
        POINTL pt;
        int idx, len;

        int width = 0;
        int height = 0;

        for(int x = 0; x < lines; ++x)
        {
            idx = RichEdit1->Perform(EM_LINEINDEX, x, 0);
            len = RichEdit1->Perform(EM_LINELENGTH, idx, 0);

            RichEdit1->Perform(EM_POSFROMCHAR, (WPARAM)&pt;  idx+len);
            if( width < pt.x )
                width = pt.x;
        }

        for(int x = 0; x < len; ++x)
        {
            RichEdit1->Perform(EM_POSFROMCHAR, (WPARAM)&pt;  idx+x);
            if( height < pt.y )
                height = pt.y;
        }

        RichEdit1->Width = (width + 5);
        RichEdit1->Height =  (height + 5);
    }

Gambit


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vladimir Stefanovic  
View profile  
 More options Dec 3 2005, 3:04 am
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Vladimir Stefanovic" <antiv...@po.sbb.co.yu>
Date: Sat, 3 Dec 2005 09:04:02 +0100
Local: Sat, Dec 3 2005 3:04 am
Subject: Re: About TCanvas, TControlCanvas, TextHeight

> An alternative way to calculate the dimensions of the TRichEdit
> content is to not involve any Canvas at all.
> [CODE]

Thank you... I'll try the code...

--
Best regards,
Vladimir Stefanovic


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vladimir Stefanovic  
View profile  
 More options Dec 3 2005, 11:31 am
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Vladimir Stefanovic" <antiv...@po.sbb.co.yu>
Date: Sat, 3 Dec 2005 17:31:12 +0100
Local: Sat, Dec 3 2005 11:31 am
Subject: Re: About TCanvas, TControlCanvas, TextHeight
The code finds width OK, but the height remains 5.

>        for(int x = 0; x < len; ++x)

I'v chaged the existing part of code like this, and I hope
it's OK now... (there were also some typos ; -> ,)

   for(int x = 0; x < lines; ++x)

Thanks...

--
Best regards,
Vladimir Stefanovic


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vladimir Stefanovic  
View profile  
 More options Dec 4 2005, 6:58 am
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Vladimir Stefanovic" <antiv...@po.sbb.co.yu>
Date: Sun, 4 Dec 2005 12:58:41 +0100
Local: Sun, Dec 4 2005 6:58 am
Subject: Re: About TCanvas, TControlCanvas, TextHeight
... and finally I just want to confirm that this method
(by Remy Lenbeau) worked *fine* with both 96 and 120
DPI (dots per inch) resolutions.

--
Best regards,
Vladimir Stefanovic


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Remy Lebeau (TeamB)  
View profile  
 More options Dec 5 2005, 3:06 pm
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Remy Lebeau \(TeamB\)" <no.s...@no.spam.com>
Date: Mon, 5 Dec 2005 12:06:57 -0800
Local: Mon, Dec 5 2005 3:06 pm
Subject: Re: About TCanvas, TControlCanvas, TextHeight

"Vladimir Stefanovic" <antiv...@po.sbb.co.yu> wrote in message

news:4391c820@newsgroups.borland.com...

> The code finds width OK, but the height remains 5.

I forgot that EM_POSFROMCHAR returns the  coordinates of the top-level
corner of a character.  Use EM_GETCHARFORMAT to get the width and height of
a character as well.  For example (again, untested):

    int num_lines = RichEdit1->Perform(EM_GETLINECOUNT, 0, 0);
    if( num_lines > 0 )
    {
        POINTL pt;
        int line_idx, line_len;

        int width = 0;
        int height = 0;

        CHARFORMAT fmt;
        CHARRANGE cr;

        // these are so that changes to the current selection later
        // on will not be displayed onscreen while looping...
        RichEdit1->Perform(WM_SETREDRAW, FALSE, 0);
        int oldmask = RichEdit1->Perform(EM_SETEVENTMASK, 0, 0);

        try
        {
            for(int x = 0; x < num_lines; ++x)
            {
                line_idx = RichEdit1->Perform(EM_LINEINDEX, x, 0);
                line_len = RichEdit1->Perform(EM_LINELENGTH, line_idx, 0);

                RichEdit1->Perform(EM_POSFROMCHAR, (int)&pt;  line_idx +
line_len);

                if( width < pt.x )
                    width = pt.x;
            }

            // line_idx remains pointing to the last line at this point...

            for(int x = 0; x < line_len; ++x)
            {
                memset(&fmt, 0, sizeof(fmt);
                fmt.cbSize = sizeof(fmt);
                fmt.dwMask = CFM_SIZE;

                cr.cpMin = (line_idx + x);
                cr.cpMax = (cr.cpMin + 1);

                RichEdit1->Perform(EM_EXSETSEL, 0, (int)&cr);
                RichEdit1->Perform(EM_GETCHARFORMAT, TRUE, (int)&fmt);
                RichEdit1->Perform(EM_POSFROMCHAR, (int)&pt;  cr.cpMin);

                if( height < (pt.y + fmt.yHeight) )
                    height = (pt.y + fmt.yHeight);
            }

            RichEdit1->Width = (width + 5);
            RichEdit1->Height =  (height + 5);
        }
        __finally
        {
            RichEdit1->Perform(EM_SETEVENTMASK, 0, oldmask);
            RichEdit1->Perform(WM_SETREDRAW, TRUE, 0);
            RichEdit1->Invalidate();
        }
    }

> I'v chaged the existing part of code like this, and I
> hope it's OK now... (there were also some typos ; -> ,)

>    for(int x = 0; x < lines; ++x)

That was not the correct thing to do with that loop.  I was intentionally
looping through the characters of the last line only, not looping through
all of the lines a second time.  I was attempting to find the largest
character in the last line, as that would dicate the height of the RichEdit.

Gambit


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vladimir Stefanovic  
View profile  
 More options Dec 6 2005, 6:44 am
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Vladimir Stefanovic" <antiv...@po.sbb.co.yu>
Date: Tue, 6 Dec 2005 12:44:33 +0100
Local: Tues, Dec 6 2005 6:44 am
Subject: Re: About TCanvas, TControlCanvas, TextHeight
Hi,

I tried everything but still couldn't get the proper HEIGHT.

>            // line_idx remains pointing to the last line at this point...

There is a (possible) bug here, because 'line_len' is always 0
after last iteration (?!), and so the loop is unreachable.

>            for(int x = 0; x < line_len; ++x)
>            {
>                memset(&fmt, 0, sizeof(fmt);
>                fmt.cbSize = sizeof(fmt);
>                fmt.dwMask = CFM_SIZE;

I also tried to hardoce the line_len, but still there is something
wrong in the code in this (second) loop.

--
Best regards,
Vladimir Stefanovic


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Mark Jacobs  
View profile  
 More options Dec 6 2005, 8:10 am
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: Mark Jacobs <http://www.jacobsm.com/mjmsg.htm?mj@critical>
Date: Tue, 06 Dec 2005 13:10:17 +0000
Local: Tues, Dec 6 2005 8:10 am
Subject: Re: About TCanvas, TControlCanvas, TextHeight
I would use the DrawText method like this :-

// qstxt is a RichEdit control

   int heti; TControlCanvas *cCanvas; RECT r;
   cCanvas=new TControlCanvas(); cCanvas->Font->Assign(qstxt->Font);
   cCanvas->Control=qstxt; r.right=qstxt->Width-25; r.left=2;
   heti=DrawText(cCanvas->Handle,qstxt->Text.c_str(),-1,&r,
                 DT_CALCRECT|DT_WORDBREAK);
   delete cCanvas;

// heti now contains the height

--
Mark Jacobs
http://www.dkcomputing.co.uk


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Remy Lebeau (TeamB)  
View profile  
 More options Dec 6 2005, 3:40 pm
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Remy Lebeau \(TeamB\)" <no.s...@no.spam.com>
Date: Tue, 6 Dec 2005 12:40:13 -0800
Local: Tues, Dec 6 2005 3:40 pm
Subject: Re: About TCanvas, TControlCanvas, TextHeight

"Mark Jacobs" <http://www.jacobsm.com/mjmsg.htm?mj@critical> wrote in
message news:43958d5b$1@newsgroups.borland.com...

> I would use the DrawText method like this :-

That won't take the RichEdit's formatting into account at all.

Gambit


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Remy Lebeau (TeamB)  
View profile  
 More options Dec 6 2005, 3:39 pm
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Remy Lebeau \(TeamB\)" <no.s...@no.spam.com>
Date: Tue, 6 Dec 2005 12:39:36 -0800
Local: Tues, Dec 6 2005 3:39 pm
Subject: Re: About TCanvas, TControlCanvas, TextHeight

"Vladimir Stefanovic" <antiv...@po.sbb.co.yu> wrote in message

news:4395796e@newsgroups.borland.com...

> There is a (possible) bug here, because 'line_len' is always 0 after last

iteration (?!)

The only way that can happen is if there is a blank line at the end of your
text.

> I also tried to hardoce the line_len, but still there is something wrong
> in the code in this (second) loop.

Can you be a little more specific?

Gambit


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vladimir Stefanovic  
View profile  
 More options Dec 7 2005, 5:01 am
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Vladimir Stefanovic" <antiv...@po.sbb.co.yu>
Date: Wed, 7 Dec 2005 11:01:52 +0100
Local: Wed, Dec 7 2005 5:01 am
Subject: Re: About TCanvas, TControlCanvas, TextHeight

> Can you be a little more specific?

One of the problems is:
RichEdit1->Perform(EM_GETLINECOUNT, 0, 0);
which returns the undesired lines count. I've elaborated
that in the code below.

__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
    // make it small because of testing
    RichEdit1->Width=60;
    RichEdit1->Height=60;

    // clear the default (RichEdit1) contents
    RichEdit1->Lines->Clear();

    // remarks "x : y" are "line_idx : line_len" by the ShowMessage() in the
loop

    // 0:14
    RichEdit1->Lines->Add("1234 567890123");

    // 16:32
    RichEdit1->Lines->Add("1234 567890123 45678901234567890");

    // 50:14, 66:14, 82:14, 98:14, 114:14
    for(int x = 0; x<5; ++x)
       RichEdit1->Lines->Add("1234 567890123");

    //130:18
    RichEdit1->Lines->Add("1234 567890123 456");

    // 150:0  (???)
    // This is because  RichEdit1->Perform(EM_GETLINECOUNT, 0, 0);
    // returns 9 !

}

//------------------------------------------------------------------------- --

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    int num_lines = RichEdit1->Perform(EM_GETLINECOUNT, 0, 0);

    // 9 (???)
    ShowMessage ( num_lines );

    // 8
    ShowMessage ( RichEdit1->Lines->Count );

    // num_lines = 8;
    // even if I hardoce this to 8
    // the HEIGHT is not correct. It has much bigger value (maybe doubled)

    if( num_lines > 0 )
    {
        POINTL pt;
        int line_idx, line_len;

        int width = 0;
        int height = 0;

        CHARFORMAT fmt;
        CHARRANGE cr;

        for(int x = 0; x < num_lines; ++x)
        {
            line_idx = RichEdit1->Perform(EM_LINEINDEX, x, 0);
            line_len = RichEdit1->Perform(EM_LINELENGTH, line_idx, 0);

            RichEdit1->Perform(EM_POSFROMCHAR, (int)&pt,  line_idx +
line_len);

            if( width < pt.x )
                width = pt.x;

            // test
            ShowMessage( "line_idx="+IntToStr(line_idx)+",
line_len="+IntToStr(line_len) );
        }

        // Gambit: line_idx remains pointing to the last line at this
point...

        for(int x = 0; x < line_len; ++x)
        {
            memset(&fmt, 0, sizeof(fmt) );
            fmt.cbSize = sizeof(fmt);
            fmt.dwMask = CFM_SIZE;

            cr.cpMin = (line_idx + x);
            cr.cpMax = (cr.cpMin + 1);

            RichEdit1->Perform(EM_EXSETSEL, 0, (int)&cr);
            RichEdit1->Perform(EM_GETCHARFORMAT, TRUE, (int)&fmt);
            RichEdit1->Perform(EM_POSFROMCHAR, (int)&pt,  cr.cpMin);

            if( height < (pt.y + fmt.yHeight) )
                height = (pt.y + fmt.yHeight);
        }
        RichEdit1->Width = (width + 5);
        RichEdit1->Height =  (height + 5);
    }

}

Also, why did you abandon the approach:

         for(int x = 0; x < len; ++x)
        {
            RichEdit1->Perform(EM_POSFROMCHAR, (WPARAM)&pt;  idx+x);
            if( height < pt.y )
                height = pt.y;
        }

which seem to worked fine?

Sorry for bothering you with this so muh time.

--
Best regards,
Vladimir Stefanovic


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Remy Lebeau (TeamB)  
View profile  
 More options Dec 7 2005, 2:19 pm
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Remy Lebeau \(TeamB\)" <no.s...@no.spam.com>
Date: Wed, 7 Dec 2005 11:19:10 -0800
Local: Wed, Dec 7 2005 2:19 pm
Subject: Re: About TCanvas, TControlCanvas, TextHeight

"Vladimir Stefanovic" <antiv...@po.sbb.co.yu> wrote in message

news:4396b2d6@newsgroups.borland.com...

> RichEdit1->Perform(EM_GETLINECOUNT, 0, 0);
> which returns the undesired lines count.

The VCL gets around that issue by decrementing the line count if the last
line has a length of 0, ie:

    int line_count = RichEdit1->Perform(EM_GETLINECOUNT, 0, 0);
    if( RichEdit1->Perform(EM_LINELENGTH, RichEdit1->Perform(EM_LINEINDEX,
line_count-1, 0), 0) == 0 )
        --line_count;

> Also, why did you abandon the approach:

>          for(int x = 0; x < len; ++x)
>         {
>             RichEdit1->Perform(EM_POSFROMCHAR, (WPARAM)&pt;  idx+x);
>             if( height < pt.y )
>                 height = pt.y;
>         }

> which seem to worked fine?

Because it was not accurate to begin with.  EM_POSFROMCHAR returns the pixel
offset of the top-left corner of a character.  I incorrectly assumed that
the y offset would include the actual height of the character, which it does
not.  EM_GETCHARFORMAT, on the other hand, can return the actual height of a
character, which I then add to the top-left offset of the character.

Gambit


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vladimir Stefanovic  
View profile  
 More options Dec 7 2005, 2:32 pm
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Vladimir Stefanovic" <antiv...@po.sbb.co.yu>
Date: Wed, 7 Dec 2005 20:32:39 +0100
Local: Wed, Dec 7 2005 2:32 pm
Subject: Re: About TCanvas, TControlCanvas, TextHeight
Gambit,

The last block of code which calculates the height still does
not work accutare. Do you see what could be wrong with it?

With the changes I made to determine num_lines, the code
calculates the height in much size more than it should...

        for(int x = 0; x < line_len; ++x)
        {
            memset(&fmt, 0, sizeof(fmt) );
            fmt.cbSize = sizeof(fmt);
            fmt.dwMask = CFM_SIZE;

            cr.cpMin = (line_idx + x);
            cr.cpMax = (cr.cpMin + 1);

            RichEdit1->Perform(EM_EXSETSEL, 0, (int)&cr);
            RichEdit1->Perform(EM_GETCHARFORMAT, TRUE, (int)&fmt);
            RichEdit1->Perform(EM_POSFROMCHAR, (int)&pt,  cr.cpMin);

            if( height < (pt.y + fmt.yHeight) )
                height = (pt.y + fmt.yHeight);
        }

--
Best regards,
Vladimir Stefanovic

"Vladimir Stefanovic" <antiv...@po.sbb.co.yu> wrote in message

news:4396b2d6@newsgroups.borland.com...


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Remy Lebeau (TeamB)  
View profile  
 More options Dec 7 2005, 6:36 pm
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Remy Lebeau \(TeamB\)" <no.s...@no.spam.com>
Date: Wed, 7 Dec 2005 15:36:52 -0800
Local: Wed, Dec 7 2005 6:36 pm
Subject: Re: About TCanvas, TControlCanvas, TextHeight

"Vladimir Stefanovic" <antiv...@po.sbb.co.yu> wrote in message

news:439738a0@newsgroups.borland.com...

> The last block of code which calculates the height still does
> not work accutare. Do you see what could be wrong with it?

It does not convert the yHeight value.  The documentation for the CHARFORMAT
structure does not state the unit of measurement that is used.  It turns out
that the yHeight (and yOffset) value is in twips, not pixels.  So you have
to convert the value to pixels manually.  With that in mind, the following
code gets much closer to the truer sizes for me:

    int num_lines = RichEdit1->Perform(EM_GETLINECOUNT, 0, 0);
    if( num_lines > 0 )
    {
        if( RichEdit1->Perform(EM_LINELENGTH,
RichEdit1->Perform(EM_LINEINDEX, num_lines-1, 0), 0) == 0 )
            --num_lines;
    }
    if( num_lines > 0 )
    {
        // this is so that changes to the current selection later
        // on will not be displayed onscreen while looping...
        RichEdit1->Perform(WM_SETREDRAW, FALSE, 0);
        try
        {
            // this is to speed up access to the RichEdit by disabling
notifications...
            int oldmask = RichEdit1->Perform(EM_SETEVENTMASK, 0, 0);
            try
            {
                // this is to preserve the current selection so that it can
be restored later...
                CHARRANGE oldrange = {0};
                RichEdit1->Perform(EM_EXGETSEL, 0, (int)&oldrange);
                try
                {
                    POINTL pt;
                    int line_idx, line_len;

                    int width = 0;
                    int height = 0;
                    int char_height;

                    CHARFORMAT fmt;
                    CHARRANGE cr;

                    // this is used in the twips->pixels conversion
                    HDC hdc = GetDC(RichEdit1->Handle);
                    int LogicalPixelsY = GetDeviceCaps(hdc, LOGPIXELSY);
                    ReleaseDC(RichEdit1->Handle, hdc);

                    for(int x = 0; x < num_lines; ++x)
                    {
                        line_idx = RichEdit1->Perform(EM_LINEINDEX, x, 0);
                        line_len = RichEdit1->Perform(EM_LINELENGTH,
line_idx, 0);
                        RichEdit1->Perform(EM_POSFROMCHAR, (int)&pt,
line_idx + line_len);
                        if( width < pt.x )
                            width = pt.x;
                    }

                    // line_idx remains pointing to the last line at this
point...

                    for(int x = 0; x < line_len; ++x)
                    {
                        memset(&fmt, 0, sizeof(fmt));
                        fmt.cbSize = sizeof(fmt);
                        fmt.dwMask = CFM_SIZE;

                        cr.cpMin = (line_idx + x);
                        cr.cpMax = (cr.cpMin + 1);

                        RichEdit1->Perform(EM_EXSETSEL, 0, (int)&cr);
                        RichEdit1->Perform(EM_GETCHARFORMAT, SCF_SELECTION,
(int)&fmt);
                        RichEdit1->Perform(EM_POSFROMCHAR, (int)&pt,
cr.cpMin);

                        // divide by 20 to convert twips to points, and
                        // then use MulDiv() to convert points to pixels...
                        char_height = MulDiv(fmt.yHeight / 20,
LogicalPixelsY, 72);

                        if( height < (pt.y + char_height) )
                            height = (pt.y + char_height);
                    }

                    // RichEdit1->Width = (width + 5);
                    // RichEdit1->Height =  (height + 5);

                    ShowMessage(AnsiString(width) + "," +
AnsiString(height));
                }
                __finally
                {
                    RichEdit1->Perform(EM_EXSETSEL, 0, (int)&oldrange);
                }
            }
            __finally
            {
                RichEdit1->Perform(EM_SETEVENTMASK, 0, oldmask);
            }
        }
        __finally
        {
            RichEdit1->Perform(WM_SETREDRAW, TRUE, 0);
            RichEdit1->Invalidate();
        }
    }

The only problem left is that the lowercase 'g' and 'y' characters are still
not calculated properly.  The pixel offset of the top-left corner is correct
but the height reported by EM_GETCHARFORMAT seems to be missing some extra
spacing that actually exists in those characters.  I don't have a solution
for that.

Gambit


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vladimir Stefanovic  
View profile  
 More options Dec 8 2005, 2:47 am
Newsgroups: borland.public.cppbuilder.vcl.components.using
From: "Vladimir Stefanovic" <antiv...@po.sbb.co.yu>
Date: Thu, 8 Dec 2005 08:47:39 +0100
Local: Thurs, Dec 8 2005 2:47 am
Subject: Re: About TCanvas, TControlCanvas, TextHeight
Thanks for you effort. The code works fine in my app.

I'm not so affected by problems with y&g&j characters because
I'm not going to use LARGE fonts where such deviations can be
too obvious.

Thanks again.

--
Best regards,
Vladimir Stefanovic


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google