Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

After form / ribbon released I get error "1923 - Object LOTHISFORM is not found" #18

Open
VfpImaging opened this issue Jul 20, 2023 · 11 comments

Comments

@VfpImaging
Copy link

This happens occasionally under production only, I still could not get the right steps.
I am using some short scripts for the ribbon buttons.
It seems that if I close the Form during the execution of a process EXECSCRIPT gets angry ;-)

@LOGOmichael
Copy link

I just stumpled across a very related point where the definition of loThisForm is defined.

I found this weird to do so, but i do understand the neccesity of it. I marked it for me to find something better.

...especially because i really do not like the nameing. loThisfoform suggests it is local, but indeed this is explicity defined as public and a name so simple as "loThisform" is destined to collide with other (local) defintion in surrounding codes.

But that's only my 2 cent on this 😃

@VfpImaging
Copy link
Author

I worked a little bit more on that.
This issue was because the dropdown menu was still alive, and the menu was still trying to fire using ExecScript the commands.
After I added on Destroy() event of my form : Thisform.RemoveObject("oRibbon") the dropdown menu was imediately closed and the error did not happen again.
Anyway, to avoid this issue I would auto close the Menu form when on the "MouseLeave" event, avoiding some known timer issues.

@DougHennig
Copy link
Owner

@VfpImaging Unfortunately, there is no MouseLeave event for a form, so I have to use a timer instead.

Also, if i drop down a menu for a button and then close the form, the menu disappears. Can you give me some steps to reproduce this using the sample form that comes with the project, or provide me with some code I can run to create the ribbon and then steps to reproduce the problem?

@VfpImaging
Copy link
Author

Hi Doug,
Yes, but you could add all menu items in a container, of the same size of the Main form, so that we could have a "MouseLeave" event!
I know this would bring some extra work, I truly don't know if it's worth. My issue was happening because I instantiated the ribbon class using NewObject, and some object references were probably being held.
Usng "RemoveObject" in my form's Destroy event solved the issue, and the Menu was gone!

@DougHennig
Copy link
Owner

Thanks for the suggestion. I will consider doing that in the future.

@VfpImaging
Copy link
Author

Been playing a little more, and noticed that in my form the menu is not released when another menu is opened. Crazy then, both menus are opened at the same time, see the animated GIF below. If you give me some hints, I could try to debug it and look for the issue. I played with the sample form provided, but it works perfectly. IOW, the issue happens only on my side.

RibbonMenu

@DougHennig
Copy link
Owner

I'd have to see your code. It almost looks like two events are firing.

@VfpImaging
Copy link
Author

VfpImaging commented Aug 4, 2023

Here it is, I made a big "CleanUp at the code", trying to identify the problematic object.
Also removed from the parent form all the API Calls, removed the Ctl32 objects and scrollbars.
Using the ribbon in an "InScreen" form

Below is the code that generates the video below:

LOCAL lcImagePath
m.lcImagePath = ADDBS(_SCREEN._FoxyPath) +  "Images\" 

THISFORM.NEWOBJECT("oRibbon", "SFRIBBON", "PR_SFRIBBON.VCX", _SCREEN._FoxyModule)

WITH THIS.oRibbon
	* Set up the Home tab.
	m.loTab = .ADDTAB("Home")

	WITH m.loTab
		.CAPTION = "Home"

		* Set up the New section.
		m.loSection = .AddSection()
		WITH m.loSection
			.CAPTION = "Output"
			* Show the Save to file button
				m.loButton = .AddButton()
				WITH m.loButton
					.CAPTION = "Save Report"
					.Image = lcImagePath + "pr_Save_32_0.bmp"
					.AddBar("Save as PDF", "_goFP._oExHandler.DoSave(2)", m.lcImagePath + "pr_Pdf.bmp")
					.AddBar("Save as XLS", "_goFP._oExHandler.DoSave(5)", m.lcImagePath + "pr_Excel.bmp")
				ENDWITH && loButton
		ENDWITH

		* Set up the ZOOM section.
		m.loSection = .AddSection()
		WITH m.loSection
			.CAPTION = "Zoom"
			m.loButton = .AddButton()
			WITH m.loButton
				.CAPTION = "Zoom"
				.Image = m.lcImagePath + "pr_Zoomin_32.bmp"
				.AddBar(ZOOM_LEVEL_PROMPT_50_LOC, "Thisform.ActionSetZoom2(3)")
				.AddBar(ZOOM_LEVEL_PROMPT_75_LOC, "Thisform.ActionSetZoom2(4)")
				.AddBar(ZOOM_LEVEL_PROMPT_100_LOC, "Thisform.ActionSetZoom2(5)")
				.AddBar(ZOOM_LEVEL_PROMPT_150_LOC, "Thisform.ActionSetZoom2(6)")
				.AddBar(ZOOM_LEVEL_PROMPT_200_LOC, "Thisform.ActionSetZoom2(7)")
			ENDWITH
		ENDWITH
	ENDWITH && m.loTab

	* Auto-select the Home tab.
	.HOME.SELECTED = .T.

ENDWITH

THISFORM.oRibbon.LEFT = 1
THISFORM.oRibbon.TOP  = 1
THISFORM.oRibbon.VISIBLE = .T.

RibbonMenu2

@VfpImaging
Copy link
Author

VfpImaging commented Aug 4, 2023

I went a little bit further with my tests,

In "SfRibbonToolbarButton.ShowMenu()", adding the following code solved the issue of the two menu forms visible:

LOCAL loExc
TRY
	* If the last menu is visible, close it.
	IF NOT PEMSTATUS(_Screen, "oLastMenu", 5)
		_Screen.AddProperty("oLastMenu", "")
	ENDIF

	LOCAL loLastMenu as Control
	m.loLastMenu = _Screen.oLastMenu

	IF VARTYPE(NVL(m.loLastMenu,"")) = "O" AND m.loLastMenu.Menu.Visible
		m.loLastMenu.Menu.HideMenu()
		RELEASE loThisform
	ENDIF
	_Screen.oLastMenu = This

CATCH TO m.loExc
	SET STEP ON
ENDTRY


* The original code comes below:

* Display the menu below ourselves.
local llInScreen
m.llInScreen = Thisform.HWnd = _screen.HWnd
dodefault(objtoclient(This, 1) + ;
	  This.Height + Thisform.Top + ;
	  iif(m.llInScreen, 0, sysmetric(9) + sysmetric(4)) + ;
	  iif(Thisform.Desktop or m.llInScreen, 0, sysmetric(9) + sysmetric(20)), ;
	  objtoclient(This, 2) + Thisform.Left + iif(m.llInScreen, 0, sysmetric(3)))

The "oLastMenu" property should reside on the main object, and obviously be properly released on "destroy()"

RibbonMenu3

@VfpImaging
Copy link
Author

VfpImaging commented Aug 4, 2023

Whenever a user clicks outside the menu it will loose focus, so even better and sweeter than the above, "Deactivate()" comes to the rescue:

  • in "SfRibbonMenuForm.Deactivate()" or maybe "LostFocus", add the magic command below:

This.Hide()

@DougHennig
Copy link
Owner

The problem with using This.Hide in SFRibbonMenuForm.Deactivate is when a menu has a submenu, the first menu disappears when the submenu is displayed. I went with the oLastMenu solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants