Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: VERY WEIRD???

1 view
Skip to first unread message

Lisa Pearlson

unread,
Oct 14, 2004, 9:40:43 PM10/14/04
to
yeah, simple STRUCTS do not need a copy constructor as far as I know.
It just performs a memory copy I think.

Either way, I think the problem is elsewhere...
GetTextExtentPoint32 seems to fail...
Hmmm...

Lisa

"Bill Thompson" <bil...@rgv.rr.com> wrote in message
news:%23dMNitj...@TK2MSFTNGP15.phx.gbl...
> "Lisa Pearlson" <n...@spam.plz> wrote in message
> news:enAFaQes...@TK2MSFTNGP14.phx.gbl...
> > I have a simple function, written in two ways.
> >
> > SIZE GetAxisTextExtentX() {
> > TCHAR t[MAX_TCHAR_FTOA];
> > SIZE szmin, szmax;
> > FloatToString((double)m_TScales.xmin, t, m_nDecimalsX);
> > ::GetTextExtentPoint32(m_hDC, t, _tcslen(t), &szmin);
> > FloatToString((double)m_TScales.xmax, t, m_nDecimalsX);
> > ::GetTextExtentPoint32(m_hDC, t, _tcslen(t), &szmax);
> > szmax.cx = max(szmin.cx, szmax.cx);
> > szmax.cy = max(szmin.cy, szmax.cy);
> > return szmax;
> > }
> >
> > BOOL GetAxisTextExtentX(LPSIZE lpSize) {
> > ASSERT(lpSize);
> > TCHAR t[MAX_TCHAR_FTOA];
> > SIZE szmin, szmax;
> > FloatToString((double)m_TScales.xmin, t, m_nDecimalsX);
> > ::GetTextExtentPoint32(m_hDC, t, _tcslen(t), &szmin);
> > FloatToString((double)m_TScales.xmax, t, m_nDecimalsX);
> > ::GetTextExtentPoint32(m_hDC, t, _tcslen(t), &szmax);
> > lpSize->cx = max(szmin.cx, szmax.cx);
> > lpSize->cy = max(szmin.cy, szmax.cy);
> > return TRUE;
> > }
> >
> >
> > Now, the first function how I wanted it.. and it was to be used this
way:
> > SIZE sz = GetAxisTextExtentX();
> >
> > However, sz ends up with very odd large negative values, while we within
> the
> > function, right before the return szmax statement, szmax holds correct
> > values. Somehow the transfer goes wrong when it shouldn't.
> >
> > So I rewrite the function in the second way and called it this way:
> > SIZE sz;
> > GetAxisTextExtentX(&sz);
> >
> > But still, I get the odd values, while within the function everything is
> > fine.. how is this possible?
> >
> > Lisa
> >
> >
> >
>
> this snippet seems to work fine:
>
> SIZE TestMe()
> {
> SIZE szmin, szmax;
> szmin.cx = 50;
> szmin.cy = 25;
> szmax.cx = 75;
> szmax.cy = 12;
> szmax.cx = max(szmin.cx, szmax.cx);
> szmax.cy = max(szmin.cy, szmax.cy);
> return szmax;
> }
>
> ...
>
> SIZE MySize = TestMe();
> TRACE("MySize %d,%d\n", MySize.cx, MySize.cy);
>
> Trace Output:
> MySize 75,25
>
> There shouldn't be a problem returning SIZE since it will be passed to the
> caller. This makes me suspect that something you don't expect is going on
> with FloatToString or GetTextExtent.
>
>


Florent

unread,
Oct 14, 2004, 8:08:07 AM10/14/04
to

"Lisa Pearlson" <n...@spam.plz> wrote in message
news:enAFaQes...@TK2MSFTNGP14.phx.gbl...
>I have a simple function, written in two ways.
>
> SIZE GetAxisTextExtentX() {
> TCHAR t[MAX_TCHAR_FTOA];
> SIZE szmin, szmax;
> FloatToString((double)m_TScales.xmin, t, m_nDecimalsX);
> ::GetTextExtentPoint32(m_hDC, t, _tcslen(t), &szmin);
> FloatToString((double)m_TScales.xmax, t, m_nDecimalsX);
> ::GetTextExtentPoint32(m_hDC, t, _tcslen(t), &szmax);
> szmax.cx = max(szmin.cx, szmax.cx);
> szmax.cy = max(szmin.cy, szmax.cy);
> return szmax;
> }
>
> Now, the first function how I wanted it.. and it was to be used this way:
> SIZE sz = GetAxisTextExtentX();

