Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Drawing;
- using System.Runtime.InteropServices;
- namespace bot
- {
- class DXCapture
- {
- private static SlimDX.Direct3D9.Direct3D _direct3D9 = new SlimDX.Direct3D9.Direct3D();
- private static Dictionary<IntPtr, SlimDX.Direct3D9.Device> _direct3DDeviceCache = new Dictionary<IntPtr, SlimDX.Direct3D9.Device>();
- /// Захват скриншота окна hWnd
- public static Bitmap CaptureWindow(IntPtr hWnd)
- {
- Rectangle rect = NativeMethods.GetAbsoluteClientRect(hWnd);
- return CaptureRegionDirect3D(hWnd, rect);
- }
- // Захват региона окна
- // hWnd - указатель на окно
- // region - захватываемая область
- public static Bitmap CaptureRegionDirect3D(IntPtr handle, Rectangle region)
- {
- IntPtr hWnd = handle;
- Bitmap bitmap = null;
- Rectangle r = NativeMethods.GetAbsoluteClientRect(hWnd);
- WinAPI.SetWindowPos(hWnd, hWnd, 0, 0, r.Width, r.Height, Constants.API_SHOWWINDOW);
- WinAPI.SetForegroundWindow(hWnd);
- WinAPI.SetFocus(hWnd);
- // We are only supporting the primary display adapter for Direct3D mode
- SlimDX.Direct3D9.AdapterInformation adapterInfo = _direct3D9.Adapters.DefaultAdapter;
- SlimDX.Direct3D9.Device device;
- #region Get Direct3D Device
- // Retrieve the existing Direct3D device if we already created one for the given handle
- if (_direct3DDeviceCache.ContainsKey(hWnd))
- {
- device = _direct3DDeviceCache[hWnd];
- }
- // We need to create a new device
- else
- {
- // Setup the device creation parameters
- SlimDX.Direct3D9.PresentParameters parameters = new SlimDX.Direct3D9.PresentParameters();
- parameters.BackBufferFormat = adapterInfo.CurrentDisplayMode.Format;
- Rectangle clientRect = NativeMethods.GetAbsoluteClientRect(hWnd);
- parameters.BackBufferHeight = clientRect.Height;
- parameters.BackBufferWidth = clientRect.Width;
- parameters.Multisample = SlimDX.Direct3D9.MultisampleType.None;
- parameters.SwapEffect = SlimDX.Direct3D9.SwapEffect.Discard;
- parameters.DeviceWindowHandle = hWnd;
- parameters.PresentationInterval = SlimDX.Direct3D9.PresentInterval.Default;
- parameters.FullScreenRefreshRateInHertz = 0;
- // Create the Direct3D device
- device = new SlimDX.Direct3D9.Device(_direct3D9, adapterInfo.Adapter, SlimDX.Direct3D9.DeviceType.Hardware, hWnd, SlimDX.Direct3D9.CreateFlags.SoftwareVertexProcessing, parameters);
- _direct3DDeviceCache.Add(hWnd, device);
- }
- #endregion
- // Capture the screen and copy the region into a Bitmap
- using (SlimDX.Direct3D9.Surface surface = SlimDX.Direct3D9.Surface.CreateOffscreenPlain(device, adapterInfo.CurrentDisplayMode.Width, adapterInfo.CurrentDisplayMode.Height, SlimDX.Direct3D9.Format.A8R8G8B8, SlimDX.Direct3D9.Pool.SystemMemory))
- {
- device.GetFrontBufferData(0, surface);
- // Update: thanks digitalutopia1 for pointing out that SlimDX have fixed a bug
- // where they previously expected a RECT type structure for their Rectangle
- bitmap = new Bitmap(SlimDX.Direct3D9.Surface.ToStream(surface, SlimDX.Direct3D9.ImageFileFormat.Bmp, new Rectangle(region.Left, region.Top, region.Width, region.Height)));
- // Previous SlimDX bug workaround: new Rectangle(region.Left, region.Top, region.Right, region.Bottom)));
- }
- return bitmap;
- }
- }
- /// Обёртки к WIN32 Api
- #region Native Win32 Interop
- [Serializable, StructLayout(LayoutKind.Sequential)]
- internal struct RECT
- {
- public int Left;
- public int Top;
- public int Right;
- public int Bottom;
- public RECT(int left, int top, int right, int bottom)
- {
- this.Left = left;
- this.Top = top;
- this.Right = right;
- this.Bottom = bottom;
- }
- public Rectangle AsRectangle
- {
- get
- {
- return new Rectangle(this.Left, this.Top, this.Right - this.Left, this.Bottom - this.Top);
- }
- }
- public static RECT FromXYWH(int x, int y, int width, int height)
- {
- return new RECT(x, y, x + width, y + height);
- }
- public static RECT FromRectangle(Rectangle rect)
- {
- return new RECT(rect.Left, rect.Top, rect.Right, rect.Bottom);
- }
- }
- [System.Security.SuppressUnmanagedCodeSecurity()]
- internal sealed class NativeMethods
- {
- /// <summary>
- /// Get a windows client rectangle in a .NET structure
- /// </summary>
- /// <param name="hwnd">The window handle to look up</param>
- /// <returns>The rectangle</returns>
- internal static Rectangle GetClientRect(IntPtr hwnd)
- {
- RECT rect = new RECT();
- WinAPI.GetClientRect(hwnd, out rect);
- return rect.AsRectangle;
- }
- /// <summary>
- /// Get a windows rectangle in a .NET structure
- /// </summary>
- /// <param name="hwnd">The window handle to look up</param>
- /// <returns>The rectangle</returns>
- internal static Rectangle GetWindowRect(IntPtr hwnd)
- {
- RECT rect = new RECT();
- WinAPI.GetWindowRect(hwnd, out rect);
- return rect.AsRectangle;
- }
- internal static Rectangle GetAbsoluteClientRect(IntPtr hWnd)
- {
- Rectangle windowRect = NativeMethods.GetWindowRect(hWnd);
- Rectangle clientRect = NativeMethods.GetClientRect(hWnd);
- // This gives us the width of the left, right and bottom chrome - we can then determine the top height
- int chromeWidth = (int)((windowRect.Width - clientRect.Width) / 2);
- return new Rectangle(new Point(windowRect.X + chromeWidth, windowRect.Y + (windowRect.Height - clientRect.Height - chromeWidth)), clientRect.Size);
- }
- internal static void MakeWindowActive(IntPtr hWnd)
- {
- }
- }
- #endregion
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement