Click here to Skip to main content
15,893,487 members
Articles / Desktop Programming / Win32

Mirror keys for multiboxing MMORPG games like WOW/LOTRO

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
7 Mar 2013CPOL5 min read 20.7K   800   3  
Raw input 64-bit .NET classes.

public class Processes
{
	private static int SecondPollTimeToDetectProcessClosingsAndOpenings = 5;
	private System.ComponentModel.BackgroundWorker bwCheckProcesses = new System.ComponentModel.BackgroundWorker();
	public SystemEvent ObjectCreated = new SystemEvent(SystemEvents.EVENT_OBJECT_CREATE);
	public SystemEvent ObjectDestroyed = new SystemEvent(SystemEvents.EVENT_OBJECT_DESTROY);
	public event ProcessClosedEventEventHandler ProcessClosedEvent;
	public delegate void ProcessClosedEventEventHandler(int processId);
	public event ProcessOpenedEventEventHandler ProcessOpenedEvent;
	public delegate void ProcessOpenedEventEventHandler(int processId);
	public event ProcessListChangedNamesEventHandler ProcessListChangedNames;
	public delegate void ProcessListChangedNamesEventHandler(string[] names);
	public event ProcessListChangedTitlesEventHandler ProcessListChangedTitles;
	public delegate void ProcessListChangedTitlesEventHandler(string[] titles);
	private System.Collections.SortedList ProcessList = new System.Collections.SortedList();
	private System.Collections.ArrayList ProcessNames = new System.Collections.ArrayList();
	private System.Collections.ArrayList ProcessTitles = new System.Collections.ArrayList();
	private System.Collections.Hashtable ProcessListAll = new System.Collections.Hashtable();
	private System.Collections.ArrayList ProcessNamesAll = new System.Collections.ArrayList();
	private System.Collections.ArrayList ProcessTitlesAll = new System.Collections.ArrayList();
	private string ProcessNamesPrev = "";
	private string ProcessTitlesPrev = "";
    private System.DateTime LastChecked = new System.DateTime(0);
	private string LastCheckedHwnd = "0000000000000000";

