void SetupWindowCapture() { //UpdateCursorInfo(); // Get the device context if (isDesktop) { hdc = Win32Funcs.GetDC(IntPtr.Zero); } else { hdc = Win32Funcs.GetWindowDC(hwnd); } // Create a device context to use yourself hDest = Win32Funcs.CreateCompatibleDC(hdc); Win32Types.RECT windowRect; if (isDesktop) { Win32Types.MonitorInfo mi = new Win32Types.MonitorInfo(); mi.cbSize = Marshal.SizeOf(mi); Win32Funcs.GetMonitorInfo(hwnd, ref mi); windowRect = mi.rcMonitor; } else { // Get the size of the window Win32Funcs.GetWindowRect(hwnd, out windowRect); } // Sets the width and height of the captured window windowWidth = windowRect.Width; windowHeight = windowRect.Height; if (onlyCaptureMouse) { windowWidth = cursorRect.Width; windowHeight = cursorRect.Height; } // From http://stackoverflow.com/questions/7502588/createcompatiblebitmap-and-createdibsection-memory-dcs bmi = new Win32Types.BitmapInfo(); bmi.bmiHeader.Init(); bmi.bmiHeader.biSize = (uint)Marshal.SizeOf(bmi); bmi.bmiHeader.biWidth = windowWidth; bmi.bmiHeader.biHeight = -windowHeight; // top-down bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biCompression = Win32Consts.BitmapCompressionMode.BI_RGB; IntPtr outBits; curRenderingBitmap = Win32Funcs.CreateDIBSection(hdc, ref bmi, (uint)Win32Consts.DIB_Color_Mode.DIB_PAL_COLORS, out outBits, IntPtr.Zero, (uint)0); oldhDest = Win32Funcs.SelectObject(hDest, curRenderingBitmap); }
// Update is called once per frame public Texture2D GetWindowTexture(out bool didChange) { bool didMouseChange; cursorBytes = mouseCapture.GetAlignedBytes(out didMouseChange); mouseRect = WindowCapture.cursorRect; didChange = false; if (firstTime) { didChange = true; firstTime = false; } if (getDesktop) { if (desktopFrameData != null && desktopFrameData.Length > 0 && desktopWidth != 0 && desktopHeight != 0) { if (desktopTexture == null || desktopTexture.width != desktopWidth || desktopTexture.height != desktopHeight) { //desktopTexture = new Texture2D(curFrameWidth, curFrameHeight, TextureFormat.ARGB32, false); //testPointer = desktopTexture.GetNativeTexturePtr(); } lock (actuallyGoLock) { if (cursorBytes != null) { for (int y = 0; y < mouseCapture.windowRect.Width; y++) { for (int x = 0; x < mouseCapture.windowRect.Height; x++) { int sx = x + mouseRect.Left; int sy = y + mouseRect.Top; int pos = (x + y * mouseRect.Width) * 3; int sPos = (sx + sy * desktopWidth) * 4; if (sPos < 0 || sPos + 3 > desktopFrameData.Length) { continue; } float mb = cursorBytes[pos]; float mg = cursorBytes[pos + 1]; float mr = cursorBytes[pos + 2]; desktopFrameData[sPos] = (byte)Mathf.Clamp(Mathf.Round(mb), 0, 255); // b desktopFrameData[sPos + 1] = (byte)Mathf.Clamp(Mathf.Round(mg), 0, 255); // g desktopFrameData[sPos + 2] = (byte)Mathf.Clamp(Mathf.Round(mr), 0, 255); // r } } } } desktopTexture.LoadRawTextureData(desktopFrameData); desktopTexture.Apply(); } } return(desktopTexture); }
public static void UpdateCursorInfo() { // TODO - make sure everything here is cleaned up properly? // I'm pretty sure it is but it is good to check //int x = 0, y = 0; //return CaptureCursor (ref x, ref y); Win32Types.CursorInfo ci = new Win32Types.CursorInfo(); ci.cbSize = Marshal.SizeOf(typeof(Win32Types.CursorInfo)); if (!Win32Funcs.GetCursorInfo(ref ci)) { return; } // Todo: this will change if cursor icon changes (via http://stackoverflow.com/questions/358527/how-to-tell-if-mouse-pointer-icon-changed?rq=1), // So then we can make more expensive and accurate cursor things and only update as needed IntPtr cursorPointer = ci.hCursor; cursorHandle = cursorPointer; int iconWidth = Win32Funcs.GetSystemMetrics(Win32Consts.SystemMetric.SM_CXICON) + 1; int iconHeight = Win32Funcs.GetSystemMetrics(Win32Consts.SystemMetric.SM_CYICON) + 1; iconDims = new System.Drawing.Point(iconWidth, iconHeight); Win32Types.IconInfo hotSpotInfo = new Win32Types.IconInfo(); Win32Funcs.GetIconInfo(cursorPointer, out hotSpotInfo); //Win32funcs.DrawIcon(hdcBitmap, 1, 1, cursorPointer); hotspot = new System.Drawing.Point(hotSpotInfo.xHotspot + 1, hotSpotInfo.yHotspot + 1); if (hotSpotInfo.hbmColor != IntPtr.Zero) { Win32Funcs.DeleteObject(hotSpotInfo.hbmColor); } if (hotSpotInfo.hbmMask != IntPtr.Zero) { Win32Funcs.DeleteObject(hotSpotInfo.hbmMask); } Win32Types.PointL cursorPos; Win32Funcs.GetCursorPos(out cursorPos); int cursorX = cursorPos.x - hotspot.X; int cursorY = cursorPos.y - hotspot.Y; cursorRect = new Win32Types.RECT(cursorX, cursorY, cursorX + iconDims.X, cursorY + iconDims.Y); }
public static bool GetScreenRect(out Win32Types.RECT result) { return(Win32Funcs.GetWindowRect(Win32Funcs.GetDesktopWindow(), out result)); }
public static extern bool GetWindowRect(IntPtr hWnd, out Win32Types.RECT lpRect);
public byte[] GetWindowBitmapUsingBitBlt(out int numBytesPerRow) { windowRect = new Win32Types.RECT(); bool result; if (isDesktop) { Win32Types.MonitorInfo mi = new Win32Types.MonitorInfo(); mi.cbSize = Marshal.SizeOf(mi); result = Win32Funcs.GetMonitorInfo(hwnd, ref mi); if (result) { windowRect = mi.rcMonitor; } } else { // Get the size of the window result = Win32Funcs.GetWindowRect(hwnd, out windowRect); } if (onlyCaptureMouse) { windowRect = cursorRect; result = true; } if (!result) { // Failed getting rect numBytesPerRow = 0; return(null); } // If they resized the window we need to reinit the memory if (windowWidth != windowRect.Width || windowHeight != windowRect.Height) { CleanupWindowCapture(); SetupWindowCapture(); windowWidth = windowRect.Width; windowHeight = windowRect.Height; } // Use the previously created device context with the bitmap Win32Funcs.SelectObject(hDest, curRenderingBitmap); if (onlyCaptureMouse) { if (isDesktop) { Win32Funcs.BitBlt(hDest, 0, 0, cursorRect.Width, cursorRect.Height, hdc, windowRect.Left, windowRect.Top, Win32Consts.TernaryRasterOperations.SRCCOPY); } else { Win32Funcs.BitBlt(hDest, cursorRect.Left, cursorRect.Height, cursorRect.Width, cursorRect.Height, hdc, 0, 0, Win32Consts.TernaryRasterOperations.SRCCOPY); } Win32Funcs.DrawIconEx(hDest, 1, 1, cursorHandle, cursorRect.Width, cursorRect.Height, 0, IntPtr.Zero, Win32Consts.DI_NORMAL); } else { // Copy from the screen device context to the bitmap device context if (isDesktop) { Win32Funcs.BitBlt(hDest, 0, 0, windowRect.Width, windowRect.Height, hdc, windowRect.Left, windowRect.Top, Win32Consts.TernaryRasterOperations.SRCCOPY); } else { Win32Funcs.BitBlt(hDest, 0, 0, windowRect.Width, windowRect.Height, hdc, 0, 0, Win32Consts.TernaryRasterOperations.SRCCOPY); } Win32Funcs.DrawIconEx(hDest, cursorRect.Left, cursorRect.Top, cursorHandle, cursorRect.Width, cursorRect.Height, 0, IntPtr.Zero, Win32Consts.DI_NORMAL); } Win32Types.BITMAP bitmap = new Win32Types.BITMAP(); Win32Funcs.GetObjectBitmap(curRenderingBitmap, Marshal.SizeOf(bitmap), ref bitmap); numBytesPerRow = bitmap.bmWidthBytes; if (bitmapBytes == null || bitmapBytes.Length != bitmap.bmHeight * bitmap.bmWidthBytes) { bitmapBytes = new byte[bitmap.bmHeight * bitmap.bmWidthBytes]; } if (bitmap.bmBits != IntPtr.Zero) { Marshal.Copy(bitmap.bmBits, bitmapBytes, 0, bitmapBytes.Length); } if (bitmapBytes == null || bitmapBytes.Length == 0) { return(null); } return(bitmapBytes); }
public byte[] GetWindowBitmapUsingBitBlt(out int numBytesPerRow) { windowRect = new Win32Types.RECT(); bool result; if (isDesktop) { Win32Types.MonitorInfo mi = new Win32Types.MonitorInfo(); mi.cbSize = Marshal.SizeOf(mi); result = Win32Funcs.GetMonitorInfo(hwnd, ref mi); if (result) { windowRect = mi.rcMonitor; } } else { // Get the size of the window result = Win32Funcs.GetWindowRect(hwnd, out windowRect); } if (onlyCaptureMouse) { windowRect = cursorRect; result = true; } if (!result) { // Failed getting rect numBytesPerRow = 0; return(null); } // If they resized the window we need to reinit the memory if (windowWidth != windowRect.Width || windowHeight != windowRect.Height) { CleanupWindowCapture(); SetupWindowCapture(); windowWidth = windowRect.Width; windowHeight = windowRect.Height; } oldhDest = Win32Funcs.SelectObject(hDest, curRenderingBitmap); Win32Types.BITMAP bitmap = new Win32Types.BITMAP(); Win32Funcs.GetObjectBitmap(curRenderingBitmap, Marshal.SizeOf(bitmap), ref bitmap); if (onlyCaptureMouse) { if (isDesktop) { Win32Funcs.BitBlt(hDest, 0, 0, cursorRect.Width, cursorRect.Height, hdc, windowRect.Left, windowRect.Top, Win32Consts.TernaryRasterOperations.SRCCOPY); } else { Win32Funcs.BitBlt(hDest, cursorRect.Left, cursorRect.Height, cursorRect.Width, cursorRect.Height, hdc, 0, 0, Win32Consts.TernaryRasterOperations.SRCCOPY); } Win32Funcs.DrawIconEx(hDest, 1, 1, cursorHandle, cursorRect.Width, cursorRect.Height, 0, IntPtr.Zero, Win32Consts.DI_NORMAL); } else { // Copy from the screen device context to the bitmap device context var testing = false; if (isDesktop) { Win32Funcs.BitBlt(hDest, 0, 0, windowRect.Width, windowRect.Height, hdc, windowRect.Left, windowRect.Top, Win32Consts.TernaryRasterOperations.SRCCOPY); } else { if (testing) { Win32Funcs.BitBlt(hDest, 0, 0, windowRect.Width, windowRect.Height, hdc, 0, 0, Win32Consts.TernaryRasterOperations.SRCCOPY); } else { if (needsGDIp) { Bitmap map = new Bitmap(windowRect.Width, windowRect.Height); Graphics graphics = Graphics.FromHdc(hDest); try { graphics.CopyFromScreen(new System.Drawing.Point(windowRect.Left, windowRect.Top), System.Drawing.Point.Empty, windowRect.Size, CopyPixelOperation.SourceCopy); } finally { map.Dispose(); graphics.Dispose(); } } } } Win32Funcs.DrawIconEx(hDest, cursorRect.Left, cursorRect.Top, cursorHandle, cursorRect.Width, cursorRect.Height, 0, IntPtr.Zero, Win32Consts.DI_NORMAL); } numBytesPerRow = bitmap.bmWidthBytes; if (bitmapBytes == null || bitmapBytes.Length != bitmap.bmHeight * bitmap.bmWidthBytes) { bitmapBytes = new byte[bitmap.bmHeight * bitmap.bmWidthBytes]; } if (bitmap.bmBits != IntPtr.Zero) { Marshal.Copy(bitmap.bmBits, bitmapBytes, 0, bitmapBytes.Length); } if (bitmapBytes == null || bitmapBytes.Length == 0) { return(null); } Win32Funcs.DeleteObject(bitmap.bmBits); Win32Funcs.SelectObject(hDest, oldhDest); return(bitmapBytes); }