initial oogynize check in _ this actually used to work!

This commit is contained in:
2016-02-14 21:16:31 -08:00
parent b183af5d55
commit 532ea133bc
337 changed files with 30692 additions and 0 deletions

207
GUILib/ScreenCapture.cs Normal file
View File

@@ -0,0 +1,207 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Forms;
using System.Reflection;
using Foo.Platform;
using Foo.Platform.Win32;
namespace Foo.GUILib
{
public class ScreenCapture
{
// Declare the Log4net Variable
private static log4net.ILog Log = Logger.GetLog4NetInterface(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Saves a Window using a DC of the Full Screen, then crops the window out of the
/// full screen capture. We have to do this because SaveWindowUsingDCNBitBlt() doesn't
/// work for all programs that overwrite the glass area on Aero (like MS Office)
/// </summary>
/// <remarks>
/// IMP! - This function will work on some multiple monitor configurations but currently NOT all!
/// If for example, the primary display is on the left and sec on the right, and the window is on the
/// right monitor, then all x and y values will be positive, (We currently only handle multiple monitors,
/// where one x or y value is negative!),
/// ~more calculations must be done for multiple x, multiple y positive configurations
/// </remarks>
/// <param name="hWnd">handle to a Window</param>
public Image SaveWindowUsingFullScreenShotCrop(IntPtr hWnd)
{
try
{
// First get the Window Rect
RECT rectWnd;
Win32Functions.GetWindowRect(hWnd, out rectWnd);
// Now figure out which monitor the window is in
IntPtr hMonitor = Win32Functions.MonitorFromRect(ref rectWnd, (int)Win32_Constants.MONITOR_DEFAULTTONEAREST);
// Get the szDevice Name for the Monitor
MONITORINFOEX monitorinfoex = new MONITORINFOEX();
monitorinfoex.cbSize = Marshal.SizeOf(monitorinfoex);
if (!Win32Functions.GetMonitorInfo(hMonitor, ref monitorinfoex))
return null;
// Use szDevice to create a DC
IntPtr hDC = Win32Functions.CreateDC(monitorinfoex.szDeviceName, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
//Here we make a compatible device context in memory for screen device context.
IntPtr hMemDC = Win32Functions.CreateCompatibleDC(hDC);
// Let's get all the monitor dimensions we need
Rectangle rectDim = monitorinfoex.rcMonitor.AsRectangle;
int DisplayHeight = rectDim.Height;
int DisplayWidth = rectDim.Width;
//The .net way to retrieve dimensions
Screen screen = Screen.FromHandle(hWnd);
//We create a compatible bitmap of screen size using screen device context.
IntPtr hBitmap = Win32Functions.CreateCompatibleBitmap(hDC, DisplayWidth, DisplayHeight);
if (hBitmap != IntPtr.Zero)
{
//Here we select the compatible bitmap in memeory device context and keeps the refrence to Old bitmap.
IntPtr hOld = (IntPtr)Win32Functions.SelectObject(hMemDC, hBitmap);
//We copy the Bitmap to the memory device context.
Win32Functions.BitBlt(hMemDC, 0, 0, DisplayWidth, DisplayHeight, hDC, 0, 0, Win32_Constants.SRCCOPY);
//We select the old bitmap back to the memory device context.
Win32Functions.SelectObject(hMemDC, hOld);
//We delete the memory device context.
Win32Functions.DeleteDC(hMemDC);
//Delete the screen device context.
Win32Functions.DeleteDC(hDC);
//Image is created by Image bitmap handle and stored in local variable.
Image image = (Image)System.Drawing.Image.FromHbitmap(hBitmap);
// * For Debugging *
//string strFileNameNPathWExtPNG = (Env.GetSnapshotDirectory() + @"\" + hWnd.ToString() + ".png");
//image.Save(strFileNameNPathWExtPNG, System.Drawing.Imaging.ImageFormat.Png);
//Release the memory for compatible bitmap.
Win32Functions.DeleteObject(hBitmap);
////
// Imp! - Now we want to crop the Window out of the Screen Image
// NOTE! - Here we convert the screen positions into the corresponding
// image position on that screen
////
int height = rectWnd.AsRectangle.Height;
int width = rectWnd.AsRectangle.Width;
rectWnd.left = Math.Abs(rectWnd.left - screen.Bounds.Left);
rectWnd.right = rectWnd.left + width;
rectWnd.top = Math.Abs(rectWnd.top - screen.Bounds.Top);
rectWnd.bottom = rectWnd.top + height;
// Convert the Rectangle for .Net Use
Rectangle rectangleWnd = rectWnd.AsRectangle;
Bitmap bmpImage = new Bitmap(image);
Bitmap bmpCrop = bmpImage.Clone(rectangleWnd, bmpImage.PixelFormat);
//Bitmap bmpCrop = (Bitmap)image;
//bmpCrop = bmpCrop.Clone(rectangleWnd, bmpCrop.PixelFormat);
return (Image)bmpCrop;
}
}
catch (Exception e)
{
Log.Error(string.Format("{0}() - Error thrown", MethodBase.GetCurrentMethod().Name), e);
}
return null;
}
/// <summary>
/// Saves the Window using a DC, this works well for bUseClientDC = true, but doesn't
/// work when using the Window's DC because of Aero drawing via directx, the window frame
/// won't be in the image
/// </summary>
/// <param name="hWnd">handle to a Window</param>
/// <param name="bUseClientDC">true to use ClientDC, false to use WindowDC</param>
public Image SaveWindowUsingDCNBitBlt(IntPtr hWnd, bool bUseClientDC)
{
try
{
SIZE size;
IntPtr hDC;
IntPtr hBitmap;
Image image;
RECT Rect = new RECT();
if (bUseClientDC)
Win32Functions.GetClientRect(hWnd, out Rect);
else
Win32Functions.GetWindowRect(hWnd, out Rect);
size.cx = (Rect.right - Rect.left);
size.cy = (Rect.bottom - Rect.top);
// TRY USING GetDCEx() - May actually do better
//hDC = Win32Functions.GetDCEx(hWnd);
if (bUseClientDC)
hDC = Win32Functions.GetDC(hWnd);
else
hDC = Win32Functions.GetWindowDC(hWnd);
//Here we make a compatible device context in memory for screen device context.
IntPtr hMemDC = Win32Functions.CreateCompatibleDC(hDC);
//We create a compatible bitmap of screen size using screen device context.
hBitmap = Win32Functions.CreateCompatibleBitmap(hDC, size.cx, size.cy);
if (hBitmap != IntPtr.Zero)
{
//Here we select the compatible bitmap in memeory device context and keeps the refrence to Old bitmap.
IntPtr hOld = (IntPtr)Win32Functions.SelectObject(hMemDC, hBitmap);
//We copy the Bitmap to the memory device context.
Win32Functions.BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, Win32_Constants.SRCCOPY);
//We select the old bitmap back to the memory device context.
Win32Functions.SelectObject(hMemDC, hOld);
//We delete the memory device context.
Win32Functions.DeleteDC(hMemDC);
//We release the screen device context.
Win32Functions.ReleaseDC(hWnd, hDC);
//Image is created by Image bitmap handle and stored in local variable.
image = (Image)System.Drawing.Image.FromHbitmap(hBitmap);
// * For Debugging *
//string strFileNameNPathWExtPNG = (Env.GetSnapshotDirectory() + @"\" + hWnd.ToString() + ".png");
//image.Save(strFileNameNPathWExtPNG, System.Drawing.Imaging.ImageFormat.Png);
//Release the memory for compatible bitmap.
Win32Functions.DeleteObject(hBitmap);
return image;
}
else
{
Log.Error(string.Format("{0}() - hBitmap is Null, something is wrong", MethodBase.GetCurrentMethod().Name));
}
}
catch (Exception e)
{
Log.Error(string.Format("{0}() - Error thrown", MethodBase.GetCurrentMethod().Name), e);
}
return null;
}
}
}