Skip to content

Commit aa67fd4

Browse files
committed
Issues #150 Support of screenshots for windows with hardware accelerated rendering
1 parent 989f826 commit aa67fd4

File tree

11 files changed

+314
-33
lines changed

11 files changed

+314
-33
lines changed

SmartSystemMenu/Forms/MainForm.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,13 @@ private void SysCommand(object sender, SysCommandEventArgs e)
599599

600600
case MenuItemId.SC_SAVE_SCREEN_SHOT:
601601
{
602-
var bitmap = WindowUtils.PrintWindow(window.Handle);
602+
var result = WindowUtils.PrintWindow(window.Handle, out var bitmap);
603+
if (!result || !WindowUtils.IsCorrectScreenshot(window.Handle, bitmap))
604+
{
605+
Thread.Sleep(1000);
606+
WindowUtils.CaptureWindow(window.Handle, false, out bitmap);
607+
}
608+
603609
var dialog = new SaveFileDialog
604610
{
605611
OverwritePrompt = true,
@@ -625,7 +631,13 @@ private void SysCommand(object sender, SysCommandEventArgs e)
625631

626632
case MenuItemId.SC_COPY_SCREEN_SHOT:
627633
{
628-
var bitmap = WindowUtils.PrintWindow(window.Handle);
634+
var result = WindowUtils.PrintWindow(window.Handle, out var bitmap);
635+
if (!result || !WindowUtils.IsCorrectScreenshot(window.Handle, bitmap))
636+
{
637+
Thread.Sleep(1000);
638+
WindowUtils.CaptureWindow(window.Handle, false, out bitmap);
639+
}
640+
629641
Clipboard.SetImage(bitmap);
630642
}
631643
break;

SmartSystemMenu/Native/Constants.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,5 +146,10 @@ static class Constants
146146
public const int SE_PRIVILEGE_ENABLED = 0x02;
147147

148148
public const int SEND_CHILD_HANDLE = 1;
149+
150+
public const int CURSOR_SHOWING = 0x00000001;
151+
152+
public const int DI_COMPAT = 0x0004;
153+
public const int DI_NORMAL = 0x0003;
149154
}
150155
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System;
2+
3+
namespace SmartSystemMenu.Native.Enums
4+
{
5+
[Flags]
6+
public enum CopyPixelOperations
7+
{
8+
NoMirrorBitmap = -2147483648,
9+
10+
/// <summary>dest = BLACK, 0x00000042</summary>
11+
Blackness = 66,
12+
13+
///<summary>dest = (NOT src) AND (NOT dest), 0x001100A6</summary>
14+
NotSourceErase = 1114278,
15+
16+
///<summary>dest = (NOT source), 0x00330008</summary>
17+
NotSourceCopy = 3342344,
18+
19+
///<summary>dest = source AND (NOT dest), 0x00440328</summary>
20+
SourceErase = 4457256,
21+
22+
/// <summary>dest = (NOT dest), 0x00550009</summary>
23+
DestinationInvert = 5570569,
24+
25+
/// <summary>dest = pattern XOR dest, 0x005A0049</summary>
26+
PatInvert = 5898313,
27+
28+
///<summary>dest = source XOR dest, 0x00660046</summary>
29+
SourceInvert = 6684742,
30+
31+
///<summary>dest = source AND dest, 0x008800C6</summary>
32+
SourceAnd = 8913094,
33+
34+
/// <summary>dest = (NOT source) OR dest, 0x00BB0226</summary>
35+
MergePaint = 12255782,
36+
37+
///<summary>dest = (source AND pattern), 0x00C000CA</summary>
38+
MergeCopy = 12583114,
39+
40+
///<summary>dest = source, 0x00CC0020</summary>
41+
SourceCopy = 13369376,
42+
43+
/// <summary>dest = source OR dest, 0x00EE0086</summary>
44+
SourcePaint = 15597702,
45+
46+
/// <summary>dest = pattern, 0x00F00021</summary>
47+
PatCopy = 15728673,
48+
49+
/// <summary>dest = DPSnoo, 0x00FB0A09</summary>
50+
PatPaint = 16452105,
51+
52+
/// <summary>dest = WHITE, 0x00FF0062</summary>
53+
Whiteness = 16711778,
54+
55+
/// <summary>
56+
/// Capture window as seen on screen. This includes layered windows
57+
/// such as WPF windows with AllowsTransparency="true", 0x40000000
58+
/// </summary>
59+
CaptureBlt = 1073741824,
60+
}
61+
}

SmartSystemMenu/Native/Gdi32.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
using SmartSystemMenu.Native.Enums;
4+
5+
namespace SmartSystemMenu.Native
6+
{
7+
static class Gdi32
8+
{
9+
[DllImport("gdi32.dll", EntryPoint = "CreateCompatibleDC", SetLastError = true)]
10+
public static extern IntPtr CreateCompatibleDC([In] IntPtr hdc);
11+
12+
[DllImport("gdi32.dll", EntryPoint = "SelectObject")]
13+
public static extern IntPtr SelectObject([In] IntPtr hdc, [In] IntPtr hgdiobj);
14+
15+
[DllImport("gdi32.dll", EntryPoint = "BitBlt", SetLastError = true)]
16+
[return: MarshalAs(UnmanagedType.Bool)]
17+
public static extern bool BitBlt([In] IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, [In] IntPtr hdcSrc, int nXSrc, int nYSrc, CopyPixelOperations dwRop);
18+
19+
[DllImport("gdi32.dll", EntryPoint = "StretchBlt", SetLastError = true)]
20+
[return: MarshalAs(UnmanagedType.Bool)]
21+
public static extern bool StretchBlt([In] IntPtr hdc, int nXDest, int nYDest, int nWidthDest, int nHeightDest, [In] IntPtr hdcSrc, int nXSrc, int nYSrc, int nWidthSource, int nHeightSource, CopyPixelOperations dwRop);
22+
23+
[DllImport("gdi32.dll")]
24+
public static extern IntPtr CreateDIBSection(IntPtr hdc, [In] ref IntPtr pbmi, uint pila, out IntPtr ppvBits, IntPtr hSection, uint dwOffset);
25+
26+
[DllImport("gdi32.dll", EntryPoint = "DeleteDC")]
27+
public static extern bool DeleteDC([In] IntPtr hdc);
28+
29+
[DllImport("gdi32.dll")]
30+
public static extern int GetObject(IntPtr hgdiobj, int cbBuffer, IntPtr lpvObject);
31+
32+
[DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
33+
[return: MarshalAs(UnmanagedType.Bool)]
34+
public static extern bool DeleteObject([In] IntPtr hObject);
35+
36+
[DllImport("gdi32.dll")]
37+
public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
38+
39+
[DllImport("gdi32.dll")]
40+
internal static extern int GetDeviceCaps(IntPtr hdc, int capindex);
41+
42+
[DllImport("gdi32.dll")]
43+
internal static extern bool PatBlt(IntPtr hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, uint dwRop);
44+
}
45+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
4+
namespace SmartSystemMenu.Native.Structs
5+
{
6+
[StructLayout(LayoutKind.Sequential)]
7+
struct CURSORINFO
8+
{
9+
public Int32 cbSize;
10+
public Int32 flags;
11+
public IntPtr hCursor;
12+
public POINTAPI ptScreenPos;
13+
}
14+
15+
[StructLayout(LayoutKind.Sequential)]
16+
struct POINTAPI
17+
{
18+
public int x;
19+
public int y;
20+
}
21+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
4+
namespace SmartSystemMenu.Native.Structs
5+
{
6+
[StructLayout(LayoutKind.Sequential)]
7+
struct ICONINFO
8+
{
9+
public bool fIcon;
10+
public Int32 xHotspot;
11+
public Int32 yHotspot;
12+
public IntPtr hbmMask;
13+
public IntPtr hbmColor;
14+
}
15+
}

SmartSystemMenu/Native/User32.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,27 @@ static class User32
129129
[DllImport("user32.dll")]
130130
public static extern IntPtr GetDesktopWindow();
131131

132+
[DllImport("user32.dll")]
133+
public static extern IntPtr GetWindowDC(IntPtr ptr);
134+
135+
[DllImport("user32.dll")]
136+
public static extern IntPtr GetDC(IntPtr hWnd);
137+
138+
[DllImport("user32.dll")]
139+
public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc);
140+
141+
[DllImport("user32.dll")]
142+
public static extern bool GetCursorInfo(out CURSORINFO pci);
143+
144+
[DllImport("user32.dll")]
145+
public static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO piconinfo);
146+
147+
[DllImport("user32.dll")]
148+
public static extern bool DrawIconEx(IntPtr hdc, int xLeft, int yTop, IntPtr hIcon, int cxWidth, int cyHeight, int istepIfAniCur, IntPtr hbrFlickerFreeDraw, int diFlags);
149+
150+
[DllImport("user32.dll")]
151+
public static extern bool DestroyIcon(IntPtr hIcon);
152+
132153
[DllImport("user32.dll")]
133154
[return: MarshalAs(UnmanagedType.Bool)]
134155
public static extern bool SetWindowPos(IntPtr handle, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);

SmartSystemMenu/Program.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,12 @@ static void ProcessCommandLine(ToggleParser toggleParser, ApplicationSettings se
390390
// Copy Screenshot
391391
if (toggleParser.HasToggle("copyscreenshot"))
392392
{
393-
var bitmap = WindowUtils.PrintWindow(window.Handle);
393+
var result = WindowUtils.PrintWindow(window.Handle, out var bitmap);
394+
if (!result || !WindowUtils.IsCorrectScreenshot(window.Handle, bitmap))
395+
{
396+
WindowUtils.CaptureWindow(window.Handle, false, out bitmap);
397+
}
398+
394399
Clipboard.SetImage(bitmap);
395400
}
396401

@@ -404,7 +409,12 @@ static void ProcessCommandLine(ToggleParser toggleParser, ApplicationSettings se
404409
//Save Screenshot
405410
if (toggleParser.HasToggle("s") || toggleParser.HasToggle("savescreenshot"))
406411
{
407-
var bitmap = WindowUtils.PrintWindow(window.Handle);
412+
var result = WindowUtils.PrintWindow(window.Handle, out var bitmap);
413+
if (!result || !WindowUtils.IsCorrectScreenshot(window.Handle, bitmap))
414+
{
415+
WindowUtils.CaptureWindow(window.Handle, false, out bitmap);
416+
}
417+
408418
var dialog = new SaveFileDialog
409419
{
410420
OverwritePrompt = true,

SmartSystemMenu/SmartSystemMenu.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@
156156
<Compile Include="Native\Advapi32.cs" />
157157
<Compile Include="Native\Dwmapi.cs" />
158158
<Compile Include="Native\Enums\AccentState.cs" />
159+
<Compile Include="Native\Enums\CopyPixelOperations.cs" />
159160
<Compile Include="Native\Enums\DPI_AWARENESS_CONTEXT.cs" />
160161
<Compile Include="Native\Enums\DWM_BB.cs" />
161162
<Compile Include="Native\Enums\GetAncestorFlags.cs" />
@@ -172,6 +173,7 @@
172173
<Compile Include="Native\Enums\TOKEN_TYPE.cs" />
173174
<Compile Include="Native\Enums\WindowCompositionAttribute.cs" />
174175
<Compile Include="Native\Enums\WindowShowStyle.cs" />
176+
<Compile Include="Native\Gdi32.cs" />
175177
<Compile Include="Native\Hooks.cs" />
176178
<Compile Include="Native\Kernel32.cs" />
177179
<Compile Include="Native\Ntdll.cs" />
@@ -180,7 +182,9 @@
180182
<Compile Include="Native\Structs\ConsoleScreenBufferInfo.cs" />
181183
<Compile Include="Native\Structs\Coord.cs" />
182184
<Compile Include="Native\Structs\CopyDataStruct.cs" />
185+
<Compile Include="Native\Structs\CURSORINFO.cs" />
183186
<Compile Include="Native\Structs\DWM_BLURBEHIND.cs" />
187+
<Compile Include="Native\Structs\ICONINFO.cs" />
184188
<Compile Include="Native\Structs\KeyboardLLHookStruct.cs" />
185189
<Compile Include="Native\Structs\LUID.cs" />
186190
<Compile Include="Native\Structs\LUID_AND_ATTRIBUTES.cs" />

0 commit comments

Comments
 (0)