Skip to content

Commit 3f87e01

Browse files
committed
Added a menu item to save the window screenshot.
1 parent ced5818 commit 3f87e01

File tree

7 files changed

+121
-41
lines changed

7 files changed

+121
-41
lines changed

SmartSystemMenu/Code/Common/NativeMethods.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ static class NativeMethods
107107
[return: MarshalAs(UnmanagedType.Bool)]
108108
public static extern Boolean GetWindowRect(IntPtr handle, out Rect lpRect);
109109

110+
[DllImport("user32.dll")]
111+
[return: MarshalAs(UnmanagedType.Bool)]
112+
public static extern Boolean PrintWindow(IntPtr handle, IntPtr hdc, Int32 nFlags);
113+
110114
[DllImport("user32.dll")]
111115
[return: MarshalAs(UnmanagedType.Bool)]
112116
public static extern Boolean GetClientRect(IntPtr handle, out Rect lpRect);

SmartSystemMenu/Code/Common/SystemMenu.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ public Boolean Exists
8989
public const Int32 SC_ALIGN_DEFAULT = 0x4799;
9090
public const Int32 SC_ALIGN_CUSTOM = 0x4800;
9191
public const Int32 SC_ALIGN_MONITOR = 0x4801;
92+
public const Int32 SC_SAVE_SCREEN_SHOT = 0x4802;
9293

9394
#endregion
9495

@@ -108,6 +109,7 @@ public void Create()
108109
NativeMethods.InsertMenu(windowMenuHandle, index, NativeConstants.MF_BYPOSITION | NativeConstants.MF_SEPARATOR, IntPtr.Zero, "");
109110
NativeMethods.InsertMenu(windowMenuHandle, index + 1, NativeConstants.MF_BYPOSITION, SC_INFORMATION, "Information");
110111
NativeMethods.InsertMenu(windowMenuHandle, index + 2, NativeConstants.MF_BYPOSITION, SC_TOPMOST, "Always On Top");
112+
NativeMethods.InsertMenu(windowMenuHandle, index + 3, NativeConstants.MF_BYPOSITION, SC_SAVE_SCREEN_SHOT, "Save Window Screenshot");
111113

112114
_sizeMenuHandle = NativeMethods.CreateMenu();
113115
NativeMethods.InsertMenu(_sizeMenuHandle, -1, NativeConstants.MF_BYPOSITION, SC_SIZE_640_480, "640x480");
@@ -127,7 +129,7 @@ public void Create()
127129
NativeMethods.InsertMenu(_sizeMenuHandle, -1, NativeConstants.MF_BYPOSITION, SC_SIZE_DEFAULT, "Default");
128130
NativeMethods.InsertMenu(_sizeMenuHandle, -1, NativeConstants.MF_BYPOSITION | NativeConstants.MF_SEPARATOR, 0, "");
129131
NativeMethods.InsertMenu(_sizeMenuHandle, -1, NativeConstants.MF_BYPOSITION, SC_SIZE_CUSTOM, "Custom...");
130-
NativeMethods.InsertMenu(windowMenuHandle, index + 3, NativeConstants.MF_BYPOSITION | NativeConstants.MF_POPUP, _sizeMenuHandle, "Resize");
132+
NativeMethods.InsertMenu(windowMenuHandle, index + 4, NativeConstants.MF_BYPOSITION | NativeConstants.MF_POPUP, _sizeMenuHandle, "Resize");
131133

132134
_alignmentMenuHandle = NativeMethods.CreateMenu();
133135
NativeMethods.InsertMenu(_alignmentMenuHandle, -1, NativeConstants.MF_BYPOSITION, SC_ALIGN_MONITOR, "Monitor");
@@ -145,7 +147,7 @@ public void Create()
145147
NativeMethods.InsertMenu(_alignmentMenuHandle, -1, NativeConstants.MF_BYPOSITION, SC_ALIGN_DEFAULT, "Default");
146148
NativeMethods.InsertMenu(_alignmentMenuHandle, -1, NativeConstants.MF_BYPOSITION | NativeConstants.MF_SEPARATOR, 0, "");
147149
NativeMethods.InsertMenu(_alignmentMenuHandle, -1, NativeConstants.MF_BYPOSITION, SC_ALIGN_CUSTOM, "Custom...");
148-
NativeMethods.InsertMenu(windowMenuHandle, index + 4, NativeConstants.MF_BYPOSITION | NativeConstants.MF_POPUP, _alignmentMenuHandle, "Alignment");
150+
NativeMethods.InsertMenu(windowMenuHandle, index + 5, NativeConstants.MF_BYPOSITION | NativeConstants.MF_POPUP, _alignmentMenuHandle, "Alignment");
149151

150152
_transparencyMenuHandle = NativeMethods.CreateMenu();
151153
NativeMethods.InsertMenu(_transparencyMenuHandle, -1, NativeConstants.MF_BYPOSITION, SC_TRANS_00, "0% (opaque)");
@@ -163,7 +165,7 @@ public void Create()
163165
NativeMethods.InsertMenu(_transparencyMenuHandle, -1, NativeConstants.MF_BYPOSITION, SC_TRANS_DEFAULT, "Default");
164166
NativeMethods.InsertMenu(_transparencyMenuHandle, -1, NativeConstants.MF_BYPOSITION | NativeConstants.MF_SEPARATOR, 0, "");
165167
NativeMethods.InsertMenu(_transparencyMenuHandle, -1, NativeConstants.MF_BYPOSITION, SC_TRANS_CUSTOM, "Custom...");
166-
NativeMethods.InsertMenu(windowMenuHandle, index + 5, NativeConstants.MF_BYPOSITION | NativeConstants.MF_POPUP, _transparencyMenuHandle, "Transparency");
168+
NativeMethods.InsertMenu(windowMenuHandle, index + 6, NativeConstants.MF_BYPOSITION | NativeConstants.MF_POPUP, _transparencyMenuHandle, "Transparency");
167169

168170
_priorityMenuHandle = NativeMethods.CreateMenu();
169171
NativeMethods.InsertMenu(_priorityMenuHandle, -1, NativeConstants.MF_BYPOSITION, SC_PRIORITY_REAL_TIME, "Real Time: 24");
@@ -172,12 +174,12 @@ public void Create()
172174
NativeMethods.InsertMenu(_priorityMenuHandle, -1, NativeConstants.MF_BYPOSITION, SC_PRIORITY_NORMAL, "Normal: 8");
173175
NativeMethods.InsertMenu(_priorityMenuHandle, -1, NativeConstants.MF_BYPOSITION, SC_PRIORITY_BELOW_NORMAL, "Below Normal: 6");
174176
NativeMethods.InsertMenu(_priorityMenuHandle, -1, NativeConstants.MF_BYPOSITION, SC_PRIORITY_IDLE, "Idle: 4");
175-
NativeMethods.InsertMenu(windowMenuHandle, index + 6, NativeConstants.MF_BYPOSITION | NativeConstants.MF_POPUP, _priorityMenuHandle, "Priority");
177+
NativeMethods.InsertMenu(windowMenuHandle, index + 7, NativeConstants.MF_BYPOSITION | NativeConstants.MF_POPUP, _priorityMenuHandle, "Priority");
176178

177179
_systemTrayMenuHandle = NativeMethods.CreateMenu();
178180
NativeMethods.InsertMenu(_systemTrayMenuHandle, -1, NativeConstants.MF_BYPOSITION, SC_MINIMIZE_TO_SYSTEMTRAY, "&Mimimize To Tray");
179181
NativeMethods.InsertMenu(_systemTrayMenuHandle, -1, NativeConstants.MF_BYPOSITION, SC_MINIMIZE_ALWAYS_TO_SYSTEMTRAY, "Mimimize To Tray Always");
180-
NativeMethods.InsertMenu(windowMenuHandle, index + 7, NativeConstants.MF_BYPOSITION | NativeConstants.MF_POPUP, _systemTrayMenuHandle, "System Tray");
182+
NativeMethods.InsertMenu(windowMenuHandle, index + 8, NativeConstants.MF_BYPOSITION | NativeConstants.MF_POPUP, _systemTrayMenuHandle, "System Tray");
181183
}
182184

183185
public void Destroy()
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Windows.Forms;
6+
7+
namespace SmartSystemMenu.Code.Common
8+
{
9+
class Win32WindowWrapper : IWin32Window
10+
{
11+
public IntPtr Handle
12+
{
13+
get; private set;
14+
}
15+
16+
public Win32WindowWrapper(IntPtr handle)
17+
{
18+
Handle = handle;
19+
}
20+
}
21+
}

SmartSystemMenu/Code/Common/Window.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Threading;
66
using System.Runtime.InteropServices;
77
using System.Drawing;
8+
using System.Drawing.Imaging;
89
using System.Diagnostics;
910
using SmartSystemMenu.Code.Common.Extensions;
1011

@@ -191,6 +192,14 @@ public Boolean ExistSystemTrayIcon
191192
}
192193
}
193194

195+
public IWin32Window Win32Window
196+
{
197+
get
198+
{
199+
return new Win32WindowWrapper(Handle);
200+
}
201+
}
202+
194203
#endregion
195204

196205

@@ -398,6 +407,20 @@ public void SetPriority(Priority priority)
398407
NativeMethods.SetPriorityClass(processHandle, priorityClass);
399408
}
400409

410+
public Bitmap PrintWindow()
411+
{
412+
Rect rect;
413+
NativeMethods.GetWindowRect(Handle, out rect);
414+
var bitmap = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);
415+
using (var graphics = Graphics.FromImage(bitmap))
416+
{
417+
var hdc = graphics.GetHdc();
418+
NativeMethods.PrintWindow(Handle, hdc, 0);
419+
graphics.ReleaseHdc(hdc);
420+
}
421+
return bitmap;
422+
}
423+
401424
public static void CloseAllWindowsOfProcess(Int32 processId)
402425
{
403426
NativeMethods.EnumWindowDelegate d = delegate(IntPtr hWnd, Int32 lParam)

SmartSystemMenu/Code/Forms/MainForm.cs

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Windows.Forms;
77
using System.Diagnostics;
88
using System.IO;
9+
using System.Drawing.Imaging;
910
using SmartSystemMenu.Code.Common;
1011
using SmartSystemMenu.Code.Common.Extensions;
1112
using SmartSystemMenu.Code.Hooks;
@@ -93,8 +94,8 @@ protected override void OnLoad(EventArgs e)
9394
_cbtHook.MinMax += WindowMinMax;
9495
_cbtHook.Start();
9596

96-
//_keyboardHook = new KeyboardHook(Handle);
97-
//_keyboardHook.KeyboardEvent += WindowKeyboardEvent;
97+
_keyboardHook = new KeyboardHook(Handle);
98+
_keyboardHook.KeyboardEvent += WindowKeyboardEvent;
9899
//_keyboardHook.Start();
99100

100101
Hide();
@@ -307,32 +308,62 @@ private void WindowGetMsg(object sender, WndProcEventArgs e)
307308
case NativeConstants.SC_MAXIMIZE:
308309
{
309310
window.Menu.UncheckSizeMenu();
310-
} break;
311+
}
312+
break;
311313

312314
case SystemMenu.SC_MINIMIZE_TO_SYSTEMTRAY:
313315
{
314316
window.MinimizeToSystemTray();
315-
} break;
317+
}
318+
break;
316319

317320
case SystemMenu.SC_MINIMIZE_ALWAYS_TO_SYSTEMTRAY:
318321
{
319322
Boolean r = window.Menu.IsMenuItemChecked(SystemMenu.SC_MINIMIZE_ALWAYS_TO_SYSTEMTRAY);
320323
window.Menu.CheckMenuItem(SystemMenu.SC_MINIMIZE_ALWAYS_TO_SYSTEMTRAY, !r);
321-
} break;
324+
}
325+
break;
322326

323327
case SystemMenu.SC_INFORMATION:
324328
{
325-
InfoForm infoForm = new InfoForm(window);
326-
infoForm.Show();
327-
Window.ForceForegroundWindow(infoForm.Handle);
328-
} break;
329+
var infoForm = new InfoForm(window);
330+
infoForm.Show(window.Win32Window);
331+
}
332+
break;
333+
334+
case SystemMenu.SC_SAVE_SCREEN_SHOT:
335+
{
336+
var bitmap = window.PrintWindow();
337+
var dialog = new SaveFileDialog
338+
{
339+
OverwritePrompt = true,
340+
ValidateNames = true,
341+
Title = "Save Window Screenshot",
342+
FileName = "WindowScreenshot",
343+
DefaultExt = "bmp",
344+
RestoreDirectory = false,
345+
Filter = "Bitmap Image (.bmp)|*.bmp|Gif Image (.gif)|*.gif|JPEG Image (.jpeg)|*.jpeg|Png Image (.png)|*.png|Tiff Image (.tiff)|*.tiff|Wmf Image (.wmf)|*.wmf"
346+
};
347+
if (dialog.ShowDialog(window.Win32Window) == DialogResult.OK)
348+
{
349+
var fileExtension = Path.GetExtension(dialog.FileName).ToLower();
350+
var imageFormat = fileExtension == ".bmp" ? ImageFormat.Bmp :
351+
fileExtension == ".gif" ? ImageFormat.Gif :
352+
fileExtension == ".jpeg" ? ImageFormat.Jpeg :
353+
fileExtension == ".png" ? ImageFormat.Png :
354+
fileExtension == ".tiff" ? ImageFormat.Tiff : ImageFormat.Wmf;
355+
bitmap.Save(dialog.FileName, imageFormat);
356+
}
357+
}
358+
break;
329359

330360
case SystemMenu.SC_TOPMOST:
331361
{
332362
Boolean r = window.Menu.IsMenuItemChecked(SystemMenu.SC_TOPMOST);
333363
window.Menu.CheckMenuItem(SystemMenu.SC_TOPMOST, !r);
334364
window.MakeTopMost(!r);
335-
} break;
365+
}
366+
break;
336367

337368
case SystemMenu.SC_ROLLUP:
338369
{
@@ -346,7 +377,8 @@ private void WindowGetMsg(object sender, WndProcEventArgs e)
346377
{
347378
window.UnRollUp();
348379
}
349-
} break;
380+
}
381+
break;
350382

351383

352384
case SystemMenu.SC_SIZE_DEFAULT:
@@ -355,49 +387,52 @@ private void WindowGetMsg(object sender, WndProcEventArgs e)
355387
window.Menu.CheckMenuItem(SystemMenu.SC_SIZE_DEFAULT, true);
356388
window.ShowNormal();
357389
window.RestoreSize();
358-
} break;
390+
}
391+
break;
359392

360393
case SystemMenu.SC_SIZE_CUSTOM:
361394
{
362-
SizeForm sizeForm = new SizeForm(window);
363-
sizeForm.Show();
364-
Window.ForceForegroundWindow(sizeForm.Handle);
365-
} break;
395+
var sizeForm = new SizeForm(window);
396+
sizeForm.Show(window.Win32Window);
397+
}
398+
break;
366399

367400
case SystemMenu.SC_TRANS_DEFAULT:
368401
{
369402
window.Menu.UncheckTransparencyMenu();
370403
window.Menu.CheckMenuItem(SystemMenu.SC_TRANS_DEFAULT, true);
371404
window.RestoreTransparency();
372-
} break;
405+
}
406+
break;
373407

374408
case SystemMenu.SC_TRANS_CUSTOM:
375409
{
376-
TransparencyForm opacityForm = new TransparencyForm(window);
377-
opacityForm.Show();
378-
Window.ForceForegroundWindow(opacityForm.Handle);
379-
} break;
410+
var opacityForm = new TransparencyForm(window);
411+
opacityForm.Show(window.Win32Window);
412+
}
413+
break;
380414

381415
case SystemMenu.SC_ALIGN_DEFAULT:
382416
{
383417
window.Menu.UncheckAlignmentMenu();
384418
window.Menu.CheckMenuItem(SystemMenu.SC_ALIGN_DEFAULT, true);
385419
window.RestorePosition();
386-
} break;
420+
}
421+
break;
387422

388423
case SystemMenu.SC_ALIGN_CUSTOM:
389424
{
390-
PositionForm positionForm = new PositionForm(window);
391-
positionForm.Show();
392-
Window.ForceForegroundWindow(positionForm.Handle);
393-
} break;
425+
var positionForm = new PositionForm(window);
426+
positionForm.Show(window.Win32Window);
427+
}
428+
break;
394429

395430
case SystemMenu.SC_ALIGN_MONITOR:
396431
{
397-
ScreenForm screenForm = new ScreenForm(window);
398-
screenForm.Show();
399-
Window.ForceForegroundWindow(screenForm.Handle);
400-
} break;
432+
var screenForm = new ScreenForm(window);
433+
screenForm.Show(window.Win32Window);
434+
}
435+
break;
401436

402437
case SystemMenu.SC_SIZE_640_480: SetSizeMenuItem(window, SystemMenu.SC_SIZE_640_480, 640, 480); break;
403438
case SystemMenu.SC_SIZE_720_480: SetSizeMenuItem(window, SystemMenu.SC_SIZE_720_480, 720, 480); break;

SmartSystemMenu/Code/Forms/PositionForm.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.ComponentModel;
4-
using System.Data;
5-
using System.Drawing;
6-
using System.Linq;
7-
using System.Text;
82
using System.Windows.Forms;
93
using SmartSystemMenu.Code.Common;
104

SmartSystemMenu/SmartSystemMenu.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
<Compile Include="Code\Common\PlatformUtility.cs" />
8383
<Compile Include="Code\Common\SystemMenu.cs" />
8484
<Compile Include="Code\Common\SystemTrayMenu.cs" />
85+
<Compile Include="Code\Common\Win32WindowWrapper.cs" />
8586
<Compile Include="Code\Common\WindowAlignment.cs" />
8687
<Compile Include="Code\Forms\AboutForm.cs">
8788
<SubType>Form</SubType>

0 commit comments

Comments
 (0)