using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
namespace CPTC_System_Log
{
class GetWindowNameByPoint
{
public delegate bool CallBackPtr(IntPtr hwnd, IntPtr lParam);
[DllImport("user32.dll")]
static extern IntPtr WindowFromPoint(Point Point);
[StructLayout(LayoutKind.Sequential)]
private struct LVITEM
{
public int mask;
public int Item;
public int SubItem;
public int state;
public int stateMask;
public IntPtr pszText;
public int cchTextMax;
public int iImage;
internal int lParam;
internal int iIndent;
}
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[StructLayout(LayoutKind.Sequential)]
public struct TVITEM
{
public int mask;
public IntPtr hItem;
public int state;
public int stateMask;
public IntPtr pszText;
public int cchTextMax;
public int iImage;
public int iSelectedImage;
public int cChildren;
public IntPtr lParam;
}
[DllImport("user32.dll")]
public static extern int SendMessage(
IntPtr hWnd, // handle to destination window
uint Msg, // message
IntPtr wParam, // first message parameter
IntPtr lParam // second message parameter
);
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hwnd, int msg, int wParam, StringBuilder sb);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
// Win32 constants.
const int WM_GETTEXT = 0x000D;
const int WM_GETTEXTLENGTH = 0x000E;
public string GetText(IntPtr hWnd)
{
//StringBuilder dummy = new StringBuilder(10);
int length = SendMessage(hWnd, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero);
StringBuilder sb = new StringBuilder(length + 1);
SendMessage(hWnd, WM_GETTEXT, length + 1, sb);
return sb.ToString();
}
private const int LVM_FIRST = 0x1000;
private const int LVM_GETSELECTEDCOUNT = (LVM_FIRST + 50);
private const int LVM_GETITEMSTATE = (LVM_FIRST + 44);
private const int LVM_GETITEMTEXT = (LVM_FIRST + 45);
private const int LVM_GETITEMCOUNT = LVM_FIRST + 4;
private const int LVIF_TEXT = 0x1;
private const int LVM_GETITEMRECT = (LVM_FIRST + 14);
private const int TV_FIRST = 0x1100;
private const int TVM_GETNEXTITEM = TV_FIRST + 10;
private const int TVM_GETITEM = TV_FIRST + 12;
private const int TVM_GETVISIBLECOUNT = TV_FIRST + 16;
private const int TVM_EXPAND = TV_FIRST + 2;
private const int TVM_GETITEMRECT = TV_FIRST + 4;
private const int TVM_GETCOUNT = TV_FIRST + 5;
private const int TVM_GETINDENT = TV_FIRST + 6;
private const int TVM_SETINDENT = TV_FIRST + 7;
private const int TVM_ENSUREVISIBLE = TV_FIRST + 20;
private const int TVGN_ROOT = 0x0;
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);
const int PROCESS_TERMINATE = 0x1;
const int PROCESS_CREATE_THREAD = 0x2;
const int PROCESS_VM_OPERATION = 0x8;
const int PROCESS_VM_READ = 0x10;
const int PROCESS_VM_WRITE = 0x20;
const int PROCESS_DUP_HANDLE = 0x40;
const int PROCESS_CREATE_PROCESS = 0x80;
const int PROCESS_SET_QUOTA = 0x100;
const int PROCESS_SET_INFORMATION = 0x200;
const int PROCESS_QUERY_INFORMATION = 0x400;
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress,
uint dwSize, uint flAllocationType, uint flProtect);
const int MEM_COMMIT = 0x1000;
const int MEM_RELEASE = 0x8000;
const int PAGE_READWRITE = 0x4;
[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
//[In, Out] byte[] buffer,
IntPtr buffer,
UInt32 size,
out IntPtr lpNumberOfBytesRead
);
[DllImport("kernel32.dll")]
public static extern Int32 ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[In, Out] byte[] buffer,
UInt32 size,
out IntPtr lpNumberOfBytesRead
);
[DllImport("kernel32")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
ref LVITEM buffer, int dwSize, IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
ref TVITEM buffer, int dwSize, IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
ref RECT buffer, int dwSize, IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress,
UIntPtr dwSize, uint dwFreeType);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
public string GetWindowName(Point p)
{
StringBuilder sb = new StringBuilder();
IntPtr hwnd = WindowFromPoint(p);
StringBuilder ClassName = new StringBuilder(100);
//Get the window class name
if (GetClassName(hwnd, ClassName, ClassName.Capacity) != 0)
{
RECT rect;
GetWindowRect(hwnd, out rect);
Point p1 = new Point(p.X - rect.left, p.Y - rect.top);
string itemText = GetListViewItemFromPoint(hwnd, p1);
if (itemText.Length > 0)
{
return itemText;
}
//itemText = GetTreeViewItemFromPoint(hwnd, p1);
//if (itemText.Length > 0)
//{
// return itemText;
//}
}
string buf = GetText(hwnd);
int len;
for (len = 0; len < buf.Length && buf[len] != '\0'; len++) ;
return buf.Substring(0, len);// +" (CLASS:" + ClassName + ")";
}
public string GetListViewItemFromPoint(IntPtr hwnd, Point p)
{
StringBuilder sb = new StringBuilder();
int count = (int)SendMessage(hwnd, LVM_GETITEMCOUNT, IntPtr.Zero, IntPtr.Zero);
LVITEM LVI = new LVITEM();
IntPtr pLVI = IntPtr.Zero;
byte[] itemBuf = new byte[512];
//byte[] subItemBuf = new byte[512];
IntPtr pItemBuf = IntPtr.Zero;
//IntPtr pSubItemBuf = IntPtr.Zero;
IntPtr pRect = IntPtr.Zero;
uint pid = 0;
IntPtr process = IntPtr.Zero;
RECT rect = new RECT();
GetWindowThreadProcessId(hwnd, out pid);
process = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, 0, pid);
pLVI = VirtualAllocEx(process, IntPtr.Zero, (uint)Marshal.SizeOf(typeof(LVITEM)), MEM_COMMIT, PAGE_READWRITE);
pItemBuf = VirtualAllocEx(process, IntPtr.Zero, 512, MEM_COMMIT, PAGE_READWRITE);
//pSubItemBuf = VirtualAllocEx(process, IntPtr.Zero, 512, MEM_COMMIT, PAGE_READWRITE);
pRect = VirtualAllocEx(process, IntPtr.Zero, (uint)Marshal.SizeOf(typeof(RECT)), MEM_COMMIT, PAGE_READWRITE);
LVI.cchTextMax = 512;
for (int i = 0; i < count; i++)
{
LVI.SubItem = 0;
LVI.pszText = pItemBuf;
WriteProcessMemory(process, pLVI, ref LVI, Marshal.SizeOf(typeof(LVITEM)), IntPtr.Zero);
SendMessage(hwnd, LVM_GETITEMTEXT, (IntPtr)i, pLVI);
//LVI.SubItem = 1;
//LVI.pszText = pSubItemBuf;
//WriteProcessMemory(process, pLVI, ref LVI, Marshal.SizeOf(typeof(LVITEM)), IntPtr.Zero);
//SendMessage(hwnd, LVM_GETITEMTEXT, (IntPtr)i, pLVI);
unsafe
{
WriteProcessMemory(process, pRect, ref rect, Marshal.SizeOf(typeof(RECT)), IntPtr.Zero);
SendMessage(hwnd, LVM_GETITEMRECT, (IntPtr)i, pRect);
IntPtr bytesReaded;
ReadProcessMemory(process, pItemBuf, itemBuf, 512, out bytesReaded);
//ReadProcessMemory(process, pSubItemBuf, subItemBuf, 512, out bytesReaded);
ReadProcessMemory(process, pRect, (IntPtr)(&rect), (uint)Marshal.SizeOf(typeof(RECT)), out bytesReaded);
int len;
for (len = 0; len < 512 && itemBuf[len] != '\0'; len++) ;
////sb.Append(String.Format("{0},{1}-{2},{3} : {4},{5} ", rect.left, rect.top, rect.right, rect.bottom, p.X, p.Y));
if (rect.left <= p.X && rect.right >= p.X && rect.top <= p.Y && rect.bottom >= p.Y)
{
sb.Append(Encoding.ASCII.GetString(itemBuf).Substring(0, len));
//sb.Append("\r\n");
}
else
{
//sb.Append(Encoding.ASCII.GetString(itemBuf).Substring(0, len));
////sb.Append("\r\n");
}
rect.left = rect.right = rect.top = rect.bottom = 0;
}
}
VirtualFreeEx(process, pLVI, (UIntPtr)0, MEM_RELEASE);
VirtualFreeEx(process, pItemBuf, (UIntPtr)0, MEM_RELEASE);
//VirtualFreeEx(process, pSubItemBuf, (UIntPtr)0, MEM_RELEASE);
return sb.ToString();
}
public string GetTreeViewItemFromPoint(IntPtr hwnd, Point p)
{
StringBuilder sb = new StringBuilder();
int count = (int)SendMessage(hwnd, TVM_GETCOUNT, IntPtr.Zero, IntPtr.Zero);
TVITEM TVI = new TVITEM();
IntPtr pTVI = IntPtr.Zero;
byte[] itemBuf = new byte[512];
//byte[] subItemBuf = new byte[512];
IntPtr pItemBuf = IntPtr.Zero;
//IntPtr pSubItemBuf = IntPtr.Zero;
IntPtr pRect = IntPtr.Zero;
uint pid = 0;
IntPtr process = IntPtr.Zero;
RECT rect = new RECT();
GetWindowThreadProcessId(hwnd, out pid);
process = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, 0, pid);
pTVI = VirtualAllocEx(process, IntPtr.Zero, (uint)Marshal.SizeOf(typeof(TVITEM)), MEM_COMMIT, PAGE_READWRITE);
pItemBuf = VirtualAllocEx(process, IntPtr.Zero, 512, MEM_COMMIT, PAGE_READWRITE);
//pSubItemBuf = VirtualAllocEx(process, IntPtr.Zero, 512, MEM_COMMIT, PAGE_READWRITE);
pRect = VirtualAllocEx(process, IntPtr.Zero, (uint)Marshal.SizeOf(typeof(RECT)), MEM_COMMIT, PAGE_READWRITE);
for (int i = 0; i < count; i++)
{
unsafe
{
TVI.cchTextMax = 512;
TVI.hItem = (IntPtr)SendMessage(hwnd, TVM_GETNEXTITEM, (IntPtr)i, IntPtr.Zero);
TVI.mask = LVIF_TEXT;
TVI.pszText = pItemBuf;
WriteProcessMemory(process, pTVI, ref TVI, Marshal.SizeOf(typeof(TVITEM)), IntPtr.Zero);
SendMessage(hwnd, TVM_GETITEM, (IntPtr)0, pTVI);
//LVI.SubItem = 1;
//LVI.pszText = pSubItemBuf;
//WriteProcessMemory(process, pLVI, ref LVI, Marshal.SizeOf(typeof(LVITEM)), IntPtr.Zero);
//SendMessage(hwnd, LVM_GETITEMTEXT, (IntPtr)i, pLVI);
WriteProcessMemory(process, pRect, ref rect, Marshal.SizeOf(typeof(RECT)), IntPtr.Zero);
SendMessage(hwnd, TVM_GETITEMRECT, (IntPtr)TVI.hItem, pRect);
IntPtr bytesReaded;
ReadProcessMemory(process, pItemBuf, itemBuf, 512, out bytesReaded);
////ReadProcessMemory(process, pSubItemBuf, subItemBuf, 512, out bytesReaded);
ReadProcessMemory(process, pRect, (IntPtr)(&rect), (uint)Marshal.SizeOf(typeof(RECT)), out bytesReaded);
int len;
for (len = 0; len < 512 && itemBuf[len] != '\0'; len++) ;
sb.Append(String.Format("{0},{1}-{2},{3} {4}\r\n", rect.left, rect.top, rect.right, rect.bottom,
Encoding.ASCII.GetString(itemBuf).Substring(0, len)));
//if (rect.left <= p.X && rect.right >= p.X && rect.top <= p.Y && rect.bottom >= p.Y)
//{
// sb.Append(Encoding.ASCII.GetString(itemBuf).Substring(0, len));
// //sb.Append("\r\n");
//}
//else
//{
// //sb.Append(Encoding.ASCII.GetString(itemBuf).Substring(0, len));
// ////sb.Append("\r\n");
//}
rect.left = rect.right = rect.top = rect.bottom = 0;
}
}
VirtualFreeEx(process, pTVI, (UIntPtr)0, MEM_RELEASE);
VirtualFreeEx(process, pItemBuf, (UIntPtr)0, MEM_RELEASE);
//VirtualFreeEx(process, pSubItemBuf, (UIntPtr)0, MEM_RELEASE);
return sb.ToString();
}
}
}