2011-04-22 46 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.

相关问题