Page 1 of 1

Different nHeight() for same Dialog

Posted: Thu Mar 27, 2008 4:43 pm
by patrickmast
Hi,

I have something strange. Please concider this code:

Code: Select all

#include "FiveWin.ch"

FUNCTION Main()

   LOCAL oDlg

   DEFINE DIALOG oDlg TITLE "Test" FROM 0,0 TO 310,530 PIXEL

   @ 1, 2 SAY oDlg:nHeight OF oDlg
   @ 2, 2 SAY oDlg:nWidth OF oDlg
   
   ACTIVATE DIALOG oDlg CENTERED ON PAINT TestXY(oDlg)

RETURN NIL
                 
//-------------------------------

PROCEDURE TestXY(oDlg)

 oDlg:SetText( Str(oDlg:nHeight,3,0) +","+ Str(oDlg:nWidth,3,0) )
 
RETURN
The nHeight en nWidth that comes from the "ON PAINT TestXY(oDlg)" is different than the one in the "@ 1,2 SAY oDlg:nHeight Of oDlg".

How can I make them the same?

I discovered this when my buttons on my dialog, which are painted based on the height of the dialog, was placed different on a Vista machine than on a WindowsXP machine.

The nHeight that is in "@ 1,2 SAY..." is the same on Vista or XP, but the nHeight of the "ON PAINT.." is different on Vista than on XP.

So, I have to find a way that the nHeight() of a Dialog is the same on Vista or XP.

Please try the sample, it makes it so much simpler to explain ;-)

Patrick

Posted: Thu Mar 27, 2008 5:21 pm
by James Bott
Patrick,

>The nHeight that is in "@ 1,2 SAY..." is the same on Vista or XP, but the nHeight of the "ON PAINT.." is different on Vista than on XP.

When you use @1,2 you are using row,col coordinates which are based on the old DOS screen of 25 rows, 80 columns. The ON PAINT is using pixels.

The difference you are seeing between XP and Vista is probably because the screen resolutions are set different.

James

Posted: Thu Mar 27, 2008 7:12 pm
by patrickmast
James Bott wrote:When you use @1,2 you are using row,col coordinates which are based on the old DOS screen of 25 rows, 80 columns. The ON PAINT is using pixels.
Sorry but you must have misread my question. Its not the @SAY coordinates I need, but the coordinates of the dialog. if you run the sample, you will see :)
James Bott wrote:The difference you are seeing between XP and Vista is probably because the screen resolutions are set different.
No, it's not. The dialog should be the same height regarding the screen size. Otherwise, we need to build different dialogs per resolution right.

James, please run the sample and you will see my problem.

Patrick

Posted: Thu Mar 27, 2008 7:25 pm
by Otto
Patrick, it seems
oDlg:nHeight is returning the client rectangle.
Regards,
Otto

Image

Posted: Thu Mar 27, 2008 7:52 pm
by patrickmast
Otto wrote:Patrick, it seems oDlg:nHeight is returning the client rectangle.
Otto, thanks for pointing that out. Now, why is it different in XP versus Vista?

Look at this. Same exe, run in XP and in Vista:
Image

This is why my buttons (based on the calculation of oDlg:nHeight() ) are placed different in XP than in Vista..

Image

Image



Patrick

Posted: Thu Mar 27, 2008 8:42 pm
by James Bott
Patrick,

>This is why my buttons (based on the calculation of oDlg:nHeight() ) are placed different in XP than in Vista..

Perhaps because the title bar and borders are slightly different sizes in the two different themes?

Is there a reason you are not using dialogs defined as resources?

James

Posted: Fri Mar 28, 2008 8:01 am
by patrickmast
James Bott wrote:Perhaps because the title bar and borders are slightly different sizes in the two different themes?
Don't know. Antonio, can you help?
Is there a reason you are not using dialogs defined as resources?
Yes. If we want to build our app for a different OS, its easier not to use resource as not every _ use RC's. That's why I try to use as much @ x,y's as possible.

Now, even if this is not a good reason NOT to use RC's, it is still something that should be fixed :)

Thanks!

Patrick

Posted: Fri Mar 28, 2008 8:47 am
by James Bott
Patrick,

Here is something else to keep in mind. This is a quote from an article about coding for dialogs:

"DIALOG is the resource type, and the four number are the Left, Top, Width and Height co-ordinates. These ARE NOT PIXELS, they are in Dialog Units, which are based on the size of the font used by the system (and chosen by the user). If you have a large font selected, the dialog will be large, if you use a smaller font, the dialog will be that much smaller. This is important as it makes sure that all of the controls are the proper size to display their text in the current font. You can convert dialog units to pixels at runtime using MapDialogRect()."

The complete article is here:

http://www.winprog.org/tutorial/dialogs.html

You can also find more information by Googling "dialog units."

So, the short answer is that "fixing it" probably will require that you code it differently--and perhaps differently for different OSs.

James

Posted: Fri Mar 28, 2008 9:27 am
by Antonio Linares
Patrick,

James is totally right: When you define the dialog we are using "dialog" units, but when the dialog is already created, windows calculates the final "pixel" units, based on the used font.

You should always use oDlg:nWidth() and oDlg:nHeight() from the ON INIT clause of the dialog, as there you have the real pixel sizes.

Please review the Windows API docs for GetDialogBaseUnits():
"The GetDialogBaseUnits function returns the dialog box base units used by Windows to create dialog boxes. Both Windows and applications use these units to convert the width and height of dialog boxes and controls from dialog units, as given in dialog box templates, to pixels, and vice versa."

Posted: Fri Mar 28, 2008 9:29 am
by Antonio Linares
Patrick,

See these formulas from the Windows API docs:

The horizontal base unit is equal to the average width, in pixels, of the characters in the system font; the vertical base unit is equal to the height, in pixels, of the font. Furthermore, each horizontal base unit is equal to 4 horizontal dialog units; each vertical base unit is equal to 8 vertical dialog units. Therefore, to convert dialog units to pixels, an application applies the following formulas:

pixelX = (dialogunitX * baseunitX) / 4
pixelY = (dialogunitY * baseunitY) / 8

Similarly, to convert from pixels to dialog units, an application applies the following formulas:

dialogunitX = (pixelX * 4) / baseunitX
dialogunitY = (pixelY * 8) / baseunitY

The multiplication is performed before the division to avoid rounding problems if base units are not divisible by 4 or 8.

Posted: Fri Mar 28, 2008 9:57 am
by Antonio Linares
After further reviewing it, it seems that the different values come from a different issue:

When we create the memory template to build the dialog, FiveWin uses GetWndRect(), and this may provide different values in XP and Vista, because it is not the client dimensions, it is the total dimensions including the title bar and the borders.

Posted: Fri Mar 28, 2008 10:31 am
by patrickmast
Antonio Linares wrote:After further reviewing it, it seems that the different values come from a different issue:

When we create the memory template to build the dialog, FiveWin uses GetWndRect(), and this may provide different values in XP and Vista, because it is not the client dimensions, it is the total dimensions including the title bar and the borders.
Antonio,

Thank you for all the provided info.

Patrick