2014-09-23 275 views
2

我想获得当前的鼠标指针速度,并且我想设置它。我需要2个不同的PInvokes来获取和设置鼠标速度吗?

为了得到它,我用

Public Declare Function SystemParametersInfo Lib "user32.dll" Alias "SystemParametersInfoA" (ByVal uAction As Int32, ByVal uParam As Int32, ByRef lpvParam As Int32, ByVal fuWinIni As Int32) As Int32 

    Dim Result As Int32 = 0 
    Dim iSuccess As Integer = SystemParametersInfo(SPI_GETMOUSESPEED, 0, Result, 0) 

要设置它,我用

Public Declare Function SystemParametersInfo Lib "user32.dll" Alias "SystemParametersInfoA" (ByVal uAction As Int32, ByVal uParam As Int32, ByVal lpvParam As Int32, ByVal fuWinIni As Int32) As Int32 

    Dim iVal As Integer = 10 
    Dim iSuccess As Integer = SystemParametersInfo(SPI_SETMOUSESPEED, 0, iVal, 0) 

请注意同一功能的不同声明。

如果我将ByRef更改为ByVal或反之亦然,其中一个功能不起作用。

我真的必须以不同的方式声明相同的功能吗? 还是我犯了什么错误? 如果我这样做,有人可以告诉我如何正确地做到这一点?

回答

5

核心问题是,你不能在VB中声明过载这种方式,因为如错误消息所示,他们cannot overload each other because there differ only by parameters declared ByRef and ByVal(你没有提到错误)。这在C#中不会发生,因为您会使用inout这会更改签名。

您有几种选择,一种是使用Alias

' declaration for all ByVal args: 
Declare Function SetSysParam Lib "user32.dll" Alias "SystemParametersInfoA"... 

' one parm ByRef for getting the speed: 
Declare Function GetSysParam Lib "user32.dll" Alias "SystemParametersInfoA"... 

如果不是很明显,你会调用它们为SetSysParamGetSysParam.

代码分析/ FxCop的可能会抱怨关于你使用这些的方式,所以这里是如何实现API调用,所以它没有。从名为NativeMethods的类开始:

<DllImport("user32.dll", SetLastError:=True)> 
Private Shared Function SystemParametersInfo(uiAction As SPI, 
     uiParam As UInteger, 
     pvParam As IntPtr, 
     fWinIni As SPIF) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function 

' alias a ByRef version for GETting the speed, but this is not 
' needed since NET offers a cleaner way 
<DllImport("user32.dll", EntryPoint:="SystemParametersInfo", SetLastError:=True)> 
Private Shared Function SystemParametersInfoPVByRef(uiAction As SPI, 
     uiParam As UInteger, 
     ByRef pvParam As IntPtr, 
     fWinIni As SPIF) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function 

' other stuff for the last param 
<Flags> 
Enum SPIF 
    None = &H0 
    SPIF_UPDATEINIFILE = &H1 
    SPIF_SENDCHANGE = &H2 
    SPIF_SENDWININICHANGE = &H2 
End Enum 

' there are lots and lots of Sys Params, so use an Enum to group them 
Enum SPI 
    SETMOUSESPEED = &H71 
    GETMOUSESPEED = &H70 
End Enum 

' exposed "wrapper" for setting the value to allow a more 
' meaningful name and hiding gory details of Msg values etc 
Friend Shared Function SetMouseSpeed(speed As Integer) As Boolean 
    ' somewhat optional error checking 
    If speed < 1 Then speed = 1 
    If speed > 20 Then speed = 20 

    Return SystemParametersInfo(SPI.SETMOUSESPEED, 0, New IntPtr(speed), SPIF.None) 
End Function 

Friend Shared Function GetMouseSpeed() As Integer 
    Dim speed As New IntPtr(0) 

    ' the caller will have to evaluate the return to see if this 
    ' succeeded 
    If SystemParametersInfoPVByRef(SPI.GETMOUSESPEED, 0, speed, SPIF.None) Then 
     Return speed.ToInt32 
    Else 
     Return -1   ' magic number that API call failed 
    End If 

End Function 

NET格式的一个优点是返回。几乎所有的API调用都会返回0或1来表示成功或失败。 MarshalAs... Boolean将其转换为Net布尔值。随着时间的推移,您可以添加到类中,为各种Win32 API调用收集正确的幻数,声明,枚举和结构。这是一个共享/静态的过程,所以它被称为:

NativeMethods.SetMouseSpeed(myNewSpeed) 

的“包装”,不仅隐藏在代码中的API的凌乱的细节,它也还可以锻炼身体做什么,如果API调用失败。在获得速度的情况下,如果/当呼叫失败时,计算出返回值而不是当前速度,有些东西不可能被误读为速度值(如可能为-1)。正如代码所指出的,有很好的清洁办法让鼠标速度.NET使得超载不必要的:

mySpeed = System.Windows.Forms.SystemInformation.MouseSpeed 

最后,我要指出,这不是一个好主意,单方面改变用户在其系统上设置用户的鼠标。他们选择这个价值是有原因的。如果有足够的理由这样做,应用程序退出时应恢复原始值。

技术说明:我跑这通CA,以确保一切

0

的大小@Plutonix答案补充我将分享所有的SystemParametersInfo声明,我需要在过去出于各种目的来写的。

用法示例:

' Set Mouse Speed 
' (Minimum: 1, Maximum: 20) 
SystemParametersInfo(SPI.SPI_SETMOUSESPEED, False, 15UI, SPIF.None) 

注:我没有固定的一些便携式警告,罚全中API数据类型声明的VS代码分析工具。

''' <summary> 
''' (For setting a Boolean pvParam) 
''' Retrieves or sets the value of one of the system-wide parameters. 
''' This function can also update the user profile while setting a parameter. 
''' </summary> 
''' <param name="uiAction"> 
''' The system-wide parameter to be retrieved or set. 
''' </param> 
''' <param name="uiParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify zero for this parameter. 
''' </param> 
''' <param name="pvParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify NULL for this parameter. 
''' For information on the PVOID datatype, see Windows Data Types.</param> 
''' <param name="fWinIni"> 
''' If a system parameter is being set, specifies whether the user profile is to be updated, 
''' and if so, whether the WM_SETTINGCHANGE message is to be broadcast to all top-level windows to 
''' notify them of the change. 
''' This parameter can be zero if you do not want to update the user profile or broadcast the WM_SETTINGCHANGE message, 
''' or it can be one or more of the following values. 
''' </param> 
<DllImport("user32.dll", SetLastError:=True)> 
Friend Shared Function SystemParametersInfo(
       ByVal uiAction As SPI, 
       ByVal uiParam As UInteger, 
       ByVal pvParam As Boolean, 
       ByVal fWinIni As SPIF 
) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function 

''' <summary> 
''' (For getting a Byref Boolean pvParam) 
''' Retrieves or sets the value of one of the system-wide parameters. 
''' This function can also update the user profile while setting a parameter. 
''' </summary> 
''' <param name="uiAction"> 
''' The system-wide parameter to be retrieved or set. 
''' </param> 
''' <param name="uiParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify zero for this parameter. 
''' </param> 
''' <param name="pvParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify NULL for this parameter. 
''' For information on the PVOID datatype, see Windows Data Types.</param> 
''' <param name="fWinIni"> 
''' If a system parameter is being set, specifies whether the user profile is to be updated, 
''' and if so, whether the WM_SETTINGCHANGE message is to be broadcast to all top-level windows to 
''' notify them of the change. 
''' This parameter can be zero if you do not want to update the user profile or broadcast the WM_SETTINGCHANGE message, 
''' or it can be one or more of the following values. 
''' </param> 
<DllImport("user32.dll", EntryPoint:="SystemParametersInfo", SetLastError:=True)> 
Friend Shared Function SystemParametersInfoByRefpv(
       ByVal uiAction As SPI, 
       ByVal uiParam As UInteger, 
       ByRef pvParam As Boolean, 
       ByVal fWinIni As SPIF 
) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function 

