Skip to content

Instantly share code, notes, and snippets.

@Jadd
Last active April 24, 2017 06:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jadd/5a2810ff9d96a8f30a77059c45187c07 to your computer and use it in GitHub Desktop.
Save Jadd/5a2810ff9d96a8f30a77059c45187c07 to your computer and use it in GitHub Desktop.
WinForms drag-and-drop process selector.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Ace.UI.Forms {
public partial class ProcessSelector : UserControl {
#region Imports
private delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private const int WH_MOUSE_LL = 14;
private const int WM_LBUTTONUP = 0x202;
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int hookType, HookProc lpfn, IntPtr hMod, int dwThreadId);
[DllImport("user32.dll")]
private static extern bool UnhookWindowsHookEx(IntPtr idHook);
[DllImport("user32.dll")]
private static extern int CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
private static extern IntPtr WindowFromPoint(Point p);
[DllImport("user32.dll")]
private static extern IntPtr GetAncestor(IntPtr hwnd, uint flags);
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int processId);
#endregion
#region Properties
public Process SelectedProcess { get; private set; }
#endregion
#region Fields
private readonly HookProc _mouseHookProcedure;
private IntPtr _hookId;
private bool _dragging;
#endregion
public ProcessSelector() {
InitializeComponent();
Disposed += OnDisposed;
_mouseHookProcedure = OnMouseEvent;
}
private void OnDisposed(object sender, EventArgs e) {
UnhookMouseEvents();
}
private void TargetImage_MouseDown(object sender, MouseEventArgs e) {
HookMouseEvents();
_dragging = true;
DoDragDrop(sender, DragDropEffects.None);
}
private int OnMouseEvent(int nCode, IntPtr wParam, IntPtr lParam) {
if (_dragging && wParam.ToInt32() == WM_LBUTTONUP) {
var window = GetAncestor(WindowFromPoint(MousePosition), 2);
int processId;
GetWindowThreadProcessId(window, out processId);
var process = Process.GetProcessById(processId);
_dragging = false;
SetProcessInfo(process);
}
return CallNextHookEx(_hookId, nCode, wParam, lParam);
}
private void HookMouseEvents() {
_hookId = SetWindowsHookEx(WH_MOUSE_LL, _mouseHookProcedure, IntPtr.Zero, 0);
if (_hookId == IntPtr.Zero)
throw new Win32Exception("Cannot perform SetWindowsHookEx.");
}
private void UnhookMouseEvents() {
if (_hookId == IntPtr.Zero)
return;
UnhookWindowsHookEx(_hookId);
_hookId = IntPtr.Zero;
}
private void SetProcessInfo(Process process) {
if (InvokeRequired) {
Invoke((Action<Process>) SetProcessInfo, process);
return;
}
UnhookMouseEvents();
if (process.Id == Process.GetCurrentProcess().Id)
return;
ProcessIdValue.Text = process.Id.ToString();
ProcessNameValue.Text = process.ProcessName + ".exe";
SelectedProcess = process;
}
}
}
namespace Ace.UI.Forms {
partial class ProcessSelector {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
this.TargetImage = new System.Windows.Forms.PictureBox();
this.ProcessIdLabel = new System.Windows.Forms.Label();
this.StatusLabel = new System.Windows.Forms.Label();
this.ProcessNameValue = new System.Windows.Forms.Label();
this.ProcessNameLabel = new System.Windows.Forms.Label();
this.ProcessIdValue = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.TargetImage)).BeginInit();
this.SuspendLayout();
//
// TargetImage
//
this.TargetImage.Image = global::Ace.UI.Properties.Resources.TargetIcon;
this.TargetImage.Location = new System.Drawing.Point(0, 0);
this.TargetImage.Name = "TargetImage";
this.TargetImage.Size = new System.Drawing.Size(32, 32);
this.TargetImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.TargetImage.TabIndex = 1;
this.TargetImage.TabStop = false;
this.TargetImage.MouseDown += new System.Windows.Forms.MouseEventHandler(this.TargetImage_MouseDown);
//
// ProcessIdLabel
//
this.ProcessIdLabel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.ProcessIdLabel.Location = new System.Drawing.Point(38, 0);
this.ProcessIdLabel.Name = "ProcessIdLabel";
this.ProcessIdLabel.Size = new System.Drawing.Size(91, 15);
this.ProcessIdLabel.TabIndex = 2;
this.ProcessIdLabel.Text = "Process ID:";
//
// StatusLabel
//
this.StatusLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.StatusLabel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.StatusLabel.Location = new System.Drawing.Point(0, 33);
this.StatusLabel.Name = "StatusLabel";
this.StatusLabel.Size = new System.Drawing.Size(271, 23);
this.StatusLabel.TabIndex = 8;
this.StatusLabel.Text = "Drag the target icon over the game window...";
this.StatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// ProcessNameValue
//
this.ProcessNameValue.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.ProcessNameValue.AutoEllipsis = true;
this.ProcessNameValue.Location = new System.Drawing.Point(135, 17);
this.ProcessNameValue.Name = "ProcessNameValue";
this.ProcessNameValue.Size = new System.Drawing.Size(133, 15);
this.ProcessNameValue.TabIndex = 5;
//
// ProcessNameLabel
//
this.ProcessNameLabel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.ProcessNameLabel.Location = new System.Drawing.Point(38, 17);
this.ProcessNameLabel.Name = "ProcessNameLabel";
this.ProcessNameLabel.Size = new System.Drawing.Size(91, 15);
this.ProcessNameLabel.TabIndex = 3;
this.ProcessNameLabel.Text = "Process Name:";
//
// ProcessIdValue
//
this.ProcessIdValue.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.ProcessIdValue.AutoEllipsis = true;
this.ProcessIdValue.Location = new System.Drawing.Point(135, 0);
this.ProcessIdValue.Name = "ProcessIdValue";
this.ProcessIdValue.Size = new System.Drawing.Size(133, 15);
this.ProcessIdValue.TabIndex = 4;
//
// ProcessSelector
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Window;
this.Controls.Add(this.TargetImage);
this.Controls.Add(this.ProcessIdLabel);
this.Controls.Add(this.StatusLabel);
this.Controls.Add(this.ProcessIdValue);
this.Controls.Add(this.ProcessNameValue);
this.Controls.Add(this.ProcessNameLabel);
this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Name = "ProcessSelector";
this.Size = new System.Drawing.Size(271, 56);
((System.ComponentModel.ISupportInitialize)(this.TargetImage)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.PictureBox TargetImage;
private System.Windows.Forms.Label ProcessIdLabel;
private System.Windows.Forms.Label StatusLabel;
private System.Windows.Forms.Label ProcessNameValue;
private System.Windows.Forms.Label ProcessNameLabel;
private System.Windows.Forms.Label ProcessIdValue;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment