2

サードパーティ製のVb.netアプリケーションがあります。これは、シミュレートされた環境からの外部リソースの使用を制御する必要があり、デスクトップと対話してはなりません。ユーザーが通常、特定のキーが周囲にある特別な画面から入力する入力をシミュレートするために、テストコントロールライブラリを構築して、それを制御し、フォームイメージを.bmpに送信します。フォームを表示してタスクバーに表示することはできません。bmp出力はシミュレートされた環境によって表示されます。

PostMessageとsendKeysの使用は、メインフォームでShowInTaskbar = Falseを使用しない限り、うまく機能します。多くの読み取りとテストを行った後、私は、機能する唯一のものと思われるものを試すのに十分なことを学びました。HWND_MESSAGEパラメーターを使用して親として設定したフォームを作成しました。これにより、postMessageを受信することになっているメッセージ専用Windowsが作成され、そのイベントがサブクラス化されます。msdn

StackOverflowはすでにこれについて

残念ながら、私はそれを機能させることができないようで、誰かが私が間違っていることを教えてくれることを望んでいました。私は.netについてウェブ全体で見つけたいくつかの異なる方法をテストしていて、メッセージに入ることができませんでしたスレッドのピークとフィード(多分(多分)私の最後の希望)、タスクバーからフォームを取り出すまで、それらはすべて機能しているようです。

わかりました、ここにコードがあります:

MsgOnly.vb

Public Class MsgHandling

DllImport( "user32.dll"、SetLastError:= True、CharSet:= CharSet.Auto)> _ Public Shared Function SetParent(ByVal hWndChild As IntPtr、ByVal hWndNewParent As IntPtr)As IntPtr End Function

プライベート共有HWND_MESSAGEAsIntPtr = New 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

今のところ、他にどのような詳細を提供できるのかよくわかりません。私が見つけていないアイデアや方法として誰か?

ご入力いただきありがとうございます

4

1 に答える 1

2

回避策を見つけました。検索機能でウィンドウハンドルが見つからないことが問題のようです。いくつかの方法を試しましたが、メッセージのみが列挙されていないため、ループできないか、少なくとも成功しませんでした。

そこで、外部プログラムが読み取るハンドルを使用してファイルを作成し、そのハンドルを使用してPostMessageを作成します。これは今のところうまく機能します。もっと良い方法を見つけられたらいいのにと思いますが、少なくとも解決策として提案できることがあります。

私はまだ提案や他の可能な回避策を開いています:)。

于 2010-11-19T17:18:27.723 に答える