''' <summary> 
''' (For setting a Boolean uiParam and Boolean pvParam parameter) 
''' Retrieves or sets the value of one of the system-wide parameters. 
''' This function can also update the user profile while setting a parameter. 
''' </summary> 
''' <param name="uiAction"> 
''' The system-wide parameter to be retrieved or set. 
''' </param> 
''' <param name="uiParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify zero for this parameter. 
''' </param> 
''' <param name="pvParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify NULL for this parameter. 
''' For information on the PVOID datatype, see Windows Data Types.</param> 
''' <param name="fWinIni"> 
''' If a system parameter is being set, specifies whether the user profile is to be updated, 
''' and if so, whether the WM_SETTINGCHANGE message is to be broadcast to all top-level windows to 
''' notify them of the change. 
''' This parameter can be zero if you do not want to update the user profile or broadcast the WM_SETTINGCHANGE message, 
''' or it can be one or more of the following values. 
''' </param> 
<DllImport("user32.dll", SetLastError:=True)> 
Friend Shared Function SystemParametersInfo(
       ByVal uiAction As SPI, 
       ByVal uiParam As Boolean, 
       ByVal pvParam As Boolean, 
       ByVal fWinIni As SPIF 
) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function 

''' <summary> 
''' (For setting a IntPtr pvParam parameter) 
''' Retrieves or sets the value of one of the system-wide parameters. 
''' This function can also update the user profile while setting a parameter. 
''' </summary> 
''' <param name="uiAction"> 
''' The system-wide parameter to be retrieved or set. 
''' </param> 
''' <param name="uiParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify zero for this parameter. 
''' </param> 
''' <param name="pvParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify NULL for this parameter. 
''' For information on the PVOID datatype, see Windows Data Types.</param> 
''' <param name="fWinIni"> 
''' If a system parameter is being set, specifies whether the user profile is to be updated, 
''' and if so, whether the WM_SETTINGCHANGE message is to be broadcast to all top-level windows to 
''' notify them of the change. 
''' This parameter can be zero if you do not want to update the user profile or broadcast the WM_SETTINGCHANGE message, 
''' or it can be one or more of the following values. 
''' </param> 
<DllImport("user32.dll", SetLastError:=True)> 
Friend Shared Function SystemParametersInfo(
       ByVal uiAction As SPI, 
       ByVal uiParam As UInteger, 
       ByVal pvParam As IntPtr, 
       ByVal fWinIni As SPIF 
) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function 

''' <summary> 
''' (For setting an UInteger uiParam and pvParam parameters) 
''' Retrieves or sets the value of one of the system-wide parameters. 
''' This function can also update the user profile while setting a parameter. 
''' </summary> 
''' <param name="uiAction"> 
''' The system-wide parameter to be retrieved or set. 
''' </param> 
''' <param name="uiParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify zero for this parameter. 
''' </param> 
''' <param name="pvParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify NULL for this parameter. 
''' For information on the PVOID datatype, see Windows Data Types.</param> 
''' <param name="fWinIni"> 
''' If a system parameter is being set, specifies whether the user profile is to be updated, 
''' and if so, whether the WM_SETTINGCHANGE message is to be broadcast to all top-level windows to 
''' notify them of the change. 
''' This parameter can be zero if you do not want to update the user profile or broadcast the WM_SETTINGCHANGE message, 
''' or it can be one or more of the following values. 
''' </param> 
<DllImport("user32.dll", SetLastError:=True)> 
Friend Shared Function SystemParametersInfo(
       ByVal uiAction As SPI, 
       ByVal uiParam As UInteger, 
       ByVal pvParam As UInteger, 
       ByVal fWinIni As SPIF 
) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function 

''' <summary> 
''' (For setting an Boolean uiParam and UInteger pvParam) 
''' Retrieves or sets the value of one of the system-wide parameters. 
''' This function can also update the user profile while setting a parameter. 
''' </summary> 
''' <param name="uiAction"> 
''' The system-wide parameter to be retrieved or set. 
''' </param> 
''' <param name="uiParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify zero for this parameter. 
''' </param> 
''' <param name="pvParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify NULL for this parameter. 
''' For information on the PVOID datatype, see Windows Data Types.</param> 
''' <param name="fWinIni"> 
''' If a system parameter is being set, specifies whether the user profile is to be updated, 
''' and if so, whether the WM_SETTINGCHANGE message is to be broadcast to all top-level windows to 
''' notify them of the change. 
''' This parameter can be zero if you do not want to update the user profile or broadcast the WM_SETTINGCHANGE message, 
''' or it can be one or more of the following values. 
''' </param> 
<DllImport("user32.dll", SetLastError:=True)> 
Friend Shared Function SystemParametersInfo(
       ByVal uiAction As SPI, 
       ByVal uiParam As Boolean, 
       ByVal pvParam As UInteger, 
       ByVal fWinIni As SPIF 
) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function 

