рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдФрд░ рдУрдПрд╕ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдкрд░ рдЕрдиреБрд╕рдВрдзрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╡рд┐рднрд┐рдиреНрди рдЙрдкрдХрд░рдг рд╣реИрдВред рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди, рдЖрдИрдбреАрдИ, рд╕реНрдорд╛рд░реНрдЯ рдиреЛрдЯрдкреИрдб, рдЖрдИрдбреАрдП, рд░рд╛рдбрд╛рд░, рд╣реЗрдХреНрд╕ рдПрдбрд┐рдЯрд░реНрд╕, рдкреЗ рдПрдбрд┐рдЯрд░, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдПрдХ рд╕реМ рд╕реЗ рдЕрдзрд┐рдХ рд╕рд╛рдЗрдирд╕рд┐рдПрдВрдЯрд▓ рдЙрдкрдпреЛрдЧрд┐рддрд╛рдУрдВ - рдпрд╣ рд╕рдм рдХрдИ рдирд┐рдпрдорд┐рдд рд╕рдВрдЪрд╛рд▓рди рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдХрднреА-рдХрднреА рдРрд╕рд╛ рдХреНрд╖рдг рдЖрддрд╛ рд╣реИ рдЬрдм рдЖрдкрдХреЛ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рд╡рд┐рд╡рд┐рдзрддрд╛ рдХреЗ рдмреАрдЪ рдЖрдк рдПрдХ рдЫреЛрдЯреА рд╕реА рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХреЛ рдпрд╛рдж рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЬреЛ рдХрд┐ рдХреЗрд╡рд▓ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдФрд░ рд╕рд░рд▓ рдХрд╛рдо рдХрд░реЗрдЧреАред рдЖрдк рдЕрдкрдиреЗ рдШреБрдЯрдиреЗ рдкрд░ рдЕрдЬрдЧрд░ рдпрд╛ рдкреЙрд╡рд░реНрд╕ рдореЗрдВ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрдХреНрд╕рд░ рдЖрдк рдЗрд╕ рддрд░рд╣ рдХреЗ рд╢рд┐рд▓реНрдк рдХреЛ рдмрд┐рдирд╛ рдЖрдБрд╕реВ рдХреЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдкрдиреЗ рд╕рд╣рдпреЛрдЧрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд╛рдЭрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдпрд╣ рд╕реНрдерд┐рддрд┐ рдлрд┐рд░ рд╕реЗ рдореЗрд░реЗ рдкрд╛рд╕ рдЖрдИ рд╣реИред рдФрд░ рдореИрдВрдиреЗ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдХрд┐ рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рд╕реНрд╡рдЪреНрдЫ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рд▓реЗрдиреЗ рдФрд░ рд▓рд┐рдЦрдиреЗ рдХрд╛ рд╕рдордп рдерд╛ред рдореИрдВ рдЕрдЧрд▓реЗ рд▓реЗрдЦреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдореЗрдВ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдКрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдЕрдм рд╡рд┐рдХрд╛рд╕ рдХреЗ рджреМрд░рд╛рди рдЖрдиреЗ рд╡рд╛рд▓реА рд╕рдорд╕реНрдпрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдКрдВрдЧрд╛ред
рддреНрд░реБрдЯрд┐ рд╕реНрд╡рдпрдВ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдкреНрд░рдХрдЯ рд╣реЛрддреА рд╣реИ: рдпрджрд┐ рдЖрдк рдкрд╛рда рдХреА рдХрдИ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдорд╛рдирдХ рдкрд╛рда рдмреЙрдХреНрд╕ рдирд┐рдпрдВрддреНрд░рдг рдореЗрдВ
рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реВрдЪрдХрд╛рдВрдХ рд╕реЗ рд╢реБрд░реВ рд╣реЛ рд░рд╣реА
GetLineText () рдлрд╝рдВрдХреНрд╢рди рдкрд░ рдХреЙрд▓ рдЧрд▓рдд рд░реЗрдЦрд╛рдПрдБ
рд▓реМрдЯрд╛рдПрдБрдЧреА ред
рдЧрд▓рдд рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рднрд▓реЗ рд╣реА рд▓рд╛рдЗрдиреЗрдВ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд┐рдП рдЧрдП рдЯреЗрдХреНрд╕реНрдЯ рд╕реЗ рд╣реЛрдВрдЧреА, рд▓реЗрдХрд┐рди рдЖрдЧреЗ рд╕реНрдерд┐рдд рд╣реИ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ
рдЧреЗрдЯрд▓рд╛рдЗрдирдЯреЗрдХреНрд╕реНрдЯ () рдмрд╕ рдХреБрдЫ рд▓рд╛рдЗрдиреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрдЧрд╛ред рддреНрд░реБрдЯрд┐ рдмрд╣реБрдд рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рд╕рд╛рде рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИред рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЙрд╕рд╕реЗ рдорд┐рд▓рд╛ - рдореИрдВрдиреЗ рдПрдХ рдЯреЗрдХреНрд╕реНрдЯрдмреЙрдХреНрд╕ рдореЗрдВ 25 рдореЗрдЧрд╛рдмрд╛рдЗрдЯ рдЯреЗрдХреНрд╕реНрдЯ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреАред рдЖрдЦрд┐рд░реА рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рд╕реЗ рдПрдХ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рдкреНрд░рднрд╛рд╡ рд╕рд╛рдордиреЗ рдЖрдпрд╛ред
Google
рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рддреНрд░реБрдЯрд┐ 2011 рд╕реЗ рдореМрдЬреВрдж рд╣реИ рдФрд░ Microsoft рдХреБрдЫ рдареАрдХ рдХрд░рдиреЗ рдХреА рдЬрд▓реНрджреА рдореЗрдВ рдирд╣реАрдВ рд╣реИред
рдЙрджрд╛рд╣рд░рдг
.NET рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рдирд╣реАрдВ рд╣реИрдВред рд╣рдо рдПрдХ рдорд╛рдирдХ WPF рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рднрд░рддреЗ рд╣реИрдВ:
MainWindow.xaml
<Window x:Class="wpf_textbox.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:wpf_textbox" mc:Ignorable="d" Title="WTF, WPF?" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="20"/> <RowDefinition Height="20"/> </Grid.RowDefinitions> <TextBox Grid.Row="0" Margin="5" Name="txt" AcceptsReturn="True" AcceptsTab="True" /> <Button Grid.Row="1" Content="Fire 1!" Click="btn_OnClick" /> <Button Grid.Row="2" Content="Fire 2!" Click="btn2_OnClick" /> </Grid> </Window>
MainWindow.cs (рдЙрдкрдпреЛрдЧ рдФрд░ рдирд╛рдо рд╕реНрдерд╛рди рдХреЛ рдЫреЛрдбрд╝ рджреЗрдирд╛)
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void btn_OnClick(object sender, RoutedEventArgs e) { var sb = new StringBuilder(); for (int i = 0; i < 90009; i++) sb.AppendLine($"{i}"); txt.Text = sb.ToString(); } private void btn2_OnClick(object sender, RoutedEventArgs e) { var sb = new StringBuilder(); for (var i = 1; i < 7; i++) sb.AppendLine("req: " + 150 * i + ", get: " + txt.GetLineText(150 * i).Trim()); for (var i = 1; i < 7; i++) sb.AppendLine("req: " + 15000 * i + ", get: " + txt.GetLineText(15000 * i).Trim()); txt.Text = sb.ToString(); } }
рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдПрдХ рдЯреЗрдХреНрд╕реНрдЯрдмреЙрдХреНрд╕ рдФрд░ рджреЛ рдмрдЯрди рд╣реЛрддреЗ рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ "рдлрд╛рдпрд░ 1" рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ! (рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЯреЗрдХреНрд╕реНрдЯрдмреЙрдХреНрд╕ рднрд░реЗрдВ), рдлрд┐рд░ "рдлрд╛рдпрд░ 2!" (рдпрд╣ рд╕рдВрдЦреНрдпрд╛ рдФрд░ рдкреНрд░рд┐рдВрдЯ рджреНрд╡рд╛рд░рд╛ рд▓рд╛рдЗрдиреЛрдВ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░реЗрдЧрд╛)ред
рдЕрдкреЗрдХреНрд╖рд┐рдд рдкрд░рд┐рдгрд╛рдо:
req: 150, get: 150
req: 300, get: 300
req: 450, get: 450
req: 600, рдорд┐рд▓рддрд╛ рд╣реИ: 600
req: 750, get: 750
req: 900, рдорд┐рд▓рддрд╛ рд╣реИ: 900
req: 15000, рдорд┐рд▓рддрд╛ рд╣реИ: 15000
req: 30000, рдорд┐рд▓рддрд╛ рд╣реИ: 30000
req: 45000, рдорд┐рд▓рддрд╛ рд╣реИ: 45000
req: 60000, рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ: 60000
req: 75000, рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ: 75000
req: 90000, рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ: 90000
рд╡рд╛рд╕реНрддрд╡рд┐рдХрддрд╛:

рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ 1000 рд╕реЗ рдХрдо рдЕрдиреБрдХреНрд░рдорд┐рдд рдХреЗ рд▓рд┐рдП - рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реИ, рд▓реЗрдХрд┐рди рдмрдбрд╝реЗ 15000 рдХреЗ рд▓рд┐рдП - рдмрджрд▓рд╛рд╡ рд╢реБрд░реВ рд╣реЛ рдЧрдП рд╣реИрдВред рдФрд░ рдЖрдЧреЗ, рдФрд░ рдЕрдзрд┐рдХред
рдмрдЧ рдХрд╛ рдЕрдиреНрд╡реЗрд╖рдг рдХрд░реЗрдВ
рд╣рдо рд░рд┐рдЬрд╝реЙрд▓реНрд╡рд░ рдХреЗ рдЙрд╕ рд╣рд┐рд╕реНрд╕реЗ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ .NET рд╕реНрд░реЛрдд рдХреЛрдб рдФрд░ рд╡рд┐рд╢реЗрд╖ рд╡рд░реНрдЧ "рдЕрд╡рд╕рд░реЛрдВ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдФрд░ рдкрд░рд╛рд╡рд░реНрддрди рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреА рдЕрдзрд┐рдХрддрд╛" рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред
рдкрд░рд╛рд╡рд░реНрддрди рдХреНрд╖рдорддрд╛ рдПрдХреНрд╕реНрдЯреЗрдВрдбрд░ рдФрд░ рд╕реАрдордХ public static class ReflectionExtensions { public static T GetFieldValue<T>(this object obj, string name) { var bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; var field = obj.GetType().GetField(name, bindingFlags); if (field == null) field = obj.GetType().BaseType.GetField(name, bindingFlags); return (T)field?.GetValue(obj); } public static object InvokeMethod(this object obj, string methodName, params object[] methodParams) { var methodParamTypes = methodParams?.Select(p => p.GetType()).ToArray() ?? new Type[] { }; var bindingFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static; MethodInfo method = null; var type = obj.GetType(); while (method == null && type != null) { method = type.GetMethod(methodName, bindingFlags, Type.DefaultBinder, methodParamTypes, null); var intfs = type.GetInterfaces(); if (method != null) break; foreach (var intf in intfs) { method = intf.GetMethod(methodName, bindingFlags, Type.DefaultBinder, methodParamTypes, null); if (method != null) break; } type = type.BaseType; } return method?.Invoke(obj, methodParams); } }
рдЬрд╛рд╣рд┐рд░ рд╣реИ, рд╣рдо рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд░реЗрдЦрд╛ 8510 рдХреЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕рдорд╕реНрдпрд╛ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИред рдпрджрд┐ рдЖрдк
txt.GetLineText (8510) рдХрд╛ рдЕрдиреБрд░реЛрдз
рдХрд░рддреЗ рд╣реИрдВ , рддреЛ "8510" рд░рд┐рдЯрд░реНрди рдорд┐рд▓рддрд╛ рд╣реИред 8511 - 8511 рдХреЗ рд▓рд┐рдП, рдФрд░ 8512 рдХреЗ рд▓рд┐рдП - рдЕрдЪрд╛рдирдХ, 8513ред
рд╣рдо рдПрдХ
рдЯреЗрдХреНрд╕реНрдЯрдмреЙрдХреНрд╕ рдкрд░
GetLineText () рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ
рджреЗрдЦрддреЗ рд╣реИрдВ :

