У меня есть приложение Vb.net, созданное третьей стороной, которое я должен контролировать, используя внешние ресурсы из имитируемой среды, и не должен взаимодействовать с рабочим столом. Чтобы имитировать входные данные, которые пользователь обычно вводил бы со специального экрана с определенными клавишами вокруг него, я создал библиотеку контрольных тестов, чтобы управлять им и отправлять изображение формы в .bmp. Форма не отображается и отображается на панели задач, вывод bmp будет отображаться в смоделированной среде.
Использование PostMessage и sendKeys работают хорошо, пока у меня нет, но ShowInTaskbar = False для основной формы. После многих чтений и испытаний я выучил достаточно, чтобы попробовать то, что, кажется, единственное, что сработало бы. Я создал форму, которую я установил, используя параметр HWND_MESSAGE, это должно создать Windows только для сообщений, которая должна получать postMessage, и подклассить ее события. msdn .
StackOverflow уже об этом
К сожалению, я не могу заставить его работать, и я надеялся, что кто-нибудь скажет мне, что я делаю неправильно. Я тестировал несколько различных способов, найденных в Интернете, по поводу .net, и если не считать зайдя в ветку сообщений заглянуть и кормить (может быть (может быть) моя последняя надежда), они все, кажется, работают, пока я не заберу формы из панели задач.
Хорошо, вот код:
MsgOnly.vb
Public Class MsgHandling
DllImport ("user32.dll", SetLastError: = True, CharSet: = CharSet.Auto)> _
Открытая общая функция SetParent (ByVal hWndChild As IntPtr,
ByVal hWndNewParent As IntPtr) Как
IntPtr
Конечная функция
Частный общий HWND_MESSAGE As IntPtr = Новый IntPtr (-3)
Public Event CallBackProc(ByRef m As Message)
Public Sub setParent()
SetParent(Me.Handle, HWND_MESSAGE)
End Sub
Protected Overrides Sub WndProc(ByRef m As Message)
RaiseEvent CallBackProc(m) 'then RaiseEvent
MyBase.WndProc(m)
End Sub
End Class
Подклассы частей в форме (Не могу показать больше, чем то, что обрабатывает подклассы, вопросы конфиденциальности. Надеюсь, этого будет достаточно)
Public WithEvents Msg As New MsgHandling
Private Sub XXXXX_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'----snips
Msg.setParent()
'----snips
end sub
Private Sub CallBackProc(ByRef m As System.Windows.Forms.Message) Handles Msg.CallBackProc
Me.Text = "Rx events " & m.LParam.ToString() & " " & m.WParam.ToString()
WndProc(m)
End Sub
Форма теста
Public Class Form1
<DllImport("user32.dll")> _
Private Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Private Shared Function FindWindow( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As IntPtr
End Function
Public Shared Function SetWindowPos( _
ByVal hWnd As IntPtr, _
ByVal hWndInsertAfter As IntPtr, _
ByVal X As Int32, _
ByVal Y As Int32, _
ByVal cy As Int32, _
ByVal uFlags As Int32) _
As Boolean
End Function
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Private Declare Function AllowSetForegroundWindow Lib "user32" Alias "AllowSetForegroundWindow" (ByVal dwProcessId As Integer) As Boolean
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
Public myProcess As Process = New Process()
Private Const WM_KEYDOWN As Long = 100
Private Const WM_RBUTTONDOWN As Long = 204
Public Shared HWND_MESSAGE As IntPtr = New IntPtr(-3)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
myProcess.StartInfo.FileName = "...\XXXXXX.exe" 'Not real name
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal
myProcess.EnableRaisingEvents = True
AddHandler myProcess.Exited, AddressOf Me.SendKeysTestExited
myProcess.Start()
End Sub
Friend Sub SendKeysTestExited(ByVal sender As Object, _
ByVal e As System.EventArgs)
Dim myRxProcess As Process = DirectCast(sender, Process)
myRxProcess.Close()
End Sub
Private Sub Form1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
Dim tHwnd As Long
Dim rslt As Boolean
If myProcess.Responding Then
tHwnd = FindWindowEx(HWND_MESSAGE, 0, 0, 0)
PostMessage(HWND_MESSAGE, WM_RBUTTONDOWN, 0, "TEXT TO SEND")
Else
myProcess.Kill()
End If
End Sub
Private Sub Form1_FormClosed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
myProcess.Close()
End Sub
End Class
Не совсем уверен, какие еще детали я могу предоставить сейчас. У кого-нибудь есть идеи или способы, которые я не нашел?
Спасибо за любой ввод