Jump to content

Sub-GUI is only partially created from the second call onwards


Recommended Posts

I have a sub-GUI with a strange behavior.

This sub-GUI for a POS system is called from time to time within the main-GUI. The _first_ time it is called it is displayed completely with all controls - all controls are also fully functional (WM_COMMAND, WM_NOTIFY).

With each further call of this GUI only the first 4-5 controls are created, following controls fail (GUICtrlCreate*() = 0).

From the second call on, the last successfully created control ID is always 119. This should still be far away from the internal AutoIt limitations....

The affected GUI is always deleted after use with GUIDelete() and everything else is cleaned up afterwards as well...

I would like to provide a test script, but the script is very very large and builds completely on external applications - a call without these applications is almost not possible.

Has anyone observed such behavior before? Or even found a workaround?

( Edit: Currently I use AutoIt 3.3.14.5 on Windows 10. )

Edited by supersonic
Link to post
Share on other sites
5 hours ago, supersonic said:

Has anyone observed such behavior before?

Glad you found the solution. Yes I've had a similar issue and added comment notes at the time in one of my scripts :

GUIDelete($hGUI_Preview) ; delete the window (the handle $hGUI_Preview still contains a pointer, these are 2 different points)

$hGUI_Preview = 0 ; force the variable (handle) $hGUI_Preview to 0, then it's not a pointer any more but an Int32 variable.
                  ; It's the same principle with plenty of other functions, for example _GDIPlus_ImageDispose($hImage) 
                  ; which frees memory, but their handle still contains its value AFTER _GDIPlus_ImageDispose($hImage)
                  ; When needed, it's the programmer's job to empty the variable ($hImage = 0 or $hGUI_Preview = 0) making sure
                  ; the variable is no more a handle (pointer) but an Int32 variable, as VarGetType() would reflect it.
                  ; Only then, a test such as If $hGUI_Preview Then... will make sense, no matter its place in the script.

Edit: I got additional comments placed at the beginning of the script. Gonna add them below in case it may help a user facing the same problem :

Global $hGUI_Preview = 0

#cs
Note: it's a good thing to initialize all Global handles to 0 : it would avoid (for instance) an error during tests like "If WinExists($hGUI_Preview) Then..." on an untitled undefined window. Don't forget that a variable defined with "Global $hGUI_Preview" creates a STRING variable and then a test like If WinExists("") would return 1 (success) which is a bad thing in this case, while If WinExists(0) would return 0 (failure) and this is what we need. That explains why $hGUI_Preview = 0 has to be placed immediately after GUIDelete($hGUI_Preview) in the script, it's done !

It's VERY important to force $hGUI_Preview = 0 just after GUIDelete($hGUI_Preview) as we intend to use tests like "If WinExists($hGUI_Preview) Then..." or "If $hGUI_Preview Then..." anywhere in the script.
#ce

 

Edited by pixelsearch
added additional comment
Link to post
Share on other sites
1 hour ago, pixelsearch said:

GUIDelete($hGUI_Preview) ; delete the window (the handle $hGUI_Preview still contains a pointer, these are 2 different points)

Reason why I'm not sure (while you're right of course) that winexists makes an appropriate example

$gui = GUICreate("My GUI")
GUISetState()
Sleep(1000)
GUIDelete($gui)
Msgbox(0,"", $gui & @crlf & winexists($gui))

 

Link to post
Share on other sites

@mikell thanks for your input :)
The WinExists() example I was talking about (in the additional part of my precedent post) is this one :

Global $hGUI_Preview
Msgbox(0,"", WinExists($hGUI_Preview)) ; displays 1, though the window doesn't exist !

To avoid this, better initialize Global handles with 0 :

Global $hGUI_Preview = 0
Msgbox(0,"", WinExists($hGUI_Preview)) ; displays correctly 0

 

Edited by pixelsearch
Link to post
Share on other sites

At least I'm not the only one who had such a "problem", and somehow satisfying that it is solved in the same way :)

I wish _all_ functions like *Shutdown*(), *Destroy*(), *Delete*(), *Close*(), ... set IDs or handles to zero automatically - but in the end it's the care or responsibility of each scripter ;)

Regarding GUIDelete(), this is my favorite:

$__g_hGUI = GUIDelete($__g_hGUI) - 1

If all goes well the variable is set to zero, if not you can check the variable against -1. In the end it is not a handle/pointer anymore.

Edited by supersonic
Link to post
Share on other sites

I wish it was that simple...

My "favorit" would only work if GUIDelete() actually returned 1 on success - at least that's how it's described in the help.

In my attempts GUIDelete() always returns 0. An bug/error?

At the moment I use:

$__g_hGUI = GUIDelete($__g_hGUI) * 0 ; Forcing the variable always to be zero in any case.

WM_COMMAND and WM_NOTIFY still triggers if a window handle/pointer variable is an integer (-1, 1, ...) - this is what I observe...

Edited by supersonic
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...