Jump to content

This site uses cookies. By continuing to browse the site you are agreeing to our use of cookies. Find out more here. X
X


Photo

StringSize - M23 - New version 16 Aug 11


  • Please log in to reply
57 replies to this topic

#1 Melba23

Melba23

    I'm old - what's your excuse?

  • Moderators
  • 21,433 posts

Posted 05 May 2010 - 07:28 PM

New version - 16 Aug 11

New:

New method to get the required font into the Display Context for sizing via GetTextExtentPoint32W. Default code (by trancexx :) ) or you can add the handle of your GUI to use that font directly.

The UDF did not correctly recognise TAB characters and so undersized lines containing them. Adding 1 to the $iAttrib paramter will expand tabs to "XXXXXXXX" before sizing the text. This might mean that the returned size is slightly too wide, but at least the line will fit! See the ExtMsgBox thread for an example showing this. :(

Changed:

One or two minor code changes (improvements I hope!).

Note that that these are non-scriptbreaking changes - unless you need to expand tabs you use StringSize just as before. I realise the use of $iAttrib to pass the "expand tab" is less that ideal, but it does prevent using another parameter. :)

New UDF and new examples below and in zip. :idea:
 
3 Sep 10: Minor code change. Thanks xrewndel
19 Jun 10: Minor code change. Thanks Mat
Amended version posted 20 May 2010: - Error returns now correct

 
I just realised that although I have posted versions of this UDF many times in Help topics, I had never actually posted a "final" version here in Example scripts - better late than never, I suppose! :)

StringSize takes a text string and calculates the size of label required to hold it as well as formatting the string to fit.

Now AutoIt will, of course, size a label automatically to fit a text string, but it will not format the string in any way - what you use as the string is what you get in the label. If you do set any label sizes the text will be wrapped, but you can only determine the correct size of the label by trial and error.

StringSize will, however, reformat the string to fit in a given width and tell you the required height so that you can read it all - whatever the font type or size - and you do not have to do the formatting beforehand.

Here is a simple example to show what I mean (you need the UDF in the same folder for all the examples):
Spoiler

And here is an example showing how StringSize can deal with different fonts and text sizes:
Spoiler

You can see that the GUI is perfectly sized each time and that the button is always the right size and in the right place. StringSize returns an array which contains the formatted text to display and the size of the label needed to display it. All you need to do is to use the array elements when you create your label. Try changing the values in $aFont and $aSize if you want to try you own favourites - but beware, StringSize will return an error if you make the size so large that it cannot fit a word into the label width.

NEW A more complex example showing how formatted and unformatted text can be sized correctly. The width of GUI holding the unformatted text varies randomly in width (the current value is displayed at top right):
Spoiler

NEW And a final example showing how you can get your text in the largest possible font to fit in a given space:
Spoiler

NEW Finally here is the UDF itself:
Spoiler

NEW And all 5 files in zip format:Attached File  StringSize.zip   8.2KB   2561 downloads

I hope you find this useful - I certainly do. :)

M23

Edited by Melba23, 16 August 2011 - 12:45 PM.

  • jaberwacky, Xandy, CaptainClucks and 1 other like this
StringSize - Automatically size controls to fit text                                                               ExtMsgBox - A user customisable replacement for MsgBox
Toast - Small GUIs which pop out of the Systray                                                                Marquee - Scrolling tickertape GUIs
Scrollbars - Automatically sized scrollbars with a single command                                   GUIFrame - Subdivide GUIs into many adjustable frames
GUIExtender - Extend and retract multiple sections within a GUI                                      NoFocusLines - Remove the dotted focus lines from buttons, sliders, radios and checkboxes
ChooseFileFolder - Single and multiple selections from specified path tree structure      Notify - Small notifications on the edge of the display
Date_Time_Convert - Easily convert date/time formats, including the language               GUIListViewEx - Insert, delete, move, drag, sort and edit ListView items







#2 Mat

