Subscribe to this thread
Home - General / All posts - WaitForDialog revisited
Sloots

678 post(s)
#27-Oct-14 09:00

Hello there,

I recently purchased a new laptop, and since that moment a script that I use a lot fails over and over again.

The purpose of the script is to generate multiple surfaces from a drawing of points. It uses UI scripting to copy the selected points, paste them as a surface, filling the form with the correct parameters. It repeats the process for multiple variables.

The problems arises after the modal dialog was "invoked". I try to wait for the dialog to appear (which it does), but somehow the caption of the dlg variable remains an empty string. May be my hardware is too fast ;-).

On my previous laptop this occured every now and then, but now I can't get it to run as desired at all.

Any help appreciated.

Chris

Attachments:
ui scripting.map


http://www.mppng.nl/manifold/pointlabeler

KlausDE

6,410 post(s)
#27-Oct-14 19:29

If you have bought a killer machine the for I=1 to 10.000 .. next loop might be handeled too quick. Check the value of I or simply replace 10.000 by 20.000.


Do you really want to ruin economy only to save the planet?

Gustavo Palminha

1,010 post(s)
#28-Oct-14 12:07

The problem may be other (x86 vs x64).

I ran you script without any change using x64 it returned an error when invoking the modal dialog, however, I ran it using x86 (x32) bits and it didn't returned an error.

What I would try in your case it to change the WaitForDialog to something like the following:

--VB

Sub WaitForDialog(UI, Caption)

 Dim I, Dlg

 Do While UI.DisplaysModalDialog = False

      If UI.DisplaysModalDialog Then

         Set Dlg = UI.ModalDialog

         If Dlg.Caption = Caption Then

            Exit Sub

         End If

      End If

 Loop

End Sub

Good luck


Stay connected:

Linkedin >> http://www.linkedin.com/in/gustavopalminha

Twitter >> http://twitter.com/gustavopalminha

Other >> http://www.spatialmentor.com

adaptagis

633 post(s)
#28-Oct-14 12:46

Hi Chris

i tested your cool skript on my machin with xenon chip 3.1 ghz and 8 cores with 16 processors and 64GB RAM 8.1 on the latest Mfd 8.0.29 both versions 32 and 64 bit there were no problems at all!

I guess it is an update issue on windows or dotNet or so..

Sloots

678 post(s)
#28-Oct-14 16:02

Thanks for your help. I have tried both 32 and 64-bit version, no success. The update WaitForDialog subroutine did not help either. I'm running on a 24 GB, Intel i7, Windows 7 machine. I'll have a look at my .NET version, may be that helps...

Chris


http://www.mppng.nl/manifold/pointlabeler

danb

2,064 post(s)
#28-Oct-14 19:25

Not directly related, but a similar experience just yesterday with a UI script (pasting vector data as a surface) on a fast machine (32GB i7 Windows 7). I had to resort to nursemaiding the script throught the entire process and amongst other things tried the wait for dialog sub to fix one of the issues I was having (without success).

I did notice however that the script crashes in my process appeared to be systematic, first my script would process 1 record before crashing, then 4, then 1 and then 7. This pattern repeated all the way through processing irrespective of the tile size and individual processing time.

In the past, I have found it more reliable to run UI scripts under the debugger. Presumably this slows the script execution down enough to miss some of the timing issues? which seem to be part and parcel of UI scripting.

One useful finding I did uncover, unrelated to your situation, but perhaps useful to others was to change the Tools > Options > Scripts > Cancel user interface operations after xxx seconds.

value to something larger as it was stopping my script id the paste took over 120 seconds.

Sorry that I don't really have anything useful to offer to your situation.


Landsystems Ltd ... Know your land | www.landsystems.co.nz

tjhb
10,094 post(s)
#29-Oct-14 21:10

