Announcement

Collapse
No announcement yet.

Wm_lbuttondown

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Wm_lbuttondown

    I want to do something on the press of a button using the mouse and something else when the button is released. Without subclassing, and based on some other things in previous threads I've read here, is this a legitimate way of doing that? Am I setting myself up for some unforeseen problem? Thx, Conrad

    Code:
    #COMPILE EXE
    #DIM ALL
    
    #INCLUDE ONCE "WIN32API.INC"
    
    %IDD_DIALOG1  =  101
    %IDC_BUTTON1  = 1001
    %IDC_TEXTBOX1 = 1002
    %IDC_LABEL1   = 1003
    
    'Main Application Entry
    FUNCTION PBMAIN()
        ShowDIALOG1 %HWND_DESKTOP
    END FUNCTION
    
    'Callback
    CALLBACK FUNCTION ShowDIALOG1Proc()
        LOCAL MyButton AS LONG
        SELECT CASE AS LONG CB.MSG
            CASE %WM_INITDIALOG
                'Initialization handler- nothing here
                
            CASE %WM_NCACTIVATE
                STATIC hWndSaveFocus AS DWORD
                IF ISFALSE CB.WPARAM THEN
                    ' Save control focus
                    hWndSaveFocus = GetFocus()
                ELSEIF hWndSaveFocus THEN
                    ' Restore control focus
                    SetFocus(hWndSaveFocus)
                    hWndSaveFocus = 0
                END IF
    
            CASE %WM_SETCURSOR
                MyButton = GetDlgCtrlId(CB.WPARAM)
                SELECT CASE MyButton
                    CASE %IDC_BUTTON1
                        SELECT CASE HI(INTEGER, CB.LPARAM)
                            CASE %WM_LBUTTONDOWN                '&H201
                                'do thing A here when the mouse button is depressed
                                CONTROL SET TEXT CB.HNDL, %IDC_TEXTBOX1, "Button 1 Down!" : MESSAGEBEEP(&hFFFFFFFF)
                        END SELECT
                END SELECT
    
            CASE %WM_COMMAND
                SELECT CASE AS LONG CB.CTL
                    CASE %IDC_BUTTON1
                        IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
                            'do thing B here when the mouse button is released
                            CONTROL SET TEXT CB.HNDL, %IDC_TEXTBOX1, "Button 1 Up!" : MESSAGEBEEP(&hFFFFFFFF)
                        END IF
                END SELECT
                
        END SELECT
    END FUNCTION
    
    'Dialog
    FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
        LOCAL lRslt  AS LONG
        LOCAL hDlg   AS DWORD
        
        DIALOG NEW hParent, "Button Down Test", 167, 152, 257, 150, %WS_POPUP OR _
            %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR %WS_CLIPSIBLINGS OR _
            %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
            %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _
            %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
            
        CONTROL ADD BUTTON,  hDlg, %IDC_BUTTON1, "Button1", 80, 20, 95, 30
        CONTROL ADD TEXTBOX, hDlg, %IDC_TEXTBOX1, "TextBox1", 55, 90, 120, 30
        
        DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
        FUNCTION = lRslt
    END FUNCTION

  • #2
    Wouldn't a tooltip be more appropos?

    As written, in order to see the text but NOT click, the user would have to drag the mouse to the next 'control of interest' before reading that text and releasing the button.

    (I did not try it, but for all I know you will ALWAYS get a click notification from the control on which you originally depressed the button.. meaning all your text does is tell me I did not want to do what is now going to be done).

    With the tooltip, the user can just 'hover' and will know "what this button does"
    Last edited by Michael Mattias; 15 Jun 2009, 08:30 AM.
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      The text is here only to show that something happened for the demo. In the real application I'm going to activate and deactivate something on the press and release. Button up is never a problem because it's trapped as a click, but this seemed like a good way of getting %WM_LBUTTONDOWN without subclassing, which remains a bit of a mystery to me.

      Comment


      • #4
        good way of getting %WM_LBUTTONDOWN without subclassing, which remains a bit of a mystery to me.
        Well, now's the time to "de-mystify" it. No, it's not "Programming 101" but surely it's been covered by the time you reach "Programming 201" . Besides, if you want to write software which is something beyond plain vanilla you'll have to learn it anyway. No time like the present.

        Not to mention.... this is a pretty simple one... that is, a perfect "My First Subclass." It takes exactly thirteen (13) lines of code plus whatever you want to do when you get this message; there are more than enough examples here that you can darn need 'copy and paste' twelve (12) of those thirteen lines.

        Your approach here may well work for this application, but instead of giving yourself a fish and eating today you could teach yourself to fish and eat every day for the rest of your life.

        MCM
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Your approach here may well work for this application,
          Any reason it wouldn't work in another application?
          Rgds, Dave

          Comment


          • #6
            but instead of giving yourself a fish and eating today you could teach yourself to fish and eat every day for the rest of your life.
            but instead of giving yourself a fish and eating today you could teach yourself to fish and your wife and kids won't see you for weeks.

            Comment


            • #7
              Hey, I like fish! In reading related posts about subclassing, the view was put forth that it was actually the wrong way to go about getting information that's actually available without subclassing. I suppose there's no right and wrong when it comes to this stuff. I just put the above code into my actual application and it works like a champ. It's basically a mechanical drive system where you push and hold the button to move, then release it to stop. Starting and stopping involves sending data out the USB port to a stepper motor controller. Action is crisp and instantaneous, so I'm pretty happy with it. I see no reason the same type of code wouldn't work in lots of apps. If there was something I *had* to subclass for, ok, but why do it here? Shorter? Faster? Fewer lines? More obvious coding (not!), Street cred? thx, Conrad

              Comment


              • #8
                >Street cred?

                Well, that, and style points.... but there is something in the back of my head saying, "Trying to do this on the cheap like this is going to bite you somewhere, sometime. "

                And when it does, it will be because the user has done something for which you have not allowed.. and no way the user will remember what he/she did to "make Bad Things Happen."

                (Disclaimer: I believe trying to do anything on the cheap will come back to haunt you sooner or later).

                MCM
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  Originally posted by Michael Mattias View Post
                  >
                  (Disclaimer: I believe trying to do anything on the cheap will come back to haunt you sooner or later).

                  MCM
                  One man's cheap is another man's, well, .... thrifty?, economical?, faster?, quicker?, ...,


                  ==================================
                  Admiration, n.:
                  A polite recognition of another's
                  resemblance to ourselves.
                  Ambrose Bierce (1842-1914)
                  ==================================
                  It's a pretty day. I hope you enjoy it.

                  Gösta

                  JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
                  LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

                  Comment


                  • #10
                    Michael isn't just (totally?) being an old lady here
                    As it stands, there is a problem with the sample code: Should the cursor slide off the button while it's depressed (motor running) the release won't be detected...!
                    Here's a (cheap) fix.
                    Code:
                            CASE %WM_SETCURSOR
                                MyButton = GetDlgCtrlId(CB.WPARAM)
                                SELECT CASE MyButton
                                    CASE %IDC_BUTTON1
                                      STATIC Flag AS LONG
                                        SELECT CASE HI(INTEGER, CB.LPARAM)
                                            CASE %WM_LBUTTONDOWN                '&H201
                                                Flag = %True
                                                'do thing A here when the mouse button is depressed
                                                CONTROL SET TEXT CB.HNDL, %IDC_TEXTBOX1, "Button 1 Down!" : MESSAGEBEEP(&hFFFFFFFF)
                                        END SELECT
                                    CASE ELSE
                                      IF Flag = %True THEN
                                        Flag = %False
                                        CONTROL SEND CBHNDL, %IDC_BUTTON1, %BM_CLICK, 0, 0
                                      END IF
                                END SELECT
                    Rgds, Dave

                    Comment


                    • #11
                      Dave, excellent catch. I was thinking about whether I might be generating excess messages if the mouse wandered, but hadn't had time to check it. That's the problem using the buttonup message in the same manner, since the normal position is up, it generates tons of messages as the mouse is moved over the button. Thus the conventional detection of click for buttonup. Extra messages don't have any detrimental effect on my system, they're just inelegant and wasteful.

                      Comment


                      • #12
                        >Here's a (cheap) fix.

                        Sadly, this seems to be the way a lot of people program.

                        Fortunately the market cleans up these things and society handles the classification: WannaBe, HasBeen or NeverWas.

                        MCM
                        Michael Mattias
                        Tal Systems (retired)
                        Port Washington WI USA
                        [email protected]
                        http://www.talsystems.com

                        Comment


                        • #13
                          MCM, have you considered that you might have more value hiring yourself out as a conscience than a programmer. Lots of us evil folks only need one periodically, and would find it very limiting to have the wretched thing loaded as a TSR every morning when we wake up.

                          Comment


                          • #14
                            MCM, have you considered that you might have more value hiring yourself out as a conscience
                            Not necessarily more....but surely some.

                            The next career I want is as a speaker, writer and teacher. I want to help form the next generation of IT professionals.... and I guess that would have to include helping to form the ethos.
                            Michael Mattias
                            Tal Systems (retired)
                            Port Washington WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment


                            • #15
                              Another fix for the problem Dave Biggs uncovered would be to use ClipCursor with the button RECT coordinates. That way, the mouse could not be moved outside the button until released. I can post the code for this if anyone is interested.

                              Comment


                              • #16
                                Hi Charles,

                                I'd like to see that. - I tried to use SetCapture but couldn't get that to work..
                                Rgds, Dave

                                Comment


                                • #17
                                  The next career I want is as a speaker, writer and teacher. I want to help form the next generation of IT professionals.... and I guess that would have to include helping to form the ethos.
                                  You may want to learn a lil less "Stick" and more "Carrot" then.

                                  Speakers get paid by pompously putting people down by boasting how they did and their way is the ONLY way.

                                  Writers, generally get paid by writing what they know and how they did it.

                                  TEACHERS on the other hand, share their knowledge, and the trials and tribulations how they came to know what they know.

                                  Writers and Speakers would take offense on what I say, but TEACHERS, would agree with me completly

                                  Conrad, I hate to play devils advocate here, but some of what MCM stated above is true, "Shortcuts will be the death of you later" sort of thing.

                                  Seeing how I work with Motor Controllers on a daily basis, I think I get what you are trying to do.
                                  1.) Button Down ---> Move motor
                                  2.) Button Up ---> Stop Moving
                                  3.) As you have seen, MANY more messages are sent besides ("Motor Down"/"Motor Up") and try to only keep what you are focused on.

                                  Not an easy thing (BELIEVE ME) since I have tried the same and to date not got it totally correct.

                                  In your case, I would have to ask (what to me would be standard troubleshooting questions) but you are working on more specific and still relate to "How Do I???"

                                  1.) What is the Motor Controller? (Each has its own Quirks)
                                  2.) What is the USB adapter? (Same comment about Quirks)
                                  I assume you are trying to Jog while the button is down, and stop when it is up?
                                  Engineer's Motto: If it aint broke take it apart and fix it

                                  "If at 1st you don't succeed... call it version 1.0"

                                  "Half of Programming is coding"....."The other 90% is DEBUGGING"

                                  "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                                  Comment


                                  • #18
                                    Here is the code for using ClipCursor:

                                    Code:
                                    '[keywords] Mouse cursor constrained, Rectangular coordinates, %BS_PUSHBUTTON, ClipCursor 
                                    
                                    #COMPILE EXE
                                    #DIM ALL
                                    
                                    #INCLUDE "WIN32API.INC"
                                    
                                    %IDD_DIALOG1  =  101
                                    %IDC_BUTTON1  = 1001
                                    %IDC_TEXTBOX1 = 1002
                                    %IDC_LABEL1   = 1003
                                    
                                    
                                    FUNCTION PBMAIN()
                                        ShowDIALOG1 %HWND_DESKTOP
                                    END FUNCTION
                                    
                                    'Callback
                                    CALLBACK FUNCTION ShowDIALOG1Proc()
                                        LOCAL MyButton, hBtn, x, y AS LONG 
                                        STATIC btnDown AS LONG, r AS RECT
                                        SELECT CASE AS LONG CB.MSG
                                            CASE %WM_INITDIALOG
                                                'get rectangular coordinates of button within dialog
                                                hBtn = GetDlgItem(CB.HNDL, %IDC_BUTTON1)
                                                GetWindowRect hBtn, r
                                                x = r.nLeft: y = r.ntop
                                                GetClientRect hBtn, r
                                                r.nLeft = x: r.ntop = y
                                                r.nRight = r.nRight + x
                                                r.nBottom = r.nBottom + y
                                            CASE %WM_NCACTIVATE
                                                STATIC hWndSaveFocus AS DWORD
                                                IF ISFALSE CB.WPARAM THEN
                                                    ' Save control focus
                                                    hWndSaveFocus = GetFocus()
                                                ELSEIF hWndSaveFocus THEN
                                                    ' Restore control focus
                                                    SetFocus(hWndSaveFocus)
                                                    hWndSaveFocus = 0
                                                END IF
                                    
                                            CASE %WM_SETCURSOR
                                                MyButton = GetDlgCtrlId(CB.WPARAM)
                                                SELECT CASE MyButton
                                                    CASE %IDC_BUTTON1
                                                        SELECT CASE HI(INTEGER, CB.LPARAM)
                                                            CASE %WM_LBUTTONDOWN                '&H201
                                                                'do thing A here when the mouse button is depressed
                                                                btnDown = 1: clipCursor r
                                                                CONTROL SET TEXT CB.HNDL, %IDC_TEXTBOX1, "Button 1 Down!" : MESSAGEBEEP(&hFFFFFFFF)
                                                        END SELECT
                                                END SELECT
                                    
                                            CASE %WM_COMMAND
                                                SELECT CASE AS LONG CB.CTL
                                                    CASE %IDC_BUTTON1
                                                        IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
                                                            'do thing B here when the mouse button is released
                                                            CONTROL SET TEXT CB.HNDL, %IDC_TEXTBOX1, "Button 1 Up!" : MESSAGEBEEP(&hFFFFFFFF)
                                                            btnDown = 0: clipCursor BYVAL 0
                                                            CONTROL SEND CB.HNDL, CB.CTL, %BM_SETSTYLE, %BS_PUSHBUTTON, %TRUE
                                                        END IF
                                                END SELECT
                                                
                                        END SELECT
                                    END FUNCTION
                                    
                                    'Dialog
                                    FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
                                        LOCAL lRslt  AS LONG
                                        LOCAL hDlg   AS DWORD
                                        
                                        DIALOG NEW hParent, "Button Down Test", 167, 152, 257, 150, %WS_POPUP OR _
                                            %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR %WS_CLIPSIBLINGS OR _
                                            %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
                                            %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _
                                            %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
                                            
                                        CONTROL ADD BUTTON,  hDlg, %IDC_BUTTON1, "Button1", 80, 20, 95, 30
                                        CONTROL ADD TEXTBOX, hDlg, %IDC_TEXTBOX1, "TextBox1", 55, 90, 120, 30
                                        
                                        DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
                                        FUNCTION = lRslt
                                    END FUNCTION

                                    Comment


                                    • #19
                                      Completely off topic, but this thread sure looks like a good place to make use of the tags feature.
                                      It's a habit I'm going to have to develop!
                                      Rod
                                      In some future era, dark matter and dark energy will only be found in Astronomy's Dark Ages.

                                      Comment


                                      • #20
                                        Cliff, you've described the app perfectly. It's a very small stepper on a test fixture and no disaster would occur if it "got away" in some manner. The controller is a Peter Norberg 710 board, IMO a very nice and flexible controller for the low price. They have a dll, but because I'm not doing anything complicated or timing sensitive, I just send the board ascii commands out the USB port via a virtual comm port. In this case it couldn't be simpler- send plus or minus S to move forward and reverse, and Z to stop. There are good shortcuts and bad shortcuts. This one is direct and works perfectly so far as I can tell. If it led me through some briar patch I'd do it differently, but it's appropriate to the application. Just for example, if I were dealing with a high power system where it had the potential to hurt someone or do serious damage, I think long and hard about every possible way the code could go bad, how to recover if it did go bad (say, monitor position with an independent encoder) plus include hardware safety and shutdown mechanisms that were totally independent of software. OK, no I wouldn't, I'd just job the project out to somebody with better liabiliy insurance.

                                        Comment

                                        Working...
                                        X