justaphase
asked on
FoxPro Bindevent init form
Hello Experts!
Is it possible to Bind and a "QueryUnload" event to a form, on the event init of the same form?
I'm working on a framework, that i don't have access to the main code, only to some events, like the init form event.
And i needed to ask the user if he really wants to close the form before closing.
i tried somtehing like this:
Is it possible to Bind and a "QueryUnload" event to a form, on the event init of the same form?
I'm working on a framework, that i don't have access to the main code, only to some events, like the init form event.
And i needed to ask the user if he really wants to close the form before closing.
i tried somtehing like this:
PUBLIC xclose
xclose = .f.
PUBLIC oHandlerCloseP
oHandlerCloseP=NEWOBJECT("browlistClosePrevent")
BINDEVENT(thisform,"QueryUnload",oHandlerCloseP,"myQueryUnload")
DEFINE CLASS browlistClosePrevent AS Form
PROCEDURE myQueryUnload
IF NOT xclose
xclose = .t.
NODEFAULT
RETURN
ENDIF
RETURN
ENDDEFINE
but he says "Methods and events cannot contain nested procedures or class definitions"
ASKER
hi pcelba,
1) I can call a PRG file of course... but when and where i would call it?
2) Yes i need to intercept the closing of the form in anyway..
1) I can call a PRG file of course... but when and where i would call it?
2) Yes i need to intercept the closing of the form in anyway..
So you may place the eventhandler DEFINE CLASS to a PRG file and set this file as an additional procedure file:
SET PROCEDURE TO YourPRGfile ADDITIVE
And then you may simply create the event handler class by calling CREATEOBJECT() or NEWOBJECT(). This creation must happen before you call the BINDEVENT().
How to intercept Windows events is described e.g. here: http://scottscovellonvfp.blogspot.co.at/2005/11/bindevent-and-compile.html
http://myvfpblog.blogspot.co.at/2011/05/cool-vfp-event-binding.html
http://www.bdurham.com/vfprocks/hermantan/vfp_tooltips.htm
Some additional hints are here: http://fox.wikis.com/wc.dll?Wiki~BindEvent
http://www.markusegger.com/articles/Article.aspx?quickid=0301052
Of course, you should start in VFP help.
I may write some code later.
And the last question: Why do you think user could change his mind after clicking on the Close button?
SET PROCEDURE TO YourPRGfile ADDITIVE
And then you may simply create the event handler class by calling CREATEOBJECT() or NEWOBJECT(). This creation must happen before you call the BINDEVENT().
How to intercept Windows events is described e.g. here: http://scottscovellonvfp.blogspot.co.at/2005/11/bindevent-and-compile.html
http://myvfpblog.blogspot.co.at/2011/05/cool-vfp-event-binding.html
http://www.bdurham.com/vfprocks/hermantan/vfp_tooltips.htm
Some additional hints are here: http://fox.wikis.com/wc.dll?Wiki~BindEvent
http://www.markusegger.com/articles/Article.aspx?quickid=0301052
Of course, you should start in VFP help.
I may write some code later.
And the last question: Why do you think user could change his mind after clicking on the Close button?
ASKER
I never did that... SET PROC TO prg...
I'll try to see how to do it..
To answer you last question:
Because the form as a grid with a huge amount of records that need to be updated manually, and can take allot of time to do this work; hitting cancel or escape by accident a lose almost an hour of work?... not on the menu :)
I'll try to see how to do it..
To answer you last question:
Because the form as a grid with a huge amount of records that need to be updated manually, and can take allot of time to do this work; hitting cancel or escape by accident a lose almost an hour of work?... not on the menu :)
Maybe you don't need to set additional procedure file because NEWOBJECT() allows to specify the .PRG file containing the class definition.
To allow hours of updates without saving isn't good. The application should predict such a bad user's behavior and create temporary save points on the local harddrive. Such local "backup" is very fast so you may use some timer to do it every 5 minutes. The local savepoint is deleted after regular data saving. You may offer to restore these local data when user enters the grid next time.
Easier solution is to disable the Close ("X") button when user enters some data. Then you don't need to intercept Windows events and make the change to the form's Close button (i.e. define the BINDEVENT for button Click event).
To allow hours of updates without saving isn't good. The application should predict such a bad user's behavior and create temporary save points on the local harddrive. Such local "backup" is very fast so you may use some timer to do it every 5 minutes. The local savepoint is deleted after regular data saving. You may offer to restore these local data when user enters the grid next time.
Easier solution is to disable the Close ("X") button when user enters some data. Then you don't need to intercept Windows events and make the change to the form's Close button (i.e. define the BINDEVENT for button Click event).
ASKER
The save point, is something i already thought about, but will have to be done some other time.
And as i told you, i'm working on "framework" inside an app which is already compiled in exe, i don't have access to the code on the close button. Only to execute additional code in some events the app programmers made available, and i can't ask them to change the code for me, it's huge software house that sells this program as an end product.
I really need to intercept the close event.. and i can execute additional code in a init form event that i have access to.
And as i told you, i'm working on "framework" inside an app which is already compiled in exe, i don't have access to the code on the close button. Only to execute additional code in some events the app programmers made available, and i can't ask them to change the code for me, it's huge software house that sells this program as an end product.
I really need to intercept the close event.. and i can execute additional code in a init form event that i have access to.
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
You can bind to windows message, so you might try to intercept WM_CLOSE message, when it's sent to the HWND window handle you know. See BINDEVENT help for how to bind to windows messages via HWND of a form.
Bye, Olaf.
Bye, Olaf.
>I would guess QueryUnload is called when there is no possibility
>to stop the form closing process
Olaf, this was my first comment several hours ago... but I haven't been sitting and waiting for your post since that time :-)
The working solution is also posted and to hook the Windows event is not necessary when the close control button is disabled.
BTW, do you know the way how to suppress the FoxPro button event call in BINDEVENT? I've been trying all parameter values with no success.
>to stop the form closing process
Olaf, this was my first comment several hours ago... but I haven't been sitting and waiting for your post since that time :-)
The working solution is also posted and to hook the Windows event is not necessary when the close control button is disabled.
BTW, do you know the way how to suppress the FoxPro button event call in BINDEVENT? I've been trying all parameter values with no success.
ASKER
QueryUnload doesn't prevent the RELEASE?...
So Unload a form is different from Release a form?...
Can i remove all events of a button with UNBINDEVENTS, even those that were not made by BINDEVENT?
So Unload a form is different from Release a form?...
Can i remove all events of a button with UNBINDEVENTS, even those that were not made by BINDEVENT?
ASKER
hmm... i think i can remove all events with the EVENTHANDLER function... just trying to know how... :P
EVENTHANDLER() works in conjunction with COM objects only.
UNBINDEVENTS( ) function is used to detach events, methods, and properties that were bound using the BINDEVENT( ) function from native Visual FoxPro objects.
So there is no function available in VFP which could avoid the code included in the original object.
The Framework itself should have some switch saying "Confirm data entry cancellation" etc.
And true is the fact you cannot avoid the form closing by Form.Release call. So the code provided in my previous post is a work around in fact.
UNBINDEVENTS( ) function is used to detach events, methods, and properties that were bound using the BINDEVENT( ) function from native Visual FoxPro objects.
So there is no function available in VFP which could avoid the code included in the original object.
The Framework itself should have some switch saying "Confirm data entry cancellation" etc.
And true is the fact you cannot avoid the form closing by Form.Release call. So the code provided in my previous post is a work around in fact.
Pavel, yes I haven't read all the answers, no even yet, but I think it's rather futile to try to prevent closing with QueryUnload. If there is another one on the form, that also needs to be handled, then there is CTRL+F4. So overall there is no single exit you can block.
Your solution intercepts the close button click, do you mean the title bar close button?
And how about the other exits?
I agree it would be better the framework supports some feature to embed record check and cancellation of closing. In a framework I use there is a beforeclose method in framework forms, which is called by default and getting false as return value from there stops the closing.
You might also try something as simply as setting Closable=.f.
IF CTRL+F4 would still be a problem, in the end WM_CLOSE might be a solution, as is stated here:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms632617(v=vs.85).aspx
I tried, but the forms close button does not seem to send that message. So you have to find out what message you can intercept at all.
Bye, Olaf.
Your solution intercepts the close button click, do you mean the title bar close button?
And how about the other exits?
I agree it would be better the framework supports some feature to embed record check and cancellation of closing. In a framework I use there is a beforeclose method in framework forms, which is called by default and getting false as return value from there stops the closing.
You might also try something as simply as setting Closable=.f.
IF CTRL+F4 would still be a problem, in the end WM_CLOSE might be a solution, as is stated here:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms632617(v=vs.85).aspx
An application can prompt the user for confirmation, prior to destroying a window, by processing the WM_CLOSE message and calling the DestroyWindow function only if the user confirms the choice.
I tried, but the forms close button does not seem to send that message. So you have to find out what message you can intercept at all.
Bye, Olaf.
Yes Olaf, the CTRL-F4 is another problem...
And the code posted uses the easiest solution already. See the first line:
THIS.Closable = .F.
More complex solution would be to trap WM_SYSCOMMAND Window message and analyse parameters. The "X" Close button is identified as SC_CLOSE.
And the code posted uses the easiest solution already. See the first line:
THIS.Closable = .F.
More complex solution would be to trap WM_SYSCOMMAND Window message and analyse parameters. The "X" Close button is identified as SC_CLOSE.
ASKER
Well.. in other words i'm doomed, lol..
I'll have to try to use the your solutions and see if it helps, it's better than nothing.
I'm gonna be away from this project, so i'll have to try your suggestions some days from now.
Thank you Pcelba and Olaf. You guys are the FoxPro Masters on the web ;D
I'll have to try to use the your solutions and see if it helps, it's better than nothing.
I'm gonna be away from this project, so i'll have to try your suggestions some days from now.
Thank you Pcelba and Olaf. You guys are the FoxPro Masters on the web ;D
Two important questions:
1) DEFINE CLASS can be in a standalone PRG file only (or in procedure file). Do you have a possibility to create such file and add it to the project?
2) Do you also need to intercept the Windows event caused by the "X" control button click?