11using System ;
22using System . Diagnostics ;
3+ using System . Runtime . InteropServices ;
34using System . Windows ;
45using System . Windows . Controls ;
56using System . Windows . Input ;
7+ using System . Windows . Media ;
8+ using System . Windows . Media . Imaging ;
69using Microsoft . Build . Logging . StructuredLogger ;
710
811namespace StructuredLogViewer . Controls ;
@@ -14,6 +17,33 @@ public GraphHostControl()
1417 Initialize ( ) ;
1518 }
1619
20+ public static double DpiX ;
21+ public static double DpiY ;
22+
23+ static GraphHostControl ( )
24+ {
25+ IntPtr dc = GetDC ( IntPtr . Zero ) ;
26+
27+ if ( dc != IntPtr . Zero )
28+ {
29+ const int LOGPIXELSX = 88 ;
30+ const int LOGPIXELSY = 90 ;
31+ DpiX = GetDeviceCaps ( dc , LOGPIXELSX ) / ( double ) 96 ;
32+ DpiY = GetDeviceCaps ( dc , LOGPIXELSY ) / ( double ) 96 ;
33+
34+ ReleaseDC ( IntPtr . Zero , dc ) ;
35+ }
36+ }
37+
38+ [ DllImport ( "User32.dll" , CallingConvention = CallingConvention . StdCall , ExactSpelling = true ) ]
39+ internal static extern IntPtr GetDC ( IntPtr hWnd ) ;
40+
41+ [ DllImport ( "User32.dll" , CallingConvention = CallingConvention . StdCall , ExactSpelling = true ) ]
42+ internal static extern int ReleaseDC ( IntPtr hWnd , IntPtr hDC ) ;
43+
44+ [ DllImport ( "Gdi32.dll" , CallingConvention = CallingConvention . StdCall , ExactSpelling = true ) ]
45+ internal static extern int GetDeviceCaps ( IntPtr hdc , int nIndex ) ;
46+
1747 public event Action < string > DisplayText ;
1848 public event Action < string > GoToSearch ;
1949
@@ -138,6 +168,14 @@ private void Initialize()
138168 BorderThickness = new Thickness ( )
139169 } ;
140170
171+ var copyImageButton = new Button
172+ {
173+ Content = "Copy screenshot" ,
174+ VerticalAlignment = VerticalAlignment . Center ,
175+ Margin = new Thickness ( 0 , 0 , 8 , 0 ) ,
176+ BorderThickness = new Thickness ( )
177+ } ;
178+
141179 var depthCheckbox = new CheckBox
142180 {
143181 Content = "Layer by depth" ,
@@ -159,6 +197,11 @@ private void Initialize()
159197 Margin = new Thickness ( 0 , 0 , 8 , 0 )
160198 } ;
161199
200+ copyImageButton . Click += ( s , e ) =>
201+ {
202+ CopyImage ( ) ;
203+ } ;
204+
162205 helpButton . Click += ( s , e ) =>
163206 {
164207 Process . Start ( new ProcessStartInfo ( "https://github.com/KirillOsenkov/MSBuildStructuredLog/wiki/Graph" ) { UseShellExecute = true } ) ;
@@ -204,6 +247,7 @@ private void Initialize()
204247 toolbar . Children . Add ( invertedCheckbox ) ;
205248 toolbar . Children . Add ( searchTextBox ) ;
206249 toolbar . Children . Add ( locateButton ) ;
250+ toolbar . Children . Add ( copyImageButton ) ;
207251 toolbar . Children . Add ( helpButton ) ;
208252
209253 topToolbar . Children . Add ( searchButton ) ;
@@ -265,4 +309,20 @@ void Locate()
265309
266310 Children . Add ( graphControl . Content ) ;
267311 }
312+
313+ private void CopyImage ( )
314+ {
315+ var visual = graphControl . CanvasElement ;
316+
317+ var renderTarget = new RenderTargetBitmap (
318+ ( int ) ( visual . DesiredSize . Width * DpiX ) ,
319+ ( int ) ( visual . DesiredSize . Height * DpiY ) ,
320+ 96 * DpiX ,
321+ 96 * DpiY ,
322+ PixelFormats . Pbgra32 ) ;
323+
324+ renderTarget . Render ( visual ) ;
325+
326+ Clipboard . SetImage ( renderTarget ) ;
327+ }
268328}
0 commit comments