Detecting if a wizard is active???

Here's the deal:

I have a button which pops up a listbox.
In this listbox the available queries are displayed.
When the user doubleclicks on a query a popup form is displayed containing the query in datasheet view contained in a subform.
When the user selects a query and presses <SHIFT> + D the query is deleted.
When the user selects a query and presses <SHIFT> + A the query is opened in design view for alteration.
I also use <SHIFT> + L to give the user the ability to link a query to a certain form so when they ask for a query only the linked ones are displayed (they can switch between linked queries and all queries by pressing <SHIFT> + V)
This is all easy to control and the user isn't able to get into the database screen.

The functionality which I would like to add now is the ability to create a new query while using the wizard. I can check to see if a new object is created and pick up from there, but if the user presses cancel then no new object is created.

The question is:

How can I check if the wizard is still running? Because then I can continue my application (send the user back to the main form)

Hope someone tried his hand at this before and can help me out here :)


Who is Participating?
BrianWrenConnect With a Mentor Commented:
Every time the timer runs, it changes the contents of controlpth, hence the test is always true...

Also, each time the From_Timer event is through, the variables that are local to the Sub are destroyed.  They have procedure scope, and procedure lifetime.

All of the books on APIs recommend using aliases for the procedures.  That way, if the APIs change, the interface to them will not, because it uses the name that you gave to it.

For instance, in the 32-bit change, there were duplicates of many of the APIs made—one for standard ASCII character, one wor the new wide format for characters.  But if your API declaration implemented aliasing, all you had to do was change the name of the API to use, (adding an 'a' to the end in many cases), and the code that used the API still worked fine.

