Skip to content

Commit

Permalink
Issues #13 Fixed 2000 character limit for some types of windows
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderPro committed May 19, 2024
1 parent 16139b9 commit e534fff
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 58 deletions.
54 changes: 1 addition & 53 deletions WindowTextExtractor/Extensions/AutomationElementExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Windows.Automation;
using WindowTextExtractor.Native;
using WindowTextExtractor.Native.Structs;
using System.Windows.Automation;

namespace WindowTextExtractor.Extensions
{
Expand All @@ -28,51 +22,5 @@ public static string GetTextFromWindow(this AutomationElement element)
return element.Current.Name;
}
}

public static string GetTextFromConsole(this AutomationElement element)
{
try
{
Kernel32.FreeConsole();
var result = Kernel32.AttachConsole(element.Current.ProcessId);
if (!result)
{
var error = Marshal.GetLastWin32Error();
throw new Win32Exception(error);
}
var handle = Kernel32.GetStdHandle(Constants.STD_OUTPUT_HANDLE);
if (handle == IntPtr.Zero)
{
var error = Marshal.GetLastWin32Error();
throw new Win32Exception(error);
}
ConsoleScreenBufferInfo binfo;
result = Kernel32.GetConsoleScreenBufferInfo(handle, out binfo);
if (!result)
{
var error = Marshal.GetLastWin32Error();
throw new Win32Exception(error);
}

var buffer = new char[binfo.srWindow.Right];
var textBuilder = new StringBuilder();
for (var i = 0; i < binfo.dwSize.Y; i++)
{
uint numberOfCharsRead;
if (Kernel32.ReadConsoleOutputCharacter(handle, buffer, (uint)buffer.Length, new Coord(0, (short)i), out numberOfCharsRead))
{
textBuilder.AppendLine(new string(buffer));
}
}

var text = textBuilder.ToString().TrimEnd();
return text;
}
catch
{
Kernel32.FreeConsole();
return null;
}
}
}
}
23 changes: 18 additions & 5 deletions WindowTextExtractor/Forms/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -867,10 +867,23 @@ public bool PreFilterMessage(ref Message m)
User32.SetCursor(cursorHandle);
var cursorPosition = Cursor.Position;
var element = AutomationElement.FromPoint(new System.Windows.Point(cursorPosition.X, cursorPosition.Y));
if (element != null && element.Current.ProcessId != _processId)
var windowProcessId = element.Current.ProcessId;
if (element != null && windowProcessId != _processId)
{
var windowHandle = new IntPtr(element.Current.NativeWindowHandle);
windowHandle = windowHandle == IntPtr.Zero ? User32.WindowFromPoint(new Point(cursorPosition.X, cursorPosition.Y)) : windowHandle;
if (windowHandle == IntPtr.Zero)
{
windowHandle = User32.WindowFromPoint(new Point(cursorPosition.X, cursorPosition.Y));
if (windowHandle != IntPtr.Zero)
{
User32.GetWindowThreadProcessId(windowHandle, out windowProcessId);
var windowStyle = User32.GetWindowLong(windowHandle, Constants.GWL_STYLE);
if (((windowStyle & Constants.WS_CAPTION) != 0 || (windowStyle & Constants.WS_SYSMENU) != 0 || (windowStyle & Constants.WS_POPUP) != 0))
{
element = AutomationElement.FromHandle(windowHandle);
}
}
}

var previousHandle = IntPtr.Zero;
var previousProcessId = 0;
Expand Down Expand Up @@ -898,7 +911,7 @@ public bool PreFilterMessage(ref Message m)
return false;
}

using var process = Process.GetProcessById(element.Current.ProcessId);
using var process = Process.GetProcessById(windowProcessId);
if (element.Current.IsPassword)
{
if (process.ProcessName.ToLower() == "iexplore")
Expand Down Expand Up @@ -933,7 +946,7 @@ public bool PreFilterMessage(ref Message m)
}
else
{
var text = element.GetTextFromConsole() ?? element.GetTextFromWindow();
var text = WindowUtils.ExtractTextFromConsoleWindow(windowProcessId) ?? element.GetTextFromWindow();
text = text == null ? "" : text.TrimEnd().TrimEnd(Environment.NewLine);
if (_settings.ShowEmptyItems || (!_settings.ShowEmptyItems && !string.IsNullOrEmpty(text)))
{
Expand All @@ -947,7 +960,7 @@ public bool PreFilterMessage(ref Message m)
lock (_lockObject)
{
_windowHandle = windowHandle;
_windowProcessId = element.Current.ProcessId;
_windowProcessId = windowProcessId;
scale = _settings.Scale;
captureCursor = _settings.CaptureCursor;
}
Expand Down
5 changes: 5 additions & 0 deletions WindowTextExtractor/Native/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ static class Constants
public const int DWL_DLGPROC = 4;
public const int DWL_USER = 8;

// WindowStyle
public const long WS_CAPTION = 0x00C00000L;
public const long WS_SYSMENU = 0x00080000L;
public const long WS_POPUP = 0x80000000L;

// LayeredWindowAttributes
public const int LWA_ALPHA = 0x00000002;

Expand Down
45 changes: 45 additions & 0 deletions WindowTextExtractor/Utils/WindowUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Drawing;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Management;
using System.Windows.Forms;
using mshtml;
Expand Down Expand Up @@ -53,6 +54,50 @@ public static IList<string> GetPasswordsFromHtmlPage(IntPtr handle)
return result;
}

public static string ExtractTextFromConsoleWindow(int processId)
{
try
{
Kernel32.FreeConsole();
var result = Kernel32.AttachConsole(processId);
if (!result)
{
var error = Marshal.GetLastWin32Error();
throw new Win32Exception(error);
}
var handle = Kernel32.GetStdHandle(Constants.STD_OUTPUT_HANDLE);
if (handle == IntPtr.Zero)
{
var error = Marshal.GetLastWin32Error();
throw new Win32Exception(error);
}
result = Kernel32.GetConsoleScreenBufferInfo(handle, out var binfo);
if (!result)
{
var error = Marshal.GetLastWin32Error();
throw new Win32Exception(error);
}

var buffer = new char[binfo.srWindow.Right];
var textBuilder = new StringBuilder();
for (var i = 0; i < binfo.dwSize.Y; i++)
{
if (Kernel32.ReadConsoleOutputCharacter(handle, buffer, (uint)buffer.Length, new Coord(0, (short)i), out var numberOfCharsRead))
{
textBuilder.AppendLine(new string(buffer));
}
}

var text = textBuilder.ToString().TrimEnd();
return text;
}
catch
{
Kernel32.FreeConsole();
return null;
}
}

public static WindowInformation GetWindowInformation(IntPtr handle, Point cursorPosition)
{
var text = GetWindowText(handle);
Expand Down

0 comments on commit e534fff

Please sign in to comment.