Jump to content
Sign in to follow this  
Artisan

GDI+ Wrapping Text

Recommended Posts

Artisan

Hi all. I need a little help with GDI+.

I am attempting to display a block of pre-wrapped text using GDI+. (Ultimately I want to be able to print it, so I'm using GDI+ with GRS' UDF. But that doesn't come into play here.) I want to be able to calculate the height and width automatically based on the font and text used. I made a "small" application that asks a user for a font/style and displays a block of typical Latin "lorem ipsum" text. I'm using Melba32's and as far as I can tell it works perfectly. The size it comes up with should be large enough to hold the text. GDI+ disagrees with me, and wraps the text occasionally, causing some lines to have only 1 word and pushing lower lines out of view. Below is my code. Can anyone help me figure out what's causing this? The only current workaround I've found is to pad the width returned by _StringSize by 30 pixels, and I'd really rather not rely on something like that. I suspect there's some kind of a "frame" issue going on, like margin/padding issues in CSS, but I just can't nail it down. Thanks in advance!

EDIT - How do I preserve the tabs in my code when pasting here?

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <Misc.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include "StringSize.au3"

; GDI Fonts
; Get a font, show some text.


; Credit: Melba
; For: StringSize UDF
; http://www.autoitscript.com/forum/topic/114034-stringsize-m23-new-version-16-aug-11/

; Credit: ReFran and UEZ
; For: GDI Repainting
; Source: http://www.autoitscript.com/forum/topic/135199-table-wit-gdiborder-lines-dont-redraw/

; Credit: loremipsum.net
; For: Lorem Ipsum text
; Source: http://www.loremipsum.net/


AutoItSetOption("MustDeclareVars", 1)
Global Const $_ATTRIB = 1, $_NAME = 2, $_SIZE = 3, $_WEIGHT = 4, $_COLOR = 7 ; $aFont indices
Global Const $_TEXT = 0, $_WIDTH = 2, $_HEIGHT = 3 ; $aStringSize indices
Global $aFont, $aStringSize, $hGUI, $hGraphic, $hBrush, $hFormat, $hFamily, $hFont, $tLayout, $aInfo, $sText
Main()

Func Main()

; Sample Text
$sText = _
" 1 - Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt" & @CRLF & _
" 2 - ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci" & @CRLF & _
" 3 - tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum" & @CRLF & _
" 4 - iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat" & @CRLF & _
" 5 - nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum" & @CRLF & _
" 6 - zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis" & @CRLF & _
" 7 - eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non" & @CRLF & _
" 8 - habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes" & @CRLF & _
" 9 - demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus" & @CRLF & _
"10 - dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica," & @CRLF & _
"11 - quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta " & @CRLF & _
"12 - decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes" & @CRLF & _
"13 - in futurum. ##"

; Get font data
$aFont = _ChooseFont()
If Not IsArray($aFont) Then Return -1
$aFont[$_ATTRIB] = Number($aFont[$_ATTRIB]) ; _ChooseFont() returns an array of strings which must be converted for use
$aFont[$_SIZE] = Number($aFont[$_SIZE])
$aFont[$_WEIGHT] = Number($aFont[$_WEIGHT])
$aStringSize = _StringSize($sText, $aFont[$_SIZE], $aFont[$_WEIGHT], $aFont[$_ATTRIB], $aFont[$_NAME])
If Not IsArray($aStringSize) Then Return -1

; Build GUI
$hGUI = GUICreate("GDI+ Font Test (13 Lines)", $aStringSize[$_WIDTH] + 20, $aStringSize[$_HEIGHT] + 50)
GUICtrlCreateLabel("Font: " & $aFont[$_NAME] & ", Size: " & $aFont[$_SIZE] & ", Attribute: " & $aFont[$_ATTRIB] & ", Weight: " & $aFont[$_WEIGHT] & ", Color: " & $aFont[$_COLOR], 10, 10, $aStringSize[$_WIDTH], 20)
_GDIPlus_Startup ()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBrush = _GDIPlus_BrushCreateSolid("0xFF" & StringMid($aFont[$_COLOR], 3))
$hFormat = _GDIPlus_StringFormatCreate()
$hFamily = _GDIPlus_FontFamilyCreate($aFont[$_NAME])
$hFont = _GDIPlus_FontCreate($hFamily, $aFont[$_SIZE], $aFont[$_ATTRIB])
$tLayout = _GDIPlus_RectFCreate(10, 30, $aStringSize[$_WIDTH], $aStringSize[$_HEIGHT])
$aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $aStringSize[$_TEXT], $hFont, $tLayout, $hFormat)
GUIRegisterMsg($WM_PAINT, "_WMPAINT")
GUISetState(@SW_SHOW, $hGUI)

; Message Loop
Do
Until GUIGetMsg() == $GUI_EVENT_CLOSE

; Clean up
_GDIPlus_FontDispose($hFont)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_StringFormatDispose($hFormat)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()
EndFunc

Func _WMPAINT()
; Repaints the GDI+ stuff (border & text)
; I only tested this on Win7 (x32 and x64), but it *should* be compatible with other Windows versions
_WinAPI_RedrawWindow($hGUI, 0, 0, $RDW_UPDATENOW)
_GDIPlus_GraphicsDrawStringEx($hGraphic, $aStringSize[$_TEXT], $hFont, $aInfo[0], $hFormat, $hBrush)
_GDIPlus_GraphicsDrawRect($hGraphic, 10, 30, $aStringSize[$_WIDTH], $aStringSize[$_HEIGHT])
_WinAPI_RedrawWindow($hGUI, 0, 0, $RDW_VALIDATE)
EndFunc
Edited by Artisan

Share this post


Link to post
Share on other sites
UEZ

Try this:

 

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <Misc.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
;~ #include "StringSize.au3"

; GDI Fonts
; Get a font, show some text.


; Credit: Melba
; For: StringSize UDF
; http://www.autoitscript.com/forum/topic/114034-stringsize-m23-new-version-16-aug-11/

; Credit: ReFran and UEZ
; For: GDI Repainting
; Source: http://www.autoitscript.com/forum/topic/135199-table-wit-gdiborder-lines-dont-redraw/

; Credit: loremipsum.net
; For: Lorem Ipsum text
; Source: http://www.loremipsum.net/


AutoItSetOption("MustDeclareVars", 1)
Global Const $_ATTRIB = 1, $_NAME = 2, $_SIZE = 3, $_WEIGHT = 4, $_COLOR = 7 ; $aFont indices
Global Const $_TEXT = 0, $_WIDTH = 2, $_HEIGHT = 3 ; $aStringSize indices
Global $aFont, $aStringSize, $hGUI, $hGraphic, $hBrush, $hFormat, $hFamily, $hFont, $tLayout, $aInfo, $sText
Main()

Func Main()

    ; Sample Text
    $sText = _
            " 1 - Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt" & @CRLF & _
            " 2 - ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci" & @CRLF & _
            " 3 - tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum" & @CRLF & _
            " 4 - iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat" & @CRLF & _
            " 5 - nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum" & @CRLF & _
            " 6 - zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis" & @CRLF & _
            " 7 - eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non" & @CRLF & _
            " 8 - habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes" & @CRLF & _
            " 9 - demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus" & @CRLF & _
            "10 - dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica," & @CRLF & _
            "11 - quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta " & @CRLF & _
            "12 - decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes" & @CRLF & _
            "13 - in futurum. ##"

    ; Get font data
    $aFont = _ChooseFont()
    If Not IsArray($aFont) Then Return -1
    _GDIPlus_Startup()
    $aFont[$_ATTRIB] = Number($aFont[$_ATTRIB]) ; _ChooseFont() returns an array of strings which must be converted for use
    $aFont[$_SIZE] = Number($aFont[$_SIZE])
    $aFont[$_WEIGHT] = Number($aFont[$_WEIGHT])
;~  $aStringSize = _StringSize($sText, $aFont[$_SIZE], $aFont[$_WEIGHT], $aFont[$_ATTRIB], $aFont[$_NAME])
    $aStringSize = _GDIPlus_MeasureString($sText, $aFont[$_NAME], $aFont[$_SIZE], $aFont[$_ATTRIB])

;~  _GDIPlus_MeasureString($sString, $sFont = "Arial", $fSize = 12, $iStyle = 0)
    If Not IsArray($aStringSize) Then Return -1

    ; Build GUI
    $hGUI = GUICreate("GDI+ Font Test (13 Lines)", $aStringSize[0] + 20, $aStringSize[1] + 50)
    GUICtrlCreateLabel("Font: " & $aFont[$_NAME] & ", Size: " & $aFont[$_SIZE] & ", Attribute: " & $aFont[$_ATTRIB] & ", Weight: " & $aFont[$_WEIGHT] & ", Color: " & $aFont[$_COLOR], 10, 10, $aStringSize[0], 20)

    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hBrush = _GDIPlus_BrushCreateSolid("0xFF" & StringMid($aFont[$_COLOR], 3))
    $hFormat = _GDIPlus_StringFormatCreate()
    $hFamily = _GDIPlus_FontFamilyCreate($aFont[$_NAME])
    $hFont = _GDIPlus_FontCreate($hFamily, $aFont[$_SIZE], $aFont[$_ATTRIB])
    $tLayout = _GDIPlus_RectFCreate(10, 30, $aStringSize[0], $aStringSize[1])
