gui to substitute msgbox, better way possible

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
Jovannb
Posts: 268
Joined: 17 Jun 2014, 02:44
Location: Austria

gui to substitute msgbox, better way possible

24 Dec 2021, 11:21

Hi,

I've a lot of AHK-Programs with many lines of codes and often "msgbox" or "inputbox" is used for user intraction.
Because msgbox stops program processing and awaits user input ending, I'm looking for a possibility to substitute these msgbox-/inputbox-commands by much more flexible gui-solution.
Main issue thereby is, how to stop program processing during gui is shown respectively user input is done.
Thats a way how I found it possible (working example):

Code: Select all

#SingleInstance force
result := gui_msgbox()
return

gui_msgbox()
{
	gui, add, button, x100 y150 w100 h20 gok_Button, OK
	gui, show, xCenter yCenter w300 h300, Testgui
	
	while not guidone{
	}
	return ok_pressed

	ok_Button:
		gui, destroy
		ok_pressed := 1
		guidone := 1
	return

	GuiEscape:
	GuiClose:
		gui, destroy
		guidone := 1
	return	
}
Is there a better way using a gui similar to msgbox-command in code processing sequence ?

Regards

J.B.
AHK: 1.1.37.01 Ansi, 32-Bit; Win10 22H2 64 bit, german
User avatar
mikeyww
Posts: 27372
Joined: 09 Sep 2014, 18:38

Re: gui to substitute msgbox, better way possible

24 Dec 2021, 11:45

Code: Select all

MsgBox, 64, Result, % "#" result := gui_msgbox() "#"

gui_msgbox()
{
 Gui, Box:New, +LastFound
 Gui, Font, s10
 Gui, Add, Button, x100 y150 w100 h20, OK
 Gui, Show, w300 h300, Testgui
 WinWaitClose
 Return guiControl
 BoxButtonOK:
 guiControl := A_GuiControl
 BoxGuiEscape:
 BoxGuiClose:
 Gui, Box:Destroy
 Return
}
Or:

Code: Select all

MsgBox, 64, Result, % guiQuestion("Confirm", "Is this a MsgBox?", FOCUSBUTTON := 2, X := 200, Y := 300)

guiQuestion(title, text, focusButton := 1, x := "", y := "") { ; Show a positioned message box
 ; https://www.autohotkey.com/boards/viewtopic.php?p=435577#p435577
 Gui, Question:New, +LastFound +AlwaysOnTop
 Gui, Font, s10
 Gui, Add, Text,, %text%
 Gui, Add, Button,     w100, Yes
 Gui, Add, Button, x+m wp  , No
 GuiControl, +Default, Button%focusButton%
 GuiControl, Focus, Button%focusButton%
 Gui, Show, % (x > "" ? "x" x : "") (y > "" ? " y" y : ""), %title%
 WinWaitClose
 Return button
 QuestionButtonYes:
 QuestionButtonNo:
 QuestionGuiEscape:
 QuestionGuiClose:
 button := A_GuiControl
 Gui, Question:Destroy
 Return
}
Lepes
Posts: 141
Joined: 06 May 2021, 07:32
Location: Spain

Re: gui to substitute msgbox, better way possible

24 Dec 2021, 12:59

Jovannb wrote:
24 Dec 2021, 11:21
I'm looking for a possibility to substitute these msgbox-/inputbox-commands by much more flexible gui-solution.
J.B.
You need You are describing a "non intrusive interface", let me explain what I mean: A msgbox is a intrusive interface because it need user atention, stop user from what he is doing and should press a button.
Blender3D was the first program 20 years ago that introduced a non intrusive interface and you need to:
- supply default parameters to whatever function you need to perform, so it can be executed without user interaction
- Provide a gui that user can modify those defaults parameters and re-run the funcion
- The gui must not be modal. Msgbox is modal shown and that's why it stop execution.

So, as you can see is a new programming philosofy, you need to keep in mind don't disturb the user flow of work.

If you want to create a cube in Blender, you need to supply a measure, but Blender propose a default 2 mm cube on screen and creates a panel (that you can hide) where you can modify the properties of the cube.
If you modify something on the panel, the cube is recreated on screen inmediatly.
If you do any other function like scale the cube, move or something else, Panel is destroyed automatically

Note the Arrow at the left of the text "Add Cube" in the panel, if you click on it, you can collapse the panel and it is only visible the text "Add Cube" on the left bottom corner of the 3D View.
21_12_24__6_51_22.PNG
21_12_24__6_51_22.PNG (151.18 KiB) Viewed 572 times
jsong55
Posts: 263
Joined: 30 Mar 2021, 22:02

Re: gui to substitute msgbox, better way possible

25 Dec 2021, 11:47

mikeyww wrote:
24 Dec 2021, 11:45

Code: Select all

MsgBox, 64, Result, % "#" result := gui_msgbox() "#"

gui_msgbox()
{
 Gui, Box:New, +LastFound
 Gui, Font, s10
 Gui, Add, Button, x100 y150 w100 h20, OK
 Gui, Show, w300 h300, Testgui
 WinWaitClose
 Return guiControl
 BoxButtonOK:
 guiControl := A_GuiControl
 BoxGuiEscape:
 BoxGuiClose:
 Gui, Box:Destroy
 Return
}
Or:

Code: Select all

MsgBox, 64, Result, % guiQuestion("Confirm", "Is this a MsgBox?", FOCUSBUTTON := 2, X := 200, Y := 300)

guiQuestion(title, text, focusButton := 1, x := "", y := "") { ; Show a positioned message box
 ; https://www.autohotkey.com/boards/viewtopic.php?p=435577#p435577
 Gui, Question:New, +LastFound +AlwaysOnTop
 Gui, Font, s10
 Gui, Add, Text,, %text%
 Gui, Add, Button,     w100, Yes
 Gui, Add, Button, x+m wp  , No
 GuiControl, +Default, Button%focusButton%
 GuiControl, Focus, Button%focusButton%
 Gui, Show, % (x > "" ? "x" x : "") (y > "" ? " y" y : ""), %title%
 WinWaitClose
 Return button
 QuestionButtonYes:
 QuestionButtonNo:
 QuestionGuiEscape:
 QuestionGuiClose:
 button := A_GuiControl
 Gui, Question:Destroy
 Return
}
An unnecessarily verbose version just for fun! :bravo:

Code: Select all

pressed:=MultiBox(obj:={buttonsArray:["YES","NO"],FocusButton:3,x:100,theme:"Grass",EditValues:["Today's theme is Grass"]})
Msgbox,,Which button pressed?,% "Entire Object:`n" Obj2String(pressed)
pressed:=MultiBox(obj:={buttonsArray:["YES","NO","CANCEL"],FocusButton:2,x:200,theme:"Citrus"})
Msgbox,,Which button pressed?,% "Entire Object:`n" Obj2String(pressed)
pressed:=MultiBox(obj:={FocusButton:1,x:300,theme:"Rustic",EditValues:["1st Edit value","","3rd value"]})

MultiBox(obj:="")
{
	;https://www.autohotkey.com/boards/viewtopic.php?f=76&t=98120&p=435652#p435652
	Static ONLYEDIT1, ONLYEDIT2, ONLYEDIT3
	If !IsObject(obj)
		obj:={}
	defaultO:={buttonsArray:["YES","NO","CANCEL","CHOICE A","CHOICE B","CHOICE C","CHOICE X"]     ; Function will have default values determined here, unless specified by user
			,title:"Default Title"
			,MsgText:"Text to appear in GUI Msgbox"
			,x:""
			,y:""
			,focusButton:1
			,GuiName:"Questions"
			,fontSize:10
			,backgroundC:"548CFF"
			,textC:"CFFFDC"
			,font:"Calibri"
			,Theme:"Sky"
			,EditValues:["Bill Clinton","Donald Trump","Joe Biden"]
			,EditRows:2
			,EditWidth:300
			,NumberOfEdits:3}
	For key, value in defaultO
	{
		If (obj[key]="")
			obj[key]:=defaultO[key]
	}
	; Msgbox,% Obj2String(obj) "`n`n`nCode line #:" 93
	NumberOfButtons:=obj.buttonsArray.count()
	Switch obj.Theme
	{
		case "sky":
			obj.backgroundC:="7900FF"
			obj.textC:="93FFD8"
		Case "Citrus":
			obj.backgroundC:="EA5C2B"
			obj.textC:="F6D860"
		Case "Grass":
			obj.backgroundC:="146356"
			obj.textC:="A3DA8D"
		Case "Rustic":
			obj.backgroundC:="8E806A"
			obj.textC:="FFE6BC"
	}
	Gui,% obj.GuiName ":New", +LastFound +AlwaysOnTop
	Gui, color,% obj.backgroundC
	Gui, Font,% "s" obj.fontSize " c" obj.textC,% obj.font
	Gui, Add, Text,,% obj.MsgText
	Gui, Font, cBLACK
	Loop,% obj.NumberOfEdits
		Gui, Add, Edit,% "vONLYEDIT" A_Index "		y+m	w" obj.EditWidth " r" obj.EditRows,	% obj.EditValues[A_Index]
	Loop,% NumberOfButtons
	{
		If (A_Index=1)
			Gui, Add, Button, gPUSHED   	xm  y+m w120,								% obj.ButtonsArray[A_Index]
		Else
			Gui, Add, Button, gPUSHED 		x+m 	wp  ,								% obj.ButtonsArray[A_Index]
	}
	
	GuiControl, +Default,% "Button" obj.focusButton
	GuiControl, Focus,% "Button" obj.focusButton
	Gui, Show, % (obj.x > "" ? "x" obj.x : "") (obj.y > "" ? " y" obj.y : ""),% obj.title
	WinWaitClose
	SetTimer,CloseResultXYZ,300

	resultobj:={button:button}
	edits:=[]
	Loop,% obj.NumberOfEdits
	{
		edits.push(ONLYEDIT%A_Index%)
	}
	resultobj["edits"]:=edits
	Return resultobj

	PUSHED:
	Gui,% obj.GuiName ": Submit", NoHide
	button := A_GuiControl
	EditValue:=ONLYEDIT
	Gui,% obj.GuiName ":Destroy"
	Return
	CloseResultXYZ:
	WinClose, Result XYZ
	SetTimer,CloseResultXYZ,OFF
	Return
}
}


Obj2String(Obj,FullPath:=1,BottomBlank:=0){
	static String,Blank
	if(FullPath=1)
		String:=FullPath:=Blank:=""
	if(IsObject(Obj)){
		for a,b in Obj{
			if(IsObject(b))
				Obj2String(b,FullPath "." a,BottomBlank)
			else{
				if(BottomBlank=0)
					String.=FullPath "." a " = " b "`n"
				else if(b!="")
					String.=FullPath "." a " = " b "`n"
				else
					Blank.=FullPath "." a " =`n"
			}
	}}
	Else 									; returns the value even if not an obj
		String:=obj	"`n`n`nobj2string: Not an object"	; but says it is not an object
	return String Blank
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], Google [Bot], Mateusz53, MrDoge, peter_ahk and 355 guests