tmi*_*hty 2 .net vb.net api pinvoke
我想获得当前鼠标指针的速度,我想设置它.
为了得到它,我使用
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)
Run Code Online (Sandbox Code Playgroud)
设置它,我用
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)
Run Code Online (Sandbox Code Playgroud)
请注意相同功能的不同声明.
如果我将ByRef更改为ByVal,反之亦然,其中一个功能不起作用.
我是否真的必须以不同的方式声明相同的功能?还是我犯了什么错误?如果我这样做,有人可以告诉我如何正确地做到这一点?
核心问题是你不能以这种方式在VB中声明重载,因为正如错误消息所说,他们cannot overload each other because there differ only by parameters declared ByRef and ByVal(你没有提到错误).这不是在C#中发生,因为你会使用in和out这将更改签名.
你有几个选择,一个是使用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"...
Run Code Online (Sandbox Code Playgroud)
如果不是很明显,你会调用它们的SetSysParam和GetSysParam.
代码分析/ 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
Run Code Online (Sandbox Code Playgroud)
NET格式的一个优点是返回.几乎所有API调用都返回0或1表示成功或失败.将其MarshalAs... Boolean转换为Net布尔值.您可以随着时间的推移添加到类中,为各种Win32 API调用收集正确的幻数,声明,枚举和结构.它是一个共享/静态过程,因此它将被称为:
NativeMethods.SetMouseSpeed(myNewSpeed)
Run Code Online (Sandbox Code Playgroud)
"包装器"不仅隐藏了代码中API的不整洁细节,还可以解决API调用失败时要执行的操作.在获得速度的情况下,如果/当呼叫失败时,它会计算出返回的值而不是当前速度,这不可能被误读为速度值(例如可能为-1).正如代码中所提到的,有一种很好的方法可以在.NET中获得鼠标速度,从而不需要过载:
mySpeed = System.Windows.Forms.SystemInformation.MouseSpeed
Run Code Online (Sandbox Code Playgroud)
最后,我要提一下,单方面更改用户在其系统上的鼠标设置并不是一个好主意.他们选择这个价值是有原因的.如果有充分理由这样做,则应用程序退出时应恢复原始值.
技术说明:我通过CA运行此程序以确保所有内容的大小
| 归档时间: |
|
| 查看次数: |
315 次 |
| 最近记录: |