• Login
sketchucation logo sketchucation
  • Login
ℹ️ GoFundMe | Our friend Gus Robatto needs some help in a challenging time Learn More

Mouse Capture (Win32 API)

Scheduled Pinned Locked Moved Developers' Forum
13 Posts 3 Posters 4.5k Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    Mr.K.1
    last edited by Mr.K.1 12 Jul 2011, 15:20

    The idea is to capture the mouse via Win32 API so I can utilize all mouse buttons without Sketchup interfering (it's for a mini first person shooter in SketchyPhysics).

    Now I got it to work half way but I don't know how to read the buttons, and I know alot of you guys are more knowledgeable then me so I would appreciate the help.

    The working code I got sofar:

    • window handle
      getForegroundWindow = Win32API.new('user32', 'GetForegroundWindow', [], 'L') window_handle = getForegroundWindow.Call()

    • capture mouse input
      setCapture = Win32API.new('user32', 'SetCapture', 'L', 'L') setCapture.call(window_handle)

    • release mouse (EDIT: fixed the input parameters)
      releaseCapture = Win32API.new('user32', 'ReleaseCapture', 'V', 'L') releaseCapture.call()

    So those are the parts that work, you can try it in the Ruby console directly, until releaseCapture is called SU wont get any mouse input.
    Now I a script that reads the mouse input/clicks while the mouse is captured.

    I have found a Ruby example for reading window input messages but I'm not sure how it is suppose to work, if it's the right way to do it at all.
    ` getmessage = Win32API.new('user32', 'GetMessage', ['p', 'l', 'i', 'i'], 'l')
    dispatchmessage = Win32API.new('user32', 'DispatchMessage', 'p', 'l')
    translatemessage = Win32API.new('user32', 'TranslateMessage', 'p', 'l')

    while getmessage.call(msg, 0, 0,0)
    dispatchmessage.call(msg)
    translatemessage.call(msg)
    end`

    1 Reply Last reply Reply Quote 0
    • A Offline
      Anton_S
      last edited by 13 Jul 2011, 06:17

      So, u need to get the mouse back to react to u. You say that the release function doesn't works or return's errors in ruby console? If thats what you mean, then here is how to get it back to work:

      First when calling the release function(http://msdn.microsoft.com/en-us/library/ms646261(v=VS.85).aspx ) You should avoid extra parameters. The script says:

      @unknownuser said:

      • release mouse
        releaseCapture = Win32API.new('user32', 'ReleaseCapture', 'L', 'L') releaseCapture.call()

      The underlined "L", which represent's the number, says that while calling that function you need to add a required parameter>>, but there is nothing required. So you need to change that first "L" to "V", which is void. And then it won't require you any parameters, even though this function still doesn't has any required parameters.

      The reason Win32API was written like that >> there would be a plenty of ways to call the function, and so the user could know in what form the function is required and return its objectives.

      The second "L" is now the user's idea to choose the function's returning mode. Ex: putting "V" would make the function to return nothing.

      In my way the function should sound like that:
      releaseCapture = Win32API.new('user32', 'ReleaseCapture', 'V', 'L') releaseCapture.call()

      Then it will work - I even checked it. The mouse was captured and then released. Ex:

      ` ontick{
      if frame==10
      model=Sketchup.active_model
      entities=model.entities
      view=model.active_view

      getForegroundWindow = Win32API.new('user32', 'GetForegroundWindow', [], 'L')
      window_handle = getForegroundWindow.Call()
      setCapture = Win32API.new('user32', 'SetCapture', 'L', 'L')
      setCapture.call(window_handle)
      end

      if frame==200
      releaseCapture = Win32API.new('user32', 'ReleaseCapture', 'V', 'L')
      releaseCapture.call()
      end
      }`

      Here's the URL what explains some of that: http://phrogz.net/ProgrammingRuby/lib_windows.html#Win32API

      And Here's the windows API reference: http://msdn.microsoft.com/en-us/library/aa383749(VS.85).aspx

      If that was not what u wanted then PLEASE make it more clear!!! - My dad is really good at win32API stuff. πŸ˜„ He's Smart >> πŸ€“

      Thanks for asking!!! πŸ˜„

      1 Reply Last reply Reply Quote 0
      • M Offline
        Mr.K.1
        last edited by 13 Jul 2011, 08:44

        OK maybe I wasn't clear.

        Reading the mouse input/clicks while I have it captured is the problem, how do you do that?

        1 Reply Last reply Reply Quote 0
        • T Offline
          thomthom
          last edited by 14 Jul 2011, 10:15

          Can you combine it with a Tool - and get the mouse input via it's events?

          Thomas Thomassen β€” SketchUp Monkey & Coding addict
          List of my plugins and link to the CookieWare fund

          1 Reply Last reply Reply Quote 0
          • M Offline
            Mr.K.1
            last edited by 14 Jul 2011, 10:51

            I can but SU keeps it's own mouse click actions that mess with SketchyPhysics and will mess with the game.

            • right mouse click, always pops up a drop down menu(even when empty)
            • middle mouse click, has the default orbit tool
            • mouse scroll, has default camera zoom

            Is there a way to disable these? I tried adding things to the button events but it does not prevent the default SU actions.

            1 Reply Last reply Reply Quote 0
            • A Offline
              Anton_S
              last edited by 14 Jul 2011, 17:35

              Mr.k u know that capturing mouse is a very, very, Very good idea! β˜€
              Now Instead of Creating a SketchyPhysicsControllClient we can capture the keyboard and mouse by by hoocking the signals and sending them instead to sketchy physics operation.

              Since my dad is new to Ruby Programing Language, it takes more time for him and me to write this code. His idea is to first write it on Delphi and then me, him, and most likely with ur help would try to convert it to Ruby. πŸ˜„

              1 Reply Last reply Reply Quote 0
              • M Offline
                Mr.K.1
                last edited by 14 Jul 2011, 19:54

                I eagerly await your results, I will help out in any way I can to finally bring this old project to full life.

                I assume it would also come in very handy when making other plugins and tools.

                1 Reply Last reply Reply Quote 0
                • A Offline
                  Anton_S
                  last edited by 14 Jul 2011, 20:40

                  Well here is what I got for NOW, but it's the way where u allways have to call the function to get the input:

                  onstart{
                   require "Win32API"
                   
                   @rc=0 #var preventing release function to be called more than once, just to make the script accurate.
                   @getKeyState=Win32API.new('user32', "GetKeyState", "L", "L")
                   getForegroundWindow = Win32API.new('user32', 'GetForegroundWindow', [], 'L')
                   setCapture = Win32API.new('user32', 'SetCapture', 'L', 'L')
                   setCapture.call(getForegroundWindow.Call())
                  }
                  
                  ontick{
                   if (frame==1000 or key(" ")==1) and @rc==0 then
                    @rc=1
                    releaseCapture = Win32API.new('user32', 'ReleaseCapture', 'V', 'L')
                    releaseCapture.call()
                   end
                   model=Sketchup.active_model
                   entities=model.entities
                   view=model.active_view
                   entities[0].text=@getKeyState.call(VK_LBUTTON).inspect + "
                  " + @getKeyState.call(VK_RBUTTON).inspect
                  }
                  
                  onend{
                   if @rc==0 then
                    releaseCapture = Win32API.new('user32', 'ReleaseCapture', 'V', 'L')
                    releaseCapture.call()
                   end 
                  }
                  

                  The model is here: http://sketchup.google.com/3dwarehouse/details?mid=f0ca091fd0760cfc6a464cb0e6f0895

                  Virtual key codes: http://msdn.microsoft.com/en-us/library/dd375731(v=VS.85).aspx

                  1 Reply Last reply Reply Quote 0
                  • M Offline
                    Mr.K.1
                    last edited by 15 Jul 2011, 06:28

                    Very nice, that works perfectly in SP!
                    Is there a way to just get the full array of buttons and not call the function for every button specifically because it seems like a waste.

                    We could still use a callback feature for other plugins.
                    Maybe someone else here knows how to set that up?

                    1 Reply Last reply Reply Quote 0
                    • A Offline
                      Anton_S
                      last edited by 15 Jul 2011, 06:49

                      @unknownuser said:

                      Very nice, that works perfectly in SP!
                      Is there a way to just get the full array of buttons and not call the function for every button specifically because it seems like a waste.

                      Yes there is a way and this is what my dad will be doing. The program would receive the mouse or keyboard signals and send the input signals to sketchy physics operation, preventing them to interupt with SU.

                      1 Reply Last reply Reply Quote 0
                      • M Offline
                        Mr.K.1
                        last edited by 15 Jul 2011, 18:56

                        Any way to include mouse wheel into this, it seems there is no code for it among the button lineup.
                        Not strictly necessary but it's nice to get the control.

                        1 Reply Last reply Reply Quote 0
                        • A Offline
                          Anton_S
                          last edited by 19 Jul 2011, 23:36

                          Here is the way to get most of mouse input(no wheel scrool or side-to-side input) and all keyboard inputs.
                          http://sketchup.google.com/3dwarehouse/details?mid=e530ef9d408f78ce6a464cb0e6f0895

                          It is still not a good way to get the input messages, since it it has to be called all the time to get the input, but its also not that bad for the start. Mouse Wheel Scroll and side-to-side click input, is somewhere in the different function, but it's not really important now. My dad is still writing a script with me that would hook all keyboard and mouse messages and send them to array of active key inputs. So, the mouse wheel function is not important now because when the hoocking script would be active the function could just return us an input message of mouse wheel. Ex: forward scroll, backward scroll, side-to-side click and some more messages that would incounter the mouse wheel usage.

                          1 Reply Last reply Reply Quote 0
                          • M Offline
                            Mr.K.1
                            last edited by 22 Jul 2011, 08:58

                            So here is the jist of Anton's code:

                            Capture mouse (Sketchup will stop reacting to it):

                            getForegroundWindow=Win32API.new("user32", "GetForegroundWindow", [], "L")
                             Win32API.new("user32", "SetCapture", "L", "L").call(getForegroundWindow.call())
                            

                            Read all key states (keyboard and mouse):

                            @getKeyboardState=Win32API.new("user32", "GetKeyboardState", "P", "V")
                            @lpKeyState=" "*256
                            @getKeyboardState.call(@lpKeyState)
                            
                            

                            @lpKeyState will hold an array of 256 numbers for all the keys.
                            @lpKeyState[1,2,4] - [1]left-mouse, [2]right-mouse, [4]middle-mouse
                            @lpKeyState[48..57] - keyboard keys 0 to 9

                            Release mouse

                            Win32API.new("user32", "ReleaseCapture", "V", "L").call()
                            
                            1 Reply Last reply Reply Quote 0
                            • 1 / 1
                            1 / 1
                            • First post
                              1/13
                              Last post
                            Buy SketchPlus
                            Buy SUbD
                            Buy WrapR
                            Buy eBook
                            Buy Modelur
                            Buy Vertex Tools
                            Buy SketchCuisine
                            Buy FormFonts

                            Advertisement