none
CommandButton Click and MouseEnter RRS feed

  • Question

  • I have a form with several CommandButtons. I used MouseEnter to call a procedure that will pop-up another form when hovering over a CommandButton. When I MouseLeave, the pop-up form closes.

    The problem I'm having is this: I cannot click on the CommandButton while I am hovering over it (MouseEnter). Can someone please help to explain how to have CommandButton.Click work when CommandButton.MouseEnter has a new pop-up form up?

    Sunday, March 31, 2019 10:09 PM

Answers

  • Hi,

    You can unbind the MouseEnter event in the MouseEnter method of the CommandButton and then rebind it in the MouseClick method of the CommandButton.

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by David_S_FL Monday, April 1, 2019 10:59 PM
    Monday, April 1, 2019 2:27 AM
    Moderator
  • Hi David_S_FL

    having code for mouseenter and mouseclick shouldn't interfere like the way you describe it. Therefore, to me it seems, like you open the forms a 'Modal' and not as 'Modeless'.

    I jsut did a short test that showed that two modeless forms will work the way you want it. However....

    my way of coding something like that might differ from yours, therefore I'll go a bit into the details :)

    Just create a new empty form and place the following code in the described Methods:

    * // FORM.INIT
    
    * Before this, you have to add a new Property
    * This Pro will hold the new form.
    * This form will exist all the time until 
    * you close the masterform
    
    This.AddProperty( [oFormRef] )
    This.oFormRef = CREATEOBJECT( [form] )
    
    
    
    * // FORM.RELEASE
    
    * here you have to clean up the subform
    * otherwise, the masterform and therefore
    * the complete app will stay in scope and 
    * can't be closed
    
    Thisform.oFormRef.Release
    Thisform.oFormRef = .F.
    
    
    * Now Place a button and a label on your masterform
    * button will automatically be named command1
    * label will automatically be named label1
    
    
    
    * // FORM.COMMAND1.CLICK
    
    Thisform.label1.Caption = [Clicked]
    
    
    
    
    * // FORM.COMMAND1.MOUSEENTER
    
    LPARAMETERS nButton, nShift, nXCoord, nYCoord
    
    Thisform.Label1.Caption = [MouseEnter]
    
    Thisform.oFormRef.Left	= Thisform.Left + Thisform.Width + 5
    Thisform.oFormRef.Top	= Thisform.Top
    Thisform.oFormRef.Show()
    
    
    
    * // FORM.COMMAND1.MOUSELEAVE
    
    LPARAMETERS nButton, nShift, nXCoord, nYCoord
    
    Thisform.Label1.Caption = [MouseLeave]
    
    Thisform.oFormRef.Hide()
    
    

    Both forms are VFP baseforms, which means both a defined as 'WindowType=0-Modeless' per default.

    Just a few words to Alex' answer.

    Binding and Unbinding ist the regular way of attaching methods to events. However, the way you describe you problem (pardon me if I got that wrong ;) ), you seem to write your code directly into the objects events, just the way I did it in my above example.

    Writing code directly into a form isn't a good way. Its acceptable for a quick prototyping (like my example above) or for programmers that are just learning VFP. But in the long run it will make your code confusing.

    As VFP is an OOP language, you should make use of this and create an object that holds the code and makes use of BINDEVENT() and UNBINDEVENTS().

    Alex's answers is based on this and in case your code isn't, his answer might be a bit confusing :)

    HTH


    Gruss / Best regards
    -Tom
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible,
    you are, by definition, not smart enough to debug it. 010101100100011001010000011110000101001001101111011000110110101101110011

    • Marked as answer by David_S_FL Monday, April 1, 2019 10:58 PM
    Monday, April 1, 2019 6:32 AM
    Moderator