рд╣рдо рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рдЪреЗрдХ рдЫреЛрдбрд╝рддреЗ рд╣реИрдВ рдФрд░ рдХреЙрд▓
GetStartPositionOfLine () рджреЗрдЦрддреЗ рд╣реИрдВред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдорд╕реНрдпрд╛ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдЧрд▓рдд рд▓рд╛рдЗрди рдХреЗ рд▓рд┐рдП рд▓рд╛рдЗрди рдХреА рд╢реБрд░реБрдЖрдд рдХреА рдЧрд▓рдд рд╕реНрдерд┐рддрд┐ рд╡рд╛рдкрд╕ рдЖрдиреА рдЪрд╛рд╣рд┐рдПред
рд╣рдо рдЕрдкрдиреЗ рдХреЛрдб рдореЗрдВ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ:
var o00 = txt.InvokeMethod("GetStartPositionOfLine", 8510); var o01 = txt.InvokeMethod("GetStartPositionOfLine", 8511); var o02 = txt.InvokeMethod("GetStartPositionOfLine", 8512);
рдФрд░ рд╕рдЪреНрдЪрд╛рдИ - рдкрд╣рд▓реА рд╡рд╕реНрддреБ рдХреА рдСрдлрд╕реЗрдЯ (8510 рд╡реАрдВ рдкрдВрдХреНрддрд┐ рдХреА рд╢реБрд░реБрдЖрдд) рдХреЛ 49950 рд╡рд░реНрдгреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рджреВрд╕рд░реА рд╡рд╕реНрддреБ рдХреЗ рд▓рд┐рдП - 49956, рдФрд░ рддреАрд╕рд░рд╛ - 49968ред рдкрд╣рд▓реЗ рджреЛ 6 рд╡рд░реНрдгреЛрдВ рдХреЗ рдмреАрдЪ, рдФрд░ рдЕрдЧрд▓реЗ рдХреЗ рдмреАрдЪ / рд╡рд┐рдХрд╛рд░ - рдпрд╣ рдЧрд╛рдпрдм рд░реЗрдЦрд╛ рд╣реИред
GetStartPositionOfLine () рдХреЗ рдЕрдВрджрд░ рдЬрд╛рдПрдВ:

рдлрд┐рд░ рд╕реЗ рд╣рдо рд╕реНрдЯрд╛рд░реНрдЯ рдЪреЗрдХ рдХреЛ рдЫреЛрдбрд╝рддреЗ рд╣реИрдВ рдФрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдмрд┐рдВрджреБ рдХреА рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ, рдЬрд┐рд╕реЗ
рд▓рд╛рдЗрдирдЗрдВрдбреЗрдХреНрд╕ рдирдВрдмрд░ рдХреЗ рд╕рд╛рде рд▓рд╛рдЗрди рдкрд░ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рд╕рднреА рд░реЗрдЦрд╛рдУрдВ рдХреА рдКрдВрдЪрд╛рдИ рд▓реА рдЧрдИ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдХреЗрдВрджреНрд░ рддрдХ рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЗрди рдХреА рдЖрдзреА рдКрдВрдЪрд╛рдИ рдЬреЛрдбрд╝реА рдЧрдИ рд╣реИред
рд╣рдо рдЗрд╕реЗ рдирд╣реАрдВ рджреЗрдЦрддреЗ рд╣реИрдВред
рд╡реЗрд░реНрдЯрд┐рдХрд▓рдСрдлрд╕реЗрдЯ рдФрд░ рдпрд╣ред
рд╣реЙрд░рд┐рдЬреЙрдиреНрдЯрд▓ рдСрдлрд┐рд╕ - рд╡реЗ рд╢реВрдиреНрдп рд╣реИрдВред
рд╣рдо рдЕрдкрдиреЗ рдХреЛрдб рдореЗрдВ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ:
var lineHeight = (double) txt.InvokeMethod("GetLineHeight", null); var y0 = lineHeight * (double)8510 + lineHeight / 2.0 - txt.VerticalOffset; var y1 = lineHeight * (double)8511 + lineHeight / 2.0 - txt.VerticalOffset; var y2 = lineHeight * (double)8512 + lineHeight / 2.0 - txt.VerticalOffset;
рдореВрд▓реНрдп рддрд░реНрдХ рдХреЗ рд╕рд╛рде рдЙрдЪрд┐рдд, рд╕рд╣рд╕рдВрдмрджреНрдз рд╣реИрдВ, рд╕рдм рдХреБрдЫ рдХреНрд░рдо рдореЗрдВ рд╣реИред рд╣рдо
GetStartPositionOfLine () рдХреЛрдб рдХреЗ рд╕рд╛рде рдЖрдЧреЗ
рдмрдврд╝рддреЗ рд╣реИрдВ - рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рд╛рд░реНрдердХ рд▓рд╛рдЗрди (рд╕реНрдерд┐рддрд┐ рдХреЗ рдЕрдВрджрд░ рдкрд╣рд▓рд╛) рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рдЬреЛ рдПрдХ рдордЧрд░рдордЪреНрдЫ рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ рдФрд░
GetTextPositionFromPoint () рдкрд░ рдХреЙрд▓ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред
рд╣рдо рдЪреБрдиреМрддрд┐рдпреЛрдВ рдХреЛ рдЦреЛрд▓рддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЦреАрдВрдЪрддреЗ рд╣реИрдВред рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рджреГрд╢реНрдпрддрд╛ рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЗ рдХрд╛рд░рдг рдХреБрдЫ рдЗрдВрдЯрд░рдлреЗрд╕ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдЙрд╕реА рд░рд┐рдлреНрд▓реЗрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрдиреНрд╣реЗрдВ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
var renderScope = (txt.GetFieldValue<FrameworkElement>("_renderScope") as IServiceProvider);
рдкрд░рд┐рдгрд╛рдореА рд╡рд╕реНрддреБрдПрдВ рд╕рднреА рд╕рдорд╛рди рдСрдлрд╝рд╕реЗрдЯреНрд╕ рдХреЛ рджрд░реНрд╢рд╛рддреА рд╣реИрдВ - 49950, 49956, 49568ред рд╣рдо
рдЯреЗрдХреНрд╕реНрдЯрдмреЙрдХреНрд╕ рд╡реНрдпреВ рдХреЗ рдЕрдВрджрд░
рдЧреЗрдЯрдЯрд╛рдЗрдкрдкреЛрдЬрд┐рд╢рдирдлреНрд░реЙрдордкреНрд╡рд╛рдЗрдВрдЯ () рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдЬрд╛рддреЗ рд╣реИрдВред

рдореЗрдВ,
GetLineIndexFromPoint () рдЖрд╢рд╛рдЬрдирдХ рд▓рдЧрддрд╛ рд╣реИред рдЕрдкрдиреЗ рдХреЛрдб рдореЗрдВ рдХреЙрд▓ рдХрд░реЗрдВред
var o20 = textView.InvokeMethod("GetLineIndexFromPoint", new Point(-txt.HorizontalOffset, y0), true); var o21 = textView.InvokeMethod("GetLineIndexFromPoint", new Point(-txt.HorizontalOffset, y1), true); var o22 = textView.InvokeMethod("GetLineIndexFromPoint", new Point(-txt.HorizontalOffset, y2), true);
рд╣рдореЗрдВ 8510, 8511 рдФрд░ 8513 - рдмрд┐рдВрдЧреЛ рдорд┐рд▓рддреЗ рд╣реИрдВ! рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП:

рдирдЧреНрди рдЖрдВрдЦреЛрдВ рдХреЗ рд╕рд╛рде рднреА рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдЦреЛрдЬ рд╣реИред
_lineMetrics - рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ (рдкреНрд░рд╛рд░рдВрдн, рд▓рдВрдмрд╛рдИ, рд╕реАрдорд╛ рдЪреМрдбрд╝рд╛рдИ) рдХреА рдПрдХ рд╕реВрдЪреАред рдореИрдВ рдЦрд╝реБрд╢реА рд╕реЗ рдЕрдкрдиреА рдХрд▓рдо рд░рдЧрдбрд╝рддрд╛ рд╣реВрдБ - рдореИрдВрдиреЗ рд╕реЛрдЪрд╛ рдХрд┐ рдЬреИрд╕рд╛ рдХрд┐ рдЕрдХреНрд╕рд░ рд╣реЛрддрд╛ рд╣реИ, рд╡реЗ
+ = рдХреЗ рдмрдЬрд╛рдп
+1 рдЪрд┐рдкрдХрд╛рдирд╛ рдпрд╛
рд▓рдЧрд╛рдирд╛ рднреВрд▓ рдЧрдПред рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЛрдб рдореЗрдВ рдХреЙрдкреА рдХрд░реЗрдВ рдФрд░ рдбреАрдмрдЧ рдХрд░реЗрдВред
_LineMetrics рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдмрдВрдж рдкреНрд░рдХреГрддрд┐ рдХреЗ рдХрд╛рд░рдг,
рд╣рдо рдЗрд╕реЗ рдкреНрд░рддрд┐рдмрд┐рдВрдмреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмрд╛рд╣рд░
рдирд┐рдХрд╛рд▓рддреЗ рд╣реИрдВ ,
_line рдпрд╣ рд╣рдореЗрдВ рдкрд╣рд▓реЗ рдорд┐рд▓рд╛ рдерд╛ред рдХреБрд▓:
var lm = textView.GetFieldValue<object>("_lineMetrics"); var c = (int)lm.InvokeMethod("get_Count"); var lineMetrics = new List<Tuple<int,int,int,double>>(); for (var i = 0; i < c; i++) { var arr_o = lm.InvokeMethod("get_Item", i); var contLength = arr_o.GetFieldValue<int>("_contentLength"); var length = arr_o.GetFieldValue<int>("_length"); var offset = arr_o.GetFieldValue<int>("_offset"); var width = arr_o.GetFieldValue<double>("_width"); lineMetrics.Add(new Tuple<int, int, int, double>(contLength, length, offset, width)); } var o30 = GetLineIndexFromPoint(lineMetrics, lineHeight, new Point(-txt.HorizontalOffset, y0), true); var o31 = GetLineIndexFromPoint(lineMetrics, lineHeight, new Point(-txt.HorizontalOffset, y1), true); var o32 = GetLineIndexFromPoint(lineMetrics, lineHeight, new Point(-txt.HorizontalOffset, y2), true); private int GetLineIndexFromPoint(List<Tuple<int, int, int, double>> lm, double _lineHeight, Point point, bool snapToText) { if (point.Y < 0.0) return !snapToText ? -1 : 0; if (point.Y >= _lineHeight * (double)lm.Count) { if (!snapToText) return -1; return lm.Count - 1; } int index = -1; int num1 = 0; int num2 = lm.Count; while (num1 < num2) { index = num1 + (num2 - num1) / 2; var lineMetric = lm[index]; double num3 = _lineHeight * (double)index; if (point.Y < num3) num2 = index; else if (point.Y >= num3 + _lineHeight) { num1 = index + 1; } else { if (!snapToText && (point.X < 0.0 || point.X >= lineMetric.Item4)) { index = -1; break; } break; } } if (num1 >= num2) return -1; return index; }
рд╣рдореЗрдВ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рдорд┐рд▓рддрд╛ рд╣реИред o30, o31 рдФрд░ o32 рдХреНрд░рдорд╢рдГ 8510, 8511 рдФрд░ 8512 рд╣реИрдВред рдЬреИрд╕реЗ рдЙрдиреНрд╣реЗрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП! рд▓реЗрдХрд┐рди рдУ 20, рдУ 21 рдФрд░ рдУ 22 рдЙрдирд╕реЗ рд╕рд╣рдордд рдирд╣реАрдВ рд╣реИрдВред рдРрд╕рд╛ рдХреИрд╕реЗ? рд╣рдордиреЗ рд▓рдЧрднрдЧ рдХреЛрдб рдирд╣реАрдВ рдмрджрд▓рд╛ред рд▓рдЧрднрдЧ? рдФрд░ рдпрд╣рд╛рдБ рдЕрдВрддрд░реНрджреГрд╖реНрдЯрд┐ рдЖрддреА рд╣реИред
var lh = textView.GetFieldValue<double>("_lineHeight");

рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ - рдЕрдВрддрд░
0.0009375 рд╣реИ ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрджрд┐ рд╣рдо рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд╕рдВрдЪрдп рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рддреЗ рд╣реИрдВ - рд╣рдо 8511 рд╕реЗ рдЧреБрдгрд╛ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ 7.9790625 рдорд┐рд▓рддреЗ рд╣реИрдВред рдпрд╣ рд▓рд╛рдЗрдирд╣рд╛рдЗрдЯ рдХрд╛ рд▓рдЧрднрдЧ рдЖрдзрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рдФрд░ рдЗрд╕рд▓рд┐рдП, рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╕рдордп, рдмрд┐рдВрджреБ рд╡рд╛рдВрдЫрд┐рдд рд░реЗрдЦрд╛ рдХреЗ рдмрд╛рд╣рд░ рдЙрдбрд╝ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЕрдЧрд▓реЗ рдкрд░ рдЧрд┐рд░ рдЬрд╛рддрд╛ рд╣реИред рдПрдХ рд╣реА рдЪрд░ (рдЕрд░реНрде рдореЗрдВ) рдХреА рдЧрдгрдирд╛ рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд░реАрдХреЛрдВ рд╕реЗ рдХреА рдЧрдИ рдереА рдФрд░ рдЕрдЪрд╛рдирдХ, рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддрд╛ рдерд╛ред
рдЗрд╕ рдкрд░ рдореИрдВрдиреЗ рд░реБрдХрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдиреАрдЪреЗ рддрдХ рдкрд╣реБрдВрдЪ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдХреЙрд▓рдо рдХреА рдКрдБрдЪрд╛рдИ рдЕрд▓рдЧ рдХреНрдпреЛрдВ рдирд┐рдХрд▓реА, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдмрд╣реБрдд рдХреБрдЫ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрддрд╛ред рдпрд╣ рд╕рдВрджрд┐рдЧреНрдз рд╣реИ рдХрд┐ Microsoft рдЗрд╕реЗ рдареАрдХ рдХрд░ рджреЗрдЧрд╛, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЪрд╛рд░реЛрдВ рдУрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмреИрд╕рд╛рдЦреА рджреЗрдЦрддреЗ рд╣реИрдВред рдкреНрд░рддрд┐рдмрд┐рдВрдм-рдмреИрд╕рд╛рдЦреА - рд╕рд╣реА
_lineHeigh рдХреЛ рдПрдХ рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рд╕реНрдерд╛рди рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВред рдпрд╣ рдЧреВрдВрдЧрд╛ рд▓рдЧрддрд╛ рд╣реИ, рд╢рд╛рдпрдж рдзреАрдорд╛ рдФрд░ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рдЕрд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд╣реИред рдпрд╛ рдЖрдк рдЯреЗрдХреНрд╕реНрдЯрдмреЙрдХреНрд╕ рдХреЗ рд╕рдорд╛рдирд╛рдВрддрд░ рдЕрдкрдиреА рдЦреБрдж рдХреА рд▓рд╛рдЗрдиреЛрдВ рдХреЛ рдмрдирд╛рдП рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдХрд░реНрд╕рд░ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд▓рд╛рдЗрди рдирдВрдмрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рд╕реЗ рд▓рд╛рдЗрдиреЗрдВ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВред
рдирд┐рд╖реНрдХрд░реНрд╖
рдиреМрд╕рд┐рдЦрд┐рдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд╕реЗ рдЖрдк рдЕрдХреНрд╕рд░ рдХрдВрдкрд╛рдЗрд▓рд░ рдпрд╛ рдорд╛рдирдХ рдШрдЯрдХреЛрдВ рдореЗрдВ рдмрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рд╕реБрди рд╕рдХрддреЗ рд╣реИрдВред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╡реЗ рдЗрддрдиреЗ рдЖрдо рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рдХреЛрдИ рднреА рдЙрдирд╕реЗ рд╕реБрд░рдХреНрд╖рд┐рдд рдирд╣реАрдВ рд╣реИред рдЙрд╕ рдЙрдкрдХрд░рдг рдХреЗ рдЕрдВрджрд░ рджреЗрдЦрдиреЗ рд╕реЗ рдбрд░реЛ рдордд рдЬрд┐рд╕реЗ рдЖрдкрдХреЛ рдЬрд╝рд░реВрд░рдд рд╣реИ - рдпрд╣ рд░реЛрдорд╛рдВрдЪрдХ рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИред
рдПрдХ рдЕрдЪреНрдЫрд╛ рдХреЛрдб рд▓рд┐рдЦреЗрдВ!
рдЕрдиреНрдп рдмреНрд▓реЙрдЧ рд▓реЗрдЦ
тЖТ
рдЖрдХреНрд░рд╛рдордХ рд╕реБрд░рдХреНрд╖рд╛ рдкрд░ рдорд╢реАрди рд▓рд░реНрдирд┐рдВрдЧрдХреЛрдИ рдХрд╛рд░ рдореЗрд░реА рдЬрдЧрд╣ рдирд╣реАрдВ рд▓реЗ рд╕рдХрддреАред рдореБрд╣рд╛ рд╣рд╛ред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИред
тЖТ
IPv6 рдореЗрдВ рдЙрджреНрдзрд░рдг рдЪрд┐рд╣реНрди рдХрд╣рд╛рдБ рдбрд╛рд▓реЗрдВрд▓реЛрдЧ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕реЗ рдЕрдЪреНрдЫрд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛рдВ рдФрд░ рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рддрд░рд╣ рдХреЗ рд╢рдмреНрджреЛрдВ рдХреЗ рдмрд╛рдж, рд╡реЗ рдореБрдЭреЗ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рд░реЛрдмреЛрдЯ рдХреЗ рд╕рд╛рде рдмрджрд▓ рджреЗрдВрдЧреЗред рд╕реА.рдкреА.! рдпреВрдПрдЪрдПрдл!