;~  $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sText, $hFont, $tLayout, $hFormat)
    GUIRegisterMsg($WM_PAINT, "_WMPAINT")
    GUISetState(@SW_SHOW, $hGUI)

    ; Message Loop
    Do
    Until GUIGetMsg() == $GUI_EVENT_CLOSE

    ; Clean up
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
EndFunc   ;==>Main

Func _WMPAINT()
    ; Repaints the GDI+ stuff (border & text)
    ; I only tested this on Win7 (x32 and x64), but it *should* be compatible with other Windows versions
    _WinAPI_RedrawWindow($hGUI, 0, 0, $RDW_UPDATENOW)
    _GDIPlus_GraphicsDrawStringEx($hGraphic, $sText, $hFont, $tLayout, $hFormat, $hBrush)
    _GDIPlus_GraphicsDrawRect($hGraphic, 10, 30, $aStringSize[0], $aStringSize[1])
    _WinAPI_RedrawWindow($hGUI, 0, 0, $RDW_VALIDATE)
EndFunc   ;==>_WMPAINT

Func _GDIPlus_MeasureString($sString, $sFont = "Arial", $fSize = 12, $iStyle = 0, $bRound = True)
    Local $aSize[2]
    Local Const $hFamily = _GDIPlus_FontFamilyCreate($sFont)
    If Not $hFamily Then Return SetError(1, 0, $aSize)
    Local Const $hFormat = _GDIPlus_StringFormatCreate()
    Local Const $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $iStyle)
    Local Const $tLayout = _GDIPlus_RectFCreate(0, 0, 0, 0)
    Local Const $hGraphic = _GDIPlus_GraphicsCreateFromHWND(0)
    Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sString, $hFont, $tLayout, $hFormat)
    $aSize[0] = $bRound ? Round($aInfo[0].Width, 0) : $aInfo[0].Width
    $aSize[1] = $bRound ? Round($aInfo[0].Height, 0) : $aInfo[0].Height
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_GraphicsDispose($hGraphic)
    Return $aSize
EndFunc   ;==>_GDIPlus_MeasureString

Br,

UEZ

Edited by UEZ
  • Like 1

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
Artisan

