Announcement

Collapse
No announcement yet.

Mouse click position on graphic control

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

  • Mouse click position on graphic control

    Hello everyone,

    I am new to PB and have spent many hours searching the forums here and the web for solutions and example code, like the community alot. I am making good progress and really like PB and its stand-alone EXE's.

    I am having a hard time doing something that in VB seemed so simple.

    I want to get the X Y position of a mouse click on a graphic control located a dialog window, with the X Y values being relative to the graphic control not the screen.

    I have checked out similar QA's on this forum but am still having trouble. If someone could post an simple example it would be great.

    Thanks!

  • #2
    Code:
    local pt as pointapi
    getcursorpos pt 'gets current cursor position in screen coordinates
    mapwindowpoints %null, hwndcontrol, pt, 1 'translates screen coordinates to coordinates that are relative to control's client area. Passing %NULL to the API means the desktop window. It is assumed that 'hwndcontrol' has been filled with the hwnd value of the graphic control.

    Comment


    • #3
      Sdk Style

      Shows mouse position in window as you move mouse, click, etc....

      http://www.jose.it-berater.org/smffo...p?topic=1254.0

      unfortunately, doesn't use graphic control - just plan jane Sdk window.
      Last edited by Fred Harris; 17 Apr 2008, 02:53 PM.
      Fred
      "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

      Comment


      • #4
        That's really easy, just add the %SS_NOTIFY style to the graphic control and catch either the %STN_CLICKED or %STN_DBLCLK messages.
        Code:
        #COMPILE EXE
        #DIM ALL
        
        #INCLUDE "WIN32API.INC"
        
        %IDC_GRAPHIC1 = 1001
        
        CALLBACK FUNCTION DlgProc
          LOCAL p AS POINTAPI
        
          SELECT CASE AS LONG CBMSG
              
            CASE %WM_COMMAND
              SELECT CASE AS LONG CBCTLMSG
                CASE %STN_CLICKED
                  GetCursorPos(p)
                  ScreenToClient(GetDlgItem(CBHNDL, %IDC_GRAPHIC1), p)   
                  DIALOG SET TEXT CBHNDL, "x="+FORMAT$(p.x)+", y="+FORMAT$(p.y)
        
              END SELECT
          END SELECT
        END FUNCTION
        
        FUNCTION PBMAIN () AS LONG
          LOCAL hDlg  AS DWORD
        
          DIALOG NEW 0, "Dialog1", 221, 110, 201, 121, TO hDlg
          CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC1, "", 20, 15, 140, 70, %SS_NOTIFY
          
          GRAPHIC ATTACH hDlg, %IDC_GRAPHIC1
          GRAPHIC CLEAR %BLACK
            
          DIALOG SHOW MODAL hDlg, CALL DlgProc
        END FUNCTION
        Sincerely,

        Steve Rossell
        PowerBASIC Staff

        Comment


        • #5
          Code:
          ScreenToClient(GetDlgItem(CBHNDL, %IDC_GRAPHIC1), p)
          Good, but... on WM_COMMAND, lparam (CBLPARAM) is a handle to the control sending the notification message. So you could...
          Code:
          ScreenToClient CBLPARAM, p
          .. and now the same code works even if you have more than one graphics control on the screen sending STN_click or double click notifications.. without the need to code the "%ID_xxxxx" value for each one.

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

          Comment


          • #6
            Originally posted by Michael Mattias View Post
            Good, but... on WM_COMMAND, lparam (CBLPARAM) is a handle to the control sending the notification message. So you could...
            Code:
            ScreenToClient CBLPARAM, p
            And its easier to read and one less function call. Very good, thanks Mike.
            Sincerely,

            Steve Rossell
            PowerBASIC Staff

            Comment


            • #7


              Thanks very much you guys, your suggestions ended my frustration. All is good in the universe again!

              Comment


              • #8
                A follow up question.

                I see %STN_CLICKED, %STN_DBLCLK, %STN_ENABLE and %STN_DISABLE in the .inc file but how would one use the same technique for a right mouse button click on the same graphic control?

                Comment


                • #9
                  This can be done by subclassing the graphic control:
                  Code:
                  #COMPILE EXE
                  #DIM ALL
                  
                  #INCLUDE "WIN32API.INC"
                  
                  %IDC_GRAPHIC1 = 1001
                  
                  GLOBAL OldGrProc AS LONG
                  
                  CALLBACK FUNCTION GrProc
                    LOCAL s AS STRING
                    
                    SELECT CASE AS LONG CBMSG
                      CASE %WM_RBUTTONDOWN
                        s = "Right Button Down at "
                        GOTO DisplayAction
                        
                      CASE %WM_LBUTTONDOWN
                        s = "Left button Down at "
                        GOTO DisplayAction
                        
                      CASE %WM_MOUSEMOVE
                        s = "Mouse move at "
                        GOTO DisplayAction
                        
                    END SELECT
                    
                    FUNCTION = CallWindowProc(OldGrProc, CBHNDL, CBMSG, CBWPARAM, CBLPARAM)
                    EXIT FUNCTION
                    
                    DisplayAction:
                      DIALOG SET TEXT GetParent(CBHNDL), s+FORMAT$(LO(WORD, CBLPARAM))+","+FORMAT$(HI(WORD, CBLPARAM))
                  END FUNCTION
                  
                  CALLBACK FUNCTION DlgProc
                    LOCAL p AS POINTAPI
                  
                    SELECT CASE AS LONG CBMSG
                      CASE %WM_INITDIALOG
                        OldGrProc = SetWindowLong(GetDlgItem(CBHNDL, %IDC_GRAPHIC1), %GWL_WNDPROC, CODEPTR(GrProc))
                      
                      CASE %WM_DESTROY
                        SetWindowLong(GetDlgItem(CBHNDL, %IDC_GRAPHIC1), %GWL_WNDPROC, OldGrProc)
                        
                    END SELECT
                  END FUNCTION
                  
                  FUNCTION PBMAIN () AS LONG
                    LOCAL hDlg  AS DWORD
                  
                    DIALOG NEW 0, "Dialog1", 221, 110, 201, 121, TO hDlg
                    CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC1, "", 20, 15, 140, 70, %SS_NOTIFY
                  
                    GRAPHIC ATTACH hDlg, %IDC_GRAPHIC1
                    GRAPHIC CLEAR %BLACK
                  
                    DIALOG SHOW MODAL hDlg, CALL DlgProc
                  
                  END FUNCTION
                  Sincerely,

                  Steve Rossell
                  PowerBASIC Staff

                  Comment


                  • #10
                    Cursor statement

                    I'm using PBWin8.04 and want to get acces to the MOUSE and CURSOR functions, however when I compile I'm getting the Error Message : Missing declaration : Cursor .
                    I'm afraid I'm missing something important .
                    Just a quick idea here ?

                    Comment


                    • #11
                      The MOUSE and CURSOR statements are only valid in a PBCC. What are you trying to accomplish? Maybe myself or another can help you with this?
                      Sincerely,

                      Steve Rossell
                      PowerBASIC Staff

                      Comment


                      • #12
                        Thanks very much Steve. That code helps me not only with the button click process, but also helps me understand the PB callback process better.

                        Thanks again.

                        Comment


                        • #13
                          Originally posted by Steve Rossell View Post
                          The MOUSE and CURSOR statements are only valid in a PBCC. What are you trying to accomplish? Maybe myself or another can help you with this?
                          Thnaks fo the reply .
                          Whats the difference between PBwin and PBCC anyhow ?
                          I want to be able to get the coordinates on the screen where I get my mouse on.

                          Comment


                          • #14
                            PBCC creates 32-bit console applications, see the description of what a console is in the PBCC documentation at http://www.powerbasic.com/support/he...a_console_.htm. PBWin creates 32-bit gui (graphical user interface) applications. A gui application is one that allows the user interact with graphical elements (controls) such as buttons, text boxes, comboboxes, etc. MS Word, Internet Explorer, Adobe Photoshop are all examples of gui applications.

                            Getting the coordinates of the mouse when a control is clicked on is done via callback (see http://www.powerbasic.com/support/he.../callbacks.htm) routine in gui applications. If you tell me what type of control you need to capture a mouse click or any other mouse events on, I will help in any way I can.

                            If you are new to gui/event style programming, take a look at the PowerBASIC Quick Start Tutorials at http://www.powerbasic.com/support/quickstart/index.html. These are especially useful for new users coming from a DOS or console style programming background.
                            Sincerely,

                            Steve Rossell
                            PowerBASIC Staff

                            Comment


                            • #15
                              PBWin vs PBCC

                              Thanks for the information : this explains a lot .
                              So the two compilers can't be mixed , each using their own syntax .
                              I'm relative new with the GUI environment and took a look at the link above . Digging in the syntax I see the following line to appear :
                              %USEMACROS =1.
                              I wanted to find a reference for this command ( find "%", "use" ) but could find it . Should I look somewhere else ?

                              Comment


                              • #16
                                First of all, the WinApi Call "GetCursorPos" will give you the screen coordinates were the mouse currently is. If you need that in client coordinates, you can use either the MapWindowPoints or ScreenToClient WinAPI functions.

                                Yes, you will need to get comfortable calling WinApi functions if you want to create non-trivial applications. This is not an "if", it's a "when" you decide to invest some learning time in this. Fortunately there are over 2700 postings in the Source Code Forum and I'll bet at least 2500 of them use Windows' API calls.

                                Second, for the %USEMACROS thing... Refer to the help file twice: first, see "equates," then see #IF or "conditional compilation." Both topics are fundamental to programming with the PB compilers.

                                Third, also on the %USEMACROS thing... see MACRO in the help file OR change that line to %USEMACROS=0 until you do.

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

                                Comment

                                Working...
                                X