added samples
[windows-sources.git] / sdk / samples / WPFSamples / FragmentProvider / visualbasic / listfragment.vb
blob20b6bc288378499852974fd40b7230d5eb9a5734
1 '************************************************************************************************
3 ' File: ListFragment.vb
5 ' Description: Implements a UI Automation provider for a custom list control.
6 '
7 ' See ProviderForm.cs for a full description of this sample.
8 '
9 '
10 ' This file is part of the Microsoft Windows SDK Code Samples.
12 ' Copyright (C) Microsoft Corporation. All rights reserved.
14 ' This source code is intended only as a supplement to Microsoft
15 ' Development Tools and/or on-line documentation. See these other
16 ' materials for detailed information regarding Microsoft code samples.
18 ' THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
19 ' KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20 ' IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
21 ' PARTICULAR PURPOSE.
23 '***********************************************************************************************
25 Imports System
26 Imports System.Collections.Generic
27 Imports System.Text
28 Imports System.Drawing
29 Imports System.Windows.Forms
30 Imports System.Windows.Automation.Provider
31 Imports System.Windows.Automation
32 Imports System.Collections
33 Imports System.Threading
38 Public Class ListProvider
39 Implements IRawElementProviderFragmentRoot, ISelectionProvider
40 ' Control that contains the list.
41 Private OwnerListControl As CustomListControl
42 ' Window handle of the control.
43 Private WindowHandle As IntPtr
46 ''' <summary>
47 ''' Constructor
48 ''' </summary>
49 ''' <param name="control">
50 ''' The control for which this object is providing UI Automation functionality.
51 ''' </param>
52 Public Sub New(ByVal control As CustomListControl)
53 OwnerListControl = control
54 WindowHandle = control.Handle
56 End Sub 'New
58 #Region "IRawElementProviderSimple Members"
61 ''' <summary>
62 ''' Retrieves the object that supports the specified control pattern.
63 ''' </summary>
64 ''' <param name="patternId">The pattern identifier</param>
65 ''' <returns>
66 ''' The supporting object, or null if the pattern is not supported.
67 ''' </returns>
68 Public Function GetPatternProvider(ByVal patternId As Integer) As Object _
69 Implements IRawElementProviderFragment.GetPatternProvider
70 If patternId = SelectionPatternIdentifiers.Pattern.Id Then
71 Return Me
72 End If
73 Return Nothing
75 End Function 'GetPatternProvider
79 ''' <summary>
80 ''' Gets provider property values.
81 ''' </summary>
82 ''' <param name="propertyId">The property identifier.</param>
83 ''' <returns>The value of the property.</returns>
84 Public Function GetPropertyValue(ByVal propertyId As Integer) As Object _
85 Implements IRawElementProviderFragment.GetPropertyValue
87 If propertyId = AutomationElementIdentifiers.ControlTypeProperty.Id Then
88 Return ControlType.List.Id
89 ' It is necessary to supply a value for IsKeyboardFocusable in a Windows Forms control,
90 ' because this value cannot be discovered by the HWND host provider. This is not
91 ' necessary for a Win32 provider.
92 ElseIf propertyId = AutomationElementIdentifiers.IsKeyboardFocusableProperty.Id Then
93 Return True
94 ElseIf propertyId = AutomationElementIdentifiers.FrameworkIdProperty.Id Then
95 Return "Custom"
96 End If
97 Return Nothing
99 End Function 'GetPropertyValue
101 ''' <summary>
102 ''' Gets the host provider.
103 ''' </summary>
104 ''' <remarks>
105 ''' Fragment roots return their window providers; most others return null.
106 ''' </remarks>
108 ReadOnly Property HostRawElementProvider() As IRawElementProviderSimple _
109 Implements IRawElementProviderSimple.HostRawElementProvider
111 Return AutomationInteropProvider.HostProviderFromHandle(WindowHandle)
112 End Get
113 End Property
115 ''' <summary>
116 ''' Gets provider options.
117 ''' </summary>
118 ReadOnly Property ProviderOptions() As ProviderOptions _
119 Implements IRawElementProviderSimple.ProviderOptions
121 Return ProviderOptions.ServerSideProvider
122 End Get
123 End Property
125 #End Region
126 Private Members As IRawElementProviderSimple
129 #Region "IRawElementProviderFragment Members" '
131 ''' <summary>
132 ''' Gets the bounding rectangle.
133 ''' </summary>
134 ''' <remarks>
135 ''' Fragment roots should return an empty rectangle. UI Automation will get the rectangle
136 ''' from the host control (the HWND in this case).
137 ''' </remarks>
138 Public ReadOnly Property BoundingRectangle() As System.Windows.Rect _
139 Implements IRawElementProviderFragment.BoundingRectangle
142 Return System.Windows.Rect.Empty
143 End Get
144 End Property
146 ''' <summary>
147 ''' Gets the root of this fragment.
148 ''' </summary>
150 Public ReadOnly Property FragmentRoot() As IRawElementProviderFragmentRoot _
151 Implements IRawElementProviderFragment.FragmentRoot
153 Return Me
154 End Get
155 End Property
158 ''' <summary>
159 ''' Gets any fragment roots that are embedded in this fragment.
160 ''' </summary>
161 ''' <returns>Null in this case.</returns>
162 Public Function GetEmbeddedFragmentRoots() As IRawElementProviderSimple() _
163 Implements IRawElementProviderFragment.GetEmbeddedFragmentRoots
165 Return Nothing
166 End Function 'GetEmbeddedFragmentRoots
169 ''' <summary>
170 ''' Gets the runtime identifier of the UI Automation element.
171 ''' </summary>
172 ''' <returns>Fragment roots return null.</returns>
173 Public Function GetRuntimeId() As Integer() _
174 Implements IRawElementProviderFragmentRoot.GetRuntimeId
176 Return Nothing
177 End Function 'GetRuntimeId
180 ''' <summary>
181 ''' Navigates to adjacent elements in the UI Automation tree.
182 ''' </summary>
183 ''' <param name="direction">Direction of navigation.</param>
184 ''' <returns>The element in that direction, or null.</returns>
185 ''' <remarks>The provider only returns directions that it is responsible for.
186 ''' UI Automation knows how to navigate between HWNDs, so only the custom item
187 ''' navigation needs to be provided.
188 '''</remarks>
189 Public Function Navigate(ByVal direction As NavigateDirection) _
190 As IRawElementProviderFragment _
191 Implements IRawElementProviderFragment.Navigate
193 If direction = NavigateDirection.FirstChild Then
194 Return GetProviderForIndex(0)
195 ElseIf direction = NavigateDirection.LastChild Then
196 Return GetProviderForIndex((OwnerListControl.ItemCount - 1))
197 End If
198 Return Nothing
200 End Function 'Navigate
203 ''' <summary>
204 ''' Responds to a client request to set the focus to this control.
205 ''' </summary>
206 ''' <remarks>Setting focus to the control is handled by the parent window.</remarks>
207 Public Sub SetFocus() _
208 Implements IRawElementProviderFragment.SetFocus
210 Throw New Exception("The method is not implemented.")
211 End Sub 'SetFocus
213 #End Region
216 #Region "IRawElementProviderFragmentRoot Members"
218 Private Delegate Function PointToClientDelegate(ByVal point As System.Drawing.Point) As System.Drawing.Point
220 ''' <summary>
221 ''' Gets the child element at the specified point.
222 ''' </summary>
223 ''' <param name="x">Distance from the left of the application window.</param>
224 ''' <param name="y">Distance from the top of the application window.</param>
225 ''' <returns>The provider for the element at that point.</returns>
226 Public Function ElementProviderFromPoint(ByVal x As Double, ByVal y As Double) _
227 As IRawElementProviderFragment _
228 Implements IRawElementProviderFragmentRoot.ElementProviderFromPoint
230 Dim index As Integer = -1
231 Dim screenPoint As System.Drawing.Point = New System.Drawing.Point(CInt(x), CInt(y))
233 ' Call PointToClient by delegation to avoid clashing with UI thread.
234 Dim conversionDelegate As PointToClientDelegate = _
235 New PointToClientDelegate(AddressOf OwnerListControl.PointToClient)
236 Dim result As Object = OwnerListControl.Invoke(conversionDelegate, screenPoint)
237 Dim clientPoint As System.Drawing.Point = CType(result, System.Drawing.Point)
239 index = OwnerListControl.ItemIndexFromPoint(clientPoint)
240 If index = -1 Then
241 Return Nothing
242 End If
243 Return GetProviderForIndex(index)
244 End Function 'ElementProviderFromPoint
248 ''' <summary>
249 ''' Returns the child element that is selected when the list gets focus.
250 ''' </summary>
251 ''' <returns>The selected item.</returns>
252 Function GetFocus() As IRawElementProviderFragment _
253 Implements IRawElementProviderFragmentRoot.GetFocus
255 Dim index As Integer = OwnerListControl.SelectedIndex
256 Return GetProviderForIndex(index)
257 End Function 'IRawElementProviderFragmentRoot.GetFocus
259 #End Region
261 #Region "ISelectionProvider Members" '
263 ''' <summary>
264 ''' Specifies whether selection of more than one item at a time is supported.
265 ''' </summary>
267 Public ReadOnly Property CanSelectMultiple() As Boolean _
268 Implements ISelectionProvider.CanSelectMultiple
271 Return False
272 End Get
273 End Property
276 ''' <summary>
277 ''' Returns the UI Automation provider for the selected list items.
278 ''' </summary>
279 ''' <returns>The selected items.</returns>
280 ''' <remarks>Because this is a single-selection list box,
281 ''' only one item is returned.</remarks>
282 Public Function GetSelection() As IRawElementProviderSimple() _
283 Implements ISelectionProvider.GetSelection
285 Dim index As Integer = OwnerListControl.SelectedIndex
286 Return New IRawElementProviderSimple() {GetProviderForIndex(index)}
288 End Function 'GetSelection
290 ''' <summary>
291 ''' Specifies whether the list must have an item selected at all times.
292 ''' </summary>
293 ''' <returns>True if selection is required.</returns>
294 Public ReadOnly Property IsSelectionRequired() As Boolean _
295 Implements ISelectionProvider.IsSelectionRequired
298 Return True
299 End Get
300 End Property
302 #End Region
304 #Region "Helper methods"
306 ''' <summary>
307 ''' Gets the UI Automation provider for the item at the specified index.
308 ''' </summary>
309 ''' <param name="index">Index of the item.</param>
310 ''' <returns>The provider object, or null if the index is out of range.</returns>
311 Public Function GetProviderForIndex(ByVal index As Integer) _
312 As IRawElementProviderFragment
314 Dim OwnerCustomListItemCount As Integer = OwnerListControl.ItemCount - 1
315 If index < 0 OrElse index > OwnerCustomListItemCount Then
316 Return Nothing
317 End If
318 Return CType(Me.OwnerListControl.GetItem(index).Provider, IRawElementProviderFragment)
319 End Function 'GetProviderForIndex
321 #End Region
323 #Region "UI Automation Event Handlers"
325 ''' <summary>
326 ''' Responds to a focus change by raising an event.
327 ''' </summary>
328 ''' <param name="listItem">The item that has received focus.</param>
329 Public Shared Sub OnFocusChange(ByVal listItem As CustomListItem)
331 If AutomationInteropProvider.ClientsAreListening Then
332 Dim args As New AutomationEventArgs( _
333 AutomationElementIdentifiers.AutomationFocusChangedEvent)
334 AutomationInteropProvider.RaiseAutomationEvent( _
335 AutomationElementIdentifiers.AutomationFocusChangedEvent, _
336 listItem.Provider, args)
337 End If
339 End Sub 'OnFocusChange
341 ''' <summary>
342 ''' Responds to a selection change by raising an event.
343 ''' </summary>
344 ''' <param name="listItem">The item that has been selected.</param>
345 Public Shared Sub OnSelectionChange(ByVal listItem As CustomListItem)
346 If AutomationInteropProvider.ClientsAreListening Then
347 Dim args As New AutomationEventArgs( _
348 SelectionItemPatternIdentifiers.ElementSelectedEvent)
349 AutomationInteropProvider.RaiseAutomationEvent( _
350 SelectionItemPatternIdentifiers.ElementSelectedEvent, _
351 listItem.Provider, args)
352 End If
354 End Sub 'OnSelectionChange
357 ''' <summary>
358 ''' Responds to an addition to the UI Automation tree structure by raising an event.
359 ''' </summary>
360 ''' <param name="list">
361 ''' The list to which the item was added.
362 ''' </param>
363 ''' <remarks>
364 ''' For the runtime Id of the item, pass 0 because the provider cannot know
365 ''' what its actual runtime Id is.
366 ''' </remarks>
367 Public Shared Sub OnStructureChangeAdd(ByVal list As CustomListControl)
368 If AutomationInteropProvider.ClientsAreListening Then
369 Dim fakeRuntimeId(1) As Integer
370 fakeRuntimeId(0) = 0
371 Dim args As New StructureChangedEventArgs( _
372 StructureChangeType.ChildrenBulkAdded, fakeRuntimeId)
373 AutomationInteropProvider.RaiseStructureChangedEvent( _
374 CType(list.Provider, IRawElementProviderSimple), args)
375 End If
377 End Sub 'OnStructureChangeAdd
380 ''' <summary>
381 ''' Responds to a removal from the UI Automation tree structure by raising an event.
382 ''' </summary>
383 ''' <param name="list">
384 ''' The list from which the item was removed.
385 ''' </param>
386 ''' <remarks>
387 ''' For the runtime Id of the list, pass 0 because the provider cannot know
388 ''' what its actual runtime ID is.
389 ''' </remarks>
390 Public Shared Sub OnStructureChangeRemove(ByVal list As CustomListControl)
391 If AutomationInteropProvider.ClientsAreListening Then
392 Dim fakeRuntimeId(1) As Integer
393 fakeRuntimeId(0) = 0
394 Dim args As New StructureChangedEventArgs( _
395 StructureChangeType.ChildrenBulkRemoved, fakeRuntimeId)
396 AutomationInteropProvider.RaiseStructureChangedEvent( _
397 CType(list.Provider, IRawElementProviderSimple), args)
398 End If
400 End Sub 'OnStructureChangeRemove
402 #End Region
404 End Class 'ListProvider