MXS: CreateDialog Enter/Escape Button

MXS: CreateDialog Enter/Escape Button

istan
Advisor Advisor
1,305 Views
7 Replies
Message 1 of 8

MXS: CreateDialog Enter/Escape Button

istan
Advisor
Advisor

Is there any way to end a modal dialog via <Enter> or <Escape>?

"Default buttons" would have been great..

I use of course "escapeenable:false" to supress the error message..

0 Likes
1,306 Views
7 Replies
Replies (7)
Message 2 of 8

denisT.MaxDoctor
Advisor
Advisor

@istan wrote:

Is there any way to end a modal dialog via <Enter> or <Escape>?

"Default buttons" would have been great..

I use of course "escapeenable:false" to supress the error message..


end with <Escape> and "not escapable" at the same time? Sorry, but I don’t understand what you want from a modal dialog.

0 Likes
Message 3 of 8

istan
Advisor
Advisor

a) I use "escapeenable:false" since I don't want to get an error message in the MXS listener

b) usually standard windows dialogs support <ESC> for aborting a dialog (IDCANCEL) and <Enter> for the OK-button (IDOK)

 

0 Likes
Message 4 of 8

miauuuu
Collaborator
Collaborator

Can you put a [OK/Cancel] button in your modal dialog and set the focus to it? When the dialog appears the user has to press Enter and the on btn_Cancel do event will close the dialog.

 

This works on max 2020

 

global rol_modal
try(destroyDialog rol_modal)catch()
rollout rol_modal "miauu"
(
label lbl_01 "Press Escape to close the dialog"
)
createdialog rol_modal modal:true escapeEnable:false

 

https://miauu-maxscript.com/
0 Likes
Message 5 of 8

denisT.MaxDoctor
Advisor
Advisor

do something with on-the-fly .net assembly and timer:

fn createKeyboardAssembly =
(
	source = ""
	source += "using System;\n"
	source += "using System.Runtime.InteropServices;\n"
	source += "public class VirtualKeys\n"
	source += "{\n"
	source += "    const int VK_ESCAPE = 0x1B;\n"
	source += "    const int VK_RETURN = 0x0D;\n"
	source += "    const int KEY_PRESSED = 0x80;\n"
	source += "    [DllImport(\"user32.dll\", CharSet = CharSet.Auto, ExactSpelling = true)]\n"
	source += "    static extern short GetKeyState(int virtualKeyCode);\n"
	source += "    public bool IsEscapePressed() { return (GetKeyState(VK_ESCAPE) & KEY_PRESSED) == KEY_PRESSED; }\n"
	source += "    public bool IsReturnPressed() { return (GetKeyState(VK_RETURN) & KEY_PRESSED) == KEY_PRESSED; }\n"
	source += "}\n"

	csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
	compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"

	compilerParams.ReferencedAssemblies.Add("System.dll");

	compilerParams.GenerateInMemory = true
	compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)

	compilerResults.CompiledAssembly
)


try(destroydialog warning_dialog) catch()
rollout warning_dialog "Warning" width:191
(
	local vk_assembly = createKeyboardAssembly()
	local vk = vk_assembly.CreateInstance "VirtualKeys"
	
	local result = #default

	label text_lb "Press ESC or ENTER..." align:#left
		
	timer quit_timer interval:10
	on quit_timer tick do
	(
		case of
		(
			(vk.IsEscapePressed()):
			(
				result = #escape
				destroydialog warning_dialog
			)
			(vk.IsReturnPressed()):
			(
				result = #ok
				destroydialog warning_dialog
			)
		)
	)
		
	on warning_dialog close do
	(
		format ">> closed with %\n" result
	)
	on warning_dialog open do
	(
	)
)
createdialog warning_dialog modal:on escapeEnable:off

 

 

0 Likes
Message 6 of 8

denisT.MaxDoctor
Advisor
Advisor

or make it more universal:

fn createKeyboardAssembly =
(
	source = ""
	source += "using System;\n"
	source += "using System.Runtime.InteropServices;\n"
	source += "public class VirtualKeys\n"
	source += "{\n"
	source += "    const int KEY_PRESSED = 0x80;\n"
	source += "    [DllImport(\"user32.dll\", CharSet = CharSet.Auto, ExactSpelling = true)]\n"
	source += "    static extern short GetKeyState(int virtualKeyCode);\n"
	source += "    public bool IsKeyPressed(int key) { return (GetKeyState(key) & KEY_PRESSED) == KEY_PRESSED; }\n"
	source += "}\n"

	csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
	compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"

	compilerParams.ReferencedAssemblies.Add("System.dll");

	compilerParams.GenerateInMemory = true
	compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)

	compilerResults.CompiledAssembly
)

try(destroydialog warning_dialog) catch()
rollout warning_dialog "Warning" width:191
(
	local VK_ESCAPE = 0x1B
	local VK_RETURN = 0x0D
	local VK_SPACE  = 0x20

	local vk_assembly = createKeyboardAssembly()
	local vk = vk_assembly.CreateInstance "VirtualKeys"
	
	local result = #default

	label text_lb "Press ESC or ENTER..." align:#left
		
	timer quit_timer interval:10
	on quit_timer tick do
	(
		case of
		(
			(vk.IsKeyPressed(VK_ESCAPE)):
			(
				result = #escape
				destroydialog warning_dialog
			)
			(vk.IsKeyPressed(VK_RETURN)):
			(
				result = #ok
				destroydialog warning_dialog
			)
			(vk.IsKeyPressed(VK_SPACE)):
			(
				result = #space
				destroydialog warning_dialog
			)
		)
	)
		
	on warning_dialog close do
	(
		format ">> closed with %\n" result
	)
	on warning_dialog open do
	(
	)
)
createdialog warning_dialog modal:on escapeEnable:off
Message 7 of 8

istan
Advisor
Advisor

I hoped it would be more simple 😉 Nevertheless thx for the example!!

0 Likes
Message 8 of 8

istan
Advisor
Advisor

@miauuuu wrote:

Can you put a [OK/Cancel] button in your modal dialog and set the focus to it? When the dialog appears the user has to press Enter and the on btn_Cancel do event will close the dialog.

 


Nice try, but this idea fails, as soon as you have a text field in the dialog, which has the focus.. The ok and cancel buttons have to work independantly of any other currently focussed control..

0 Likes