【问题标题】:Messed with SystemParametersInfo and Booleans pvParam parameter与 SystemParametersInfo 和布尔 pvParam 参数混淆
【发布时间】:2014-01-13 18:51:02
【问题描述】:

我正在尝试使用SystemParametersInfo 函数来设置布尔参数,这只是我将设置的布尔参数之一的示例:

' I try to set a boolean parameter, but no matter if I use False or True, 
' the parameter on the SO is always activated.
SystemParametersInfo(SPI.SPI_SETCURSORSHADOW, 0UI, False, SPIF.None)

' I check the modified parameter but always is positive.
Dim MyBoolean As Boolean = False
SystemParametersInfo(SPI.SPI_GETCURSORSHADOW, 0UI, MyBoolean, SPIF.None)

MsgBox(MyBoolean) ' Always is 'True', 
' and in the Advanced properties of the SO;
' the 'Show shadow under mouse' option is always checked.

这是另一个例子:

' Enable Accelerator Keys Visibility ( The underlined keys of the ContextMenu )
NativeMethods.SystemParametersInfo(SPI.SPI_SETKEYBOARDCUES, 0UI, True, SPIF.None)

MSDN 中的文档都说要使用 False 布尔值来禁用参数:

''' <summary>
''' Enables or disables a shadow around the cursor. 
''' The pvParam parameter is a BOOL variable. 
''' Set pvParam to TRUE to enable the shadow or FALSE to disable the shadow. 
''' This effect appears only if the system has a color depth of more than 256 colors.
''' Windows NT, Windows Me/98/95:  This value is not supported.
''' </summary>

但事实是,一旦启用它们,我就找不到禁用它们的方法,我尝试直接使用布尔值,也使用布尔变量,并使用 SPIF 参数的组合,没办法,如果我激活一个参数我无法将其关闭,我想我做错了什么但是......是什么?。

PS:我使用的是 Windows 8 x64

这是SystemParametersInfo 部分:

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

<Description("SPI System-wide parameter - Used in SystemParametersInfo function")>
Public Enum SPI As UInteger

    SPI_SETKEYBOARDCUES = &H100B
    SPI_GETCURSORSHADOW = &H101A
    SPI_SETCURSORSHADOW = &H101B

End Enum

<Description("SPIF System-wide parameter - Used in SystemParametersInfo function")>
<Flags>
Enum SPIF

    ''' <summary>
    ''' None
    ''' </summary>
    None = &H0

    ''' <summary>
    ''' Writes the new system-wide parameter setting to the user profile.
    ''' </summary>
    SPIF_UPDATEINIFILE = &H1

    ''' <summary>
    ''' Broadcasts the WM_SETTINGCHANGE message after updating the user profile.
    ''' </summary>
    SPIF_SENDCHANGE = &H2

    ''' <summary>
    ''' Same as SPIF_SENDCHANGE.
    ''' </summary>
    SPIF_SENDWININICHANGE = &H2

End Enum

【问题讨论】:

    标签: .net vb.net windows api winapi


    【解决方案1】:

    所有 Win32 API 的东西都倾向于适用于 True 为 1(或者实际上不是零 IIRC)的 C/C++。您需要将 MyBoolean 更改为 Integer 并使用 0 或 1。您还必须更改 API 签名:

    <DllImport("user32.dll")> _
     Private Shared Sub SystemParametersInfo(uiAction As UInteger, 
           uiParam As UInteger, ByRef pvParam As Integer, fWinIni As UInteger)
    
     End Sub
    

    这也是为什么您会看到 0 和 1 以及很多很多您正在处理的 WndProc 消息的返回。在很多情况下,它的T/F返回消息是否被处理。

    【讨论】:

    • 谢谢,但我已经完成了你所说的一切,但我仍然无法关闭这些值(假)。 PS:我正在使用您的签名进行测试,但是“子”声明是正确的吗?我喜欢其他 10 个签名,都是功能
    • 您可以根据需要将其更改为函数。不过,回报似乎很少符合文档。
    • 我刚刚将 Byref 更改为 Byval 并且工作了!但将其保留为 byval 是个好主意吗? (我知道区别,但我不明白为什么当我试图将 ByRef 设置为 0 时,函数会将布尔值更改为 1)
    • 我可能打错了(正在查看我一长串的列表),但 PInvoke 将它作为 byRef,但只要它有效......这可能是其中之一您应该在应用程序消息泵启动之前设置的内容。即在Application.Run之前调用
    猜你喜欢
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    • 2013-11-28
    • 2021-11-22
    • 2014-01-12
    • 1970-01-01
    • 2023-04-03
    相关资源
    最近更新 更多