|
|
|
Title:
|
Take a screenshot of an open window
|
Language:
|
C#
|
|
Description:
|
Given a handle of an open window, takes a screenshot of that window and returns it as an image object.
|
Views:
|
376
|
|
Author:
|
Matt Schmidt
|
Date Added:
|
8/15/2008
|
Copy
|
Code
|
|
1 /// <summary>
2 /// Takes a screenshot of a specified window and keeps the result in the clipboard.
3 /// </summary>
4 /// <param name="hwnd">Window handle</param>
5 private System.Drawing.Image GetScreenshot(int hwnd)
6 {
7 SetWindowPos((IntPtr)hwnd, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
8
9 //?? it works but why?
10 Thread.Sleep(100);
11
12 SetForegroundWindow((IntPtr)hwnd);
13
14 uint intReturn = 0;
15 INPUT structInput;
16 structInput = new INPUT();
17 structInput.type = (uint)1;
18 structInput.ki.wScan = 0;
19 structInput.ki.time = 0;
20 structInput.ki.dwFlags = 0;
21 structInput.ki.dwExtraInfo = 0;
22
23 //Key down Alt Key
24 structInput.ki.wVk = (ushort)VK.MENU;
25 intReturn = SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
26
27 //Key down Print Screen
28 structInput.ki.wVk = (ushort)VK.SNAPSHOT;//vk;
29 intReturn = SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
30
31 //Key up Print Screen
32 structInput.ki.dwFlags = KEYEVENTF_KEYUP;
33 structInput.ki.wVk = (ushort)VK.SNAPSHOT;//vk;
34 intReturn = SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
35
36 //Key up Alt
37 structInput.ki.dwFlags = KEYEVENTF_KEYUP;
38 structInput.ki.wVk = (ushort)VK.MENU;
39 intReturn = SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
40
41 //Need to let the print screen copy catch up with the rest of the code, other wise the clipboard will be read before
42 //it is written to
43 Thread.Sleep(100);
44
45 Win32.SetWindowPos((IntPtr)hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, Win32.TOPMOST_FLAGS);
46
47 System.Windows.Forms.IDataObject data = Clipboard.GetDataObject();
48
49 try
50 {
51 if (data.GetDataPresent(DataFormats.Bitmap))
52 {
53 System.Drawing.Image image = (System.Drawing.Image)data.GetData(DataFormats.Bitmap, true);
54 return image;
55 }
56 else throw new Exception("Expected bitmap image.");
57 }
58 catch (Exception ex)
59 {
60 return null;
61 }
62 }
63
64 // For Windows Mobile, replace user32.dll with coredll.dll
65 [DllImport("user32.dll")]
66 [return: MarshalAs(UnmanagedType.Bool)]
67 public static extern bool SetForegroundWindow(IntPtr hWnd);
68
69 [DllImport("user32.dll")]
70 public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,
71 int Y, int cx, int cy, uint uFlags);
72
73 public const ushort KEYEVENTF_KEYUP = 0x0002;
74
75 public enum VK : ushort
76 {
77 SHIFT = 0x10,
78 CONTROL = 0x11,
79 MENU = 0x12,
80 ESCAPE = 0x1B,
81 BACK = 0x08,
82 TAB = 0x09,
83 RETURN = 0x0D,
84 PRIOR = 0x21,
85 NEXT = 0x22,
86 END = 0x23,
87 HOME = 0x24,
88 LEFT = 0x25,
89 UP = 0x26,
90 RIGHT = 0x27,
91 DOWN = 0x28,
92 SELECT = 0x29,
93 PRINT = 0x2A,
94 EXECUTE = 0x2B,
95 SNAPSHOT = 0x2C,
96 INSERT = 0x2D,
97 DELETE = 0x2E,
98 HELP = 0x2F,
99 NUMPAD0 = 0x60,
100 NUMPAD1 = 0x61,
101 NUMPAD2 = 0x62,
102 NUMPAD3 = 0x63,
103 NUMPAD4 = 0x64,
104 NUMPAD5 = 0x65,
105 NUMPAD6 = 0x66,
106 NUMPAD7 = 0x67,
107 NUMPAD8 = 0x68,
108 NUMPAD9 = 0x69,
109 MULTIPLY = 0x6A,
110 ADD = 0x6B,
111 SEPARATOR = 0x6C,
112 SUBTRACT = 0x6D,
113 DECIMAL = 0x6E,
114 DIVIDE = 0x6F,
115 F1 = 0x70,
116 F2 = 0x71,
117 F3 = 0x72,
118 F4 = 0x73,
119 F5 = 0x74,
120 F6 = 0x75,
121 F7 = 0x76,
122 F8 = 0x77,
123 F9 = 0x78,
124 F10 = 0x79,
125 F11 = 0x7A,
126 F12 = 0x7B,
127 OEM_1 = 0xBA, // ',:' for US
128 OEM_PLUS = 0xBB, // '+' any country
129 OEM_COMMA = 0xBC, // ',' any country
130 OEM_MINUS = 0xBD, // '-' any country
131 OEM_PERIOD = 0xBE, // '.' any country
132 OEM_2 = 0xBF, // '/?' for US
133 OEM_3 = 0xC0, // '`~' for US
134 MEDIA_NEXT_TRACK = 0xB0,
135 MEDIA_PREV_TRACK = 0xB1,
136 MEDIA_STOP = 0xB2,
137 MEDIA_PLAY_PAUSE = 0xB3,
138 LWIN = 0x5B,
139 RWIN = 0x5C
140 }
141
142 public struct KEYBDINPUT
143 {
144 public ushort wVk;
145 public ushort wScan;
146 public uint dwFlags;
147 public long time;
148 public uint dwExtraInfo;
149 };
150
151 [StructLayout(LayoutKind.Explicit, Size = 28)]
152 public struct INPUT
153 {
154 [FieldOffset(0)]
155 public uint type;
156 [FieldOffset(4)]
157 public KEYBDINPUT ki;
158 };
159
160 public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
161 public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
162 public static readonly IntPtr HWND_TOP = new IntPtr(0);
163 public static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
164
165 // From winuser.h
166 public const UInt32 SWP_NOSIZE = 0x0001;
167 public const UInt32 SWP_NOMOVE = 0x0002;
168 public const UInt32 SWP_NOZORDER = 0x0004;
169 public const UInt32 SWP_NOREDRAW = 0x0008;
170 public const UInt32 SWP_NOACTIVATE = 0x0010;
171 public const UInt32 SWP_FRAMECHANGED = 0x0020; /* The frame changed: send WM_NCCALCSIZE */
172 public const UInt32 SWP_SHOWWINDOW = 0x0040;
173 public const UInt32 SWP_HIDEWINDOW = 0x0080;
174 public const UInt32 SWP_NOCOPYBITS = 0x0100;
175 public const UInt32 SWP_NOOWNERZORDER = 0x0200; /* Don't do owner Z ordering */
176 public const UInt32 SWP_NOSENDCHANGING = 0x0400; /* Don't send WM_WINDOWPOSCHANGING */
177
178 public const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;
|
|
Notes
|
|
Because of synchronization issues, a few Thread.Sleeps are required, else the program will do things like trying to read the clipboard before its written to and not giving the window enough time to take focus before taking the screenshot. Sending ALT+Print Screen programmatically is dirty, but it works. Make sure you include the win32 COM wrappers at the bottom.
|
|
|