[Function] ScrollBox

Post your working scripts, libraries and tools
FanaticGuru
Posts: 1441
Joined: 30 Sep 2013, 22:25

[Function] ScrollBox

09 Oct 2014, 18:35

ScrollBox

Creates a Gui that is used somewhat like MsgBox except that it has scrollbars and is resizable by dragging the corner. It also allows for other formatting options similar to any other Gui but in an easy to use function.

Code: Select all

;{ ScrollBox
; Fanatic Guru
; 2016 11 18
; Version 1.20
;
; FUNCTION to Create Gui Scroll Box 
;
;------------------------------------------------
;
; Method:
;   ScrollBox(String, Options, Label)
;
;   Parameters:
;   1) {String} String to be displayed in scroll box
;
;   2) {Options}
;		d		destroy Gui if exist and recreate new
;		w		word wrap
;		p		pause until Gui closed
;		h		hide Gui if exist
;		s		show Gui if exist
;		l		left justified
;		r		right justified
;		c		center justified
;		p%%		p followed by a number for ms to pause
;		f%%		f followed by a number for font size
;		f{%%}	f followed by font options in format of Gui font command
;		x%%		x followed by a number for x box location
;		y%% 	y followed by a number for y box location
;		h%%		h followed by a number for height of box
;		w%%		w followed by a number for width of box
;		t%%		t followed by a number for tab stop (can be multiple)
;		b1		OK button, pauses for response
;		b2		YES / NO buttons, pauses for response
;					Options of existing Gui can not be changed except for position and size
;
;	3)  {Label}	Identifier for dealing with multiply Gui, also the Label at the top of Gui
;				Used to create the Gui name, all non-valid characters are striped
;				If Label exist and String is null and Options is null then Gui is destroyed
;					Otherwise Gui will be updated with new string
;					And Options x, y, h, w can be used to reposition and resize Gui Window
;
;				If String and Label are null then all Gui are destroyed
;
; Returns: 
;		1		OK or YES button pushed
;		0		NO button pushed
;		-1		Gui closed or escaped without pushing button
;		-2		Gui either had no pause or pause finished causing Gui to close
;
; Global:
;   Creates a series of global gui labels prefixed with ScrollBox_Gui_Label_
;
; Note:
;	When scroll box attempts to auto adjust control to fit text it will fail on very large strings.
; 	If scroll box is given a height and width then larger strings can be displayed.
;	Closing the box or hitting escape will destroy the gui.
;
; Example:
;	ScrollBox(Text, "w b2 p5000 f{s16 cRed bold, Arial} x50 y50 h400 w400")
;
ScrollBox(String := "", Options := "", Label := "")
{
	Static Gui_List, Gui_Index
	DetectHiddenWindows, % (Setting_A_DetectHiddenWindows := A_DetectHiddenWindows) ? "On" :
	SetWinDelay, % (Setting_A_WinDelay := A_WinDelay) ? 0 : 0
	if !Gui_List
		Gui_List := {}
	if Label
	{
		Gui_Label := "ScrollBox_Gui_Label_" RegExReplace(Label, "i)[^0-9a-z#[email protected]\$]", "")
		Gui_Hwnd := Gui_List[Gui_Label]
		Win_Hwnd := DllCall("GetParent", UInt, Gui_Hwnd)
		if RegExMatch(RegExReplace(Options, "\{.*}"), "i)d")
			Gui, %Gui_Label%:Destroy
		else if WinExist("ahk_id " Win_Hwnd)
		{
			if String
				GuiControl,,%Gui_Hwnd%, %String%
			WinGetPos, WinX, WinY, WinW, WinH
			if RegExMatch(Options, "i)x(\d+)", Match)
				WinX := Match1
			if RegExMatch(Options, "i)y(\d+)", Match)
				WinY := Match1
			if RegExMatch(Options, "i)w(\d+)", Match)
				WinW := Match1
			if RegExMatch(Options, "i)h(\d+)", Match)
				WinH := Match1
			Winmove, ahk_id %Win_Hwnd%,, WinX, WinY, WinW, WinH
			if RegExMatch(Options, "i)h(?!\d)", Match)
				Gui, %Gui_Label%:Hide
			if RegExMatch(Options, "i)s", Match)
				Gui, %Gui_Label%:Show
			DetectHiddenWindows, %Setting_A_DetectHiddenWindows%
			SetWinDelay, %Setting_A_WinDelay%
			return
		}
	}
	else
	{
		Gui_Index ++
		Gui_Label := "ScrollBox_Gui_Label_" Gui_Index
	}
	if (!String and !Options)
	{
		if Label
		{
			Gui_List.Delete(Gui_Label)
			Gui, %Gui_Label%:Destroy
		}
		else
		{
			for key, element in Gui_List
				Gui, %key%:Destroy
			Gui_List := {}
		}
		DetectHiddenWindows, %Setting_A_DetectHiddenWindows%
		SetWinDelay, %Setting_A_WinDelay%
		return
	}
	Gui %Gui_Label%:Default
	Gui +LabelAllGui
	Adjust1 := 10
	ButtonPushed := -2
	if RegExMatch(Options, "i)f(\d+)", Match)
	{
		Gui, Font, s%Match1%
		Adjust1 := Match1
	}
	else if RegExMatch(Options, "i)f\{(.*)}", Match)
	{
		Options := RegExReplace(Options, "i)f\{.*}")
		StringSplit, Match, Match1, `,
		Gui, Font, %Match1%, % Trim(Match2)
		RegExMatch(Match1, "i)s(\d+)", Adjust)
	}
	else
		Gui, Font
	Gui, Margin, 20, 20
	Gui, +MinSize200x200 +Resize
	Gui, Color, FFFFFF
	Opt := "hwndGui_Hwnd ReadOnly -E0x200  "
	if !(Options ~= "i)w(?!\d)")
		Opt .= "+0x300000 -wrap "
	if RegExMatch(Options, "i)h(\d+)", Match)
		Opt .= "h" Match1 " ", Control := true 
	if RegExMatch(Options, "i)w(\d+)", Match)
		Opt .= "w" Match1 " ", Control := true
	if (Options ~= "i)c")
		Opt .= "center "
	if (Options ~= "i)l")
		Opt .= "left "
	if (Options ~= "i)r")
		Opt .= "right "
	Loop
	{
		Pos ++
		if (Pos := RegExMatch(Options, "i)t(\d+)", Match, Pos))
			Opt .= "t" Match1 " "
	} until !Pos
	Opt_Show := "AutoSize "
	if RegExMatch(Options, "i)x(\d+)", Match)
		Opt_Show .= "x" Match1 " "
	if RegExMatch(Options, "i)y(\d+)", Match)
		Opt_Show .= "y" Match1 " "
	if Control
	{
		Gui, Add, Edit, % Opt
		GuiControl, , %Gui_Hwnd%, %String%
	}
	else
		Gui, Add, Edit, % Opt, %String%
	if RegExMatch(Options, "i)b(1|2)", Match)
	{
		Button := Match1
		if (Button = 1)
			Gui, Add, Button, gAllGuiButtonOK hwndScrollBox_Button1_Hwnd Default, OK
		else
		{
			Gui, Add, Button, gAllGuiButtonYES hwndScrollBox_Button1_Hwnd Default, YES
			Gui, Add, Button, gAllGuiButtonNO hwndScrollBox_Button2_Hwnd, % " NO "
		}
	}
	Gui, Show, % Opt_Show, % Label ? Label : "ScrollBox"
	Gui_List[Gui_Label] := Gui_Hwnd
	Win_Hwnd := DllCall("GetParent", UInt, Gui_Hwnd)
	WinGetPos,X,Y,W,H, ahk_id %Win_Hwnd%
	WinMove, ahk_id %Win_Hwnd%,,X,Y,W-1,H-1 ; Move
	WinMove, ahk_id %Win_Hwnd%,,X,Y,W,H ; And Move Back to Force Recalculation of Margins
	if Button
		ControlSend,,{Tab}{Tab}+{Tab}, ahk_id %Gui_Hwnd% ; Move to Button
	else
		ControlSend,,^{Home}, ahk_id %Gui_Hwnd% ; Unselect Text and Move to Top of Control
	DllCall("HideCaret", "Int", Gui_Hwnd)
	if ((Options ~= "i)p(?!\d)") or (!(Options ~= "i)p") and Button))
		while (ButtonPushed = -2)
			Sleep 50
	else if RegExMatch(Options, "i)p(\d+)", Match)
	{
		TimeEnd := A_TickCount + Match1
		while (A_TickCount < TimeEnd and ButtonPushed = -2)
			Sleep 50
		Gui_List.Delete(Gui_Label)
		Gui, Destroy
	}
	DetectHiddenWindows, %Setting_A_DetectHiddenWindows%
	SetWinDelay, %Setting_A_WinDelay%
	Gui, 1:Default
	return ButtonPushed

	AllGuiSize:
		Resize_Gui_Hwnd := Gui_List[A_Gui]
		if Button
		{
			if (Button = 1)
			{
				EditWidth := A_GuiWidth - 20
				EditHeight := A_GuiHeight - 20 - (Adjust1 * 3)
				ButtonX := EditWidth / 2  - Adjust1
				ButtonY := EditHeight + 20 + (Adjust1/6)   
				GuiControl, Move, %Resize_Gui_Hwnd%, W%EditWidth% H%EditHeight%
				GuiControl, Move, %ScrollBox_Button1_Hwnd%, X%ButtonX% Y%ButtonY%
			}
			else
			{
				EditWidth := A_GuiWidth - 20
				EditHeight := A_GuiHeight - 20 - (Adjust1 * 3)
				Button1X := EditWidth / 4 - (Adjust1 * 2)
				Button2X := 3 * EditWidth / 4  - (Adjust1 * 1.5)
				ButtonY := EditHeight + 20 + (Adjust1/6) 
				GuiControl, Move, %Resize_Gui_Hwnd%, W%EditWidth% H%EditHeight%
				GuiControl, Move, %ScrollBox_Button1_Hwnd%, X%Button1X% Y%ButtonY%
				GuiControl, Move, %ScrollBox_Button2_Hwnd%, X%Button2X% Y%ButtonY%
			}
		}
		else
		{
			EditWidth := A_GuiWidth - 20
			EditHeight := A_GuiHeight - 20
			GuiControl, Move, %Resize_Gui_Hwnd%, W%EditWidth% H%EditHeight%
		}
	return

	AllGuiButtonOK:
		ButtonPushed := 1
		Gui, %A_Gui%:Destroy
		Gui_List.Delete(A_Gui)
	return

	AllGuiButtonYES:
		ButtonPushed := 1
		Gui, %A_Gui%:Destroy
		Gui_List.Delete(A_Gui)
	return

	AllGuiButtonNO:
		ButtonPushed := 0
		Gui, %A_Gui%:Destroy
		Gui_List.Delete(A_Gui)
	return

	AllGuiEscape:
	AllGuiClose:
		ButtonPushed := -1
		Gui, %A_Gui%:Destroy
		Gui_List.Delete(A_Gui)
	return

}
Here is some example code for using it:

Code: Select all

S = 
(
Each script is a plain text file containing commands to be executed by the program (AutoHotkey.exe). A script may also contain hotkeys and hotstrings, or even consist entirely of them. However, in the absence of hotkeys and hotstrings, a script will perform its commands sequentially from top to bottom the moment it is launched. (       )

To create a new script:
1.Download and install AutoHotkey.
2.Right-click an empty spot on your desktop or in a folder of your choice.
3.In the menu that appears, select New -> AutoHotkey Script. (Alternatively, select New -> Text Document.) (       )
4.Type a name for the file, ensuring that it ends in .ahk. For example: Test.ahk
5.Right-click the file and choose Edit                   Script.
6.On a new blank line, type the following:
 #space::Run www.google.com

)

Loop 40
{
	T := T "`n" A_Index "`t" S
}

MsgBox % "Returned = " ScrollBox(T)	; Display Gui and continue on with script with no pause
MsgBox % "Returned = " ScrollBox(T, "P") ; Display Gui and pause for it to close
MsgBox % "Returned = " ScrollBox(T, "w b2 f{s16 cRed, Arial} x50 y50 h400 w400") ; 2 buttons and Gui pauses for response
MsgBox % "Returned = " ScrollBox(T, "f32 b1 x50 y50 h400 w400") ; 1 button and Gui pauses for response
MsgBox % "Returned = " ScrollBox(T, "p3000 f{s16 cBlue bold underline} x50 y50 h400 w400") ; no buttons and Gui pauses for 3 seconds or until closed
MsgBox % "Returned = " ScrollBox(T, "p3000 b2 f{s16, Myriad Pro} x350 y350 h400 w400") ; 2 buttons and Gui pauses for 3 seconds or until closed or button pushed


ExitApp
Example code showing multiply Gui.

Code: Select all

Data =
(
Where can I find the official build, or older releases?
Why do some lines in my script never execute?
Why does my script run fine in XP but not in Vista or Windows 7 or 8?
I can't edit my script via tray icon because it won't start due to an error. Can I find my script somewhere else?
How can I find and fix errors in my code?
Can I run AHK from a USB drive?
Why is the Run command unable to launch my game or program?
How can the output of a command line operation be retrieved?
How can a script close, pause, or suspend other script(s)?
How can a repeating action be stopped without exiting the script?
How can performance be improved for games or at other times when the CPU is under heavy load?
How can context sensitive help for AutoHotkey commands be used in any editor?
How to detect when a web page is finished loading?
How can dates and times be compared or manipulated?
How can I send the current Date and/or Time?
How can I send text to a window which isn't active or isn't visible?
Why don't Hotstrings, Send, and MouseClick work in certain games?
How can Winamp be controlled even when it isn't active?
How can MsgBox's button names be changed?
How can I change the default editor, which is accessible via context menu or tray icon?
How can I save the contents of my GUI associated variables?
Can I draw something with AHK?
How can I start an action when a window appears, closes or becomes [in]active?
My antivirus program flagged AHK as malware. Does it really contain a virus?
How do I put my hotkeys and hotstrings into effect automatically every time I start my PC?
I'm having trouble getting my mouse buttons working as hotkeys. Any advice?
How can tab and space be defined as hotkeys?
How can keys or mouse buttons be remapped so that they become different keys?
How do I detect the double press of a key or button?
How can a hotkey or hotstring be made exclusive to certain program(s)? In other words, I want a certain key to act as it normally does except when a specific window is active.
How can a prefix key be made to perform its native function rather than doing nothing?
How can the built-in Windows shortcut keys, such as Win+U (Utility Manager) and Win+R (Run), be changed or disabled?
Can I use wildcards or regular expressions in Hotstrings?
How can I use a hotkey that is not in my keyboard layout?
My keypad has a special 000 key. Is it possible to turn it into a hotkey?
)

ScrollBox(Data, "w f{s16 cRed bold, Times New Roman}", "Unsorted")
Sort, Data
ScrollBox(Data,"w r x200 y200 h400 w500 f{bold}", "Sorted")
Sort, Data, R
ScrollBox(Data,"f{s12 cBlue, Lucida Console} x600 y600 h700 w300", "Reverse Sorted")

MsgBox
ScrollBox(,"h","Sorted") ; Hide ScrollBox

MsgBox
ScrollBox(,"s","Sorted") ; Show ScrollBox

MsgBox
H := (A_ScreenHeight - 38) / 3
W := A_ScreenWidth / 3

ScrollBox(, "x1" "y1" "h"H "w"W, "Unsorted") ; Reposition and Resize ScrollBox
ScrollBox(, "x1" "y"H "h"H "w"W, "Sorted") ; Reposition and Resize ScrollBox
ScrollBox(, "x1" "y"H*2 "h"H "w"W, "Reverse Sorted") ; Reposition and Resize ScrollBox

MsgBox
ScrollBox("String Changed to This",,"Unsorted") ; Change String in ScrollBox

MsgBox
if (1 = ScrollBox("New Box Created after Destroying Existing One`n`nPush OK Within 5 Seconds to Destroy All ScrollBoxes","d w c f{s18 cFuchsia} b1 p5000","Unsorted"))
	ScrollBox()

Esc::ExitApp
Most of the options are inline with how it would be done in a Gui manually.

The function assumes you want to pause and wait if there are buttons unless you put a specific pause amount then it will only pause for that amount of time while waiting for a button push.

An anomaly is that if you put no size for the control and let it choose its own size based on the text put in to it, then it dies if you try to put too much text into it. In the range of several 100k but if you specific a width and height then it seems to be able to hold more. I tried a 37 meg text file and it worked when I set the size of the Gui. I had to raise my #MaxMem though. I am not sure of AHKs upper limits on variables and Gui but I do not use this for massive file display and that is not really its purpose.

It is just a quick and easy way to display stuff that is a little too big for a MsgBox.

FG
Last edited by FanaticGuru on 11 Apr 2018, 13:36, edited 3 times in total.
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

[Function] Timer - Create and Manage Timers
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
GitHub: cocobelgica

Re: [Function] ScrollBox

09 Oct 2014, 22:48

Nice :) Can be used for debugging and will also come in handy for built-in help/docs for scripts. I have something similar which dumps the text into the script's main window. No formatting and buttons though... mainly for debugging only.
FanaticGuru
Posts: 1441
Joined: 30 Sep 2013, 22:25

Re: [Function] ScrollBox

10 Oct 2014, 01:52

Coco wrote:Nice :) Can be used for debugging and will also come in handy for built-in help/docs for scripts. I have something similar which dumps the text into the script's main window. No formatting and buttons though... mainly for debugging only.
Yea, I had a simpler version without any options or buttons that I used mainly for debugging when I needed to see what was in a variable but it was too much for a MsgBox.

I found it pretty useful as a function in my library and figured I would post it. But since I was posting it, I figured I would fancy it up so maybe someone would find it useful for more than just debugging. Especially useful for newer users that might have trouble creating a resizable and scrolling gui manually.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

[Function] Timer - Create and Manage Timers
FanaticGuru
Posts: 1441
Joined: 30 Sep 2013, 22:25

Re: [Function] ScrollBox

30 Apr 2015, 14:34

Updated on First Page

Version: 1.1 Change Log:
Support for multiply ScrollBoxes being displayed at the same time
Additional options like hide, show, destroy, text justification
Ability to move and resize existing ScrollBoxes
Ability to change text displayed in existing ScrollBox

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

[Function] Timer - Create and Manage Timers
User avatar
Tomer
Posts: 314
Joined: 21 Aug 2016, 05:11

Re: [Function] ScrollBox

11 Apr 2018, 08:17

amazing!
tnx
FanaticGuru
Posts: 1441
Joined: 30 Sep 2013, 22:25

Re: [Function] ScrollBox

11 Apr 2018, 13:45

Updated on First Page

Version: 1.2 Change Log:
Added support for setting tab stops. For example t30 t50 would set tab stops at character positions 30 and 50 in the Gui.

@Tomer, thanks. Have not looked at this code in awhile even though I use the function in my library fairly often. Your post prompted me to notice that I had a newer version that I never posted.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

[Function] Timer - Create and Manage Timers

Return to “Scripts and Functions”

Who is online

Users browsing this forum: No registered users and 24 guests