The value you are trying to return is "szmax" but it was created inside the
function.
So naturaly as soon as you exit the function the system get rid of "szmax",
('cause you are only using it inside the function).

SIZE does not have a copy contructor, (in fact it has no constructor), look
in the file windef.h and you will see what i mean.

So what you should do is change the SIZE to CSize in 'cause it does have a
copy contructor.
CSize GetAxisTextExtentX() {
otherwise use the second function that is also valid.

>
> Lisa
>

Florent


Lisa Pearlson

unread,
Oct 14, 2004, 9:41:37 PM10/14/04
to
Besides, your solution does not explain why the second method where I pass a
pointer to SIZE as a parameter also fails.


"Florent" <spamb...@myoddweb.com> wrote in message
news:Om7M$ZesEH...@tk2msftngp13.phx.gbl...

Sergey Kochkarev

unread,
Oct 15, 2004, 4:12:44 AM10/15/04
to
"Lisa Pearlson" <n...@spam.plz> wrote in message news:<enAFaQes...@TK2MSFTNGP14.phx.gbl>...
> I have a simple function, written in two ways.
>
> SIZE GetAxisTextExtentX() {
> TCHAR t[MAX_TCHAR_FTOA];
> SIZE szmin, szmax;
> FloatToString((double)m_TScales.xmin, t, m_nDecimalsX);
> ::GetTextExtentPoint32(m_hDC, t, _tcslen(t), &szmin);
> FloatToString((double)m_TScales.xmax, t, m_nDecimalsX);
> ::GetTextExtentPoint32(m_hDC, t, _tcslen(t), &szmax);
> szmax.cx = max(szmin.cx, szmax.cx);
> szmax.cy = max(szmin.cy, szmax.cy);
> return szmax;
> }
>
> BOOL GetAxisTextExtentX(LPSIZE lpSize) {
> ASSERT(lpSize);

> TCHAR t[MAX_TCHAR_FTOA];
> SIZE szmin, szmax;
> FloatToString((double)m_TScales.xmin, t, m_nDecimalsX);
> ::GetTextExtentPoint32(m_hDC, t, _tcslen(t), &szmin);
> FloatToString((double)m_TScales.xmax, t, m_nDecimalsX);
> ::GetTextExtentPoint32(m_hDC, t, _tcslen(t), &szmax);
> lpSize->cx = max(szmin.cx, szmax.cx);
> lpSize->cy = max(szmin.cy, szmax.cy);
> return TRUE;
> }
>
>
> Now, the first function how I wanted it.. and it was to be used this way:
> SIZE sz = GetAxisTextExtentX();
>
> However, sz ends up with very odd large negative values, while we within the
> function, right before the return szmax statement, szmax holds correct
> values. Somehow the transfer goes wrong when it shouldn't.
>
> So I rewrite the function in the second way and called it this way:
> SIZE sz;
> GetAxisTextExtentX(&sz);
>
> But still, I get the odd values, while within the function everything is
> fine.. how is this possible?
>
> Lisa


Hi, Lisa!

What seems to be wrong is that GetTextExtentPoint32 does not calculate
sizes. It seems like m_hDC or t are invalid. Check that the function
returns TRUE. If not, get the reason using GetLastError();

By the way, have you tried debugger? But a breakpoint on
GetTextExtentPoint32, press F5 and wait until your program stops (do
something to make it stop :).
Step over the function and check t, m_hdc and your SIZE struct.

You get negative values because VC does not follow ANSI C++ standard.
According to standard, any local variable should be initialized by
compiler (size.cx and size.cy should be zeroes). But Microsoft does
not seem to follow standards.

To guys,
Any struct has a copy constructor even if you don't want it. A
standard copy constructor does not do memory copy, it applies copiing
for each struct member.

Doug Harrison [MVP]

unread,
Oct 15, 2004, 11:31:22 AM10/15/04
to
Florent wrote:

>
>"Lisa Pearlson" <n...@spam.plz> wrote in message
>news:enAFaQes...@TK2MSFTNGP14.phx.gbl...
>>I have a simple function, written in two ways.
>>
>> SIZE GetAxisTextExtentX() {
>> TCHAR t[MAX_TCHAR_FTOA];
>> SIZE szmin, szmax;
>> FloatToString((double)m_TScales.xmin, t, m_nDecimalsX);
>> ::GetTextExtentPoint32(m_hDC, t, _tcslen(t), &szmin);
>> FloatToString((double)m_TScales.xmax, t, m_nDecimalsX);
>> ::GetTextExtentPoint32(m_hDC, t, _tcslen(t), &szmax);
>> szmax.cx = max(szmin.cx, szmax.cx);
>> szmax.cy = max(szmin.cy, szmax.cy);
>> return szmax;
>> }
>>
>> Now, the first function how I wanted it.. and it was to be used this way:
>> SIZE sz = GetAxisTextExtentX();
>
>The value you are trying to return is "szmax" but it was created inside the
>function.
>So naturaly as soon as you exit the function the system get rid of "szmax",
>('cause you are only using it inside the function).

Actually, it returns a copy of szmax to the caller. If szmax were an array,
you'd be right, because then a pointer to the array's first element would be
returned to the caller, and being a local object, the array would no longer
exist.

>SIZE does not have a copy contructor, (in fact it has no constructor), look
>in the file windef.h and you will see what i mean.

That's irrelevant. All classes and structs are copyable by default. In the
absence of a user-defined copy ctor, the compiler writes a default copy ctor
that does member-wise copying, and that's all SIZE needs.

>So what you should do is change the SIZE to CSize in 'cause it does have a
>copy contructor.
> CSize GetAxisTextExtentX() {
>otherwise use the second function that is also valid.

That's not gonna help. What Lisa already has appears to be valid. The
problem lies with code she hasn't shown. On NT-based Windows, I'd recommend
checking the return value of GetTextExtentPoint32, and if it's zero, call
GetLastError.

--
Doug Harrison
Microsoft MVP - Visual C++

Lisa Pearlson

unread,
Oct 15, 2004, 8:20:50 PM10/15/04
to
Thanks to you and everybody else.
The issue was indeed with the m_hDC member. Problem is now fixed.
Sometimes a good night's rest helps. ;-)

Lisa

"Doug Harrison [MVP]" <d...@mvps.org> wrote in message
news:d3rvm05v26prthsi0...@4ax.com...


> Sergey Kochkarev wrote:
>
> >You get negative values because VC does not follow ANSI C++ standard.
> >According to standard, any local variable should be initialized by
> >compiler (size.cx and size.cy should be zeroes). But Microsoft does
> >not seem to follow standards.
>

> The standard does not say that. Non-static local variables that are
neither
> initialized explicitly by the user nor implicitly by a default ctor have
> indeterminate initial values. What you say is true for static duration
> objects, but not auto or dynamically allocated objects.

Doug Harrison [MVP]

unread,
Oct 15, 2004, 11:31:23 AM10/15/04
to
Lisa Pearlson wrote:

>Either way, I think the problem is elsewhere...
>GetTextExtentPoint32 seems to fail...

GetTextExtentPoint32
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/fontext_8smq.asp

Return Values
If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Windows NT/2000/XP: To get extended error information, call GetLastError

Sergey Kochkarev

unread,
Oct 18, 2004, 4:40:44 AM10/18/04
to
"Doug Harrison [MVP]" <d...@mvps.org> wrote in message news:<d3rvm05v26prthsi0...@4ax.com>...
> Sergey Kochkarev wrote:
>
> >You get negative values because VC does not follow ANSI C++ standard.
> >According to standard, any local variable should be initialized by
> >compiler (size.cx and size.cy should be zeroes). But Microsoft does
> >not seem to follow standards.
>
> The standard does not say that. Non-static local variables that are neither
> initialized explicitly by the user nor implicitly by a default ctor have
> indeterminate initial values. What you say is true for static duration
> objects, but not auto or dynamically allocated objects.

Are you sure?

ANSI C++ standard, 8.2 Initializers.

If no initializer is specified for an object, and the object is of
(possibly c-qualified) class type (or array or record thereof),
pointer, pointer-to-member, or type reference type, the object shall
be default-initialized;

What is MVP?

Doug Harrison [MVP]

unread,
Oct 18, 2004, 3:13:07 PM10/18/04
to
Sergey Kochkarev wrote:

>"Doug Harrison [MVP]" <d...@mvps.org> wrote in message news:<d3rvm05v26prthsi0...@4ax.com>...
>> Sergey Kochkarev wrote:
>>
>> >You get negative values because VC does not follow ANSI C++ standard.
>> >According to standard, any local variable should be initialized by
>> >compiler (size.cx and size.cy should be zeroes). But Microsoft does
>> >not seem to follow standards.
>>
>> The standard does not say that. Non-static local variables that are neither
>> initialized explicitly by the user nor implicitly by a default ctor have
>> indeterminate initial values. What you say is true for static duration
>> objects, but not auto or dynamically allocated objects.
>
>Are you sure?

Yes.

>ANSI C++ standard, 8.2 Initializers.
>
>If no initializer is specified for an object, and the object is of
>(possibly c-qualified) class type (or array or record thereof),
>pointer, pointer-to-member, or type reference type, the object shall
>be default-initialized;

It would help if you quoted the right section of the standard, 8.5/9, quoted
the whole paragraph, and quoted it accurately. Here's paragraph 8.5/9 in its
entirety:

<q>


If no initializer is specified for an object, and the object is of (possibly

cv-qualified) non-POD class type (or array thereof), the object shall be
default-initialized; if the object is of const-qualified type, the
underlying class type shall have a user-declared default constructor.
Otherwise, if no initializer is specified for an object, the object and its
subobjects, if any, have an indeterminate initial value(90); if the object
or any of its subobjects are of const-qualified type, the program is
ill-formed.
</q>

You need to relate this to what you said earlier, "According to standard,


any local variable should be initialized by compiler (size.cx and size.cy

should be zeroes)", where "size" had the Windows type "SIZE", which is a
POD-struct.

>What is MVP?

http://mvp.support.microsoft.com/

0 new messages