[Edit. I have tested this on my laptop and get no error with Chris's original code. Perhaps my laptop is too slow. No error using the alternative below either, of course. I hope Chris can try this.]

No one has so far suggested a test that actually halts execution before proceeding. Everything just tests and/or waits for a specific number of loop iterations, then continues. To make the code actually hang until it's safe to proceed, try e.g.

-- vbscript

Sub WaitForDialog(caption)

    With Application.UserInterface

        Do ' Nothing (spin a core)

        Loop Until .DisplaysModalDialog

        Do ' Nothing (spin a core)

        Loop Until .ModalDialog.Caption = caption

    End With

End Sub

Obviously this will potentially hang forever, e.g. if you pass in a caption that doesn't arise. In practice it would be much better to add a timeout condition, using the system clock.

But as a test, if this doesn't wait for the dialog you expect, then something else is wrong.

tjhb
10,094 post(s)
#29-Oct-14 21:28

OK I think I see the problem.

I've tested on my desktop (which is waaay toooo fast) and get the following issue, with both Chris's version of WaitForDialaog() and with mine.

For me the problem is in the attempt to rename the surface, "after" its creation. I get an "Index out of range" error at line 46.

Is that what you get Chris? (Why didn't you say so??!!)

Remember the script is running in a different thread from the thread(s) Manifold uses internally, so strictly speaking we need to check our timing with respect to everything we expect Manifold to do.

Here we need to wait for the expected result component to come into existence, before we attempt to rename it.

As a quick fix for testing (you would want to add a timeout for code you'll actually use, to avoid the possibility of a permanent hang), add this after the current line 45 (sNewName = ...):

WaitForComponent(sNewName)

Then:

Sub WaitForComponent(name)

    Do ' Nothing (spin a core)

    Loop Until Document.ComponentSet.ItemByName(name) >= 0

End Sub

(That fixes the issue for me.)

tjhb
10,094 post(s)
#29-Oct-14 21:57

...Kind of.

It also strikes a new problem.

Chris's code renames the first surface from the expected initial value, i.e. the original drawing name plus " 2", to a custom name. But it doesn't rename the associated terrain, which therefore retains the infix " 2".

So what happens on the second pass through the loop? The "expected" name is the same: the original drawing name plus " 2". Only it isn't, because Manifold sees the existing terrain based on that pattern, and raises the suffix " 2" to " 3". So now when we attempt to check the a surface with the "expected" name exists, we rightly hit an infinite loop.

The best way to fix this is both to add a proper timeout to the WaitForComponent() function, and avoid using "expected" component names.

To do that, before beginning surface creation, run a function to store a list of current component IDs in an array (or names, but using IDs is quicker), and a second function to take an array of IDs and a component type, and return the first ID of a current component of that type that is not listed in the array. Run the second function after creating each new surface, to find its ID. (Wrinkle: as we've seen, the second function will also need to wait and check, to ensure that Manifold has actually created the new component(s), before searching the current component set for new IDs.)

danb

2,064 post(s)
#30-Oct-14 00:22

Very interesting Tim, I think most of what you mention here has relevance to my situation.


Landsystems Ltd ... Know your land | www.landsystems.co.nz

Sloots

678 post(s)
#30-Oct-14 09:27

I get an error ("Index out of range") at line 28, no matter the version of the WaitForDialog sub. To be more precise... with your sub that waits for ever in case the dialog never appears, the dialog appears, no error occurs, the dialog does not get filled with the correct parameters. If i cancel the dialog, or press OK, I can't close Mfd anymore because it still has a script running. That's the script that is still waiting for a dialog to appear.

Somehow the appearance of the dialog is not detected by the script....


http://www.mppng.nl/manifold/pointlabeler

tjhb
10,094 post(s)
#01-Nov-14 01:02

Thanks Chris, I missed that note in your code.

Try waiting for the dialog controls to become enabled, before adjusting them.

E.g. add before line 28—

WaitForControl dlg.ControlSet("ButtonOK")

then a new subroutine—

Sub WaitForControl(control)

    'Application.History.Log "Wait for control: " & uicontrol.Name & "..." & vbCrLf, True

    Do ' nothing

    Loop Until control.Enabled

    'Application.History.Log "Control is enabled" & vbCrLf, True

End Sub

Sloots

678 post(s)
#01-Nov-14 23:17

Unfortunately it does not work either. Same error which seems logical to me, because dlg.ControlSet is empty so referring to an element in that set generates an "index out of range" error.

Thanks for looking into it.

Chris


http://www.mppng.nl/manifold/pointlabeler

tjhb
10,094 post(s)
#02-Nov-14 04:57

Yes that does seem logical.

As far as I can see then the only useful fix is to introduce a delay (say, a second) at the point where you expect the dialog to show.

Here's a function I use for this where necessary (coming...).

tjhb
10,094 post(s)
#02-Nov-14 05:17

The problem (I'm pretty sure) is that Manifold can't Paste from the Windows clipboard immediately after issuing the Copy instruction. There must be some delay, a requirement that becomes significant with large drawings of source data or (as you've noticed) with a very fast machine.

So the answer is to add a manual delay. For your test drawing, try just one second, but if the source drawing is large, try three seconds or more.

Private Sub Delay(s, doLog)

    Dim i

    Dim start

    For i = 1 To s

        start = Now

        Do ' Nothing

        Loop Until DateDiff("s", start, Now) >= 1

            ' More robust than Timer function

            ' if operation spans midnight

        If doLog Then Application.History.Log "."True

    Next

    If doLog Then Application.History.Log vbCrLf, True

End Sub

The s parameter is the number of seconds of delay, and the doLog argument is Boolean.

Sloots

678 post(s)
#03-Nov-14 08:48

Still no luck...


http://www.mppng.nl/manifold/pointlabeler

tjhb
10,094 post(s)
#03-Nov-14 09:13

Really? What are you seeing now?

Can you post the whole exact script you are trying to run, with the exact drawing for which it arises, and the exact error message(s) you are seeing, with line numbers?

tjhb
10,094 post(s)
#03-Nov-14 09:39

Plus a screenshot of the error.

And how many seconds did you wait for?

Sloots

678 post(s)
#03-Nov-14 12:02

I've attached a map file as I use it for testing. After opening I immediately runn the script. I use the 32-bit version for testing purposes, because this allows me to stop the script and debug if I want to.

The current version gives no error, but keeps waiting for a modal dialog with the caption "Paste as Surface" forever. In the Watch Pane I can see the the Application.UserInterface.DisplaysModalDialog = true, but the caption remains an empty string, and the ControlSet contains no controls at all. See the screenshot I attached.

Attachments:
scripting.png
ui scripting.map


http://www.mppng.nl/manifold/pointlabeler

tjhb
10,094 post(s)
#03-Nov-14 23:55

Without a debugger, that script runs correctly for me in both 64-bit and 32-bit Manifold, version 8.0.29.

Can you confirm (1) whether you are using 8.0.29 too, and whether the script runs correctly for you (2) under 64-bit Manifold, and (3) under 32-bit Manifold but without using a debugger?

I don't normally use the Manifold debugger (a lack of imagination on my part—I am married to 64-bit Manifold), so in an attempt to match your situation as closely as possible OK I have installed the Microsoft Script Debugger and relaunched Manifold.

I've set a breakpoint to match the breakpoint visible in your screen shot, at line 59 (Loop Until .ModalDialog.Caption = caption). Now I open the Watches pane, then run the script under the debugger.

At the breakpoint I click on the Watches pane (more on this below) and add a new watch, on Application.UserInterface. (This can equally be done before starting the script—it makes no difference here.) I expand its node to the ModalDialog object, and the Caption property shows the expected value "Paste As Surface".

Apart from the fact that the Caption shown for you is the empty string, something else looks odd here, and perhaps it may point towards the answer to your problem, or part of it.

In the Watches pane, using the debugging facilities provided by the 32-bit PDM installed with the Microsoft Script Debugger (following the procedure in the Manifold manual), the Type column for Application.UserInterface, ModalDialog, ControlSet, Panes, Toolbar in all cases shows "Object" (which is how ActiveX languages like vbscript see them).

For you, the Type column shows the names of interfaces to .NET class names, IUserInterface and (I think) IUserInterfaceControl. Plus you have a list of [Methods] for each class, with their return values, whereas I don't.

Why the difference? I am guessing that you have not installed the Microsoft Script Debugger, but have perhaps registered Manifold with the PDM provided with Visual Studio 2013. (I don't know how to do that. I'd be interested to know.) Or perhaps you have done something else—but not what I have done. Can you say what debugger facilities you have installed and how?

Does this matter though?

One reason why it might matter is that using a debugger, or at any rate the Watches pane, is not fully compatible with User Interface scripting if modal dialogs are called.

To use the Watches pane, you have to click on it and give it focus. If a UserInterface dialog was active and modal, then giving focus to another window means the earlier dialog is no longer modal. Well, it may remain modal within its own thread, but that only highlights the point that the debugger—or the Watches pane—must also have its own thread, and perhaps that is not far from the heart of the issue.

Resuming my narrative from a few paragraphs ago: the script is halted at the breakpoint at line 59, the Paste As Surface dialog is open, and I'm in the Watches pane looking at object values.

To resume script execution, I can't simply press the "play" button again (i.e. Run under Debugger). If I try that, the Watches panel flashes a few times to let me know it has focus (is modal). I can switch to the Paste as Surface dialog and give that focus; and I can double-click back inside the Watches pane to give that focus. But I only have a choice between those two threads. What I can't do is give focus back to the underlying user interface in order to get the script to resume.

Instead I must either dismiss the Paste As Surface dialog (by clicking OK or Cancel), or close the Watches pane and then dismiss the Paste As Surface dialog. Now I can resume the script—but of course the Paste As Surface dialog has gone, and the UserInterface.ModalDialog object with it, so the script throws an (unnamed) error.

I don't know how that compares with your experience Chris—exactly because I think you are using a different debugger mechanism than me.

What it shows is that there are naturally some issues in trying to integrate a debugger with scripted modal dialogs. Add to this the fact that the script itself is supposed to be running in its own thread (a separate thread from the Manifold application itself—with both these threads under the control of a third thread running the debugger?) and the situation looks very complicated.

Going back to my first questions—do you actually have a problem with this script when it is run not under a debugger? If you don't, great.

But if you do, is there any chance that the debugger mechanism you are using (which I am guessing is not the standard ActiveX debugger but something .NET) is messing up relations between the main Manifold thread and the scripting engine thread, even when the debugger is not in use?

tjhb
10,094 post(s)
#04-Nov-14 00:32

Here's a picture, as close as I can get to yours (note the differences).

Attachments:
scripting 2.png

Sloots

678 post(s)
#05-Nov-14 09:29

First of all thanks for your help.

Can you confirm (1) whether you are using 8.0.29 too, and whether the script runs correctly for you (2) under 64-bit Manifold, and (3) under 32-bit Manifold but without using a debugger?

Ad (1) Yes

Ad (2) 32-bit or 64-bit, with or without debugger, no success.

I have installed Microsoft Script Debugger. The result is that in the watch pane the Type column shows "Object", just like in your situation. But unfortunately the script still fails.

I have installed Visual Studio with comes with a debugger I suppose, but I never explicitely installed a debugger. (Until now...)

I think I'll pass it on to Tech support....


http://www.mppng.nl/manifold/pointlabeler

tjhb
10,094 post(s)
#05-Nov-14 09:40

Good idea. It is beyond us.

tjhb
10,094 post(s)
#05-Nov-14 21:11

I am still very confused about two things though.

(1) Why does this script apparently fail, where it does, only for you? Can anyone else get it to fail in the same way (for clarity, without a debugger)?

(2) How is it that you were able to use the debugger (under 32-bit Manifold only, as expected), without having installed the Microsoft Script Debugger? How did Manifold hook into the Visual Studio .NET debugger (if it did)?

I have Visual Studio 2005 Standard, Visual Studio 2008 Standard, Visual Studio 2010 Professional and Visual Studio 2013 Professional installed, and the only way I can access the debugger in Manifold 32-bit is to install the Microsoft Script Debugger.

What do other people see?

tjhb
10,094 post(s)
#06-Nov-14 06:51

(I'm hoping that half a dozen people here might find time to answer both those questions.)

Sloots

678 post(s)
#06-Nov-14 08:19

Yesterday, out of the blue, the script worked! I didn't do anything special. No reboot, no new software, nothing. I was running another instance of Manifold which was executing a script (not this one, but a script that generates and exports images), and to my surprise the script ran fine. Even when I remove the WaitForDialog and Delay sub routines!!!

Unfortunately the magic has gone. Can't get it to run anymore.

While it was running fine, I was working in a train with a very bad internet connection, but I hope this has nothing to do with the whole situation....


http://www.mppng.nl/manifold/pointlabeler

Sloots

678 post(s)
#19-Nov-14 19:12

I was working in a train with a very bad internet connection, but I hope this has nothing to do with the whole situation....

Today I was working in a cafe. At some point the WiFi connection failed. Guess what happened... The script worked!!! When I arrived at home I decided to test if the internet connection played a role. I diabled my wireless internet connection, et voila, the script ran without flawless. Even with all the delay stuff removed!

I can live with this workaround, but I'm flabbergasted!

Anyone some ideas why?


http://www.mppng.nl/manifold/pointlabeler

tjhb
10,094 post(s)
#19-Nov-14 19:49

Yes (and I have been hesitating to say this): Google Chrome, which I noticed you have installed on your system.

Chrome seems to monitor a large number of processes, very deeply, in order to send data home, in complete accordance with its licence agreement.

If you remove it* (don't be too shocked if this takes a long time) then I would guess you will have no more problems, even when online.

[*Edit: and also Google desktop search, Google toolbar, and so on, perhaps obviously.]

(Sticking my neck out, I think with Chrome, Google have failed in their core precept.)

If this does (or doesn't) make a difference, please do report back.

cartomatic

905 post(s)
#21-Nov-14 03:53

not sure if i would blame chrome for the dialog not working. well at least mine does not mess with manifold. or not yet (the other points pretty much on the spot ;)


maps made easy - www.cartomatic.pl || www.cartoninjas.net

Sloots

678 post(s)
#21-Nov-14 09:34

I agree. I had Chrome installed on my previous laptop without any problem.


http://www.mppng.nl/manifold/pointlabeler

tjhb
10,094 post(s)
#22-Nov-14 01:23

I agree it's unlikely that Chrome is the cause, but:

(1) have you tried uninstalling Chrome, and retesting?

(2) have you got a better idea?

(3) have you heard back from Tech?

Above all though, I'd be really interested to know who else (apart from Chris) sees the names of interfaces to .NET classes, rather than plain ActiveX "Object", in the Type column of the Watches pane, when using the Manifold debugger.

It seems no one else could be bothered to check, which is disappointing.

danb

2,064 post(s)
#22-Nov-14 19:21

Does this help Tim?


Landsystems Ltd ... Know your land | www.landsystems.co.nz

tjhb
10,094 post(s)
#22-Nov-14 22:33

Yes! Thanks!

And no! I'm confused. I wonder what is different between your setup (and Chris's) and mine. Do you have the Microsoft Script Debugger installed Dan? Do you have Visual Studio? (And—I have to ask, since there's no point pretending to hide my paranoia now—Chrome?)

tjhb
10,094 post(s)
#23-Nov-14 03:38

Somewhat less confused, still a bit embarrassed. I'll try to clear up this non-issue.

As the manual says, the Manifold debugger requires some version of the Microsoft Process Debug Manager.

Some versions of Visual Studio install the Process Debug Manager automatically. VS2005 doesn't seem to; VS2008 installs version 9.x; 2010 doesn't seem to (or doesn't add a new version); I don't know about VS2012; VS2013 installs version 12.x.

(a) If you have one of those versions installed, Manifold sees it, enables the debugger, and the Watches pane will show .NET type names.

(b) If not, you can install the Microsoft Script Debugger, as suggested in the manual. This includes a much older version 6.x of the Process Debug Manager. This also enables the debugger, but here the Watches pane will show ActiveX type names.

The wrinkle (well, two wrinkles). If you are in position (a), and then install the Microsoft Script Debugger (even though you don't need it), Manifold will use its version (6.x) of pdm.dll rather than a later version. If you then remove the Microsoft Script Debugger, the Manifold debugger is now disabled, even though the later versions of pdm.dll are (still) present, and indeed even though pdm.dll version 6.x is also still present, since the uninstaller forgot to remove it. Both these wrinkles may be due to the installer and uninstaller for the Microsoft Script Debugger first overwriting, and afterwards removing, a registry setting that Manifold uses to detect the current version of pdm.dll.

So that's clear--and irrelevant. But it was bugging me.

danb

2,064 post(s)
#24-Nov-14 01:06

Yes, No, Not now (Firefox)


Landsystems Ltd ... Know your land | www.landsystems.co.nz

tjhb
10,094 post(s)
#24-Nov-14 07:02

Well that undoes 100% of my analysis.

Could be worse.

Gustavo Palminha

1,010 post(s)
#06-Nov-14 11:05

(1) Why does this script apparently fail, where it does, only for you? Can anyone else get it to fail in the same way (for clarity, without a debugger)?

For me it works now with x86 and x64 Manifold v8.0.27, but it didn't work when using he "original" WaitForComponent.

(2) How is it that you were able to use the debugger (under 32-bit Manifold only, as expected), without having installed the Microsoft Script Debugger? How did Manifold hook into the Visual Studio .NET debugger (if it did)?

Excluding Microsoft Script Debugger or Visual Studio, I think newer versions of Internet Explorer (8+) have a tightly integrated script debugger, possibly this may be used by other applications like Manifold.


Stay connected:

Linkedin >> http://www.linkedin.com/in/gustavopalminha

Twitter >> http://twitter.com/gustavopalminha

Other >> http://www.spatialmentor.com

tjhb
10,094 post(s)
#07-Nov-14 23:56

Excluding Microsoft Script Debugger or Visual Studio, I think newer versions of Internet Explorer (8+) have a tightly integrated script debugger, possibly this may be used by other applications like Manifold.

Yes thanks, but you haven't tested that, have you?

For me fully enabling the IE (11) debugger has no effect in Manifold.

Can anyone replicate Chris's exact experience in the Manifold debugger, or use the Manifold debugger without installing the Microsoft [ActiveX] Script Debugger?

If so how?

yves61
438 post(s)
online
#20-Nov-14 14:06

@ Sloots

I am refferring to my findings here: http://www.georeference.org/forum/t124358#124386.

Scripts may throw an error when run from different Windows System Languages. So caption names on buttons may differ ..., and this may be well causing a Dialog script to throw an error like it did to me. Do not know if that is part of your problem.

Yves

Manifold User Community Use Agreement Copyright (C) 2007-2021 Manifold Software Limited. All rights reserved.