Last active
April 24, 2017 06:48
-
-
Save Jadd/5a2810ff9d96a8f30a77059c45187c07 to your computer and use it in GitHub Desktop.
WinForms drag-and-drop process selector.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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