Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.
These events fire when forms and pages become active or inactive. For a project hook, these events fire when the associated project becomes active or inactive.
PROCEDURE oObject.Activate | oObject.Deactivate
Forms, formsets, toolbars, pages and project hooks all have these events, and their behavior feels a little different for each. Let’s start with toolbars because they’re the simplest. A toolbar’s Activate fires when you Show the toolbar. Its Deactivate fires when you Hide it. Period. End of story—even if the toolbar has a control on it that can gain focus. It doesn’t matter—Activate doesn’t fire even when you land on that control.
Pages next. A page's Activate fires in two situations—when that page comes to the top of the page frame (that is, when you change pages) and when focus on a form is on the page and the form is activated. (A page is not refreshed when it comes to the top; check out Refresh for details and UIEnable for a solution.) A page's Deactivate fires only when a different page in the page frame comes to the top. We can't figure out why the page behaves differently when the form is activated than when it's deactivated. We could argue this one either way—that is, we'd be comfortable with either the page's Activate and Deactivate firing when the form loses focus, or not firing when the form loses focus. But why are they different? |
A form’s Activate fires whenever that form comes to the top (conceptually—it may not be physically “on top”). Normally this happens because the user clicks on the form while another form has focus or because the tab sequence brings focus to a control on the form. A form’s Deactivate fires whenever another form gets focus. Show and Hide fire Activate and Deactivate respectively, too.
A formset’s Activate fires whenever any form in the set is activated. That’s right, the formset’s Activate fires when a different form comes to the top. In fact, the formset’s Activate fires after the Deactivate of the old form and before the new form’s Activate. The formset’s Deactivate fires only when you Hide the formset or focus moves out of the formset.
Now, the oddball in this group. In VFP 7, Activate and Deactivate were added to the ProjectHook base class, something we’d devoutly hoped for. As you’d expect, Activate fires whenever the associated project gets focus, and Deactivate fires when the project loses focus (say, when you click into the Command Window). These events are most useful when you have multiple projects open, because you can make sure each has the appropriate environment, so you use the right controls, store things in the right place, and so forth.
When the project is "rolled up" (collapsed), the project hook's Activate doesn't fire when you click on the title bar. Activate for the project hook of a collapsed project does fire when you click on one of the tabs to expand it. We consider the first behavior a bug, since Activate does fire when you click on the title bar of an expanded project. |
This next one, much as we dislike it, we can't bring ourselves to call it a bug. When a project is docked, the project hook's Activate and Deactivate methods don't ever fire. We think that, in this situation, the project is acting like a toolbar, and as we said above, Activate and Deactivate almost never fire for toolbars. So this one is probably by design. Unfortunately, it means we can't do a lot of the things we'd like to do with these events, since we can't count on their firing. |
Destroying an object does not fire its Deactivate event, nor does creating it fire its Activate event. The latter is an issue for project hooks, in one situation. When you choose to have VFP reopen a project at startup (by checking the appropriate check box in the Options dialog), the associated project hook’s Activate method doesn’t fire on the way in. The work-around here is to call the same code from the Init method.
* Only the active page in a page frame is refreshed by
* the PageFrame's Refresh method. So, when you move a page
* to the top, it's generally a good idea to refresh it.
* You'd do that in the page's Activate method:
This.Refresh()
Activate Window, Deactivate Window, Form, Formset, Hide, Page, PageFrame, ProjectHook, Show, Toolbar, UIEnable