	private string LastCheckedHwndAttempted = "8888888888888888";
    public void OnObjectCreated(System.IntPtr hWinEventHook, uint eventType, System.IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
	{
		if (idChild != 0) {
			CheckProcesses(hwnd.ToString("X16"));
		}
	}

	public void OnObjectDestroyed(System.IntPtr hWinEventHook, uint eventType, System.IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
	{
		if (ProcessListAll.Contains(hwnd)) {
			CheckProcesses("");
		}
	}

	private void CheckProcesses(string Hwnd)
	{
        if (Hwnd.Equals("")) { Hwnd = "FFFFFFFFFFFFFFFF"; }
	    System.TimeSpan last = new System.TimeSpan(System.DateTime.Now.Ticks - LastChecked.Ticks);
		if (last.TotalSeconds < SecondPollTimeToDetectProcessClosingsAndOpenings) {
			LastCheckedHwndAttempted = Hwnd;
		} else {
			LastChecked = System.DateTime.Now;
			if (LastCheckedHwndAttempted != LastCheckedHwnd) {
				LastCheckedHwnd = Hwnd;
				LastCheckedHwndAttempted = Hwnd;
				try {
					ProcessListAll.Clear();
					System.Diagnostics.Process[] mProcesses = System.Diagnostics.Process.GetProcesses();
					for (int x = 0; x <= mProcesses.Length - 1; x++) {
						if ((mProcesses[x].MainWindowHandle != System.IntPtr.Zero) && (!ProcessListAll.Contains(mProcesses[x].MainWindowHandle))) {
							ProcessListAll.Add(mProcesses[x].MainWindowHandle, null);
						}
						string thisName =System.Convert.ToString(mProcesses[x].ProcessName.Trim());
						if (((thisName != null)) && (thisName.Length > 0) && (!ProcessNamesAll.Contains(thisName))) {
							ProcessNamesAll.Add(thisName);
						}
						ProcessNamesAll.Sort();
						string thisTitle =System.Convert.ToString(mProcesses[x].MainWindowTitle.Trim());
						if (((thisTitle != null)) && (thisTitle.Length > 0) && (!ProcessTitlesAll.Contains(thisTitle))) {
							ProcessTitlesAll.Add(thisTitle);
						}
						ProcessTitlesAll.Sort();
					}
				} catch (System.Exception ex) {
					System.Diagnostics.Debug.WriteLine(ex.ToString());
				}
				try {
					System.Collections.SortedList newProcessList = new System.Collections.SortedList();
					System.Diagnostics.Process[][] mProcesses = new System.Diagnostics.Process[ProcessNames.Count][];
					for (int x = 0; x <= ProcessNames.Count - 1; x++) {
						string thisName =System.Convert.ToString(ProcessNames[x]);
						mProcesses[x] = System.Diagnostics.Process.GetProcessesByName(thisName);
                        int i;
						for (i = 0; i <= mProcesses[x].Length - 1; i++) {
							if (ProcessTitles.Contains(mProcesses[x][i].MainWindowTitle)) {
								newProcessList.Add(mProcesses[x][i].Id, mProcesses[x][i]);
							}
						}
					}
					foreach (int processId in newProcessList.Keys) {
						if (!ProcessList.ContainsKey(processId)) {
							ProcessList.Add(processId, newProcessList[processId]);
							OnProcessChange(1, processId);
						}
					}
					int[] k = new int[ProcessList.Count];
					ProcessList.Keys.CopyTo(k, 0);
                    int j;
					for (j = 0; j <= k.Length - 1; j++) {
						if (!newProcessList.ContainsKey(k[j])) {
							ProcessList[k[j]] = null;
							ProcessList.Remove(k[j]);
							OnProcessChange(0, k[j]);
						}
					}
				} catch (System.Exception ex) {
					System.Diagnostics.Debug.WriteLine(ex.ToString());
				}
				ProcessNamesAll.Sort();
                object[] ProcessNamesAllObjectArray = ProcessNamesAll.ToArray();
                string[] ProcessNamesAllStringArray = System.Array.ConvertAll<object, string>(ProcessNamesAllObjectArray, o => o.ToString());
				string names = string.Join(",", ProcessNamesAllStringArray);
				ProcessTitlesAll.Sort();
                object[] ProcessTitlesAllObjectArray = ProcessTitlesAll.ToArray();
                string[] ProcessTitlesAllStringArray = System.Array.ConvertAll<object, string>(ProcessTitlesAllObjectArray, o => o.ToString());
				string titles = string.Join(",", ProcessTitlesAllStringArray);
				if (ProcessNamesPrev != names) {
					ProcessNamesPrev = names;
					OnProcessChange(2, names);
				}
				if (ProcessTitlesPrev != titles) {
					ProcessTitlesPrev = titles;
					OnProcessChange(3, titles);
				}
			}
		}
	}

	public void OnProcessChange(int progress, object e)
	{
		if (progress == 0) {
			if ((((ProcessClosedEvent != null)) && (ProcessClosedEvent.GetInvocationList().Length > 0))) {
				if (ProcessClosedEvent != null) {
					ProcessClosedEvent(System.Convert.ToInt32(e));
				}
			}
		} else if (progress == 1) {
			if ((((ProcessOpenedEvent != null)) && (ProcessOpenedEvent.GetInvocationList().Length > 0))) {
				if (ProcessOpenedEvent != null) {
					ProcessOpenedEvent(System.Convert.ToInt32(e));
				}
			}
		} else if (progress == 2) {
			if ((((ProcessListChangedNames != null)) && (ProcessListChangedNames.GetInvocationList().Length > 0))) {
				if (ProcessListChangedNames != null) {
					ProcessListChangedNames(System.Convert.ToString(e).Split(','));
				}
			}
		} else if (progress == 3) {
			if ((((ProcessListChangedTitles != null)) && (ProcessListChangedTitles.GetInvocationList().Length > 0))) {
				if (ProcessListChangedTitles != null) {
					ProcessListChangedTitles(System.Convert.ToString(e).Split(','));
				}
			}
		}
	}


	private void CheckProcesses(object sender, System.ComponentModel.DoWorkEventArgs e)
	{
		while (true) {
			if (bwCheckProcesses.CancellationPending == true) {
				e.Cancel = true;
				break; // TODO: might not be correct. Was : Exit While

			} else {
			}
			System.Threading.Thread.Sleep(SecondPollTimeToDetectProcessClosingsAndOpenings * 1000);
		}
	}

	public Processes(System.Collections.ArrayList Names, System.Collections.ArrayList Titles)
	{
        ObjectCreated.SystemEventHandler +=new SystemEvent.SystemEventEventHandler(OnObjectCreated);
        ObjectDestroyed.SystemEventHandler += new SystemEvent.SystemEventEventHandler(OnObjectDestroyed);
        bwCheckProcesses.DoWork +=new System.ComponentModel.DoWorkEventHandler(CheckProcesses);
		if ((Names != null))
			ProcessNames = Names;
		if ((Titles != null))
			ProcessTitles = Titles;
		bwCheckProcesses.WorkerReportsProgress = true;
		bwCheckProcesses.WorkerSupportsCancellation = true;
		bwCheckProcesses.RunWorkerAsync();
	}

	public void AddProcessName(string name)
	{
		if (!ProcessNames.Contains(name)) {
			ProcessNames.Add(name);
		}
	}

	public void RemoveProcessName(string name)
	{
		if (ProcessNames.Contains(name)) {
			ProcessNames.Remove(name);
		}
	}

	public void AddProcessTitle(string title)
	{
		if (!ProcessTitles.Contains(title)) {
			ProcessTitles.Add(title);
		}
	}

	public void RemoveProcessTitle(string title)
	{
		if (ProcessTitles.Contains(title)) {
			ProcessTitles.Remove(title);
		}
	}

	public System.Diagnostics.Process this[int index] {
		get {
			System.Diagnostics.Process result = null;
			if (index >= 0 && index < ProcessList.Count) {
				try {
					result = (System.Diagnostics.Process)ProcessList.GetByIndex(index);
				} catch (System.Exception ex) {
					System.Diagnostics.Debug.WriteLine(ex.ToString());
				}
			}
			return result;
		}
	}

	public int length {
		get { return ProcessList.Count; }
	}

}


By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions