VB.NET 兼容的 sendmessage 和 sendmessagetimeout API

问题描述 投票:0回答:1

基本上:我想要一个

sendmessage
sendmessagetimeout
用于 VB.NET 的 API,其他人已经使用过并且知道它可以工作。

我的 VB .net 应用程序需要

sendmessage
sendmessagetimeout
的 API。 我已经搜索了很多,我发现的所有内容似乎都不起作用:要么消息似乎没有发送,要么消息似乎是在
msg
参数始终为 0 的情况下发送的,并且
wparam 
设置为我为
msg
设置输入的内容。 Pinvoke 似乎也总是抛出一个
AccessViolationException
,因为我不知道是什么原因。 我尝试调整变量的放置位置,但毫不奇怪,变量没有简单的逻辑切换。

我尝试过pinvoke的:

<DllImport("user32.dll", SetLastError:=True)> _
Public Shared Function SendMessageTimeout(ByVal windowHandle As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByVal flags As SendMessageTimeoutFlags, ByVal timeout As Integer, ByRef result As IntPtr) As IntPtr
End Function

和 allapi 的:

Declare Function SendMessageTimeout Lib "user32" Alias "SendMessageTimeoutA" (ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As String, ByVal fuFlags As Long, ByVal uTimeout As Long, lpdwResult As Long) As Long

等等,但它们似乎不起作用。

所以我想知道

sendmessage
和/或
sendmessagetimeout
的 API,您知道这项工作!如果 VB.net 没有针对这些函数的正确 API,我可以使用哪些替代函数来完成与这两个函数相同的任务?

编辑:

或者,我可能错误地发送了消息,所以只是为了确保这不是问题:

我想发送

WM_WININICHANGE
,所以我使用:

  • hwnd = HWND_BROADCAST = 0xffff = 65535
  • 消息 = WM_WININICHANGE = 0x001A = 26
  • wparam 和 lparam 为 0

但我尝试过使用

wparam
lparam
的其他值,通常没有区别。当尝试
sendmessagetimeout
时,我还使用:

  • 标志 = SMTO_ABORTIFHUNG = 2
  • 超时 = 1000 = 1 秒
  • 然后 0 为结果。
.net vb.net sendmessage
1个回答
4
投票

是的,第一个是正确的。不要使用旧式的

Declare Function...Lib
声明;支持它们只是为了与 VB 6 兼容。新样式的 P/Invoke 定义如下所示:

<DllImport("user32.dll", SetLastError:=True)> _
Public Shared Function SendMessageTimeout(ByVal hWnd As IntPtr,
                                          ByVal msg As Integer,
                                          ByVal wParam As IntPtr,
                                          ByVal lParam As IntPtr,
                                          ByVal flags As SendMessageTimeoutFlags,
                                          ByVal timeout As Integer,
                                          ByRef result As IntPtr) As IntPtr
End Function

但是发送

WM_WININICHANGE
可能不是;此消息早已过时。文档明确指出:

注意: 提供

WM_WININICHANGE
消息只是为了与早期版本的系统兼容。应用程序应使用
WM_SETTINGCHANGE
消息。

因此,我建议使用

WM_SETTINGCHANGE
,即使 Windows 标头在技术上将它们定义为相同的值。这不是合同,如果您使用正确的名称,您的代码将更具可读性。阅读该文件的文档,它说:

应用程序在更改系统参数时应将

WM_SETTINGCHANGE
发送到所有顶级窗口。 (此消息不能直接发送到窗口。)要将
WM_SETTINGCHANGE
消息发送到所有顶级窗口,请使用
SendMessageTimeout
函数,并将
hwnd
参数设置为
HWND_BROADCAST

很好,至少你已经把那部分做好了。下一个任务是编写代码来实际调用该函数并广播消息。比如:

Public Shared ReadOnly HWND_BROADCAST As New IntPtr(&HFFFF)
Public Const WM_SETTINGCHANGE As Integer = &H001A

<Flags()> _
Public Enum SendMessageTimeoutFlags
    SMTO_NORMAL = 0
    SMTO_BLOCK = 1
    SMTO_ABORTIFHUNG = 2
    SMTO_NOTIMEOUTIFNOTHUNG = 8
End Enum  

Public Sub BroadcastChangeMessage()
    Dim returnValue As IntPtr = SendMessageTimeout(HWND_BROADCAST,
                                                   WM_SETTINGCHANGE,
                                                   IntPtr.Zero,
                                                   IntPtr.Zero,
                                                   SendMessageTimeoutFlags.SMTO_ABORTIFHUNG Or SendMessageTimeoutFlags. SMTO_NOTIMEOUTIFNOTHUNG,
                                                   5000,
                                                   IntPtr.Zero)
    If returnValue = IntPtr.Zero Then
        MessageBox.Show("Something went wrong and the function failed. Error code: " _
                        & Marshal.GetLastWin32Error().ToString())
    End If
End Sub

请注意,我正在检查

SendMessageTimeout
函数的返回值。我忘记了当您指定
HWND_BROADCAST
以及是否收到有意义的错误代码时它是如何工作的,但总是值得检查成功或失败。

© www.soinside.com 2019 - 2024. All rights reserved.