2014-09-23 283 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