基本上:我想要一个用于VB.NET的sendmessage和sendmessagetimeout 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
等等,他们似乎没有工作。
所以我想知道任何关于发送消息的APIS和/或sendmessagetimeout你知道的那项工作!如果这些函数的VB.net没有正确的API,我可以使用哪些替代函数来完成与那些2相同的任务?
提前感谢您提供的任何信息:)
编辑:
或者我可能不正确地发送消息,所以只是为了确保不应该是问题:
我想发送WM_WININICHANGE,所以我正在使用:
但是我已经尝试过wparam和lparam的其他值,通常没有区别。在尝试sendmessagetimeout时,我也使用:
答案 0 :(得分:3)
是的,第一个是正确的。不要使用旧式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
消息发送到所有顶级窗口,请使用hwnd
函数并将HWND_BROADCAST
参数设置为{{1} }。
很好,至少你已经有了这个部分。下一步的业务是编写代码以实际调用该函数并广播该消息。类似的东西:
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
并且你得到一个有意义的错误代码时,我完全忘记它是如何工作的,但总是值得检查成功或失败。