|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionMicrosoft made it fairly easy to implement a custom debugger visualizer for Visual Studio and there are numerous samples on the Web. Credits
BackgroundThe solution consists of using a [Serializable]
public sealed class SerializableGraphics : IDisposable
{
private readonly Bitmap bitmap;
public SerializableGraphics(Graphics graphics)
{
if (graphics == null)
{
throw new ArgumentNullException("graphics");
}
FieldInfo fi = graphics.GetType().GetField
("backingImage", BindingFlags.NonPublic | BindingFlags.Instance);
if (fi != null)
{
Bitmap bm = (Bitmap)fi.GetValue(graphics);
if (bm != null)
{
// graphics was derived from image : clone internal bitmap
bitmap = (Bitmap)bm.Clone();
}
else
{
// graphics without backing image : bitblt to new bitmap
Size sz = graphics.VisibleClipBounds.Size.ToSize();
bitmap = new Bitmap(sz.Width, sz.Height, graphics);
drawToBitmap(bitmap, graphics);
}
}
}
public Bitmap Bitmap
{
get { return bitmap; }
}
private static void drawToBitmap(Image bitmap, Graphics graphics)
{
using(Graphics g = Graphics.FromImage(bitmap))
{
IntPtr hdcDst = g.GetHdc();
IntPtr hdcSrc = graphics.GetHdc();
try
{
if (!SafeNativeMethods.BitBlt(
hdcDst, 0, 0, bitmap.Width, bitmap.Height,
hdcSrc, 0, 0, CopyPixelOperation.SourceCopy))
{
throw new Win32Exception();
}
}
finally
{
g.ReleaseHdc(hdcDst);
graphics.ReleaseHdc(hdcSrc);
}
}
}
public void Dispose()
{
if (bitmap != null)
{
bitmap.Dispose();
}
}
}
A derived internal class GraphicsVisualizerObjectSource : VisualizerObjectSource
{
public override void GetData(object target, System.IO.Stream outgoingData)
{
Graphics data = (Graphics) target;
base.GetData(new SerializableGraphics(data), outgoingData);
}
}
On the debugger side, the data is unwrapped and displayed. public class GraphicsVisualizer : DialogDebuggerVisualizer
{
protected override void Show(IDialogVisualizerService windowService,
IVisualizerObjectProvider objectProvider)
{
using (SerializableGraphics wrapper =
(SerializableGraphics)objectProvider.GetObject())
{
using (BitmapVisualizerForm form = new BitmapVisualizerForm())
{
form.DebugBitmap = wrapper.Bitmap;
windowService.ShowDialog(form);
}
}
}
}
Finally the [assembly: DebuggerVisualizer(typeof(GraphicsVisualizer),
typeof(GraphicsVisualizerObjectSource),
Target = typeof(Graphics), Description = "Graphics debugger visualizer")]
OptionsBy default, the Other Goodies (See Source)The ImprovementsMy code provides just a simple readonly visualization, more info of the Using the CodeDrop the compiled DLL in ..\Microsoft Visual Studio 8\Common7\Packages\Debugger\Visualizers or the user-specific MyDocuments\Visual Studio 2005\Visualizers folder. When debugging and at a breakpoint, the little magnifying glass will appear in the datatip for Points of InterestThe code was tested on Visual Studio 2005/ Windows XP only. Note that, the History
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||