Ve své aplikaci potřebuji výstup z jiné externí aplikace, takže se snažím tuto externí aplikaci vzdáleně ovládat (klikat na její tlačítka, posílat klávesové zkratky,...). Zatím jsem zvládl udělení fokusu té externí aplikaci, poslání klávesových zkratek pro vyvolání dialogu i stisk tlačítek v tom dialogu. Takto nějak může vypadat kód:
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> Private Shared Function FindWindowEx(ByVal parentHandle As IntPtr, ByVal childAfter As IntPtr, ByVal lclassName As String, ByVal windowTitle As String) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr
End Function
Public Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hwnd As Integer) As Integer
Public Declare Auto Function FindWindow Lib "user32.dll" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
Public Declare Function IsIconic Lib "user32.dll" (ByVal hwnd As Integer) As Boolean
Public Declare Function ShowWindow Lib "user32.dll" (ByVal hwnd As Integer, ByVal nCmdShow As Integer) As Integer
Public Const SW_RESTORE As Integer = 9
Public Const SW_SHOW As Integer = 5
Const BM_CLICK As Integer = &HF5
Private MaximCaption As String
Sub FocusWindow(ByVal strWindowCaption As String, ByVal strClassName As String)
Dim hWnd As Integer
hWnd = FindWindow(strClassName, strWindowCaption)
If hWnd > 0 Then
SetForegroundWindow(hWnd)
If IsIconic(hWnd) Then 'Restore if minimized
ShowWindow(hWnd, SW_RESTORE)
Else
ShowWindow(hWnd, SW_SHOW)
End If
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
For Each p As Process In Process.GetProcesses
If p.MainWindowTitle = String.Empty = False Then
'lstMain.Items.Add(p.ProcessName & " # " & p.MainWindowTitle & " # " & p.Id)
If InStr(p.MainWindowTitle, "MaxIm") Then
MaximCaption = p.MainWindowTitle
End If
End If
Next
FocusWindow(MaximCaption, Nothing)
SendKeys.Send("%(A)")
SendKeys.Send("{a}")
System.Windows.Forms.Application.DoEvents()
' ''stisk tlacitka Process v PinPoint okne
Dim hParent As IntPtr = FindWindowEx(IntPtr.Zero, hParent, "#32770", "PinPoint Astrometry")
If Not hParent.Equals(IntPtr.Zero) Then
Dim hChild As IntPtr = FindWindowEx(hParent, hChild, "Button", "P&rocess")
If Not hChild.Equals(IntPtr.Zero) Then
SendMessage(hChild, BM_CLICK, 0, 0)
Else
MessageBox.Show("Child Window Not Found")
End If
Else
MessageBox.Show("Main Window Not Found")
End If
End Sub
End Class
Po stisknutí Button1 se žádané okno stane aktivním, vyšlu na něj dvě klávesová zkratky pro vyvolání dialogu, ale toto vyvolání dialogu neproběhne, pokud z kódu neodstraním tu část začínající 'stisk tlacitka Process v PinPoint okne (má provést stisk jednoho tlačítka v tom dialogu). Když tu část kódu pro stisk tlačítka v tom dialogu odstraním, tak se dialog zobrazí, pokud tam tu část kód nechám, tak se dialog neotevře a celé to skončí tím MessageBox.Show("Main Window Not Found") , protože se to dialogové okno neotevřelo. Pro mě naprosto nepochopitelné, jako kdyby ta část pro stisk tlačítka proběhla dříve, než se zobrazí ten dialog. Pokud si pokusně udělám dvě aplikace, kdy jedna otevře externí aplikaci, vyšle klávesové zkratky pro vyvolání dialogu a druhou, která jen klikne ta to jedno tlačítko, tak to funguje obojí tak, jak chci, ale pokud tyto dvě samostatné aplikace složím v jednu (viz ten horní kód), tak to prostě nejede. Můžete se někdo podívat na ten kód, v čem by mohl být problém?
|