Announcement

Collapse
No announcement yet.

Finding the EXACT width of a line of text

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

  • Mike Trader
    replied
    THanks Mark,

    Now that I know the fonts are different I will give it another try.

    Sometines the simplist things give me the most trouble. These little functions are a minefield. Figuring out these things for the first time often feels like the following test:


    Time limit: 2 hours. Begin immediately.

    HISTORY
    Describe the history of the Papacy from its origins to the present day,
    concentrating especially , but not exclusively, on its social, political,
    economic, religious and philosophical impact on Europe, Asia, America, and
    Africa. Be brief, concise and specific.

    MEDICINE
    You have been provided with a razor blade, a piece of gauze, and a bottle of
    scotch. Remove your appendix. Do not suture until your work has been
    inspected. You have fifteen minutes.

    PUBLIC SPEAKING
    2500 riot-crazed aborigines are storming the classroom. Calm them. You may
    use any ancient language except Latin or Greek.

    BIOLOGY
    Create life. Estimate the differences in subsequent human culture if this
    form of life had developed 500 million years earlier, with special attention
    to its affect on the English Parliamentary System. Prove your thesis.

    MUSIC
    Write a piano concerto. Orchestrate and perform it with flute and drum.
    You will find a piano under your seat.

    PSYCHOLOGY
    Based on your knowledge of their works, evaluate the emotional stability,
    degree of adjustment, and the repressed frustrations of each of the
    following: Alexander of Aphrodisis, Ramses II, Hammurabi. Support your
    evaluation with quotations from each man's work, making appropriate
    references. It is not necessary to translate.

    SOCIOLOGY
    Estimate the social problems which might accompany the end of the world.
    Construct an experiment to test your theory.

    ENGINEERING
    The disassembled parts of a high-powered rifle have been placed on your
    desk. You will also find an instruction manual, printed in Swahili. In 10
    minutes, a hungry Bengal tiger will be admitted to the room Take whatever
    action you feel necessary. Be prepared to justify your decision.

    ECONOMICS
    Develop a realistic plan for refinancing the national debt. Trace the
    possible effects of your plan in the following areas: Cubism, the Donatist
    Controversy, and the Wave Theory of Light. Outline a method for preventing
    these effects. Criticize this method from all possible points of view.
    Point out the deficiencies in your point of view, as demonstrated in your
    answer to the last question.

    POLITICAL SCIENCE
    There is a red telephone on the desk beside you. Start World War III.
    Report at length on its socio-political effects, if any.

    EPISTEMOLOGY
    Take a position for or against truth. Prove the validity of your stand.

    PHYSICS
    Explain the nature of matter. Include in your answer an evaluation of the
    impact of the development of mathematics on science.

    PHILOSOPHY
    Sketch the development of human thought. Estimate its significance. Compare
    with the development of any other kind of thought.

    ASTRONOMY
    You have been given limitless supplies of hydrogen and helium and smaller
    quantities of the heavy metals. Create the universe. Note: This is a
    take-home question. Return project in six days.

    (author unknown)


    ------------------
    Kind Regards
    Mike

    Leave a comment:


  • mark smit
    Guest replied
    Hello Mike,

    I personally use the DrawText API to figure out the bounding RECT for my text string.

    Code:
    DIM rcBound AS RECT
    DIM szText AS ASCIIZ * 256
    DIM hDC AS LONG
     
    szText = "Here is some example text"
     
    DrawText hDC, szText, LEN(szText), rcBound, %DT_CALCRECT or %DT_LEFT
    rcBound.nTop = 0
    rcBound.nLeft = 0
    rcBound.nRight = Text Width
    rcBound.nBottom = Text Height

    DT_CALCRECT Determines the width and height of the rectangle. If there are multiple lines of text, DrawText uses the width of the rectangle pointed to by the rcBound parameter and extends the base of the rectangle to bound the last line of text. If there is only one line of text, DrawText modifies the right side of the rectangle so that it bounds the last character in the line. In either case, DrawText returns the height of the formatted text but does not draw the text.

    ------------------
    Cheers!



    [This message has been edited by mark smit (edited May 12, 2001).]

    Leave a comment:


  • Borje Hagsten
    replied
    Just for fun: it's actually possible to do this before creating a dialog too,
    and resize directly at creation by using the desktop's DC. When this can be
    useful? Well, for own tooltips-like messages, for example. Silly sample:
    Code:
    #COMPILE EXE
    #INCLUDE "win32api.INC"
    '-------------------------------------------------------------------------
    CALLBACK FUNCTION DlgProc
      select case cbmsg
          CASE %WM_CTLCOLORDLG, %WM_CTLCOLORSTATIC
             SetBkColor cbwparam, GetSysColor(%COLOR_INFOBK) 'make it look like tooltips..
             function = GetSysColorBrush(%COLOR_INFOBK)
     
          CASE %WM_KEYUP, %WM_SYSKEYUP, %WM_MOUSEMOVE, %WM_KILLFOCUS
             DIALOG END cbhndl  'kill dialog at these..
     
          CASE %WM_DESTROY
             PostQuitMessage 0  'make sure dialog is destroyed properly at WM_KILLFOCUS..
     
       END SELECT
    END FUNCTION
     
    '-----------------------------------------------------------------------------
    FUNCTION PBMAIN
       LOCAL hDlg AS LONG, hFont AS LONG, hdc AS LONG, WdPix AS LONG, HtPix AS LONG, _
             El AS STRING, lpSize AS SIZEL
     
       El = "***This is a TEST string***"
       hDC  = GetDC(%HWND_DESKTOP)
         hFont = GetStockObject(%ANSI_VAR_FONT)
         hFont = SelectObject(hDC, hFont)              'otherwise System font is used..
         GetTextExtentPoint32 hDC, BYVAL STRPTR(EL), LEN(El), lpSize
         SelectObject hDC, hFont                       'select original font back
       ReleaseDC %HWND_DESKTOP, hDC
     
       WdPix = lpSize.cx + 6
       HtPix = (lpSize.cy + 1) * 3  'in this sample, make room for three lines
     
       DIALOG NEW 0, "", ,, 0, 0, %WS_POPUP or %WS_BORDER TO hDlg
       DIALOG PIXELS hDlg, WdPix, HtPix TO UNITS WdPix, HtPix
       DIALOG SET SIZE hDlg, WdPix, HtPix
     
       El = El + $CRLF + $CRLF + FORMAT$(WdPix) + " Dlg Units wide"
       CONTROL ADD LABEL, hDlg, 100, El, -1, 0, WdPix, HtPix, %SS_CENTER
     
       DIALOG SHOW MODAL hDlg CALL DlgProc
    END FUNCTION

    ------------------

    Leave a comment:


  • Mike Trader
    replied
    aaaaaaaaaaaaaaaaaaaaaaaaaaaah!

    I assumed the Dialog used the system font. duh.

    thx so much Borje

    ------------------
    Kind Regards
    Mike

    Leave a comment:


  • Borje Hagsten
    replied
    Because of the font problem I mentioned. The DC you get via GetDc uses
    System font initially for calculations, but DDT dialogs and controls
    is set to use ANSI font for size calculations, etc. Therefore, one must
    select DDT control's or dialog's font into the DC first. Following in
    %WM_INITDIALOG gives much better result:
    Code:
                hDC  = GetDC(hWnd)
                   hFont = SendMessage(hWnd, %WM_GETFONT, 0, 0)  'must select hWnd's font into DC,
                   hFont = SelectObject(hDC, hFont)              'otherwise System font is used..
                   GetTextExtentPoint32 hdc, BYVAL STRPTR(EL), LEN(El), lpSize
                   SelectObject hDC, hFont                       'select original font back
                ReleaseDC hWnd, hDC
    ------------------
    Forgot: If dialog has 3D borders, one need to include those in size.
    Usually 4-5 pixels extra per side, but other border widths may exist.
    If you add like 10 pixels extra to width and height you get from
    GetTextExtentPoint32, size should be enough..


    [This message has been edited by Borje Hagsten (edited May 11, 2001).]

    Leave a comment:


  • Mike Trader
    replied
    Thx Borje,
    I get it, but why doesnt this work?

    #COMPILE EXE
    #REGISTER NONE
    #DIM ALL
    #INCLUDE "win32api.INC"
    '-------------------------------------------------------------------------
    CALLBACK FUNCTION DlgProc
    STATIC hFont AS LONG
    LOCAL El AS STRING, lpSize AS SizeL, WdPix AS LONG, HtPix AS LONG, hWnd AS LONG, hdc AS LONG
    El = "***This is a TEST string***"
    SELECT CASE CBMSG
    CASE %WM_INITDIALOG
    CONTROL ADD LABEL, CBHNDL, 100, "", 1, 1, 600, 200
    hWnd = GetDlgItem( CBHNDL, 100 )
    hDC = GetDC(hWnd)
    GetTextExtentPoint32 hdc, BYVAL STRPTR(EL), LEN(El), lpSize
    WdPix = lpSize.cx
    HtPix = lpSize.cy + 60
    DIALOG PIXELS CBHNDL, WdPix, HtPix TO UNITS WdPix, HtPix
    DIALOG SET SIZE CBHNDL, WdPix, HtPix ' should set the Width
    CONTROL SET TEXT CBHNDL, 100, EL + $CRLF + $CRLF + FORMAT$(WdPix) + " Dlg Units"
    ReleaseDC hWnd, hDC
    CASE %WM_DESTROY
    END SELECT
    END FUNCTION

    '-----------------------------------------------------------------------------
    FUNCTION PBMAIN
    LOCAL hDlg AS LONG
    DIALOG NEW 0, "", ,, 600, 200, %WS_CAPTION OR %WS_SYSMENU TO hDlg
    DIALOG SHOW MODAL hDlg CALL DlgProc
    END FUNCTION


    ------------------
    Kind Regards
    Mike

    Leave a comment:


  • Borje Hagsten
    replied
    Resizing dialog or controls can be done in WM_INITDIALOG, or even in
    PBMAIN/WINMAIN, right after dialog/control has been created. Using the
    function above, just send control's handle + text to get textwidth back
    in pixels. Then use DIALOG PIXELS hDlg&, x&, y& TO UNITS xx&, yy&
    if you want use DIALOG SET SIZE.., or return value directly if you use
    MoveWindow or SetWindowPos to resize and position dialog.


    ------------------

    Leave a comment:


  • Borje Hagsten
    replied
    One very important thing when it comes to using GetTextExtentPoint32
    is that one must select correct font into DC, otherwise System font
    is used in calculation, which may give wrong result if Ansi font is
    used in control or dialog. Following gives rather good result:
    Code:
    '********************************************************************
    ' Get physical width of text string
    '********************************************************************
    FUNCTION GetTextWidth(BYVAL hWnd AS LONG, BYVAL txt AS STRING) AS LONG
      LOCAL hDc AS LONG, hFont AS LONG, lpSize AS SIZEL
     
      hDc = GetDc(hWnd)                               'get handle for proper device context
        hFont = SendMessage(hWnd, %WM_GETFONT, 0, 0)  'must select hWnd's font into DC,
        hFont = SelectObject(hDC, hFont)              'otherwise System font is used..
        CALL GetTextExtentPoint32(hDc, BYVAL STRPTR(txt), LEN(txt), lpSize)
        SelectObject hDC, hFont                       'select original font back
      ReleaseDC hWnd, hDc                             'and release DC
     
      'FUNCTION = lpSize.cy                           '<- for textheight..
      FUNCTION = lpSize.cx                            '<- function returns the textwidth
    END FUNCTION

    ------------------

    Leave a comment:


  • Mike Trader
    replied
    OK.
    What do i use for hdc befor I have even created a dialog box?

    I need to calculate how big the dlg box is based on a line of text BEFOR i create the dialog.

    I guess I could create it and resize it in the CASE %WM_INITDIALOG. Is that how its done?

    In that case would hdc = CBHNDL ?

    ------------------
    Kind Regards
    Mike

    Leave a comment:


  • Jules Marchildon
    replied
    Mike;

    AS Lance points out, GetTextExtentPoint32() is the required function.
    Code fragment from working example...

    Code:
            CASE %WM_PAINT
     
                hdc = BeginPaint(hWnd,ps)
                Call GetTextMetrics(hdc,tm)
                linespacing = tm.tmHeight + tm.tmInternalLeading
     
                For entry = 0 to %NUMENTRIES -1
                    ColStart = 0
                    For i = 0 to %NUMCOLS-1
                        select case i
                                 case 0
                                    sztext = Info(entry).title
                                    exit select
                                 case 1
                                    sztext = Info(entry).author
                                    exit select
                                 case 2
                                    sztext = Info(entry).publisher
                                    exit select
                                 case 3
                                    sztext = Info(entry).date
                                    exit select
                        end select
                 Call GetTextExtentPoint32(hdc,sztext,len(sztext),sz)
     
                j= 2
                while ((Columns(i) - %SPACING) < sz.cx)
                      chrs = Columns(i) / tm.tmAveCharWidth
     
                      sOld$=sztext
                      sNew$=left$(sOld$,chrs-j) + "..."
                      sztext=sNew$
       
                      Call GetTextExtentPoint32(hdc,szText,len(szText),sz)
                      incr j
                wend
     
                Call TextOut(hdc,ColStart + %SPACING, _
                             HeaderHeight +(entry*linespacing), _
                             sztext,len(sztext))
     
                ColStart = ColStart + Columns(i)
     
              Next
     
           Next
     
                Call EndPaint(hWnd, ps)
    HTH
    Regards,
    Jules

    Leave a comment:


  • Lance Edmonds
    replied
    GetTextExtentPoint32()



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

    Leave a comment:


  • Mike Trader
    started a topic Finding the EXACT width of a line of text

    Finding the EXACT width of a line of text

    Is there anyway to determine the exact width of a line of text that is to be displayed in a dialog box?

    I guess it could be in Dialog units or Pixels cos I can convert it but so far all the methods i have read and tried in Poffs are not exact.

    bu& = GetDialogBaseUnits()
    UnitW = CLNG(LOWRD(bu&)) ' get width of system font
    UnitH = CLNG(HIWRD(bu&)) ' get height of system font

    returns 8 as the "average" system font width. I had to dive that by 2 !!! to get anything close to a real world number.

    Obviously I takes lee space than W. so is it possible to go through the string to be displayed and calculate a sum in pixel i guess, of all the letters that is dead nuts accurate?



    ------------------
    Kind Regards
    Mike
Working...
X