我正在使用 Windows Messages API在两个Windows窗体应用程序之间进行通信.我拿出了一个表单,该表单是应用程序的一部分,并将其放入自己的应用程序中,以便在加载时,用户仍然可以在一个单独
我需要能够在两个应用程序之间进行通信,以便现在单独的应用程序表单可以告诉主应用程序打开什么.
我在主应用程序的主窗体上使用此代码,它工作得很好…除非主窗体没有焦点.
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) Try Select Case m.Msg Case &H400 BS.BuildString(m.LParam) Case Else MyBase.WndProc(m) End Select Catch ex As Exception End Try End Sub
我之前从未使用过Windows Message API,我只是通过查找表单之间的通信来抓住这个,所以我是新手.通过做更多研究我知道的是我需要一个仅消息窗口来处理消息.我不明白该怎么做.
我看了一些像this one这样的文章和解决方案,我认为我遇到的问题是我不知道如何实现它.
编辑1
以下是第二个应用程序查找和发送到主应用程序的方式.
'used to send a message using SendMessage API to the 'main app to open the ID Private WithEvents BS As New BuildString 'get this running process Dim proc As Process = Process.GetCurrentProcess() 'get all other (possible) running instances Dim processes As Process() = Process.GetProcessesByName("ProcessName") If processes.Length > 0 Then 'iterate through all running target applications For Each p As Process In processes 'now send the ID to the running instance of the main app BS.PostString(p.MainWindowHandle, &H400, 0, "ID:" & ID) Next Else MessageBox.Show("Main application not running") End If
这是两个应用程序中BuildString的类.
Imports System.Text Public Class BuildString Private Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer Public Event StringOK(ByVal Result As String) Private hwnd As Integer = 0 Private wMsg As Integer = 0 Private wParam As Integer = 0 Private lParam As String = "" Private tempA(-1) As Byte Private enc As Encoding = Encoding.UTF8 Public Property Encode() As Encoding Get Return enc End Get Set(ByVal value As Encoding) enc = value End Set End Property Public Sub BuildString(ByVal b As IntPtr) If b <> 0 Then 'build temp array Dim tempB(tempA.Length) As Byte tempA.CopyTo(tempB, 0) tempB(tempA.Length) = b ReDim tempA(tempB.Length - 1) tempB.CopyTo(tempA, 0) Else 'decode byte array to string Dim s As String If enc Is Encoding.UTF8 Then s = Encoding.UTF8.GetString(tempA) ElseIf enc Is Encoding.Unicode Then s = Encoding.Unicode.GetString(tempA) ElseIf enc Is Encoding.ASCII Then s = Encoding.ASCII.GetString(tempA) Else s = Encoding.Default.GetString(tempA) End If 'send out result string via event RaiseEvent StringOK(s) ReDim tempA(-1) End If End Sub Public Sub PostString(ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) Me.hwnd = hwnd Me.wMsg = wMsg Me.wParam = wParam Me.lParam = lParam 'create a new thread to post window message Dim t As Threading.Thread t = New Threading.Thread(AddressOf SendString) t.Start() End Sub Private Sub SendString() 'create byte array Dim ba() As Byte 'encode string to byte array If enc Is Encoding.UTF8 Then ba = Encoding.UTF8.GetBytes(lParam) ElseIf enc Is Encoding.Unicode Then ba = Encoding.Unicode.GetBytes(lParam) ElseIf enc Is Encoding.ASCII Then ba = Encoding.ASCII.GetBytes(lParam) Else ba = Encoding.Default.GetBytes(lParam) End If Dim i As Integer For i = 0 To ba.Length - 1 'start post message PostMessage(hwnd, wMsg, wParam, ba(i)) Next 'post a terminator message to destination window PostMessage(hwnd, wMsg, wParam, 0) End Sub
结束班
以下是在解码消息后运行的主应用程序上的代码.
Private Sub SB_StringOK(ByVal Result As String) Handles BS.StringOK Dim sArray() As String = Result.Split(";") 'rest of the code to open the ID End Sub感谢@JustinRyan我用 FindWindow想出来了.
我将此添加到我发送消息的第二个应用程序中.
Private Declare Function FindWindow1 Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
我没有找到应用程序进程,而是找到了我想要的窗口,并在发送消息中将其直接发送给它.
Dim parenthwnd As Integer = FindWindow1(Nothing, "Form Name") BS.PostString(parenthwnd, &H400, 0, "ID:" & ID)
它就像我需要的那样工作.
由于答案在评论中,我不确定如何显示正确的答案.请让我知道在这种情况下的正确礼仪,以给予用户应有的信誉.