Mat

    43 38 48 31 30 4E 34 4F 32

  • MVPs
  • 5,057 posts

Posted 05 May 2010 - 07:40 PM

Hang on a sec... You release plenty of other UDF's for which this is needed (Toast, Extended MsgBox etc.) and never post this??

Is making a GUI the most effective way of doing this? MeasureString is probably a better way to go.

#3 Melba23

Melba23

    I'm old - what's your excuse?

  • Moderators
  • 21,433 posts

Posted 05 May 2010 - 08:03 PM

Mat,

You release plenty of other UDF's for which this is needed (Toast, Extended MsgBox etc.) and never post this??

Not quite, the UDF was indeed included in the topics of the UDFs you mention - and in many other topics scattered across the Help sections - I just never released it as a standalone UDF in the Examples section. :)

Not sure I understand your second point. Why else do you need to get the size of a chunk of text if not to put it in a GUI? :idea:

M23
StringSize - Automatically size controls to fit text                                                               ExtMsgBox - A user customisable replacement for MsgBox
Toast - Small GUIs which pop out of the Systray                                                                Marquee - Scrolling tickertape GUIs
Scrollbars - Automatically sized scrollbars with a single command                                   GUIFrame - Subdivide GUIs into many adjustable frames
GUIExtender - Extend and retract multiple sections within a GUI                                      NoFocusLines - Remove the dotted focus lines from buttons, sliders, radios and checkboxes
ChooseFileFolder - Single and multiple selections from specified path tree structure      Notify - Small notifications on the edge of the display
Date_Time_Convert - Easily convert date/time formats, including the language               GUIListViewEx - Insert, delete, move, drag, sort and edit ListView items

#4 Kip

Kip

    Into the JavaScript

  • Active Members
  • PipPipPipPipPipPip
  • 1,690 posts

Posted 05 May 2010 - 08:21 PM

There are plenty of UDF's like this. Even I made one and posted in Examples. I can't find it for you now, though.

#5 Datenshi

Datenshi

    Prodigy

  • Active Members
  • PipPipPip
  • 179 posts

Posted 05 May 2010 - 08:25 PM

Melba, can this be used to get stringsize in order to resize a "progressOn" window, to fit the strings within it?(currently it has a default size)

I'd like a way to resize the ProgressOn window based on the text within it. Too long strings get cut off.

Edited by Datenshi, 05 May 2010 - 08:26 PM.


#6 James

James

    Universalist

  • MVPs
  • 10,284 posts

Posted 05 May 2010 - 08:29 PM

There are plenty of UDF's like this. Even I made one and posted in Examples. I can't find it for you now, though.

Here you go.

#7 Mat

Mat

    43 38 48 31 30 4E 34 4F 32

  • MVPs
  • 5,057 posts

Posted 05 May 2010 - 09:45 PM

My point is that always making GUI's is not a particularly glamorous solution. As I have not tried to make the function myself I cannot say if it will be easy to do or not, but making a GUI and then deleting it just to get the size of a label... Sounds more like a workaround to me.

An idea I've just had is possibly a new function for sizing an existing label, then returning the size. That would stop the need for extra GUI's, save on speed, and do what this is probably going to be used for anyway. You only need to input an id for a label and a width, and it will do its stuff and return a height.

As mentioned, I am not 'in the know' and so all this is complete speculation from looking at your code.

#8 Melba23

Melba23

    I'm old - what's your excuse?

  • Moderators
  • 21,433 posts

Posted 06 May 2010 - 07:36 AM

Mat,

Sounds more like a workaround to me

Please do try another way - there is room for all of them. :idea:

Kip,

There are plenty of UDF's like this. Even I made one and posted in Examples

This is not like your UDF - try it and see! :)

M23

Edit: Speeling!

Edited by Melba23, 06 May 2010 - 07:39 AM.

