|
-
Mar 27th, 2011, 05:09 AM
#1
[RESOLVED] Retrieving mouse speed
I am writing a program in which the user can vary the mouse speed, and I need to restore it to its original value on exit. I am able to set the mouse speed OK but I cannot read it. Here's some test code (VB2010):
Code:
<System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint:="SystemParametersInfo")> _
Public Shared Function SystemParametersInfo(ByVal uAction As Int32, ByVal uParam As Int32, ByVal pvParam As IntPtr, ByVal fuWinIni As Int32) As Int32
End Function
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Const SPI_GETMOUSESPEED As Int32 = &H70
Const SPI_SETMOUSESPEED As Int32 = &H71
Dim setValue As Integer = 17
Dim setValuePtr As New IntPtr(setValue)
Dim getValue As Integer
Dim getValuePtr As New IntPtr(getValue)
SystemParametersInfo(SPI_SETMOUSESPEED, 0, setValuePtr, 0)
SystemParametersInfo(SPI_GETMOUSESPEED, 0, getValuePtr, 1)
Console.WriteLine(getValue.ToString)
End Sub
This sets the mouse speed correctly (to 17 in the above code) but the console output is always 0. Can anyone see what's wrong?
The msdn documentation is as follows:
-
Mar 27th, 2011, 08:08 AM
#2
Fanatic Member
Re: Retrieving mouse speed
I'll take a look, have you checked the pointer value for the get function, that it is non-zero? Not sure if new IntPtr(val) returns a pointer...
EDIT
Yep the pointer returned 0.
Code:
Dim setValue As Integer = 17
Dim setValuePtr As New IntPtr(setValue)
Dim getValue As Integer
Dim getValuePtr As New IntPtr(getValue)
MsgBox(getValuePtr) 'Zero here
You have to use ByRef instead of ByVal to get the value. This works with me:
Code:
<System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint:="SystemParametersInfo")> _
Public Shared Function SystemParametersInfoGet(ByVal uAction As SPI, ByVal uParam As Int32, ByRef pvParam As IntPtr, ByVal fuWinIni As SPIF) As Int32
End Function
<System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint:="SystemParametersInfo")> _
Public Shared Function SystemParametersInfoSet(ByVal uAction As SPI, ByVal uParam As Int32, ByVal pvParam As IntPtr, ByVal fuWinIni As SPIF) As Int32
End Function
Public Enum SPI As Int32
GETMOUSESPEED = &H70
SETMOUSESPEED = &H71
End Enum
Public Enum SPIF As Int32
UPDATEINIFILE = 0
SENDCHANGE = 1
SENDWININICHANGE = 2
End Enum
Private Sub Routine()
Dim setValue As Integer = 17
Dim getValue As Integer
SystemParametersInfoSet(SPI.SETMOUSESPEED, 0, setValue, 0)
MsgBox("is set")
SystemParametersInfoGet(SPI.GETMOUSESPEED, 0, getValue, 1)
MsgBox("got: " & getValue)
End Sub
EDIT
Since I hold an API class (own project) I added this property to the class:
Code:
Public Enum Action As Int32
GETMOUSESPEED = &H70
SETMOUSESPEED = &H71
End Enum
Public Shared Property MOUSESPEED() As Integer
Get
Dim rval As Integer = 0
SystemParametersInfoGet(Action.GETMOUSESPEED, 0, rval, 0)
Return rval
End Get
Set(ByVal value As Integer)
SystemParametersInfoSet(Action.SETMOUSESPEED, 0, value, 1)
End Set
End Property
May you find it useful, use it.
Last edited by bergerkiller; Mar 27th, 2011 at 08:30 AM.
-
Mar 27th, 2011, 10:37 AM
#3
Re: Retrieving mouse speed
Rep+ to you bergerkiller: ByRef is the answer! It looks simple in retrospect but I spent a ridiculous amount of time trying to get this to work and didn't think of that. I'm not sure whether I need to structure the Sub into a Get and a Set version for my present purposes since ByRef seems to work fine in both cases. But your code is very clear and I will certainly end up defining a property following your example.
Cheers, BB
-
Mar 27th, 2011, 10:47 AM
#4
Re: Retrieving mouse speed
 Originally Posted by boops boops
