[Aporte] Captura de Pantalla en C#

Iniciado por samuelhm, 30 Mayo 2014, 13:01 PM

0 Miembros y 1 Visitante están viendo este tema.

samuelhm

Me costó encontrar la manera de hacer una captura de una ventana en c#, en c++ estaba apuntado en un post con chincheta,pero en c# no encontré nada, por si alguien alguna vez busca el modo, asi es como lo he podido hacer:

MetodosNativos.CS
Código (csharp) [Seleccionar]

public static class MetodosNativos
   {
public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter
       
       [DllImport("gdi32.dll")]
       public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest,
           int nWidth, int nHeight, IntPtr hObjectSource,
           int nXSrc, int nYSrc, int dwRop);
       
       [DllImport("gdi32.dll")]
       public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth,int nHeight);
     
       [DllImport("gdi32.dll")]
       public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
       
       [DllImport("gdi32.dll")]
       public static extern bool DeleteDC(IntPtr hDC);
       
       [DllImport("gdi32.dll")]
       public static extern bool DeleteObject(IntPtr hObject);
       
       [DllImport("gdi32.dll")]
       public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
     

       /*User32.Dll*/
       [StructLayout(LayoutKind.Sequential)]
       public struct RECT
       {
           public int left;
           public int top;
           public int right;
           public int bottom;
       }
       public enum GetWindow_Cmd : uint
       {
           GW_HWNDFIRST = 0,
           GW_HWNDLAST = 1,
           GW_HWNDNEXT = 2,
           GW_HWNDPREV = 3,
           GW_OWNER = 4,
           GW_CHILD = 5,
           GW_ENABLEDPOPUP = 6
       }
       [DllImport("user32.dll")]
       public static extern IntPtr GetDesktopWindow();
       
       [DllImport("user32.dll")]
       public static extern IntPtr GetWindowDC(IntPtr hWnd);
       
       [DllImport("user32.dll")]
       public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
       
       [DllImport("user32.dll")]
       public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
}

Capturadora.cs
Código (csharp) [Seleccionar]

<....Codigo de la clase
public static Bitmap CapturarVentana(IntPtr handle)
       {
           try
           {
               RedimensionarVentana(handle);
               // get te hDC of the target window
               IntPtr hdcSrc = MetodosNativos.GetWindowDC(handle);
               // get the size
               MetodosNativos.RECT windowRect = new MetodosNativos.RECT();
               MetodosNativos.GetWindowRect(handle, ref windowRect);
               int width = windowRect.right - windowRect.left;
               int height = windowRect.bottom - windowRect.top;
               // create a device context we can copy to
               IntPtr hdcDest = MetodosNativos.CreateCompatibleDC(hdcSrc);
               // create a bitmap we can copy it to,
               // using GetDeviceCaps to get the width/height
               IntPtr hBitmap = MetodosNativos.CreateCompatibleBitmap(hdcSrc, width, height);
               // select the bitmap object
               IntPtr hOld = MetodosNativos.SelectObject(hdcDest, hBitmap);
               // bitblt over
               MetodosNativos.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, MetodosNativos.SRCCOPY);
               // restore selection
               MetodosNativos.SelectObject(hdcDest, hOld);
               // clean up
               MetodosNativos.DeleteDC(hdcDest);
               MetodosNativos.ReleaseDC(handle, hdcSrc);
               // get a .NET image object for it
               Bitmap bmp = Bitmap.FromHbitmap(hBitmap);
               MetodosNativos.DeleteObject(hBitmap);
               return bmp;
           }
           catch (Exception err) {MessageBox.show(err.ToString()); return null; }
           
       }
....Codigo...->


El metodo retorna un Bitmap de la ventana que le digas como parametro, aunque tambien se podria hacer sin retorno y hacer bmp.save("ruta\archivo.bmo"); si lo que buscas es crear un archivo con la captura.

samuelhm

Otra cosa que no podia hacer en c#, era conseguir Expander/Contraer todos los elementos, como por ejemplo los bucles.
Acostumbrado a visual c++ me era super incomodo, pero lo conseguí con este paquete de expansión:
http://visualstudiogallery.msdn.microsoft.com/6c3c5dec-1534-4c42-81b1-cfd4615fd0e9