Last active
April 4, 2025 11:15
-
-
Save blackholeearth/f5f52168179e67c98a023d01693ae1a4 to your computer and use it in GitHub Desktop.
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.Collections.Generic; | |
using System.Windows.Forms; | |
using System.ComponentModel; | |
using System.Drawing; | |
using System.Runtime.InteropServices; | |
namespace Experiment_VS_Graphics_FromHwnd | |
{ | |
public class Form1 : Form | |
{ | |
private IContainer components = null; | |
private Timer timer1; | |
System.Diagnostics.Process visualStudio; | |
HashSet<IntPtr> windowHandles = new HashSet<IntPtr>(); | |
protected override void Dispose(bool disposing) | |
{ | |
if (disposing && (components != null)) | |
{ | |
components.Dispose(); | |
} | |
base.Dispose(disposing); | |
} | |
private void InitializeComponent() | |
{ | |
this.components = new System.ComponentModel.Container(); | |
this.timer1 = new System.Windows.Forms.Timer(this.components); | |
this.SuspendLayout(); | |
// | |
// timer1 | |
// | |
this.timer1.Enabled = true; | |
this.timer1.Interval = 5000; | |
this.timer1.Tick += new System.EventHandler(this.timer1_Tick); | |
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); | |
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; | |
this.ClientSize = new System.Drawing.Size(284, 262); | |
this.Name = "Form1"; | |
this.Text = "Form1"; | |
this.ResumeLayout(false); | |
} | |
public Form1() | |
{ | |
InitializeComponent(); | |
visualStudio = System.Diagnostics.Process.GetProcessesByName("devenv")[0]; | |
EnumWindows(WindowReceiver, IntPtr.Zero); //populate windowHandles with top level windows | |
} | |
void EnumerateWindowsRecursivelyImpl(IntPtr hWnd) | |
{ | |
if (hWnd == IntPtr.Zero || !windowHandles.Add(hWnd)) return; | |
EnumerateWindowsRecursivelyImpl(GetWindow(hWnd, (uint)GetWindow_Cmd.GW_CHILD)); | |
EnumerateWindowsRecursivelyImpl(GetWindow(hWnd, (uint)GetWindow_Cmd.GW_HWNDNEXT)); | |
} | |
bool WindowReceiver(IntPtr hWnd, IntPtr dontCare) | |
{ | |
uint pid; | |
GetWindowThreadProcessId(hWnd, out pid); | |
if (pid == (uint)visualStudio.Id) | |
{ | |
windowHandles.Add(hWnd); | |
EnumerateWindowsRecursivelyImpl(GetWindow(hWnd, (uint)GetWindow_Cmd.GW_CHILD)); | |
} | |
return true; | |
} | |
private void timer1_Tick(object sender, EventArgs e) | |
{ | |
windowHandles.Clear(); | |
EnumWindows(WindowReceiver, IntPtr.Zero); //populate windowHandles with top level windows | |
foreach (var window in windowHandles) | |
{ | |
var gfx = Graphics.FromHwnd(window); | |
gfx.DrawString("Have fun!", Font, Brushes.Black, 10, 10); | |
gfx.Dispose(); | |
} | |
} | |
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); | |
[DllImport("user32.dll")] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); | |
[DllImport("user32.dll", SetLastError = true)] | |
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); | |
[DllImport("user32.dll", SetLastError = true)] | |
static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd); | |
enum GetWindow_Cmd : uint | |
{ | |
GW_HWNDFIRST = 0, | |
GW_HWNDLAST = 1, | |
GW_HWNDNEXT = 2, | |
GW_HWNDPREV = 3, | |
GW_OWNER = 4, | |
GW_CHILD = 5, | |
GW_ENABLEDPOPUP = 6 | |
} | |
} | |
static class Program | |
{ | |
/// <summary> | |
/// The main entry point for the application. | |
/// </summary> | |
[STAThread] | |
static void Main() | |
{ | |
Application.EnableVisualStyles(); | |
Application.SetCompatibleTextRenderingDefault(false); | |
Application.Run(new Form1()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
answer taken from : https://stackoverflow.com/a/34365438/3137362
Use the System.Drawing.Graphics.FromHwnd method, passing in the HWND for the designer window.
Get the HWND by drilling down into the window handles for visual studio, via pinvoke. Perhaps use tools like Inspect to find window classes and other information that might help you identify the correct (designer) window.
I've written a C# program to get you started here.
*pasted bin is Blocked - copied to gist.github*