StringSize - Automatically size controls to fit text                                                               ExtMsgBox - A user customisable replacement for MsgBox
Toast - Small GUIs which pop out of the Systray                                                                Marquee - Scrolling tickertape GUIs
Scrollbars - Automatically sized scrollbars with a single command                                   GUIFrame - Subdivide GUIs into many adjustable frames
GUIExtender - Extend and retract multiple sections within a GUI                                      NoFocusLines - Remove the dotted focus lines from buttons, sliders, radios and checkboxes
ChooseFileFolder - Single and multiple selections from specified path tree structure      Notify - Small notifications on the edge of the display
Date_Time_Convert - Easily convert date/time formats, including the language               GUIListViewEx - Insert, delete, move, drag, sort and edit ListView items

#9 Yoriz

Yoriz

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 356 posts

Posted 06 May 2010 - 12:04 PM

Cheers, ive been using a version of this already, may be differant in the version you posted but note that i found the need to guiswitch to the gui i was creating when adding controls after using stringsize.
Local $HeaderTextSize = _StringSize($sHeaderText, $oSelf.HeaderFontSize, $oSelf.HeaderFontWeight,$oSelf.HeaderFontAttribute, $oSelf.HeaderFontFontName)     GUISwitch(HWnd($oSelf.GuiHandle))     $HeaderTextSize[1] += 2     $hCtrl = _oGUICtrlLabel($sHeaderText, $iLeft, $iTop, $HeaderTextSize[2], $HeaderTextSize[1], BitOR($SS_CENTER,$SS_CENTERIMAGE))

GDIPlusDispose - A modified version of GDIPlus that auto disposes of its own objects before shutdown of the Dll using the same function Syntax as the original.EzMySql UDF - Use MySql Databases with autoit with syntax similar to SQLite UDF.

#10 Melba23

Melba23

    I'm old - what's your excuse?

  • Moderators
  • 21,433 posts

Posted 06 May 2010 - 04:20 PM

Datenshi,

Apologies, I missed your post earlier in the noise! :)

can this be used to get stringsize in order to resize a "progressOn" window

Of course, but you need to use WinMove and ControlMove to resize the dialog, labels and progress bar. How you do it depends on whether you want to use a very wide dialog with a single line of text or a block of wrapped text with a normal width dialog (see the examples): :idea:
AutoIt         
#include "StringSize.au3" ; The long text we want to fit in the dialog $sText = "I am a very long line and I will not fit within the width of a normal ProgressOn dialog even with a lot of dieting!" ; Wide dialog $aSize = _StringSize($sText, 11, 800, 0, "Segoe UI") ProgressOn("Progress Meter", $sText, "0 percent") WinMove("Progress Meter", "", (@DesktopWidth - ($aSize[2] + 30)) / 2, Default, $aSize[2] + 30) ControlMove("Progress Meter", "", "[CLASS:msctls_progress32; INSTANCE:1]", Default, Default, $aSize[2] - 15) For $i = 10 to 100 step 10     Sleep(1000)     ProgressSet( $i, $i & " percent") Next ProgressSet(100 , "Done", "Complete") Sleep(500) ProgressOff() ; Wrapped text $aSize = _StringSize($sText, 11, 800, 0 , "Segoe UI", 250) ProgressOn("Progress Meter", $aSize[0], "0 percent") WinMove("Progress Meter", "", (@DesktopWidth - ($aSize[2] + 30)) / 2, Default, $aSize[2] + 30, $aSize[3] + 80) ControlMove("Progress Meter", "", "[CLASS:Static; INSTANCE:1]", Default, Default, $aSize[2], $aSize[3]) ControlMove("Progress Meter", "", "[CLASS:msctls_progress32; INSTANCE:1]", Default, $aSize[3] - 5, $aSize[2] - 15) ControlMove("Progress Meter", "", "[CLASS:Static; INSTANCE:2]", Default, $aSize[3] + 20) For $i = 10 to 100 step 10     Sleep(1000)     ProgressSet( $i, $i & " percent") Next ProgressSet(100 , "Done", "Complete") Sleep(500) ProgressOff()

I had to guess at the caption font, but the values I chose seem to work well - and the values for resizing the dialog and the controls were chosen empirically as well. :( Why the progress bar needs to be set to a smaller width I have no idea - blame Bill Gates! :)

I hope that is what you wanted. :)

M23
StringSize - Automatically size controls to fit text                                                               ExtMsgBox - A user customisable replacement for MsgBox
Toast - Small GUIs which pop out of the Systray                                                                Marquee - Scrolling tickertape GUIs
Scrollbars - Automatically sized scrollbars with a single command                                   GUIFrame - Subdivide GUIs into many adjustable frames
GUIExtender - Extend and retract multiple sections within a GUI                                      NoFocusLines - Remove the dotted focus lines from buttons, sliders, radios and checkboxes
ChooseFileFolder - Single and multiple selections from specified path tree structure      Notify - Small notifications on the edge of the display
Date_Time_Convert - Easily convert date/time formats, including the language               GUIListViewEx - Insert, delete, move, drag, sort and edit ListView items

#11 Melba23

Melba23

    I'm old - what's your excuse?

  • Moderators
  • 21,433 posts

Posted 06 May 2010 - 07:00 PM

Yoriz,

i found the need to guiswitch to the gui i was creating when adding controls after using stringsize

Sorry about that. :idea: As MAt pointed out, the UDF does create and then destroy a GUI (to get the font object required for sizing) so I imagine this is what is causing the problem.

I have only ever used the UDF BEFORE creating the GUI and any of its controls so I had not noticed this before. Let me think for a while about how we might get around it. :)

M23
StringSize - Automatically size controls to fit text                                                               ExtMsgBox - A user customisable replacement for MsgBox
Toast - Small GUIs which pop out of the Systray                                                                Marquee - Scrolling tickertape GUIs
Scrollbars - Automatically sized scrollbars with a single command                                   GUIFrame - Subdivide GUIs into many adjustable frames
GUIExtender - Extend and retract multiple sections within a GUI                                      NoFocusLines - Remove the dotted focus lines from buttons, sliders, radios and checkboxes
ChooseFileFolder - Single and multiple selections from specified path tree structure      Notify - Small notifications on the edge of the display
Date_Time_Convert - Easily convert date/time formats, including the language               GUIListViewEx - Insert, delete, move, drag, sort and edit ListView items

#12 Yoriz

Yoriz

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 356 posts

Posted 06 May 2010 - 07:58 PM

Hey no need to appologise, i just got used to swoppping back :idea: . would this work ?
$hWndPrevious = GUISwitch(WinGetHandle("Program Manager","")) ; at the start of your udf function If $hWndPrevious Then GUISwitch($hWndPrevious) ; just before returning from your udf function

There may be a nicer way to get the previous window.

Edited by Yoriz, 06 May 2010 - 08:00 PM.

GDIPlusDispose - A modified version of GDIPlus that auto disposes of its own objects before shutdown of the Dll using the same function Syntax as the original.EzMySql UDF - Use MySql Databases with autoit with syntax similar to SQLite UDF.

#13 Melba23

Melba23

    I'm old - what's your excuse?

  • Moderators
  • 21,433 posts

Posted 07 May 2010 - 12:50 PM

Yoriz,

I do not get the same problem as you when I use StringSize and then try to create more controls in a GUI: :idea:
AutoIt         
#include <GUIConstantsEx.au3> #include "StringSize.au3" $sText = "pppppppppppp ppppp ppppppppp pppppppppp ppppppppppp ppppppp ppppp ppp" ; Create GUI $hGUI = GUICreate("Test", 500, 500) ; Create first control $hButton = GUICtrlCreateButton("Test", 10, 100, 80, 30) ; Run StringSize $aSize = _StringSize($sText, Default, Default, Default, Default, 200) ; Create second control $hLabel = GUICtrlCreateLabel($aSize[0], 10, 10, 200, $aSize[3]) GUISetState(@SW_SHOW, $hGUI) While 1     Switch GUIGetMsg()         Case $GUI_EVENT_CLOSE             Exit     EndSwitch WEnd