If they change the APIs, all of the applications that use them would break.  That would be a bad move . . .  (They're pretty stable, in other words.)

how are you opening this new query in wizard mode?  Also, what kind of query (simple, crosstab, duplicates, or unmatched??)
GOLLEMAuthor Commented:

I'm opening the wizard using:
DoCmd.RunCommand NewObjectQuery

The user gets to decide what he wants to do, although I'm thinking on restricting this by using Sendkeys to make the first choice
(SendKeys isn't dangerous here, because a wizard is modal and changing the focus to another application would take longer than the evaluation of the SendKeys statement)

This isn't a time-critical question, because my main form is a pop-up form which fills the entire screen. This way no user can even see the database window, let alone use it.  The wizard is a pop-up too, so it doesn't disappear behind the main form.
Of course I could put code in my OnGotFocus event for my main form, because the user is bound to click on it when nothing else happens, but If the user chose to customise the query at the end of the wizard, then it doesn't make sense to have him click on the main form before it disappears and reveals the open query.

If I were a user, that would look kinda strange to me...

Hope this clarifies things a bit.... :)


Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Create a form with a text box on it that is tall.

Put a close button on it.

Set the timer event of the form to make a list of all open forms, and then list them in the tall text box.

When the wizard is open, there should be a specific form open, which will 'go away' when the wizard is closed.

Open theis form, find out what form that is, and then test for that form to be open as the indicater that the wizard is active.

GOLLEMAuthor Commented:

What code do you have in mind?

Is there VB-code that will accomplish this?

I've tried Screen.ActiveForm and although this does generate results for some parts of wizards it does not change value when the database-window is selected or the start-screen for each wizard (inwhich you choose the type of wizard) .

Also I tried the following: I made a form with two textboxes on it and a timer-event
The first textbox displays the active form, the second displays whether the form in textbox1 is still active.

When I open a form this works, but when I close the form and the focus is set to the database-window, nothing happens....
I'm guessing that all other actions are suspended when the database-window recieves the focus

Any thoughts on this????


nce you know the name of the form, (let's say that it is "zwizQryBldr"), then you would look for it with

   If SysCmd(acSysCmdGetObjectState, acForm, "zwizQryBldr") = 1

(The one only means that it is open.  But since you don't have the ability to 'design' wizard forms, that seems like it would be enough...)

The database window is not a form, in the context that you are looking at.  That is, it is not listed in the Forms collection.

I'm curious:  The wizard that you are looking for;  is this a wizard the you created, or one of the addins of Access?

GOLLEMAuthor Commented:

All functionality I described above is achieved with standard MS-Access functionality and wizards. The problem was that when a new object is created there is no entry in MSysObjects which you can check to see if the user has closed the object he/she is designing or viewing.

I was right about MS-Access suspending all timers when the database-window recieves the focus. I can hide the database-window, so my form recieves the focus again.

I was already using SysCmd, but didn't get any results because the code was suspended as soon as the DB-window got the focus.

I tried it again with the D-window hidden and now my second textbox did return a "no" This means that I can check for at least some of the wizards.
The standard wizard-selection screen (where you choose between for example autoform or new form in designview) does not return a formname.
This means I'll have to design a replica to have the user make the first choice and then use sendkeys for the first screen. It's not ideal, but it'll work....

A new form in designview does return a name, I'm guessing a report will too, although I can't test that here (don't have a printer available at the moment) From what I gather reports are no more than a special kind of form, so this should be true...

However a new query, table, macro or module does not return a name either.

So I now know how to look for part of the wizard, but there's still a lot to be discovered  :)

Maybe the solution can be found in the two containers MS-Access uses that aren't mentioned in the access-helpfile. (of course I'm talking about the Scipts-container and the SysRel-container)

I know my problem is already solved if I limit the user, but I kinda like trying to understand how everything works....
This is the ultimate in backward engineering *LOL*

Hope you're enjoying this as much as I am. Of course you already earned the points, but I don't want to close this thread yet :)

Kind regards,

GOLLEMAuthor Commented:
Woops... typo :

of course 'Scipts-container' has to be 'Scripts-container'
GOLLEMAuthor Commented:
The Scripts-container is for macro's of course

I wasn't thinking clearly I think :)
I created a form with a close button, a text box, and the following code:

Option Compare Database
Option Explicit

Private Sub Command2_Click(): DoCmd.Close acForm, Me.Name: End Sub
Private Sub Form_Timer():     Me!TxtBox = Timer:           End Sub

When I run this, as expected I get changing numbers in the text box, (interval = 500).

When I select the DB window, the numbers keep changing, but the title bar turns to the colors for inactive, indicating that the focus has shifted.

While the numbers are still changing, I selected 'New Table.'  The design dialog appears, and the numbers keep changing.

I select Design view, and a blank table design grid appears, and the numbers keep changing.

I pressed F1, and the form stopped updating until Help was loaded, but then the nubers started updating again, even while 'Access the EXE' didn't have the focus.

Perhaps you can get better results toward your gaol if you use APIs to cycle through the child windows of Access looking for the Caption of the child windows.  'Windows the OS' knows more about what is going on than the limited info that 'Access the EXE' exposes . . .

GOLLEMAuthor Commented:

Gotta get me a book on API.... :)

 What I did in my test was select 'new table' and then press cancel in the second screen for the wizard. I just tried an empty MsgBox in my timer and this does produce results. (It keeps popping up no matter what I select) But why then does MS-Access not report that the form that contains the wizard has been closed??

The code I used was:

Private Sub Form_Timer()
Dim controlpth As String
On Error GoTo Timer_Err

If Not Screen.ActiveForm.Name = "QueryBox1" Then
  controlpth = Screen.ActiveForm.Name
End If
Forms![test].Controls(0).Text = controlpth
If Not SysCmd(acSysCmdGetObjectState, acForm, controlpth) = 0 Then
  Forms![test].Controls(1).Caption = "Yes"
  Forms![test].Controls(1).Caption = "No"
End If

End Sub

Forms![test].Controls(0) is a textbox
Forms![test].Controls(1) is a label

When I add a watch for SysCmd(acSysCmdGetObjectState, acForm, "frui_frmMain") It does turn to zero when the wizard is cancelled. However this is not reported to the timer. (the label would have been turned to zero then) When I open the form "QueryBox1" the value is passed to the timer and the label is updated.

Anyways, I think I need to buy myself that book on API... I heard they can change when a new os-version is released, is there a list that predicts the probability for change for API-calls?? There should be a 'core' to the windows-OS that doesn't change and probably won't in future. It would be nice to know what kind of risk you're taking for API's becoming obsolete. (and thus the code you've programmed)


GOLLEMAuthor Commented:
P.S. with the second screen for the wizard i meant selecting 'new form' and then 'form wizard'
GOLLEMAuthor Commented:
Adjusted points from 50 to 75
GOLLEMAuthor Commented:

There's an idea... I'll add a watch for controlpth tomorrow and see how that changes.
However if the value were null then the line 'Forms![test].Controls(0).Text = controlpth' would have to generate an error or am I mistaken about this???

Anyway, I'll try that tomorrow... Thank you for your help and suggestions on this. Don't wanna keep bothering you with this....
Maybe someday I'll be able to return the favor (although I don't expect that to happen anytime soon ;^) )


GOLLEMAuthor Commented:


I tried controlpth as a global variable.... didn't help :(

MS-Access seems to be reporting an error because no form is active. the number for the generated error is 0.

When I comment out the lines using Screen.ActiveForm the error is gone.

I found a solution though... :)

Wizards are modal, so the only thing i have to do is create a small form with a checkbox control on it  and have the timer keep trying to set the focus to that form.
As soon as the checkbox recieves the focus, the wizard has ended.
Since the checkbox is on a different form, there is no need to make the main form visible until the wizard has ended.
I can even hide the alternate form by using Application.echo and the visible property of the form.

I knew there had to be a simple way around this mess.... :)

This is why I always keep looking until I've found a satisfactory answer.


Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.