Announcement

Collapse
No announcement yet.

Help converting Dialog Units to Pixels

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Help converting Dialog Units to Pixels

    I'm trying to convert dialog units to pixels using the win32 sdk
    formula:

    Code:
    Local lTemp As Long
      Local baseX As Long
      Local baseY As Long
     
      lTemp = GetDialogBaseUnits
      baseX = LoWrd(lTemp)
      baseY = HiWrd(lTemp)
    then to get the pixels:
    Code:
    PixelX = (DialogUnitX * baseX) / 4
      PixelY = (DialogUnitY * baseY) / 8
    But when I used it to create a window with CreateWindowEx I get wrong
    dimentions.

    When I use the build in function DIALOG UNITS hDlg, x, y TO PIXELS xx,yy
    don't work because my dialog wasn't created with DDT; but this function
    get correct values.

    Anybody can help me converting dialog units to pixels with Api calls.

    Steve Mc Gregor


  • #2
    steve, the matter is not easy - i also had problems and i still haven't the ideas clear.

    first problem: dimensions declaration.
    1- the createwindowex call specifies the window size - that is, with caption and frame included.
    2- the dialog new specifies the client area, in dialog units.

    second problem: the font
    1- windows created via createwindowex use system_font by default.
    1- ddt dialogs use ansi_var_font (i don't know is it is a windows or powerbasic default).

    i'm almost sure getdialogbaseunits refers to system_font, which is wider than ansi_var_font. to get the exact font dimensions is not easy (see http://www.powerbasic.com/support/pb...ead.php?t=3617

    hence the problems are: to know the caption and frame dimensions (use getsystemmetrics); to setup the desired font to the window; to get the correct base units.

    i don't know if i'm right on all this stuff - i really hope some guy will give us a good explanation.

    aldo

    ------------------
    Rgds, Aldo

    Comment


    • #3
      Steve;

      Dialog Units are based on the average size of the font used by the
      dialog. While working with the System font (default for dialogs)
      isn't too bad since the character size is 8 x 16 pixels, DDT created
      dialogs use the MS Sans Serif 8 PT Font (same as ANSI_VAR_FONT)
      which has a character size of 6 x 13 pixels.

      Since Dialogs units are calculated as follows :

      CharWidth/4=XDialogUnit
      CharHeight/8=YDialogUnit

      You can see the difference between the System Font and the MS Sans Serif
      font:

      System Font:

      8/4=2 pixels
      16/8=2 pixels

      Dialog Unit is 2 x 2 pixels.

      MS Sans Serif Font (DDT):

      6/4=1.5 pixels
      13/8=1.625 pixels

      Now the above only holds true when the end users system wide font
      setting is : Small Fonts

      If the end user's system is set to large fonts, the average font
      size is large (System Font is 10 x 20 which still divides well).

      GetDialogBaseUnits is only good for use with the System Font, so
      is useless for DDT created Dialogs, but can be used with Windows
      created using CreateWindowEx or Dialogs created using the API, which
      use the System Font (no font defined in Resource template).




      ------------------
      Chris Boss
      Computer Workshop
      Developer of "EZGUI"
      http://cwsof.com
      http://twitter.com/EZGUIProGuy

      Comment


      • #4
        Using the following code I get correct the vertical dimentions:
        Code:
          Local hDc   As Long
          Local TextM As TEXTMETRIC
        
          hDc = getDC(hParent)
        
          Call SelectObject(hDc, GetStockObject(%ANSI_VAR_FONT))
          Call GetTextMetrics(hDc, TextM)
          baseX = TextM.tmAveCharWidth
          baseY = TextM.tmHeight + TextM.tmExternalLeading
        
          Call ReleaseDC (hParent, hDc)
        Then I use baseX and baseY values wit the formula:

        Code:
          PixelX = (DialogUnitX * baseX) / 4
          PixelY = (DialogUnitY * baseY) / 8
        Can anybody help.

        Steve

        Comment


        • #5
          I finaly solved my problem with this code:

          Code:
            Local hDc   As Long
            Local hFont As Long
            Local TextM As TEXTMETRIC
          
            hDc = getDC(hParent)
            hFont = GetStockObject(%ANSI_VAR_FONT)
          
            Call SelectObject(hDc, hFont)
            Call GetTextMetrics(hDc, TextM)
          
            baseX = TextM.tmAveCharWidth + 1 	' If I don't add a unit i get wrong X dimention
            baseY = TextM.tmHeight + TextM.tmExternalLeading
          
            Call SelectObject (hDc, hFont)
            Call ReleaseDC (hParent, hDc)
          
            xx = GetSystemMetrics(%SM_CXDLGFRAME) * 2     			    'Left and Right Borders
            yy = GetSystemMetrics(%SM_CYDLGFRAME) * 2 + GetSystemMetrics(%SM_CYSIZE)  'Top and Bottom Borders and Title Bar
          then when you create a window:

          Code:
            hMdi = CreateWindowEx(%WS_EX_MDICHILD, _
                                        szClassName, _
                                        "Tipo de cambio", _
                                        %WS_CAPTION Or %WS_BORDER Or %WS_SYSMENU Or %WS_VISIBLE Or %WS_MINIMIZEBOX, _
                                        %CW_USEDEFAULT, _
                                        %CW_USEDEFAULT, _
                                        (208 * baseX) / 4 + xx, _ ' This formula for X
                                        (201 * baseY) / 8 + yy, _ ' This one for Y
                                        hMdiClient, _
                                        %NULL, _
                                        hInst, _
                                        ByVal %NULL)
          It works perfectly in Win98 and WinNT.

          Steve

          Comment


          • #6
            PixelX = (DialogUnitX * baseX) / 4 in C and PB can return different results.
            In C a result is rounded according arithmetic rulles:
            0.5 and greater = 1
            In Pb: greater than 0.5 = 1

            Example: 100 / 8 in C will be 13 (test API MulDiv); in PB - 12.
            That's why I use something like (DialogUnitX * baseX) / 4 + 0.001 (unf. data type conversion)


            ------------------
            E-MAIL: [email protected]

            Comment


            • #7
              That is a good point - PowerBASIC uses Bankers Rounding. For values where the fractional part is exactly 0.5, become rounded toward the nearest even number. This gives the best overall distribution of rounded values, and PowerBASIC has always used this technique.

              The addition of a very small (bias) value simply forces your code to rounds upward when the fractional part = exactly 0.5, regardless of the absolute value.

              For example, 12.5 + 0.001 gets rounded to 13 because the small bias value prevented bankers rounding from being applied. Without this bias, 12.5 would have been rounded to 12.

              BTW, this is documented in the manual.

              ------------------
              Lance
              PowerBASIC Support
              mailto:[email protected][email protected]</A>
              Lance
              mailto:[email protected]

              Comment


              • #8
                Why not use the MulDiv API function mentioned by Semen ?

                I use it for code that calculates Font heights based on the system
                wide font setting (small/large fonts) !



                ------------------
                Chris Boss
                Computer Workshop
                Developer of "EZGUI"
                http://cwsof.com
                http://twitter.com/EZGUIProGuy

                Comment

                Working...
                X