Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Force a form to deactivate and let another activate

Status
Not open for further replies.

TamarGranor

Programmer
Jan 26, 2005
2,479
US
I have a pair of forms that are related (in a parent/child kind of way). There's code in my framework so that if I move the record pointer in the parent form, the child form moves to the corresponding record. That's all working.

This application allows only one form to be in edit mode at a time, so there's framework code in the main data entry form class's Deactivate method that checks whether the form being deactivated is in edit mode and if so, prompts the user to either cancel the edit or stay on the current form.

What I'm working on now is having a textbox on each of these two forms where the user can scan a barcode and it will position the parent form on the record indicated by the barcode and then open or position the child form on the corresponding record in edit mode. That is, if the child form is not open, open it; otherwise, just reposition. But in either case, switch to edit mode.

If the child form is closed when I do this, the scan textbox on the parent form works as I need it to. But if the child form is already open, I see the message about having to either cancel the edit or stay put. What's happening is that to do what we need, we have to refresh the parent form (which then allows us to update the child form using a custom method).

The problem is that having done so, the parent form has focus, and I can't find a way to force it to deactivate and hand focus over to the child form before I switch the child form into edit mode. I've tried using ACTIVATE WINDOW, and setting focus to a control on the child form, and doing both, and I still see that the parent form's Deactivate method doesn't fire until after the code that changes the child form's mode.

So I'm looking for a surefire way to have the parent form's deactivate run when I want it to (other than closing the parent form). Any ideas?

Tamar

 
Can you shrink this down to a runable demo? I mean I could try, but the ingredients are not all clear to me.

I understand the main problem is to avoid a deadlock problem of the security prompt and my first instinct was how about introducinng a mode that overrides this interaction and allows to switch anything you need to switch programmatical even if it needs to violate something for a short moment. The other thing I usually think about to solve such timing problems is running a timer that does what's necessary to do in say just 1 or 10 ms and then release.

Well, the detail question is what triggers a deactivate, isn't it?

You said both forms have the barcode textbox, and the problematic case is the child form is open and in edit mode (by the automatism of a first barcode), so shouldn't the second barcode scan be on the childform textbox? Why would a user activate the parent form to scan, right? So couldn't the barcode processing code in the child forms barcode textbox end the edit mode to be able to do everything necessary everywhere and end up in the records for the new barcode in parent and child with child form put into edit mode again?

Or is the barcode scanner programmed with a prefix hotkey that always activates only the parent barcode textbox?

Well, you see I struggle a bit to get my head around this whole setup, but maybe that's already giving you ideas.

Chriss
 
One thing I remember is that one of the reasons bindevent to windows events was introduced is to enable reacting to the deactivation of _screen to detect and react to application switching. And I guess that could also be used to detect an active form change, though that's not what you need here, you have form activate and deactivate for that. But maybe it works better or different and easier to program than the deactivate event, because in bindevents you can choose the delegate to act before or after the actual event, can't you? So that's another arrow in the quiver, isn't it?

Chriss
 
I experimented with eventtracking (not helpfull when both forms are logged as form1) and then simply debugout in activate/deactivate events and what I see is that the active forms deactivate always runs before the activate event of the form becoming active, so the natural order, nothing unusual.

So, when your child form has focus and refreshes the parent form which, as you say, gets focus by that refreshing, then firstly child deactivate will run, secondly parent activate and then something in parent should put focus back to the childform, which would cause parent deactivate before child activate. I don't see where the problem is.

Tamar said:
and I still see that the parent form's Deactivate method doesn't fire until after the code that changes the child form's mode.
Where's the code that changes the child forms mode?

Tamar said:
But if the child form is already open, I see the message about having to either cancel the edit or stay put.
That's to be expected, isn't it? As you say the parent form becomes activated by refreshing - I don't see this happening if I just would call parentform.refresh, but you seem to do more. In itself no problem, but then wouldn't it be good as I said in my first response to have a mode that suppresses this message or automatically ends editmode of the child form before refreshing parent and finally activate editmode after navigation in the child?

I would say when the child form receives a new barcode through its barcode textbox while it's in editmode of a previous barcode, should the first act not be ending the editmode and saving all changes necessary associated with the previous barcode and then continue from there with the new barcode? And wouldn't that already solve all problems involved in unwanted prompt messages?

The last thing I think is when any code for parent form refreshing activates the parent form, that activation event can only occur when VFP comes back to READ EVENTS (is idle), not while the code causing it runs, so if you then want to put focus back to the child the focus change to parent may not have been done yet so setting focus back could only happen as aftermnath anyway? If that's the case a time running just once could help and also DOEVENTS could help to let the event happe that are triggered by code before it actually finishes.


Chriss
 
Thanks, Chriss, with your suggestion about turning off that check in Deactivate, I'll solved this. I added a property to the form class, normally .F., and set it to .T. at the beginning of this process and back to .F. in the end. In the framework-level Deactivate, I check this flag and if it's .T., just skip the test for being in edit more.

That's a little clunky, but as long as we're careful about when we set that flag, all should be well.

Also, should have said earlier that these textboxes aren't available in edit mode, only in view mode.

Tamar
 
I wonder if it wouldn't be simpler to change from edit to view mode and back instead of introducing this new flag, but glad you resolved the issue.

Chriss
 
When this process starts, we're in View mode, but the goal is to end up in Edit mode. Basically, the idea is that a user should be able to scan a barcode and, regardless of which of the two forms they started on, wind up on the child form in edit mode.

Tamar
 
I dopn't see why that can't be done the other way, i.e. if in editmode switch to view mode, trigger the change by barcode and go back to edit mode. If you're still in view mode, there's nothing to do, initially, but so what?
The only problem was the child window being in edit mode while the new barcode causes change navigation/refresh, wasn#t it, and first turning back to viewmode would solve that without a dirty flag, wouldn't it?

Chriss
 
No, when the barcode was scanned, both forms were in view mode. The barcode textboxes are disabled in edit mode.

The problem was that even though I was putting the right form into edit mode at the right time, at that moment, the parent form had focus, and because (for historical reasons and very hard to change at this point) the form mode is a global thing, when the parent form finally deactivated, it thought it was in edit mode and so, showed that message.

Tamar
 
Ah, that explains it - I think.

Well, as you stated yourself:
Tamar said:
as long as we're careful about when we set that flag, all should be well.

I don't assume you're not careful, but that little caveat made me think it could be solved with the mode setting, too, it becomes clearer why you searched for a way to reliably trigger the form activation. I think you could do so with SetActiveWindow or sending WM_ACTIVATE and other messages. It's not really worth digging into details. While the solution may remove the need for the flag, it would dig deep just for getting things done in the exactly wanted and controlled order of events. Just to break under some untested conditions.


Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top