All replies

  • Hi,

    You can unbind the MouseEnter event in the MouseEnter method of the CommandButton and then rebind it in the MouseClick method of the CommandButton.

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by David_S_FL Monday, April 1, 2019 10:59 PM
    Monday, April 1, 2019 2:27 AM
    Moderator
  • I'll give that a try and let you know. Thanks Alex !!!
    Monday, April 1, 2019 4:25 AM
  • Hi David_S_FL

    having code for mouseenter and mouseclick shouldn't interfere like the way you describe it. Therefore, to me it seems, like you open the forms a 'Modal' and not as 'Modeless'.

    I jsut did a short test that showed that two modeless forms will work the way you want it. However....

    my way of coding something like that might differ from yours, therefore I'll go a bit into the details :)

    Just create a new empty form and place the following code in the described Methods:

    * // FORM.INIT
    
    * Before this, you have to add a new Property
    * This Pro will hold the new form.
    * This form will exist all the time until 
    * you close the masterform
    
    This.AddProperty( [oFormRef] )
    This.oFormRef = CREATEOBJECT( [form] )
    
    
    
    * // FORM.RELEASE
    
    * here you have to clean up the subform
    * otherwise, the masterform and therefore
    * the complete app will stay in scope and 
    * can't be closed
    
    Thisform.oFormRef.Release
    Thisform.oFormRef = .F.
    
    
    * Now Place a button and a label on your masterform
    * button will automatically be named command1
    * label will automatically be named label1
    
    
    
    * // FORM.COMMAND1.CLICK
    
    Thisform.label1.Caption = [Clicked]
    
    
    
    
    * // FORM.COMMAND1.MOUSEENTER
    
    LPARAMETERS nButton, nShift, nXCoord, nYCoord
    
    Thisform.Label1.Caption = [MouseEnter]
    
    Thisform.oFormRef.Left	= Thisform.Left + Thisform.Width + 5
    Thisform.oFormRef.Top	= Thisform.Top
    Thisform.oFormRef.Show()
    
    
    
    * // FORM.COMMAND1.MOUSELEAVE
    
    LPARAMETERS nButton, nShift, nXCoord, nYCoord
    
    Thisform.Label1.Caption = [MouseLeave]
    
    Thisform.oFormRef.Hide()
    
    

    Both forms are VFP baseforms, which means both a defined as 'WindowType=0-Modeless' per default.

    Just a few words to Alex' answer.

    Binding and Unbinding ist the regular way of attaching methods to events. However, the way you describe you problem (pardon me if I got that wrong ;) ), you seem to write your code directly into the objects events, just the way I did it in my above example.

    Writing code directly into a form isn't a good way. Its acceptable for a quick prototyping (like my example above) or for programmers that are just learning VFP. But in the long run it will make your code confusing.

    As VFP is an OOP language, you should make use of this and create an object that holds the code and makes use of BINDEVENT() and UNBINDEVENTS().

    Alex's answers is based on this and in case your code isn't, his answer might be a bit confusing :)

    HTH


    Gruss / Best regards
    -Tom
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible,
    you are, by definition, not smart enough to debug it. 010101100100011001010000011110000101001001101111011000110110101101110011

    • Marked as answer by David_S_FL Monday, April 1, 2019 10:58 PM
    Monday, April 1, 2019 6:32 AM
    Moderator
  • I don't know what you mean with "unbind the MouseEnter". MouseEnter is an event without using EVENTHANDLER() nor BINDEVENTS(), you can't unbind from such an event already part of the native commandbutton class.

    In VFP you can not really create events, you can bind to properites and methods and have a separate event handler class or bind to user defined methods of the same obnject/class and you can only unbind of such pseudeo events, if you actually first created them by bindevents or as legacy technique) property_access and proprty_assign methods, MouseEnter is neither such event techniqie, it's simply a native event you can't unbind from.

    I guess Tom hit the nail assuming the new form created in mousenter is modal, that's the simplest reason no foxus events and therefore also no click or other events happen anymore outside the new modal form.

    If this is just about displaying a more fance tooltip the easiest solution is to revert to just the normal tooltips, set the buttion.tooltip text and don't forget to the form.showtips=.t.

    Otherwise go for a nonmodal form. Beside Tom'S code for the original form and command button, there's something to do for letting the poup act like a tool tip, you have to let this release whenever you click on anything else, which means the popup form should release itself in deactivate - when it loses focus. That also requires a nonmodal forms, as modal form don't ever lose the focus, they have to be closed to allow focus going elsewhere. So it's really just that modal behaviour that's in your way.

    By the way,it's a long-held untruth you need modal forms to avoid releasing them, you need to have a correctly scoped variable or in that case rather property to keep a nonmodal form from closing, modality just is the simplest solution not needing to learn about scoping, but scoping is very basic and important, so learn that.

    You always also had the NAME and LINKED clauses of DO FORM, so many don't know that, you don't know a command when only knowing its most often usage, learn all the clauses and their meaning, then you also can do this with more legacy style of coding and can still use scx and not just form classes.

    Also, the ideal object to store form references is a collection. Since that was introduced any form handler using arrays should be reprogrammed to use that, as it's much easier in the aspect of both keeping forms in scope and allow them to close without also knowing a reference to them is stored somewhere else, so this helps with having loosely coupled code and less depdendecies. 

    Bye, Olaf.

    Monday, April 1, 2019 11:20 AM
  • Hey Tom,

    Thanks for the tips. I am now getting the results I was after. Just a little background, I am new to OOP and I am coding just as you assumed. In the days of DOS, I used to program in dBase III+ and dBase 4 (If I had to) but when the onset of Windows and OOP rolled in, I basically gave up programming altogether. 30 years later, I am now retired and decided to attempt some VFP programming and I am doing so while learning as I go.

    I sure appreciate everyone's input and I can now proceed with this bug behind me.

    Thanks again Tom, Alex and everyone !!!!

    --David

    Monday, April 1, 2019 9:26 PM