2011-04-22 76 views
0

我的問題可能不是很清楚,但我只是想知道如何調用此過程或創建類似的引用,所以我可以自己調查(但如果你有代碼是歡迎.. LOL ...)創建一個服務來執行一個屏幕後,在不同的EXE(VB.NET)打開一個屏幕

基本上我有2個桌面程序(A和B)。對於A,我沒有源代碼,因爲B我有。我需要的是創建一些服務/程序,在程序A彈出一個屏幕後,自動運行B.換句話說,捕獲A顯示特定屏幕的時刻並執行B.

我的現實生活場景是我有一個非常基本的POS,我無法收集客戶的人口統計信息(郵政編碼等),所以我創建了第二個應用程序來捕獲,但我的收銀員總是忘記運行程序,我需要找到一種方法運行它顯示的畫面後(假設「更改由於」在POS,讓他們不要忘記運行它。

任何將勾縫可以理解!

感謝

回答

3

所以這裏的你如何能做到這與VB應該是很容易的,如果需要轉換爲C#一個很簡單的例子。代碼按標題搜索可見窗口。如果你打開的窗口沒有標題,你將不得不多做一些工作。您大概可以找到您的主應用程序的標題,並枚舉其子窗口。

首先,一些非託管代碼交談的Win32直接:

Option Strict On 
Option Explicit On 

Imports System.Runtime.InteropServices 
Imports System.Text 

Public Class Unmanaged 
    <DllImport("user32.dll")> 
    Public Shared Function EnumWindows(ByVal lpEnumFunc As CallBack, ByVal lParam As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean 
    End Function 
    <DllImport("user32.dll", SetLastError:=True)> 
    Public Shared Function GetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer) As Integer 
    End Function 
    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _ 
    Public Shared Function GetWindowText(ByVal hwnd As IntPtr, ByVal lpString As StringBuilder, ByVal cch As Integer) As Integer 
    End Function 
    <DllImport("user32.dll", SetLastError:=True)> _ 
    Public Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean 
    End Function 

    Public Const SW_SHOW = 5 
    Public Const SW_RESTORE = 9 
    Public Const GW_OWNER = 4 
    Public Const GWL_HWNDPARENT = (-8) 
    Public Const GWL_EXSTYLE = (-20) 
    Public Const WS_EX_TOOLWINDOW = &H80 
    Public Const WS_EX_APPWINDOW = &H40000 

    Public Delegate Function CallBack(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean 
End Class 

那麼應設置爲啓動對象非GUI模塊:

Option Explicit On 
Option Strict On 

Module Module1 
    ''//Code loosely base on http://msdntracker.blogspot.com/2008/03/list-currently-opened-windows-with.html 

    ''//This is the title of the window that we are looking for 
    Public ReadOnly WatchForTitle As String = "About Mozilla Firefox" 

    ''//This is the form that we will show when we find the above 
    Private MainForm As Form1 

    <STAThread()> 
    Public Sub Main() 
     ''//Create the form but don not show it 
     MainForm = New Form1() 

     ''//Create an infinite loop that checks to see if the target window is open and sleeps for a bit between checks 
     Do While True 
      Unmanaged.EnumWindows(AddressOf fEnumWindowsCallBack, IntPtr.Zero) 
      ''//Sleep for a bit 
      System.Threading.Thread.Sleep(500) 
     Loop 
    End Sub 

    Private Function fEnumWindowsCallBack(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean 
     ''//Ignore our own handle 
     If hwnd <> Form1.Handle Then 
      ''//Make sure its visible 
      If Unmanaged.IsWindowVisible(hwnd) Then 
       Dim lExStyle = Unmanaged.GetWindowLong(hwnd, Unmanaged.GWL_EXSTYLE) 

       ''//We probably want to ignore tool windows, but remove this if needed 
       If (((lExStyle And Unmanaged.WS_EX_TOOLWINDOW) = 0)) Then 

        ''//Create a buffer to store the title of the window 
        Dim sWindowText As New System.Text.StringBuilder(256) 

        ''//Get the title of the window 
        Dim lReturn = Unmanaged.GetWindowText(hwnd, sWindowText, sWindowText.Length - 1) 

        ''//When you are looking for window title uncomment this line 
        'Trace.WriteLine(sWindowText) 

        ''//Sanity check, make sure we found a window title 
        If lReturn <> 0 Then 
         ''//See if it matches what we are looking for 
         If sWindowText.ToString() = WatchForTitle Then 
          ''//If so, show our form 
          Form1.ShowDialog() 
         End If 
        End If 
       End If 
      End If 
     End If 
     fEnumWindowsCallBack = True 
    End Function 
End Module 

最後創建一個普通的Windows窗體稱爲Form1(或任何你想要的,你只需要在上面的模塊中改變它)。

如果你測試這個它會彈出,如果你去到Firefox的幫助 - >關於菜單打開窗體。

我應該指出,這只是一個開始。你會希望執行更好的錯誤檢查,並在程序關閉或存在時進行處理。

+0

+1,很好的答案。該OP也將需要的東西,以確保他們不會繼續顯示在對話框中一遍又一遍,而觸發窗口是可見的(這是我打擾張貼我的答案,你給了一個更詳細的一個之後的唯一原因).. 。 – forsvarir 2011-04-22 20:37:01

+0

@forsvarir,我使用'ShowDialoag'該塊,直到窗口駁回 – 2011-04-22 20:43:34

+0

非常感謝您!這是很棒的代碼。它爲我提供了我所需要的快速啓動。再次,謝謝! – chupeman 2011-04-26 15:49:07

0

與程序A交互的方式是不太可能的。不會有傳統的「事件」發生或者類似的事情。

你最好打賭就是看一些WIN32 API調用。例如,您可以使用GetPixel()將顏色返回到屏幕上的特定位置。因此,如果程序A顯示特定的圖像或屏幕與任何其他屏幕顯着不同,您可以編寫監視屏幕並檢查匹配的代碼。當發現匹配時,可以執行任何你想要的代碼,包括推出B.

相關問題