Very clever, using a "dummy" GDI graphic with no defined size to get the size needed.  It works well.  Thanks UEZ!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Similar Content

    • dadalt95
      By dadalt95
      Hi!
      I want to get the signal in this website:
      https://binary-signal.com/pt/chart/eurusd
      I have tried using _IEBodyReadText  and some _StringBetween. What happens is that the text are being update every tick and _IEBodyReadText doesn't.
      To perform the update I used  _IEAction($oIE, "refresh") but it's not good because the website block me after some time due too many requests..
      Is there any other way to get this text every tick?
      PS: The text I want to get is WAIT, CALL or PUT.
       
      Here is the code:
      global $oIE = _IECreate ('https://binary-signal.com/pt/chart/eurusd', 0, 1 , 1 , 0) Local $sText = _IEBodyReadText($oIE) $result = _StringBetween ( $sText , 'PUTEUR/USD on Binary-signal.com', 'sinal está PRONTA') ;MsgBox ( 0, "asf", $result[0]) $espera=StringInStr($result[0], "WAIT") $compra=StringInStr($result[0], "CALL") $venda=StringInStr($result[0], "PUT") ;MsgBox($MB_SYSTEMMODAL, "", $espera) $n=0 $c=0 Captar() Func Captar() ;_IENavigate($oIE, "https://binary-signal.com/pt/chart/eurusd") ;MsgBox($MB_SYSTEMMODAL, "", $n) Local $sText = _IEBodyReadText($oIE) $result = _StringBetween ( $sText , 'PUTEUR/USD on Binary-signal.com', 'sinal está PRONTA') If (Not $compra=0) And $n=0 Then MsgBox($MB_SYSTEMMODAL, "", "COMPRE") $n=1 $c=$c+1 ;_IEAction($oIE, "refresh") Sleep(60000) Captar() ElseIf (Not $venda=0) And $n=0 Then MsgBox($MB_SYSTEMMODAL, "", "VENDA") $c=$c+1 $n=1 ;_IEAction($oIE, "refresh") ;MsgBox($MB_SYSTEMMODAL, "", $n) Sleep(60000) Captar() ElseIf (Not $venda=0) And $n=1 Then ;MsgBox($MB_SYSTEMMODAL, "", "Esperando próxima rodada") $n=1 ;MsgBox($MB_SYSTEMMODAL, "", $n) ;_IEAction($oIE, "refresh") Sleep(60000) Captar() ElseIf (Not $venda=0) And $n=1 Then ;MsgBox($MB_SYSTEMMODAL, "", "Esperando próxima rodada") $n=1 ;MsgBox($MB_SYSTEMMODAL, "", $n) ;_IEAction($oIE, "refresh") Sleep(60000) Captar() Else ;MsgBox("", "", "ESPERE") $n=0 Sleep(1000) ;_IEAction($oIE, "refresh") Local $sText = _IEBodyReadText($oIE) $result = _StringBetween ( $sText , 'PUTEUR/USD on Binary-signal.com', 'sinal está PRONTA') Captar() EndIf EndFunc  
    • Reziskonh
      By Reziskonh
      Hi, everybody
      I look for GUI whose behavior similar to the message of an email client or antivirus
      In other words:
          Any PC screen able to calculate the size
          To consider the Task bar size
          To find the lower corner on the right/below and to nestle on it

      Notes:
      In GUI the GUICtrlCreateEdit field (as option) - that can be received and displayed through variable information
      Thanks a lot
      PS
      I use the translator, excuse if something is not clear
       

    • VollachR
      By VollachR
      Hi,
      I'd like to show a progress bar for an operation performed by an external program my script is running silently, I want to show it in a GUI I created using the GUICtrlCreateProgress but I have no idea how to do it.
      The important thing to point out is that there's no way of knowing how long the external program will run, as it is a file splitter and it depends on the size of file it splits and the split parts size.
      Can someone point me in the right direction or give me an example how to do so?
      This is my RunWait command:
      RunWait($MYFILES1 & '\fsplit.exe -split ' & $Size & ' mb ' & $File & " -f " & $File & "." & $extension) It uses multiple variables declared and set earlier in the script, how will I got about having the progress of that command shown using GUICtrlCreateProgress ? Is it possible?
      Thank you.
    • nacerbaaziz
      By nacerbaaziz
      Hello my friends
      I have an inquiry and I hope to find the answer here
      I want to create a graphical user interface
      but I want to hide the system menu
      I mean the window menu
      Is this possible?
      If is possible please give me how to do that
      Thanks in advance
    • helmar
      By helmar
      I was playing around with simple GUI creation.  I tend to like parameter driven coding (in prior life (years ago) as Clipper/FoxPro/dBase coder).  Just wanted to see what I could do with a GUI.
      #Region options, includes Opt('MustDeclareVars', 1) Opt("GUIOnEventMode", 1) ; Change to OnEvent mode #include <GUIConstantsEx.au3> #EndRegion options, includes Global Const $nCols = 2, $nRows = 6, $nSpacer = 10, $nBtnWidth = 150, $nBtnHeight = 30 Global $xName = 0, $xID = 0 Global $nGUIWidth = ($nCols * $nBtnWidth) + (($nCols + 1) * $nSpacer) Global $nGUIHeight = ($nRows * $nBtnHeight) + (($nRows + 1) * $nSpacer) Global $hMainGUI = GUICreate("Calculated GUI", $nGUIWidth, $nGUIHeight, -1, -1) For $xRows = 1 to $nRows ;in this arrangement, tabbing is left to right, then next row For $xCols = 1 to $nCols ;reverse the order of this line with the prior line for top to bottom tabbing, then next col $xName += 1 $xID += 1 Global $Dummy = GUICtrlCreateButton("Button" & $xName, _ ($nBtnWidth * ($xCols - 1)) + (($xCols - 1) * $nSpacer) + $nSpacer, _ ($nBtnHeight* ($xRows - 1)) + (($xRows - 1) * $nSpacer) + $nSpacer, _ $nBtnWidth, _ $nBtnHeight) GUICtrlSetOnEvent($xID+2, "Handler") Next Next GUISetOnEvent($GUI_EVENT_CLOSE, "CloseApp") GUISetState(@SW_SHOW) While 1 Sleep(10) WEnd Func CloseApp() Exit EndFunc Func Handler() MsgBox(0,0,"Button " & @GUI_CtrlId - 2) EndFunc  
×