Notifications
Clear all

[Closed] Close RCMenu programmatically

 lo1

I’m looking for a way to close or ‘un-popup’ an rcmenu through script.
The reason I want to do this is that it seems if the user receives a modal dialog while an rcmenu is visible, nothing gets focus and max is stuck.

Any ideas?

10 Replies
2 Replies
(@denist)
Joined: 2 years ago

Posts: 0

if the user receives a modal dialog while an rcmenu is visible, nothing gets focus and max is stuck.

hmm… it shouldn’t be stuck. however, the best way to close RCmenu I know is to simulate ESC pressed.

(@denist)
Joined: 2 years ago

Posts: 0

the way to close RCmenu is to send press ESC key message to its window. The problem – you have to know rcmenu’s hwnd and to be sure that any rcmenu is opened. The better solution that I see is to pop-up the modal dialog (probably warning or message in your case) in modeless mode first and make it modal after. Any newly opened modeless window closes all rcmenus. After that we Disable MAX window, and Enable our popped-up one. On close event of popped-up window we Enable MAX window back. For this solution we need a little help from C#:


global WinOpsAssembly
fn CreateWinOpsAssembly =
(
	source = "using System;
"
	source += "using System.Runtime.InteropServices;
"
	source += "class WinOps
"
	source += "{
"
	source += "	[DllImport(\"user32.dll\")]
"
	source += "	[return: MarshalAs(UnmanagedType.Bool)]
"
	source += "	public static extern bool EnableWindow(Int32 hWnd, bool bEnable);
"
	source += "}
"

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

	compilerParams.ReferencedAssemblies.Add "System.dll"
	compilerParams.GenerateInMemory = on
	compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
	
	WinOpsAssembly = compilerResults.CompiledAssembly
	WinOpsAssembly.CreateInstance "WinOps"
)
global WinOps = CreateWinOpsAssembly()

rcmenu RCtest 
(
	menuitem item0 "RC Menu"
)
try(destroydialog OwnerRol)catch()
try(destroydialog ChildRol)catch()

rollout ChildRol "Child: Pseudo-Modal" width:200
(
	label lb "Pop-up Dialog" align:#center
	
	on ChildRol close do WinOps.EnableWindow (windows.getmaxhwnd()) on
	on ChildRol open do
	(
		hwnd = windows.getChildHWND 0 ChildRol.title
		WinOps.EnableWindow (windows.getmaxhwnd()) off
		WinOps.EnableWindow hwnd[1] on
	)
)

rollout OwnerRol "Owner: Modeless" width:200
(
	button menu_bt "Open Menu" width:86 
	timer sim_tm interval:2000 active:off

	on menu_bt pressed do 
	(
		sim_tm.active = on
		popupmenu RCtest
	)
	on sim_tm tick do
	(
		sim_tm.active = off
		createDialog ChildRol pos:[700,560]
	)
)

createdialog OwnerRol pos:[600,500]

 lo1
rcmenu testMenu
(
	menuitem test "test"
)

rollout testrol2 "2" width:200
(
	button bbb "bb"
)

rollout testrol "1" width:200
(
	button openMenu "Open Menu"
	timer modalTimer interval:5000

	on openMenu pressed do popupmenu testMenu

	on modalTimer tick do
	(
		try(destroydialog testrol2)catch()
		(dotnetclass "SendKeys").sendWait "{ESC}"
		createDialog testrol2 modal:true
	)
)

createdialog testrol

Thanks for the idea Denis, unfortunately it’s not working for me. Please see attached code… am I doing it wrong?
I’ve also noticed that if I alt+tab to another window and come back to max the menu closes and everything is fine.

 lo1

Very creative solution Denis, thanks!

Funny how opening a non-modal dialog closes the RCMenu, but for some reason, this doesn’t work:


createDialog modalWindow --non-modally
destroyDialog modalWindow
createDialog modalWindow modal:true
3 Replies
(@denist)
Joined: 2 years ago

Posts: 0

what is not working? are you talking about my solution?

 lo1
(@lo1)
Joined: 2 years ago

Posts: 0

no, your solution worked perfectly. The code example I attached does not work, but that doesn’t matter, see post above this one.

(@denist)
Joined: 2 years ago

Posts: 0

ok. definitely your sample above has to work. but my goal was to stay with only one pop-up dialog solution and make all modal/modeless things inside this dialog.

 lo1

another solution I’ve found by exploring your idea that a non-modal dialog closes an rc menu:
Using a helper dialog to launch the modal dialog.

rcmenu testMenu
(
	menuitem test "test"
)

rollout modalDialog "Child: Modal" width:200
(
	button modalbutton "button in modal dialog"
)

rollout helperDialog "helperDialog" width:100
(
	timer helperTimer interval:1
	on helperTimer tick do
	(
		destroydialog helperDialog
		createDialog modalDialog modal:true
	)	
)

rollout parentDialog "Parent - not modal" width:200
(
	button openMenu "Open Menu"
	timer modalTimer interval:5000

	on openMenu pressed do popupmenu testMenu

	on modalTimer tick do createDialog helperDialog
)

createdialog parentDialog

While not as elegant as your solution, the code is simpler and seems to work. The drawback is you see a flashing rollout for a split second.

interesting topic

You may hide flashing rollout by creating it out of the screen.

on modalTimer tick do createDialog helperDialog pos:[0,-200]
1 Reply
 lo1
(@lo1)
Joined: 2 years ago

Posts: 0

Good point, thanks.