Last active
September 16, 2015 20:50
-
-
Save fushnisoft/6a8c0e21fb395bdbc3b1 to your computer and use it in GitHub Desktop.
A quick and dirty way to attach "DebugView++.exe" to a window handle. The code makes a whole bunch of assumptions and has a lot of ugliness but it is so far serving my purpose so be nice :D
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.Diagnostics; | |
using System.IO; | |
using System.Runtime.InteropServices; | |
namespace Fushnisoft.Utils | |
{ | |
internal class EmbeddedDebugView | |
{ | |
private static IntPtr _dbgViewWin = IntPtr.Zero; | |
private static BackgroundWorker _bw = new BackgroundWorker(); | |
private static IntPtr _handle = IntPtr.Zero; | |
[DllImport("user32.dll")] | |
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); | |
[DllImport("user32.dll")] | |
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); | |
[DllImport("user32.dll")] | |
static extern bool MoveWindow(IntPtr Handle, int x, int y, int w, int h, bool repaint); | |
[DllImport("user32.dll")] | |
static extern bool PostMessage(IntPtr hWnd, uint Msg, Int32 wParam, Int32 lParam); | |
[DllImport("user32.dll", SetLastError = true)] | |
static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); | |
[DllImport("user32.dll")] | |
static extern bool InvalidateRect(IntPtr hWnd, IntPtr lpRect, bool bErase); | |
[StructLayout(LayoutKind.Sequential)] | |
public struct RECT | |
{ | |
public int Left; | |
public int Top; | |
public int Right; | |
public int Bottom; | |
} | |
// Constant values were found in the "windows.h" header file. | |
private const int WM_ACTIVATEAPP = 0x001C, | |
GWL_STYLE = -16, | |
WM_CLOSE = 0x10; | |
public static class WindowStyles | |
{ | |
public static readonly Int32 | |
WS_BORDER = 0x00800000, | |
WS_CAPTION = 0x00C00000, | |
WS_CHILD = 0x40000000, | |
WS_CHILDWINDOW = 0x40000000, | |
WS_CLIPCHILDREN = 0x02000000, | |
WS_CLIPSIBLINGS = 0x04000000, | |
WS_DISABLED = 0x08000000, | |
WS_DLGFRAME = 0x00400000, | |
WS_GROUP = 0x00020000, | |
WS_HSCROLL = 0x00100000, | |
WS_ICONIC = 0x20000000, | |
WS_MAXIMIZE = 0x01000000, | |
WS_MAXIMIZEBOX = 0x00010000, | |
WS_MINIMIZE = 0x20000000, | |
WS_MINIMIZEBOX = 0x00020000, | |
WS_OVERLAPPED = 0x00000000, | |
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, | |
WS_POPUP = unchecked((int)0x80000000), | |
WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU, | |
WS_SIZEBOX = 0x00040000, | |
WS_SYSMENU = 0x00080000, | |
WS_TABSTOP = 0x00010000, | |
WS_THICKFRAME = 0x00040000, | |
WS_TILED = 0x00000000, | |
WS_TILEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, | |
WS_VISIBLE = 0x10000000, | |
WS_VSCROLL = 0x00200000; | |
} | |
internal static void Resize() | |
{ | |
if (_dbgViewWin != IntPtr.Zero && _handle != IntPtr.Zero) | |
{ | |
RECT rect = new RECT(); | |
GetWindowRect(_handle, out rect); | |
MoveWindow(_dbgViewWin, 0, 0, rect.Right - rect.Left, rect.Bottom - rect.Top, true); | |
InvalidateRect(_handle, IntPtr.Zero, true); | |
} | |
} | |
internal static void Init(int handle) | |
{ | |
_handle = new IntPtr(handle); | |
_bw.DoWork += new DoWorkEventHandler(bw_DoWork); | |
_bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); | |
_bw.RunWorkerAsync(); | |
} | |
private static void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) | |
{ | |
if (e.Result != null) | |
{ | |
_dbgViewWin = (IntPtr)e.Result; | |
SetParent(_dbgViewWin, _handle); | |
// Remove border and whatnot | |
SetWindowLong(_dbgViewWin, GWL_STYLE, WindowStyles.WS_VISIBLE); | |
// Move the window to overlay it on this window | |
RECT rect = new RECT(); | |
GetWindowRect(_handle, out rect); | |
MoveWindow(_dbgViewWin, 0, 0, rect.Right - rect.Left, rect.Bottom - rect.Top, true); | |
} | |
} | |
private static void bw_DoWork(object sender, DoWorkEventArgs e) | |
{ | |
string debugViewPath = "DebugView++.exe"; | |
if (debugViewPath != "" && File.Exists(debugViewPath) == true) | |
{ | |
Process p = null; | |
Process[] processes = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(debugViewPath)); | |
if (processes.Length > 0) | |
{ | |
p = processes[0]; | |
if (p.MainWindowHandle == IntPtr.Zero) | |
{ | |
p.Kill(); | |
p = null; | |
} | |
} | |
if (p == null) | |
{ | |
p = Process.Start(debugViewPath, "/f"); | |
} | |
p.WaitForInputIdle(); | |
e.Result = p.MainWindowHandle; | |
} | |
} | |
internal static void Destroy() | |
{ | |
// Stop the application | |
if (_dbgViewWin != IntPtr.Zero) | |
{ | |
// Post a close message | |
PostMessage(_dbgViewWin, WM_CLOSE, 0, 0); | |
// Delay for it to get the message | |
System.Threading.Thread.Sleep(1000); | |
// Clear internal handle | |
_dbgViewWin = IntPtr.Zero; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment