Comm.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;
using System.IO;
namespace TextBox_Connector
{
public static class Comm
{
// Set module Type
private static string type = "display";
// Set namespace
private static string nSpace = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName.Substring(0, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName.IndexOf('.'));
// Declare process
static Process p = new Process();
// Declare target handle
static IntPtr target = IntPtr.Zero;
/// <summary>
/// Delegate for thread enumeration
/// </summary>
delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);
/// <summary>
/// Delegate for child windows enumeration
/// </summary>
public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
/// <summary>
/// Sends custom message to target handle (hWnd)
/// </summary>
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SendMessage(int hWnd, int Msg, int wparam, int lparam);
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, string lParam);
/// <summary>
/// Enumerates child windows
/// </summary>
[System.Runtime.InteropServices.DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
// Constant for GETTEXT message
private const uint WM_GETTEXT = 0x000D;
// Constant for GETTEXTLENGTH message
private const int WM_GETTEXTLENGTH = 0x000E;
// Constant for SETTEXT message
private const uint WM_SETTEXT = 0x000C;
/// <summary>
/// Enumerates windows in the thread
/// </summary>
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
/// <summary>
/// Enumerates Handles from a given process
/// </summary>
static IEnumerable<IntPtr> EnumerateProcessWindowHandles(int processId)
{
var handles = new List<IntPtr>();
foreach (ProcessThread thread in Process.GetProcessById(processId).Threads)
{
EnumThreadWindows(thread.Id, (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero);
}
return handles;
}
/// <summary>
/// Callback for enumerating windows
/// </summary>
private static bool EnumWindow(IntPtr handle, IntPtr pointer)
{
// Get handle from garbage collector
GCHandle gch = GCHandle.FromIntPtr(pointer);
// Declare list
List<IntPtr> list = gch.Target as List<IntPtr>;
// Check if there's something
if (list == null)
{
// Throw exception
throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
}
// Add to list
list.Add(handle);
// Exit with true (null would cancel)
return true;
}
/// <summary>
/// Returns list of IntPtr with child windows
/// </summary>
public static List<IntPtr> GetChildWindows(IntPtr parent)
{
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
try
{
EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
return result;
}
/// <summary>
/// Gets text of control by handle
/// </summary>
public static string GetControlText(IntPtr hWnd)
{
// String builder for title
StringBuilder title = new StringBuilder();
// Size of string for holding title.
Int32 size = SendMessage((int)hWnd, WM_GETTEXTLENGTH, 0, 0).ToInt32();
// 0 = no title.
if (size > 0)
{
title = new StringBuilder(size + 1);
SendMessage(hWnd, (int)WM_GETTEXT, title.Capacity, title);
}
// Give control text back
return title.ToString();
}
/// <summary>
/// Initialization routine
/// </summary>
public static string Init(Icon icon)
{
// Start process
try
{
// Start
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location) + ".exe";
p.Start();
// Loop until it's loaded
while (p.MainWindowHandle == IntPtr.Zero)
{
Thread.Sleep(10);
p.Refresh();
}
// Check for input
bool inputSolved = false;
// Resolve input textbox
while (!inputSolved)
{
foreach (var handle in EnumerateProcessWindowHandles(p.Id))
{
// Get child windows
List<IntPtr> handles = GetChildWindows(handle);
// Hunt for "input"
foreach (IntPtr h in handles)
{
if (GetControlText(h).ToLower() == "input")
{
// Set target
target = h;
// Clear it
SendMessage(target, WM_SETTEXT, IntPtr.Zero, String.Empty);
// Set flag
inputSolved = true;
}
}
}
// Pause
Thread.Sleep(25);
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
// Exit
return string.Empty;
}
/// <summary>
/// Receives message from the framework
/// </summary>
public static string Receive(string sender, string type, string msg)
{
// Split by new line
string[] input = msg.Split(Environment.NewLine.ToCharArray());
/* Discriminate message */
// Check if OK msg
if (input[0] == "K")
{
// TODO: Process it
}
else
{
// Clear target
SendMessage(target, WM_SETTEXT, IntPtr.Zero, String.Empty);
// Send latest message
SendMessage(target, WM_SETTEXT, IntPtr.Zero, input[0]);
}
// Exit
return string.Empty;
}
/// <summary>
/// Sends message to the framework
/// </summary>
public static string Send(string msg)
{
// Try to send message
try
{
// Send
object ret = Assembly.GetEntryAssembly().GetType("BetSoftware_Loader.Comm").GetMethod("Receive", BindingFlags.Static | BindingFlags.Public).Invoke(null, new object[] { nSpace, type, msg });
// Return
return (string)ret;
}
catch (Exception)
{
// Let it fall through
}
return string.Empty;
}
}
}