Visual Studio 2017 pro 15.7.5 .Net FrameWork 4.7.1
导入的名称空间:**
System.Windows.Automation
参考组件**:
UIAutomationClient UIAutomationTypes MainForm代码:
Imports System.Diagnostics
Imports System.Windows
Imports System.Windows.Automation
Public Class MainForm
Friend GlobalHandlerEnabled As Boolean = False
Protected Friend FormsHandler As List(Of Form) = New List(Of Form)
Protected Friend ResizeHandler As EventHandler
Public Sub New()
InitializeComponent()
ResizeHandler =
Sub(obj, args)
Dim CurrentForm As Form = TryCast(obj, Form)
CurrentForm.Text = CurrentForm.Text.Split({" ("}, StringSplitOptions.None)(0) &
$" ({CurrentForm.Width}, {CurrentForm.Height})"
End Sub
Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent,
AutomationElement.RootElement,
TreeScope.Subtree,
Sub(UIElm, evt)
If Not GlobalHandlerEnabled Then Return
Dim element As AutomationElement = TryCast(UIElm, AutomationElement)
If element Is Nothing Then Return
Dim NativeHandle As IntPtr = CType(element.Current.NativeWindowHandle, IntPtr)
Dim ProcessId As Integer = element.Current.ProcessId
If ProcessId = Process.GetCurrentProcess().Id Then
Dim CurrentForm As Form = Nothing
Invoke(New MethodInvoker(
Sub()
CurrentForm = Application.OpenForms.
OfType(Of Form)().
FirstOrDefault(Function(f) f.Handle = NativeHandle)
End Sub))
If CurrentForm IsNot Nothing Then
Dim FormName As String = FormsHandler.FirstOrDefault(Function(f) f?.Name = CurrentForm.Name)?.Name
If Not String.IsNullOrEmpty(FormName) Then
RemoveHandler CurrentForm.Resize, ResizeHandler
FormsHandler.Remove(FormsHandler.Where(Function(fn) fn.Name = FormName).First())
End If
Invoke(New MethodInvoker(
Sub()
CurrentForm.Text = CurrentForm.Text & $" ({CurrentForm.Width}, {CurrentForm.Height})"
End Sub))
AddHandler CurrentForm.Resize, ResizeHandler
FormsHandler.Add(CurrentForm)
End If
End If
End Sub)
End Sub
Private Sub btnOpenForm_Click(sender As Object, e As EventArgs) Handles btnOpenForm.Click
Form2.Show(Me)
End Sub
Private Sub btnEnableHandlers_Click(sender As Object, e As EventArgs) Handles btnEnableHandlers.Click
GlobalHandlerEnabled = True
Me.Hide()
Me.Show()
End Sub
Private Sub btnDisableHandlers_Click(sender As Object, e As EventArgs) Handles btnDisableHandlers.Click
GlobalHandlerEnabled = False
If FormsHandler IsNot Nothing Then
For Each Item As Form In FormsHandler
RemoveHandler Item.Resize, ResizeHandler
Item = Nothing
Next
End If
FormsHandler = New List(Of Form)
Me.Text = Me.Text.Split({" ("}, StringSplitOptions.RemoveEmptyEntries)(0)
End Sub
End Class
注:**
之前的代码放置在应用程序起始窗体中(用于测试),但最好在需要时将模块包含在项目中,而不触及当前代码。 要使其正常工作,请添加一个包含Public Sub Main()的新模块(名为Program),并更改Project属性以从Sub Main()启动应用程序,而不是从Form启动。 删除Use Application Framework上的复选标记,然后从Startup object组合框中选择Sub Main。 所有代码都可以通过几处修改传输到Sub Main proc:
Imports System
Imports System.Diagnostics
Imports System.Windows
Imports System.Windows.Forms
Imports System.Windows.Automation
Module Program
Friend GlobalHandlerEnabled As Boolean = True
Friend FormsHandler As List(Of Form) = New List(Of Form)
Friend ResizeHandler As EventHandler
Public Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Dim MyMainForm As MainForm = New MainForm()
ResizeHandler =
Sub(obj, args)
Dim CurrentForm As Form = TryCast(obj, Form)
CurrentForm.Text = CurrentForm.Text.Split({" ("}, StringSplitOptions.None)(0) &
$" ({CurrentForm.Width}, {CurrentForm.Height})"
End Sub
Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent,
AutomationElement.RootElement,
TreeScope.Subtree,
Sub(UIElm, evt)
If Not GlobalHandlerEnabled Then Return
Dim element As AutomationElement = TryCast(UIElm, AutomationElement)
If element Is Nothing Then Return
Dim NativeHandle As IntPtr = CType(element.Current.NativeWindowHandle, IntPtr)
Dim ProcessId As Integer = element.Current.ProcessId
If ProcessId = Process.GetCurrentProcess().Id Then
Dim CurrentForm As Form = Nothing
If Not MyMainForm.IsHandleCreated Then Return
MyMainForm.Invoke(New MethodInvoker(
Sub()
CurrentForm = Application.OpenForms.
OfType(Of Form)().
FirstOrDefault(Function(f) f.Handle = NativeHandle)
End Sub))
If CurrentForm IsNot Nothing Then
Dim FormName As String = FormsHandler.FirstOrDefault(Function(f) f?.Name = CurrentForm.Name)?.Name
If Not String.IsNullOrEmpty(FormName) Then
RemoveHandler CurrentForm.Resize, ResizeHandler
FormsHandler.Remove(FormsHandler.Where(Function(fn) fn.Name = FormName).First())
End If
AddHandler CurrentForm.Resize, ResizeHandler
FormsHandler.Add(CurrentForm)
CurrentForm.Invoke(New MethodInvoker(
Sub()
CurrentForm.Text = CurrentForm.Text & $" ({CurrentForm.Width}, {CurrentForm.Height})"
End Sub))
End If
End If
End Sub)
Application.Run(MyMainForm)
End Sub
End Module
2条答案
按热度按时间yiytaume1#
下面尝试实现一个针对该问题的Automation解决方案。
将一个或多个事件处理程序附加到项目中的每个现有窗体(或其子集),而无需编辑/修改这些类的现有代码。
UIAutomation提供了一种可能的解决方案,它提供了检测新窗口何时打开的方法,并在其AutomationEvent的
EventId
设置为WindowPattern模式时将事件报告给其自己的Automation.AddAutomationEventHandler的订阅者。AutomationElement成员必须设置为AutomationElement.RootElement,
Scope
成员必须设置为TreeScope.SubTree。Automation
针对引发AutomationEvent
的每个AutomationElement
报告:Element.Name
(对应于Windows标题)Process ID
Window Handle
(作为整数值)这些值足以标识属于当前进程的Window;窗口句柄允许识别打开的
Form
示例,测试Application.OpenForms()集合。当表单被选中时,可以将新的
Event Handler
附加到所选的Event
。通过扩展这个概念,可以创建预定义的事件列表和表单列表来附加这些事件。
如果需要,可以在项目中包含类文件。
需要注意的是,某些事件在此场景中没有意义,因为
Automation
报告的是窗口已打开,因此Load()
和Shown()
事件属于过去。我已经用几个事件(
Form.Resize()
和Form.Activate()
)对此进行了测试,但在这里的代码中,为了简单起见,我只使用.Resize()
。这是过程的图形表示。
启动应用程序时,事件处理程序未附加到
.Resize()
事件。这只是因为
Boolean
字段设置为False
。单击按钮,
Boolean
字段将设置为True
,从而启用事件处理程序的注册。注册
.Resize()
事件后,所有窗体的标题都将报告窗口的当前大小。Visual Studio 2017 pro 15.7.5
.Net FrameWork 4.7.1
System.Windows.Automation
UIAutomationClient
UIAutomationTypes
MainForm
代码:之前的代码放置在应用程序起始窗体中(用于测试),但最好在需要时将模块包含在项目中,而不触及当前代码。
要使其正常工作,请添加一个包含
Public Sub Main()
的新模块(名为Program
),并更改Project属性以从Sub Main()
启动应用程序,而不是从Form启动。删除
Use Application Framework
上的复选标记,然后从Startup object
组合框中选择Sub Main
。所有代码都可以通过几处修改传输到
Sub Main
proc:ryhaxcpt2#
您可以按照@Jimi的建议使用自动化。
您可以使用My.Application.OpenForms循环访问所有打开的窗体,但在打开新窗体时,它将没有帮助。
您可以创建一些继承System. Forms. Form的ReportSizeForm类,并将窗体的继承从常规System.Windows.Forms.Form更改为ReportSizeForm。