For me that code runs without problem and both controls appear in the GUI.

Your code looks as if you are using AutoItObject - I wonder if that might be causing the problem? I do not know enough about AIO to make any sensible comments about the possibility.

M23
StringSize - Automatically size controls to fit text                                                               ExtMsgBox - A user customisable replacement for MsgBox
Toast - Small GUIs which pop out of the Systray                                                                Marquee - Scrolling tickertape GUIs
Scrollbars - Automatically sized scrollbars with a single command                                   GUIFrame - Subdivide GUIs into many adjustable frames
GUIExtender - Extend and retract multiple sections within a GUI                                      NoFocusLines - Remove the dotted focus lines from buttons, sliders, radios and checkboxes
ChooseFileFolder - Single and multiple selections from specified path tree structure      Notify - Small notifications on the edge of the display
Date_Time_Convert - Easily convert date/time formats, including the language               GUIListViewEx - Insert, delete, move, drag, sort and edit ListView items

#14 Yoriz

Yoriz

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 356 posts

Posted 07 May 2010 - 01:45 PM

Sorry about the missunderstanding, yes im using oop and its probably not that causing it either, i bet im probably creating guis in a strange way thats causing the problem. :idea:
GDIPlusDispose - A modified version of GDIPlus that auto disposes of its own objects before shutdown of the Dll using the same function Syntax as the original.EzMySql UDF - Use MySql Databases with autoit with syntax similar to SQLite UDF.

#15 Melba23

Melba23

    I'm old - what's your excuse?

  • Moderators
  • 21,433 posts

Posted 07 May 2010 - 01:53 PM

Yoriz,

Could you post some code that does not work so I could play with it. I already have the AIO UDFs. :idea:

M23
StringSize - Automatically size controls to fit text                                                               ExtMsgBox - A user customisable replacement for MsgBox
Toast - Small GUIs which pop out of the Systray                                                                Marquee - Scrolling tickertape GUIs
Scrollbars - Automatically sized scrollbars with a single command                                   GUIFrame - Subdivide GUIs into many adjustable frames
GUIExtender - Extend and retract multiple sections within a GUI                                      NoFocusLines - Remove the dotted focus lines from buttons, sliders, radios and checkboxes
ChooseFileFolder - Single and multiple selections from specified path tree structure      Notify - Small notifications on the edge of the display
Date_Time_Convert - Easily convert date/time formats, including the language               GUIListViewEx - Insert, delete, move, drag, sort and edit ListView items

#16 llewxam

llewxam

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 412 posts

Posted 18 May 2010 - 06:08 PM

I am using your code kinda backwards - I know my width maximum (160) and I know my height maximum (55), so I run my string through _StringSize with the font size set too high and decrease by one, and compare $array[3] to 55. If it is less than 55, we're gold, ExitLoop and go. Sometimes it hangs though, here is an example:

For $a = 24 To 1 Step -1     $findIt = _StringSize("CAT5E Crossover Coupler CAT5E Crossover Coupler", $a, Default, Default, "Arial", 160)     If $findIt[3] <= 55 Then         MsgBox(0, "font size to use: " & $a)         ExitLoop     EndIf Next


The above works, but run them together as "CAT5E Crossover CouplerCAT5E Crossover Coupler" and it hangs. Got a solution up your sleeve?

Thanks, wonderful UDF as always!

Ian

My projects:

Spoiler

Find something helpful? BTC donations are appreciated!
16aheZKum8J32XPzk8dFj7AzX33An6zJ6d

#17 Melba23

Melba23

    I'm old - what's your excuse?

  • Moderators
  • 21,433 posts

Posted 20 May 2010 - 12:17 PM

llewxam,

Got a solution up your sleeve?

Yes, I messed up the error-checking return code - which I had already realised while I was away last week. :idea:

The UDF should return an error if it cannot fit a word into the minimum width required - which should happen a lot in your case! I messed up the original error return code so you did not get an error returned and the UDF just ran on and on........

I have amended the UDF in the first post to get over this - but you will now need to amend your code to look for the @error returns which you will now get:
For $a = 24 To 1 Step -1     ConsoleWrite($a & " - ")     $findIt = _StringSize("CAT5E Crossover CouplerCAT5E Crossover Coupler", $a, Default, Default, "Arial", 160)     If Not @error Then         ConsoleWrite($findIt[3] & @CRLF)         If $findIt[3] <= 55 Then             MsgBox(0, "", "font size to use: " & $a)             ExitLoop         EndIf     Else         ConsoleWrite("error " & @error & @CRLF)     EndIf Next

The ConsoleWrites are obviously there to show you what is going on - you can delete them when you have seen what is going on:
24 - error 4 23 - error 4 22 - error 4 21 - error 4 20 - error 4 19 - error 4 18 - error 4 17 - 129 16 - 124 15 - 119 14 - 67 13 - 61 12 - 58 11 - 52

Sorry about that - I will try to do better next time! :)

M23
StringSize - Automatically size controls to fit text                                                               ExtMsgBox - A user customisable replacement for MsgBox
Toast - Small GUIs which pop out of the Systray                                                                Marquee - Scrolling tickertape GUIs
Scrollbars - Automatically sized scrollbars with a single command                                   GUIFrame - Subdivide GUIs into many adjustable frames
GUIExtender - Extend and retract multiple sections within a GUI                                      NoFocusLines - Remove the dotted focus lines from buttons, sliders, radios and checkboxes
ChooseFileFolder - Single and multiple selections from specified path tree structure      Notify - Small notifications on the edge of the display
Date_Time_Convert - Easily convert date/time formats, including the language               GUIListViewEx - Insert, delete, move, drag, sort and edit ListView items

#18 llewxam

llewxam

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 412 posts

Posted 20 May 2010 - 02:23 PM

Sorry about that - I will try to do better next time! :idea:


hahaha!!

I actually kinda switched things around to get around the issue differently, but will update the UDF abyway just in case. What I did was:

$fontSize = 0 Do     $findFontSize += 1     $findit = _StringSize($PlabelName, $findFontSize, Default, Default, "Arial", 160) Until $findit[3] > 55 $fontSize = $findFontSize - 1


Thankfully most of the terms used in the app aren't very large, but I want to make it not puke if at all possible :)

Thanks again, again

Ian

My projects:

Spoiler

Find something helpful? BTC donations are appreciated!
16aheZKum8J32XPzk8dFj7AzX33An6zJ6d

#19 Melba23

Melba23

    I'm old - what's your excuse?

  • Moderators
  • 21,433 posts

Posted 20 May 2010 - 02:52 PM

llewxam,

That will work because by going up in point value you should not hit an error state before finding a valid size.

But as a matter of principle, it is a good idea to do some errorchecking whan you call complex UDFs (especially when you write them!). :idea:

M23
StringSize - Automatically size controls to fit text                                                               ExtMsgBox - A user customisable replacement for MsgBox
Toast - Small GUIs which pop out of the Systray                                                                Marquee - Scrolling tickertape GUIs
Scrollbars - Automatically sized scrollbars with a single command                                   GUIFrame - Subdivide GUIs into many adjustable frames
GUIExtender - Extend and retract multiple sections within a GUI                                      NoFocusLines - Remove the dotted focus lines from buttons, sliders, radios and checkboxes
ChooseFileFolder - Single and multiple selections from specified path tree structure      Notify - Small notifications on the edge of the display
Date_Time_Convert - Easily convert date/time formats, including the language               GUIListViewEx - Insert, delete, move, drag, sort and edit ListView items

#20 KaFu

KaFu

    Hey, it's just me, KhaFoo...

  • MVPs
  • 3,396 posts

Posted 21 May 2010 - 11:36 AM

Nice approach :), saved to toolbox for later use :idea: ...




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users