''' <summary> 
''' (For setting a String pvParam parameter) 
''' Retrieves or sets the value of one of the system-wide parameters. 
''' This function can also update the user profile while setting a parameter. 
''' </summary> 
''' <param name="uiAction"> 
''' The system-wide parameter to be retrieved or set. 
''' </param> 
''' <param name="uiParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify zero for this parameter. 
''' </param> 
''' <param name="pvParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify NULL for this parameter. 
''' For information on the PVOID datatype, see Windows Data Types.</param> 
''' <param name="fWinIni"> 
''' If a system parameter is being set, specifies whether the user profile is to be updated, 
''' and if so, whether the WM_SETTINGCHANGE message is to be broadcast to all top-level windows to 
''' notify them of the change. 
''' This parameter can be zero if you do not want to update the user profile or broadcast the WM_SETTINGCHANGE message, 
''' or it can be one or more of the following values. 
''' </param> 
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True, BestFitMapping:=False)> 
Friend Shared Function SystemParametersInfo(
       ByVal uiAction As UInteger, 
       ByVal uiParam As UInteger, 
       ByVal pvParam As String, 
       ByVal fWinIni As SPIF 
) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function 

''' <summary> 
''' (For reading a String pvParam parameter) 
''' Retrieves or sets the value of one of the system-wide parameters. 
''' This function can also update the user profile while setting a parameter. 
''' </summary> 
''' <param name="uiAction"> 
''' The system-wide parameter to be retrieved or set. 
''' </param> 
''' <param name="uiParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify zero for this parameter. 
''' </param> 
''' <param name="pvParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify NULL for this parameter. 
''' For information on the PVOID datatype, see Windows Data Types.</param> 
''' <param name="fWinIni"> 
''' If a system parameter is being set, specifies whether the user profile is to be updated, 
''' and if so, whether the WM_SETTINGCHANGE message is to be broadcast to all top-level windows to 
''' notify them of the change. 
''' This parameter can be zero if you do not want to update the user profile or broadcast the WM_SETTINGCHANGE message, 
''' or it can be one or more of the following values. 
''' </param> 
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True, BestFitMapping:=False)> 
Friend Shared Function SystemParametersInfo(
       ByVal uiAction As UInteger, 
       ByVal uiParam As UInteger, 
       ByVal pvParam As StringBuilder, 
       ByVal fWinIni As SPIF 
) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function 

''' <summary> 
''' (For setting a AnimationInfo pvParam parameter) 
''' Retrieves or sets the value of one of the system-wide parameters. 
''' This function can also update the user profile while setting a parameter. 
''' </summary> 
''' <param name="uiAction"> 
''' The system-wide parameter to be retrieved or set. 
''' </param> 
''' <param name="uiParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify zero for this parameter. 
''' </param> 
''' <param name="pvParam"> 
''' A parameter whose usage and format depends on the system parameter being queried or set. 
''' For more information about system-wide parameters, see the uiAction parameter. 
''' If not otherwise indicated, you must specify NULL for this parameter. 
''' For information on the PVOID datatype, see Windows Data Types.</param> 
''' <param name="fWinIni"> 
''' If a system parameter is being set, specifies whether the user profile is to be updated, 
''' and if so, whether the WM_SETTINGCHANGE message is to be broadcast to all top-level windows to 
''' notify them of the change. 
''' This parameter can be zero if you do not want to update the user profile or broadcast the WM_SETTINGCHANGE message, 
''' or it can be one or more of the following values. 
''' </param> 
<DllImport("user32.dll", SetLastError:=True)> _ 
Friend Shared Function SystemParametersInfo(
       ByVal uiAction As SPI, 
       ByVal uiParam As UInteger, 
       ByRef pvParam As AnimationInfo, 
       ByVal fWinIni As SPIF 
) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function