Throw an exception by getting the selected text via UIA

华 张 156 信誉分
2025-01-05T17:40:32.7033333+00:00

I have a.NET 8.0 WPF application that wants to get user-selected text through UIA, but an exception was thrown when retrieving words. Here is my code

private void MainWindow_Loaded(object sender, RoutedEventArgs e)

{

_mouseHook = new MouseHook();

_mouseHook.MouseDown += MouseHook_MouseDown;

_mouseHook.MouseUp += MouseHook_MouseUp;

_mouseHook.Register();

}

private void MouseHook_MouseUp(object? sender, MouseHookEventArgs e)

{

var text = GetControlText();

selectedTBK.Text = text;

Debug.WriteLine($"Selected text: {text}");

}

private void MouseHook_MouseDown(object? sender, MouseHookEventArgs e)

{

}

private string GetControlText()

{

try

{

    IntPtr hwnd = GetForegroundWindow();

    AutomationElement rootElement = AutomationElement.FromHandle(hwnd);

    AutomationElement textBox = rootElement.FindFirst(TreeScope.Descendants,

        new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));

    if (textBox != null && textBox.TryGetCurrentPattern(TextPattern.Pattern, out object pattern))

    {

        TextPattern textPattern = (TextPattern)pattern;

        if (textPattern.DocumentRange != null)

        {

            TextPatternRange[] selection = textPattern.GetSelection();

            if (selection.Length > 0)

            {

                string selectedText = selection[0].GetText(-1);

                Debug.WriteLine($"Selected Text: {selectedText}");

                return selectedText;

            }

            else

            {

                Debug.WriteLine("No text selected.");

                return string.Empty;

            }

        }

    }

    else

    {

        Debug.WriteLine("Text control not found or does not support TextPattern.");

        return string.Empty;

    }

}

catch (AccessViolationException ex)

{

    Debug.WriteLine(ex.Message);

}

catch (ElementNotAvailableException ex)

{

    Debug.WriteLine(ex.Message);

}

catch (Exception ex)

{

    Debug.WriteLine(ex.Message);

}

return string.Empty;

}

Windows 窗体
Windows 窗体
一组用于开发图形用户界面的 .NET Framework 托管库。
117 个问题
0 个注释 无注释
{count} 票

1 个答案

排序依据: 非常有帮助
  1. Hongrui Yu-MSFT 4,200 信誉分 Microsoft 供应商
    2025-01-06T07:20:02.3266667+00:00

    Hi, @华 张. Welcome to Microsoft Q&A. 

    I used the following code to successfully obtain the value of the text. You could refer to it.

    if (textBox != null && textBox.TryGetCurrentPattern(TextPattern.Pattern, out object pattern))
    {
           TextPattern textPattern = (TextPattern)pattern;
           if (textPattern.DocumentRange != null)
           {
                 string text = textPattern.DocumentRange.GetText(-1);
                 Debug.WriteLine($"Selected Text: {text}");
                 return text;
           }
           else
           {
                 Debug.WriteLine("No text selected.");
                 return string.Empty;
           }
    }
    

    Complete code(Here I use the Click event of Button instead of the MouseHook_MouseUp event of MouseHook) MainWindow.xaml

    <Grid x:Name="MyGrid">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBox x:Name="MyText" Text="HAHA"  Background="GreenYellow" Height="50"></TextBox>
        <TextBlock x:Name="selectedTBK" Grid.Row="1" Background="DimGray" Height="50"></TextBlock>
        <Button Grid.Row="1" Height="50" Width="200" Content="Click Me!" Margin="0,120,0,0" Click="Button_Click"></Button>
    </Grid>
    

    MainWindow.xaml.cs

        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            public IntPtr GetForegroundWindow()
            {
                return new WindowInteropHelper(this).Handle;
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                var text = GetControlText();
                selectedTBK.Text = text;
    
                Debug.WriteLine($"Selected text: {text}");
            }
    
            private string GetControlText()
            {
                try
                {
                    IntPtr hwnd = GetForegroundWindow();
    
                    AutomationElement rootElement = AutomationElement.FromHandle(hwnd);
                    AutomationElement textBox = rootElement.FindFirst(TreeScope.Descendants,new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));
                    if (textBox != null && textBox.TryGetCurrentPattern(TextPattern.Pattern, out object pattern))
                    {
                        TextPattern textPattern = (TextPattern)pattern;
                        if (textPattern.DocumentRange != null)
                        {
                            string text = textPattern.DocumentRange.GetText(-1);
                            Debug.WriteLine($"Selected Text: {text}");
                            return text;
                        }
                        else
                        {
                            Debug.WriteLine("No text selected.");
                            return string.Empty;
                        }
                    }
                    else
                    {
                        Debug.WriteLine("Text control not found or does not support TextPattern.");
                        return string.Empty;
                    }
                }
                catch (AccessViolationException ex)
                {
                    Debug.WriteLine(ex.Message);
                }
    
                catch (ElementNotAvailableException ex)
                {
                    Debug.WriteLine(ex.Message);
                }
    
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }
                return string.Empty;
            }
        }
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


你的答案

问题作者可以将答案标记为“接受的答案”,这有助于用户了解已解决作者问题的答案。