<snip> I'm not sure whether I need to structure the Sub into a Get and a Set version for my present purposes since ByRef seems to work fine in both cases.
I was going to post earlier but my answer was pretty much the same as bergerkiller's. I'm pretty sure ByRef does not work in both cases, at least it does not work with the equivalent C# code.
Check the return value of SystemParametersInfo, I think you will find using ByRef to set will return 0. It's expecting a value not an address.
-
Mar 27th, 2011, 11:39 AM
#5
Fanatic Member
Re: [RESOLVED] Retrieving mouse speed
Yep, you need to use ByVal for the SET functions to work. In the documentation it says "inout", meaning the function can return a value or a value can be passed to the function. Since the function has only one possible output, I made the following "property function" for it, to simplify it all:
vb Code:
<System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint:="SystemParametersInfo")> _ Private Shared Function SystemParametersInfoGet(ByVal uAction As SPI.Action, ByVal uParam As Int32, ByRef pvParam As IntPtr, ByVal fuWinIni As Int32) As Int32 End Function <System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint:="SystemParametersInfo")> _ Private Shared Function SystemParametersInfoSet(ByVal uAction As SPI.Action, ByVal uParam As Int32, ByVal pvParam As IntPtr, ByVal fuWinIni As Int32) As Int32 End Function Public Enum Action As Int32 GETMOUSESPEED = &H70 SETMOUSESPEED = &H71 GETKEYBOARDSPEED = &HA SETKEYBOARDSPEED = &HB End Enum Public Shared Property SystemParametersInfo(ByVal uAction As SPI.Action, ByVal uParam As Int32, ByVal fuWinIni As Int32) As IntPtr Get Dim rval As IntPtr SystemParametersInfoGet(uAction, uParam, rval, fuWinIni) Return rval End Get Set(ByVal value As IntPtr) SystemParametersInfoSet(uAction, uParam, value, fuWinIni) End Set End Property
It's a nice alternative to using the two functions.Action names starting with SET need to be set, GET need to be returned by the property.
I am not sure, but it could be that SET = GET + 1, so you could do uAction + 1 in the Set of the property. And then you can remove all SET commands from the Action enumeration and remove the GET_ prefix:
vb Code:
Public Enum Action As Int32 MOUSESPEED = &H70 KEYBOARDSPEED = &HA End Enum Public Shared Property SystemParametersInfo(ByVal uAction As SPI.Action, ByVal uParam As Int32, ByVal fuWinIni As Int32) As IntPtr Get Dim rval As IntPtr SystemParametersInfoGet(uAction, uParam, rval, fuWinIni) Return rval End Get Set(ByVal value As IntPtr) SystemParametersInfoSet(uAction + 1, uParam, value, fuWinIni) End Set End Property
EDIT
Ow and you could also divide the two enumerations to two types: one for SET and one for GET.
Last edited by bergerkiller; Mar 27th, 2011 at 12:01 PM.
-
Mar 27th, 2011, 11:41 AM
#6
Re: [RESOLVED] Retrieving mouse speed
You are both right: there must be 2 subs. I understand next to nothing about APIs -- for example I don't understand how a function can do something when it doesn't have any code in it. So I should be more careful about speculating without checking . BB
-
Mar 27th, 2011, 04:22 PM
#7
Re: [RESOLVED] Retrieving mouse speed
API functions in your project don't have any code in them because they aren't really functions, they are just info about how to call functions that exist in external files, including the file name ("User32.dll"), the function name (EntryPoint:="SystemParametersInfo"), and the parameters (on the Function line).
The syntax for declaring API's is one of just a few where the syntax is worse than VB6, which made it clearer.
-
Apr 3rd, 2011, 08:08 PM
#8
Re: [RESOLVED] Retrieving mouse speed
 Originally Posted by si_the_geek
The syntax for declaring API's is one of just a few where the syntax is worse than VB6, which made it clearer.
Why doesn't VB10 have an API Viewer app like VB6?
I find it hard to use VB6 now after close to 8 months of playing around with VB10, a lot of things are so much easier, but when it comes to API...
-
Apr 4th, 2011, 03:24 AM
#9
Re: [RESOLVED] Retrieving mouse speed
A large percentage of things are built-into the .Net framework, so it isn't as useful as it was to VB6 people.
I generally use the official API documentation on MSDN (which often contains VB.Net examples at the bottom of the page), as you can be fairly sure that it is accurate and complete.
I also find http://www.pinvoke.net/ useful, and they have an addin for Visual Studio too.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|