Advertisement
bobmarley12345

stuff BitBlt memory leak

Jan 8th, 2023
1,072
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.17 KB | None | 0 0
  1. namespace REghZy.FrameControl {
  2.     /// <summary>
  3.     /// Interaction logic for MainWindow.xaml
  4.     /// </summary>
  5.     public partial class MainWindow : Window {
  6.         [DllImport("gdi32.dll")]
  7.         public static extern IntPtr CreateDC(
  8.             [MarshalAs(UnmanagedType.LPStr)] string lpszDriver,
  9.             [MarshalAs(UnmanagedType.LPStr)] string lpszDevice,
  10.             [MarshalAs(UnmanagedType.LPStr)] string lpszOutput,
  11.             IntPtr pdm);
  12.         [DllImport("gdi32.dll")]
  13.         public static extern bool DeleteObject(IntPtr hObject);
  14.         [DllImport("gdi32.dll")]
  15.         public static extern bool SelectObject(IntPtr hObject);
  16.         [DllImport("user32.dll")]
  17.         static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc);
  18.  
  19.         [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  20.         public static extern int BitBlt(
  21.             IntPtr hDC,
  22.             int x,
  23.             int y,
  24.             int nWidth,
  25.             int nHeight,
  26.             IntPtr hSrcDC,
  27.             int xSrc,
  28.             int ySrc,
  29.             int dwRop);
  30.  
  31.         private long lastFrameTime;
  32.  
  33.         public static IntPtr DESKTOP = CreateDC("DISPLAY", null, null, IntPtr.Zero);
  34.         public readonly Bitmap result;
  35.         public readonly IntPtr ptr;
  36.  
  37.         public Graphics g;
  38.  
  39.         private long nextRunTicks;
  40.  
  41.         public MainWindow() {
  42.             InitializeComponent();
  43.  
  44.             this.result = new Bitmap(1920, 1080, PixelFormat.Format24bppRgb);
  45.  
  46.             Task.Run(async () => {
  47.                 while (true) {
  48.                     Timer_Tick();
  49.                     // DateTime time = DateTime.Now;
  50.                     // if (time.Ticks > this.nextRunTicks) {
  51.                     //     this.nextRunTicks = time.Ticks + TimeSpan.FromMilliseconds(1d).Ticks;
  52.                     //     Timer_Tick();
  53.                     // }
  54.                     // else {
  55.                     //     await Task.Delay(1);
  56.                     // }
  57.                 }
  58.             });
  59.         }
  60.  
  61.         public static void RunTaskOnMainThread(Action action) {
  62.             TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
  63.             Application.Current.Dispatcher.Invoke(() => {
  64.                 try {
  65.                     action();
  66.                 }
  67.                 finally {
  68.                     tcs.TrySetResult(true);
  69.                 }
  70.             });
  71.  
  72.             tcs.Task.Wait();
  73.         }
  74.  
  75.  
  76.         private void Timer_Tick() {
  77.             long start = DateTime.Now.Ticks;
  78.             Capture(this.result, () => {
  79.                 try {
  80.                     BitmapSource source = Imaging.CreateBitmapSourceFromHBitmap(this.result.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
  81.                     source.Freeze();
  82.                     RunTaskOnMainThread(() => {
  83.                         this.Display.Text = $"Difference: {new DateTime(start - this.lastFrameTime).Millisecond} millis";
  84.                         this.Frame.Source = source;
  85.                     });
  86.                 }
  87.                 catch (Exception e) {
  88.                 }
  89.                 finally {
  90.                     // DeleteObject(this.result.GetHbitmap());
  91.                 }
  92.             });
  93.  
  94.             this.lastFrameTime = start;
  95.         }
  96.  
  97.         public static void Capture(Bitmap bitmap, Action callback) {
  98.             Rectangle bounds = new Rectangle(0, 0, 1920, 1080);
  99.             using (Graphics g = Graphics.FromImage(bitmap)) {
  100.                 int width = bounds.Size.Width;
  101.                 int height = bounds.Size.Height;
  102.                 try {
  103.                     if (BitBlt(g.GetHdc(), 0, 0, width, height, DESKTOP, bounds.Left, bounds.Top, 13369376) == 0) // 13369376 == SourceCopy
  104.                         throw new Win32Exception();
  105.                     callback();
  106.                 }
  107.                 finally {
  108.                     g.ReleaseHdc();
  109.                     // DeleteObject(hdc);
  110.                 }
  111.                 // g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size);
  112.             }
  113.  
  114.             // Rectangle bounds = new Rectangle(0, 0, 1920, 1080);
  115.             // using (Bitmap result = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format24bppRgb)) {
  116.             //     using (Graphics g = Graphics.FromImage(result)) {
  117.             //         g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size);
  118.             //         BitmapData data = result.LockBits(bounds, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
  119.             //         try {
  120.             //             unsafe {
  121.             //                 return Image.WrapMemory<Rgb24>((void*) data.Scan0, bounds.Width, bounds.Height).CloneAs<Rgb24>();
  122.             //             }
  123.             //         }
  124.             //         finally {
  125.             //             result.UnlockBits(data);
  126.             //         }
  127.             //     }
  128.             // }
  129.         }
  130.  
  131.         [StructLayout(LayoutKind.Sequential)]
  132.         private struct Rect {
  133.             public int Left;
  134.             public int Top;
  135.             public int Right;
  136.             public int Bottom;
  137.         }
  138.     }
  139. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement