public static extern bool GetCursorInfo(out CursorInfo cursorInfo);
private void CaptureFrame() { int MSBETWEENCAPTURES = 1000/framesPerSecond; int msToNextCapture = MSBETWEENCAPTURES; stopwatch.Reset(); while (!stop) { stopwatch.Start(); Point captureLocation; if (recordingWindow != null) { recordingWindow.Reset(); captureLocation = recordingWindow.Location; } else { captureLocation = new Point(recordingRectangle.X, recordingRectangle.Y); } // "Capture" GDI32.BitBlt(hDCDest, 0, 0, recordingSize.Width, recordingSize.Height, hDCDesktop, captureLocation.X, captureLocation.Y, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt); // Mouse if (RecordMouse) { CursorInfo cursorInfo = new CursorInfo(); cursorInfo.cbSize = Marshal.SizeOf(cursorInfo); Point mouseLocation = Cursor.Position; mouseLocation.Offset(-captureLocation.X, -captureLocation.Y); if (User32.GetCursorInfo(out cursorInfo)) { User32.DrawIcon(hDCDest, mouseLocation.X, mouseLocation.Y, cursorInfo.hCursor); } } // add to avi try { aviWriter.AddLowLevelFrame(bits0); } catch (Exception) { LOG.Error("Error adding frame to avi, stopping capturing."); break; } int restTime = (int)(msToNextCapture - stopwatch.ElapsedMilliseconds); // Set time to next capture, we correct it if needed later. msToNextCapture = MSBETWEENCAPTURES; if (restTime > 0) { // We were fast enough, we wait for next capture Thread.Sleep(restTime); } else if (restTime < 0) { // Compensating, as we took to long int framesToSkip = ((-restTime) / MSBETWEENCAPTURES); int leftoverMillis = (-restTime) % MSBETWEENCAPTURES; //LOG.InfoFormat("Adding {0} empty frames to avi, leftover millis is {1}, sleeping {2} (of {3} total)", framesToSkip, leftover, sleepMillis, MSBETWEENCAPTURES); aviWriter.AddEmptyFrames(framesToSkip); // check how bad it is, if we only missed our target by a few millis we hope the next capture corrects this if (leftoverMillis > 0 && leftoverMillis <= 2) { // subtract the leftover from the millis to next capture, do nothing else msToNextCapture -= leftoverMillis; } else if (leftoverMillis > 0) { // it's more, we add an empty frame aviWriter.AddEmptyFrames(1); // we sleep to the next time and int sleepMillis = MSBETWEENCAPTURES - leftoverMillis; // Sleep to next capture Thread.Sleep(sleepMillis); } } stopwatch.Reset(); } Cleanup(); }
private void CaptureFrame() { int MSBETWEENCAPTURES = 1000/framesPerSecond; int msToNextCapture = MSBETWEENCAPTURES; while (!stop) { DateTime nextCapture = DateTime.Now.AddMilliseconds(msToNextCapture); Point captureLocation; if (recordingWindow != null) { captureLocation = recordingWindow.Location; } else { captureLocation = new Point(recordingRectangle.X, recordingRectangle.Y); } // "Capture" GDI32.BitBlt(hDCDest, 0, 0, recordingSize.Width, recordingSize.Height, hDCDesktop, captureLocation.X, captureLocation.Y, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt); // Mouse if (RecordMouse) { CursorInfo cursorInfo = new CursorInfo(); cursorInfo.cbSize = Marshal.SizeOf(cursorInfo); Point mouseLocation = Cursor.Position; mouseLocation.Offset(-captureLocation.X, -captureLocation.Y); if (User32.GetCursorInfo(out cursorInfo)) { User32.DrawIcon(hDCDest, mouseLocation.X, mouseLocation.Y, cursorInfo.hCursor); } } // add to avi try { aviWriter.AddLowLevelFrame(bits0); } catch (Exception) { LOG.Error("Error adding frame to avi, stopping capturing."); break; } int sleeptime = (int)(nextCapture.Subtract(DateTime.Now).Ticks / TimeSpan.TicksPerMillisecond); if (sleeptime > 0) { Thread.Sleep(sleeptime); msToNextCapture = MSBETWEENCAPTURES; } else { // Compensating msToNextCapture = Math.Max(0, MSBETWEENCAPTURES - sleeptime); } } Cleanup(); }
public static extern bool GetCursorInfo(out CursorInfo cursorInfo);
/// <summary> /// This method will capture the current Cursor by using User32 Code /// </summary> /// <returns>A Capture Object with the Mouse Cursor information in it.</returns> public static ICapture CaptureCursor(ICapture capture) { LOG.Debug("Capturing the mouse cursor."); if (capture == null) { capture = new Capture(); } int x,y; CursorInfo cursorInfo = new CursorInfo(); IconInfo iconInfo; cursorInfo.cbSize = Marshal.SizeOf(cursorInfo); if (User32.GetCursorInfo(out cursorInfo)) { if (cursorInfo.flags == User32.CURSOR_SHOWING) { using (SafeIconHandle safeIcon = User32.CopyIcon(cursorInfo.hCursor)) { if (User32.GetIconInfo(safeIcon, out iconInfo)) { Point cursorLocation = User32.GetCursorLocation(); // Allign cursor location to Bitmap coordinates (instead of Screen coordinates) x = cursorLocation.X - iconInfo.xHotspot - capture.ScreenBounds.X; y = cursorLocation.Y - iconInfo.yHotspot - capture.ScreenBounds.Y; // Set the location capture.CursorLocation = new Point(x, y); using (Icon icon = Icon.FromHandle(safeIcon.DangerousGetHandle())) { capture.Cursor = icon; } if (iconInfo.hbmMask != IntPtr.Zero) { DeleteObject(iconInfo.hbmMask); } if (iconInfo.hbmColor != IntPtr.Zero) { DeleteObject(iconInfo.hbmColor); } } } } } return capture; }