Activeform, GetFocus(), and Popup Forms

B

Bob

I'm struggling with identifying the active form in an access
application. There are functions called from shortcut menus that need
to determine the key value of a record displayed in the form when the
shortcut menu control is activated. The method I've been trying to use
is to identify the form that has the focus when the shortcut menu is
activated. This is not working for a couple of reasons:

The active form has its popup property set to true. That means that
Screen.ActiveForm and Screen.ActiveControl refer to the only form in
the application that isn't popup, the "startup" form of the
application. Also, the Activate/Deactivate events don't fire.

The active form can't be referenced (at least directly) via the Forms
collection, because I'm opening multiple instances of the form class
via the New statement.

I've been experimenting with the Windows API GetFocus() call, which
returns the window handle of the window with the focus. I can associate
a window handle with a form object in a dictionary object, and then
refer back to it later. However, an Access form seems to have more than
one window handle depending on which control has the focus. Also,
different records in a continuous form seem to have different window
handles. Even if I wanted to go to the trouble of recording every
possible window handle in a form, it seems that GetFocus() returns a
different window handle for the same control in the same record
depending on how the control is entered.

If I wanted to give up multiple instances of the forms, I could
dedicate a shortcut menu to each form and subform, and find the form
object via the Forms collection, but that would involve a significant
change to the user interface. I have run out of ideas for identifying
the form with the focus in my application, given the design
constraints. Are there any other avenues I may not have tried? Is there
another way of passing an argument to a shortcut action at runtime,
that doesn't depend on activate/deactivate/gotfocus/lostfocus? Thanks.

Bob
 
D

Dirk Goldgar

Bob said:
I'm struggling with identifying the active form in an access
application. There are functions called from shortcut menus that need
to determine the key value of a record displayed in the form when the
shortcut menu control is activated. The method I've been trying to use
is to identify the form that has the focus when the shortcut menu is
activated. This is not working for a couple of reasons:

The active form has its popup property set to true. That means that
Screen.ActiveForm and Screen.ActiveControl refer to the only form in
the application that isn't popup, the "startup" form of the
application. Also, the Activate/Deactivate events don't fire.

The active form can't be referenced (at least directly) via the Forms
collection, because I'm opening multiple instances of the form class
via the New statement.

I've been experimenting with the Windows API GetFocus() call, which
returns the window handle of the window with the focus. I can
associate a window handle with a form object in a dictionary object,
and then refer back to it later. However, an Access form seems to
have more than one window handle depending on which control has the
focus. Also, different records in a continuous form seem to have
different window handles. Even if I wanted to go to the trouble of
recording every possible window handle in a form, it seems that
GetFocus() returns a different window handle for the same control in
the same record depending on how the control is entered.

A form has its own, constant hWnd, but if I understand it correctly,
most controls only get assigned window handles when they have the focus.
If I wanted to give up multiple instances of the forms, I could
dedicate a shortcut menu to each form and subform, and find the form
object via the Forms collection, but that would involve a significant
change to the user interface. I have run out of ideas for identifying
the form with the focus in my application, given the design
constraints. Are there any other avenues I may not have tried? Is
there another way of passing an argument to a shortcut action at
runtime, that doesn't depend on
activate/deactivate/gotfocus/lostfocus? Thanks.

It's an interesting problem, and not one I've ever thought about before.
If you're using multiple non-default instances of forms, are you storing
references to them in a global collection so as to keep them alive?
Could you maintain a global index into the collection, set when you add
a new form to the collection and modifed when you remove a form from the
collection? I'm not sure how you're using and managing the forms, so I
don't know if this is workable or not.
 
B

Bob

Exactly right. I made a class, clsAppStatus, that contains a dictionary
object. A method of the class, Form(), takes a window handle and a form
object reference and stores them in the dictionary object. Another
method of clsAppStatus, OpenForm(), takes the name of the form, creates
a non-default instance, and stores the reference in the dictionary
object. The Unload event handler for the form calls
clsAppStatus.RemoveForm() to remove the reference from the dictionary
object. Finally, clsAppStatus.ActiveForm() returns the form object
reference keyed to the window handle returned by the Windows API
GetFocus().

The problem I'm running into is that I can't get hold of the right
window handle when I right-click to open the shortcut menu. The Action
function called by the shortcut menu has no clue which of several
non-default forms has called it, so I'm using clsAppStatus.ActiveForm()
to try to figure it out. However, the value returned by GetFocus()
varies. There seems to be a finite number of window handles that can be
returned, but I can't seem to find and register all of the
possibilities before I need them.

Again, the object is to get the key value of the record in the active
form to the shortcut menu's action function, so it knows which data to
work on.

I'm beginning to think that I only have 3 ways to go: 1) give up
non-default form instances, 2) create my own shortcut menus using
borderless forms fired from the onClick event, or 3) put control
buttons on the form. I probably don't have a clue how complicated
option 2 would be, or I wouldn't actually be contemplating it. And
somehow option 3 is just aesthetically grating.

Thanks for listening. :)

Bob
 
D

Dirk Goldgar

Bob said:
Exactly right. I made a class, clsAppStatus, that contains a
dictionary object. A method of the class, Form(), takes a window
handle and a form object reference and stores them in the dictionary
object. Another method of clsAppStatus, OpenForm(), takes the name of
the form, creates a non-default instance, and stores the reference in
the dictionary object. The Unload event handler for the form calls
clsAppStatus.RemoveForm() to remove the reference from the dictionary
object. Finally, clsAppStatus.ActiveForm() returns the form object
reference keyed to the window handle returned by the Windows API
GetFocus().

The problem I'm running into is that I can't get hold of the right
window handle when I right-click to open the shortcut menu. The Action
function called by the shortcut menu has no clue which of several
non-default forms has called it, so I'm using
clsAppStatus.ActiveForm() to try to figure it out. However, the value
returned by GetFocus() varies. There seems to be a finite number of
window handles that can be returned, but I can't seem to find and
register all of the possibilities before I need them.

Again, the object is to get the key value of the record in the active
form to the shortcut menu's action function, so it knows which data to
work on.

I'm beginning to think that I only have 3 ways to go: 1) give up
non-default form instances, 2) create my own shortcut menus using
borderless forms fired from the onClick event, or 3) put control
buttons on the form. I probably don't have a clue how complicated
option 2 would be, or I wouldn't actually be contemplating it. And
somehow option 3 is just aesthetically grating.

Thanks for listening. :)

I wish I could give you an easy answer, but your situation is much too
complex, and I think you've tested all the easy approaches. The only
thing I can think of is the vague idea that the various popup forms can
only get the focus in one of two ways (maybe): by default, as another
form is closed or hidden, or by mouse or keyboard action, which might be
trappable by events of the form. Getting the focus by default should be
identifiable by unwinding the sequence in which the forms are opened.

However, the whole problem is so complex that I personally would not
attempt it unless there was something in the Windows API that I could
use. After all, the popup forms have a different parent than non-popup
forms -- I think it's the Desktop, but I'm not sure -- so maybe you
could do something with that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top