initial oogynize check in _ this actually used to work!
This commit is contained in:
285
GUILib/GUICommon.cs
Normal file
285
GUILib/GUICommon.cs
Normal file
@@ -0,0 +1,285 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using System.Diagnostics;
|
||||
|
||||
// Ooganizer Namespaces
|
||||
using Foo.Platform;
|
||||
using Foo.Platform.Interacters;
|
||||
using Foo.Platform.Win32;
|
||||
|
||||
namespace Foo.GUILib
|
||||
{
|
||||
/// <summary>
|
||||
/// This is the generic GUICommon Class, that serves us a generic implementation to
|
||||
/// everyone as to isolate ourselves from OS Changes
|
||||
/// </summary>
|
||||
public class GUICommon
|
||||
{
|
||||
// Keep track of all the origianl window positions that go
|
||||
// thru here, ~we delete them when position back to org position
|
||||
// get's called.
|
||||
private static Dictionary<IntPtr,RECT> s_orgWindowPosMap;
|
||||
private static bool s_bOutOfProc_UseBH = false;
|
||||
|
||||
// public properties
|
||||
public static bool OutOfProc { get { return s_bOutOfProc_UseBH; } }
|
||||
|
||||
// keep track of Window Positions
|
||||
static GUICommon()
|
||||
{
|
||||
s_orgWindowPosMap = new Dictionary<IntPtr, RECT>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a screen snapshot of the passed in window handle.
|
||||
/// </summary>
|
||||
/// <param name="hWnd">Window to Snap</param>
|
||||
/// <returns>a window image</returns>
|
||||
public static Image PerformSnapshot(IntPtr hWnd)
|
||||
{
|
||||
if (hWnd != IntPtr.Zero)
|
||||
{
|
||||
ScreenCapture screencap = new ScreenCapture();
|
||||
|
||||
if (Env.Theme == Env.Themes.AeroTheme)
|
||||
return screencap.SaveWindowUsingFullScreenShotCrop(hWnd);
|
||||
else
|
||||
return screencap.SaveWindowUsingDCNBitBlt(hWnd, false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Positions a window in the center at Golden Ratio and takes a snapshot.
|
||||
/// ~corner stone of our add workspace strategy
|
||||
/// </summary>
|
||||
/// <param name="hWnd">handle to the window to manipulate</param>
|
||||
/// <param name="bOutOfProc">Set to true to use ButtonHook to Perform the action</param>
|
||||
public static Image PositionWindowToGoldenPosAndTakeSnapshot(IntPtr hWnd, bool bOutOfProc)
|
||||
{
|
||||
// use ButtonHook, Yes / No?
|
||||
s_bOutOfProc_UseBH = bOutOfProc;
|
||||
|
||||
// First thing to do is to save the org position
|
||||
RECT rect;
|
||||
Win32Functions.GetWindowRect(hWnd, out rect);
|
||||
s_orgWindowPosMap[hWnd] = rect;
|
||||
|
||||
// First we fade the window totally away
|
||||
FadeWindow(hWnd, true);
|
||||
|
||||
// now we want to fade it out of the monitor center
|
||||
// However using the golden ratio as the size
|
||||
FadeWindowOutOfMonitorCenterInGoldenRatio(hWnd, rect);
|
||||
|
||||
// Make sure we are in position and drawing at this point,
|
||||
// perform the snapshot and return
|
||||
System.Threading.Thread.Sleep(10);
|
||||
|
||||
//PositionWindowBackToWhereItWas(hWnd);
|
||||
|
||||
Image image = PerformSnapshot(hWnd);
|
||||
//image.Save(@"D:\Users\HPInvent\Desktop\Snapshot1.png", System.Drawing.Imaging.ImageFormat.Png);
|
||||
//return null;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Positions a window back to where it was prior to calling PositionWindowToGoldenPosAndTakeSnapshot().
|
||||
/// ~Hence, you should call this after calling that function
|
||||
/// </summary>
|
||||
/// <param name="hWnd">handle to the window to manipulate</param>
|
||||
/// <param name="bOutOfProc">Set to true to use ButtonHook to Perform the action</param>
|
||||
public static void PositionWindowBackToWhereItWas(IntPtr hWnd, bool bOutOfProc)
|
||||
{
|
||||
// use ButtonHook, Yes / No?
|
||||
s_bOutOfProc_UseBH = bOutOfProc;
|
||||
|
||||
// try to retrieve the org value from the map
|
||||
if (!s_orgWindowPosMap.ContainsKey(hWnd))
|
||||
return;
|
||||
|
||||
RECT orgRect = s_orgWindowPosMap[hWnd];
|
||||
|
||||
// Set the Window totally invisible
|
||||
SetAlphaTransparency(hWnd, 0);
|
||||
|
||||
// As part of the effect, wait a little
|
||||
System.Threading.Thread.Sleep(60);
|
||||
|
||||
// Now just flat out position it back to where it was
|
||||
Win32Functions.SetWindowPos(hWnd, IntPtr.Zero, orgRect.left, orgRect.top, orgRect.AsRectangle.Width, orgRect.AsRectangle.Height, (uint)SetWindowPosFlags.SWP_SHOWWINDOW);
|
||||
|
||||
// Now Fade the Window out
|
||||
FadeWindow(hWnd, false);
|
||||
|
||||
//SetAlphaTransparency(hWnd, 0); // invisible
|
||||
//SetAlphaTransparency(hWnd, 255); // visible
|
||||
|
||||
// since we positioned the window back to where it was,
|
||||
// we no longer need to keep track of it's org position
|
||||
s_orgWindowPosMap.Remove(hWnd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this generic function to set the transparency
|
||||
/// </summary>
|
||||
private static void SetAlphaTransparency(IntPtr hWnd, byte alpha)
|
||||
{
|
||||
if (s_bOutOfProc_UseBH)
|
||||
BHInteracter.SetWindowTransparency(hWnd, alpha);
|
||||
else
|
||||
Win32_WrapperFunc.SetAlphaChannel(hWnd, alpha);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Golden Ratio (~1.618) is used for the Snapshot to give it the best look
|
||||
/// </summary>
|
||||
/// <param name="screen">pass in th screen for which to calculate the ratio for</param>
|
||||
/// <param name="rect">the width and height to achieve the best golden ratio for that screen</param>
|
||||
private static void CalculateGoldenRatio(Screen screen, out RECT rect)
|
||||
{
|
||||
const int _MAXHEIGHT = 1100; // max pleasing height
|
||||
const double _fGoldenRatio = 1.618;
|
||||
const double _fsafetybuffer = 10; // 10% just in case
|
||||
// safety buffer for height/width
|
||||
|
||||
int maxHeight = screen.WorkingArea.Height;
|
||||
int maxWidth = screen.WorkingArea.Width;
|
||||
|
||||
// is this a potrait screen?
|
||||
bool bIsPortrait = maxHeight > maxWidth;
|
||||
|
||||
// calculated height and width
|
||||
int height = 0;
|
||||
int width = 0;
|
||||
|
||||
// Normal Screen
|
||||
if (!bIsPortrait)
|
||||
{
|
||||
// calculated height and width;
|
||||
height = maxHeight - (int)(((double)maxHeight / 100) * _fsafetybuffer);
|
||||
width = (int)((double)height / _fGoldenRatio);
|
||||
}
|
||||
else // Portrait
|
||||
{
|
||||
width = maxWidth - (int)(((double)maxWidth / 100) * _fsafetybuffer);
|
||||
height = (int)((double)width * _fGoldenRatio);
|
||||
}
|
||||
|
||||
// Enforce that the height is not bigger than _MAXHEIGHT, anything bigger than
|
||||
// that just look unpleasant.
|
||||
if (height >= _MAXHEIGHT)
|
||||
{
|
||||
height = _MAXHEIGHT;
|
||||
width = (int)((double)height / _fGoldenRatio);
|
||||
}
|
||||
|
||||
// pass out the calculated height and width
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.bottom = height;
|
||||
rect.right = width;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to quickle fade a window
|
||||
/// </summary>
|
||||
/// <param name="bFadeIn">Set to true to fade in, false to Fade out</param>
|
||||
private static void FadeWindow(IntPtr hWnd, bool bFadeIn)
|
||||
{
|
||||
|
||||
// Stole Increment Fading from Buttonhook
|
||||
const int LOWER_INCREMENT = 7;
|
||||
const int MIDDLE_INCREMENT = 15;
|
||||
const int UPPER_INCREMENT = 25;
|
||||
|
||||
// Increment Points *inverted*
|
||||
const int LOWER_POINT = 60;
|
||||
const int MIDDLE_POINT = 160;
|
||||
const int UPPER_POINT = 230;
|
||||
|
||||
// Fade in or Fade out?
|
||||
byte alpha = (!bFadeIn)? (byte)0 : (byte)255;
|
||||
bool bDone = false;
|
||||
|
||||
if (!bFadeIn) // FadeOut
|
||||
{
|
||||
while (!bDone)
|
||||
{
|
||||
if (alpha >= UPPER_POINT)
|
||||
{
|
||||
alpha = 255; // just show the thing already
|
||||
bDone = true;
|
||||
}
|
||||
else if (alpha <= LOWER_POINT)
|
||||
alpha += LOWER_INCREMENT;
|
||||
else if (alpha <= MIDDLE_POINT)
|
||||
alpha += MIDDLE_INCREMENT;
|
||||
else
|
||||
alpha += UPPER_INCREMENT;
|
||||
|
||||
SetAlphaTransparency(hWnd, alpha);
|
||||
System.Threading.Thread.Sleep(20);
|
||||
}
|
||||
}
|
||||
else // FadeIn
|
||||
{
|
||||
while (!bDone)
|
||||
{
|
||||
if (alpha <= (255 - UPPER_POINT)) //25
|
||||
{
|
||||
alpha = 0; // just hide the thing already
|
||||
bDone = true;
|
||||
}
|
||||
else if (alpha >= (255 - LOWER_POINT)) //195
|
||||
alpha -= LOWER_INCREMENT;
|
||||
else if (alpha >= (255 - MIDDLE_POINT)) // 95
|
||||
alpha -= MIDDLE_INCREMENT;
|
||||
else
|
||||
alpha -= UPPER_INCREMENT;
|
||||
|
||||
SetAlphaTransparency(hWnd, alpha);
|
||||
System.Threading.Thread.Sleep(20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function to determine the monitor and it's center and
|
||||
/// fade out the window there in GoldenRatio Siz
|
||||
/// </summary>
|
||||
private static void FadeWindowOutOfMonitorCenterInGoldenRatio(IntPtr hWnd, RECT orgRect)
|
||||
{
|
||||
// get the screen the original rect was mostly located
|
||||
Screen screen = Screen.FromRectangle(orgRect.AsRectangle);
|
||||
|
||||
// now figure out the best rect to use for this screen
|
||||
RECT goldenRect;
|
||||
CalculateGoldenRatio(screen, out goldenRect);
|
||||
|
||||
// calculate where we must place the golden window
|
||||
// (centering it on the screen)
|
||||
Point pt = new Point();
|
||||
pt.Y = (screen.Bounds.Height - goldenRect.AsRectangle.Height) / 2;
|
||||
pt.X = (screen.Bounds.Width - goldenRect.AsRectangle.Width) / 2;
|
||||
|
||||
// Calculate the window center according to the screen
|
||||
pt.Y = screen.Bounds.Top + pt.Y;
|
||||
pt.X = screen.Bounds.Left + pt.X;
|
||||
|
||||
// Make the window totally transparent and show it in the golden ratio position
|
||||
SetAlphaTransparency(hWnd, 0);
|
||||
Win32Functions.SetWindowPos(hWnd, IntPtr.Zero, pt.X, pt.Y, goldenRect.AsRectangle.Width, goldenRect.AsRectangle.Height, (uint) SetWindowPosFlags.SWP_SHOWWINDOW);
|
||||
|
||||
// Now Fade the Window out
|
||||
FadeWindow(hWnd, false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
103
GUILib/GUILib.csproj
Normal file
103
GUILib/GUILib.csproj
Normal file
@@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{C1282050-455B-44F4-8520-1C005E38EFB2}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Foo.GUILib</RootNamespace>
|
||||
<AssemblyName>GUILib</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<SccProjectName>
|
||||
</SccProjectName>
|
||||
<SccLocalPath>
|
||||
</SccLocalPath>
|
||||
<SccAuxPath>
|
||||
</SccAuxPath>
|
||||
<SccProvider>
|
||||
</SccProvider>
|
||||
<TargetFrameworkSubset>
|
||||
</TargetFrameworkSubset>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>MyKeyFile.SNK</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\Target\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\Target\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\Components\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PresentationCore">
|
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="PresentationFramework">
|
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Data.DataSetExtensions">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="UIAutomationProvider">
|
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase">
|
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="GUICommon.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ScreenCapture.cs" />
|
||||
<Compile Include="WPFHelper.cs" />
|
||||
<Compile Include="WPFHiddenWindow.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="MyKeyFile.SNK" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Platform\Platform.csproj">
|
||||
<Project>{F6929AFC-BF61-43A0-BABD-F807B65FFFA1}</Project>
|
||||
<Name>Platform</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
BIN
GUILib/MyKeyFile.SNK
Normal file
BIN
GUILib/MyKeyFile.SNK
Normal file
Binary file not shown.
36
GUILib/Properties/AssemblyInfo.cs
Normal file
36
GUILib/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("GUILib")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("GUILib")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2009")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("451a4209-15d4-49ef-a70f-2cc6c6d524b5")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
207
GUILib/ScreenCapture.cs
Normal file
207
GUILib/ScreenCapture.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
106
GUILib/WPFHelper.cs
Normal file
106
GUILib/WPFHelper.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Media;
|
||||
using System.Windows;
|
||||
|
||||
namespace Foo.GUILib
|
||||
{
|
||||
static public class WPFHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Useful to create a simple wrapping tooltip for a wpf control
|
||||
/// </summary>
|
||||
/// <param name="strToolTipContent"></param>
|
||||
/// <param name="height">Set to 0 to leave default, else set to 0> to define max height</param>
|
||||
/// <param name="width">Set to 0 to leave default, else set to 0> to define max width</param>
|
||||
/// <returns>a ToolTip Object to assign to a control</returns>
|
||||
public static ToolTip CreateNewStringToolTip(string strToolTipContent, int height, int width)
|
||||
{
|
||||
// Create the TextBlock
|
||||
TextBlock tx = new TextBlock();
|
||||
if(height > 0)
|
||||
tx.Height = height;
|
||||
if(width > 0)
|
||||
tx.Width = width;
|
||||
tx.TextWrapping = TextWrapping.Wrap;
|
||||
tx.Text = strToolTipContent;
|
||||
|
||||
// Create the ToolTip with the TextBlock inside
|
||||
ToolTip tt = new ToolTip();
|
||||
tt.Content = strToolTipContent;
|
||||
return tt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Useful if you want to know if the Mouse cursor is over the specified Wpf Window
|
||||
/// (Uses windowsforms to do the calculations)
|
||||
/// </summary>
|
||||
/// <returns>true if the mouse cursor is over the specified form window, false otherwise</returns>
|
||||
public static bool IsMouseCursorOverWPFormWindow(Window wpfWindow)
|
||||
{
|
||||
if (wpfWindow != null)
|
||||
{
|
||||
// Get the Point location of the mouse cursor
|
||||
System.Drawing.Point point = System.Windows.Forms.Cursor.Position;
|
||||
|
||||
// Get the rect for the Navigation Form
|
||||
Point wpfFormLeftTopPoint = new Point(wpfWindow.Left, wpfWindow.Top);
|
||||
Size wpfFormSize = new Size(wpfWindow.Width, wpfWindow.Height);
|
||||
Rect rect = new Rect(wpfFormLeftTopPoint, wpfFormSize);
|
||||
|
||||
// Return if the Mouse is over the Navigation Form
|
||||
return (rect.Contains((double)point.X, (double)point.Y));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For Dynamically Creating Text ComboBox Items
|
||||
/// </summary>
|
||||
/// <param name="strContent">Text Content to Display</param>
|
||||
/// <param name="tag">object to tag to the menu item</param>
|
||||
/// <returns></returns>
|
||||
public static ComboBoxItem CreateAComboBoxItem(string strContent, object tag)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(strContent) && (tag != null))
|
||||
{
|
||||
ComboBoxItem item = new ComboBoxItem();
|
||||
item.Content = strContent;
|
||||
item.Tag = tag;
|
||||
return item;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For dynamically creating Image sources, this function helps you to create an image out of
|
||||
/// a Resource Uri. You can then assign this image to a 'Source' property on an image wpf object
|
||||
/// </summary>
|
||||
/// <param name="strRelativeResourceUri">a valid relative Resource Uri String to an image</param>
|
||||
/// <param name="ImageHeight">the output image's desired height</param>
|
||||
/// <param name="ImageWidth">the output image's desired width</param>
|
||||
/// <returns></returns>
|
||||
public static Image CreateWPFImageFromRelativeResourceUri(string strRelativeResourceUri, int ImageHeight, int ImageWidth)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(strRelativeResourceUri))
|
||||
{
|
||||
Image myImage = new Image();
|
||||
BitmapImage image = new BitmapImage();
|
||||
image.BeginInit();
|
||||
image.UriSource = new Uri(strRelativeResourceUri, UriKind.Relative);
|
||||
image.EndInit();
|
||||
myImage.Stretch = Stretch.Fill;
|
||||
myImage.Height = ImageHeight;
|
||||
myImage.Width = ImageWidth;
|
||||
myImage.Source = image;
|
||||
return myImage;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
148
GUILib/WPFHiddenWindow.cs
Normal file
148
GUILib/WPFHiddenWindow.cs
Normal file
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Media;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
|
||||
namespace Foo.GUILib
|
||||
{
|
||||
/// <summary>
|
||||
/// Class used to keep WPF Windows Hidden permanently.
|
||||
/// Should be called by Performance WPF Window 'Hidden' loads
|
||||
/// when constructed, and when loaded.
|
||||
///
|
||||
/// Note: All WPFWindow's that use this class don't set certain properties on the
|
||||
/// window until they are loaded and it's NOT a performance Cache window.
|
||||
/// </summary>
|
||||
public static class WPFHiddenWindow
|
||||
{
|
||||
private static Dictionary<IntPtr, Window> s_hWndToWindowMap = new Dictionary<IntPtr, Window>();
|
||||
|
||||
/// <summary>
|
||||
/// * Core * 'Hiding' Function. Makes sure that the Window is and
|
||||
/// stays hidden.
|
||||
/// </summary>
|
||||
/// <param name="wpfWindow">a WPF window object</param>
|
||||
private static void HideWPFWindow(Window wpfWindow)
|
||||
{
|
||||
// Force Opacity
|
||||
wpfWindow.WindowStyle = WindowStyle.None;
|
||||
wpfWindow.Opacity = 0.0;
|
||||
wpfWindow.ShowInTaskbar = false;
|
||||
wpfWindow.ShowActivated = false;
|
||||
|
||||
// Force a tiny Window in top-left corner
|
||||
wpfWindow.Width = 5;
|
||||
wpfWindow.Height = 5;
|
||||
wpfWindow.Top = 0;
|
||||
wpfWindow.Left = 0;
|
||||
wpfWindow.WindowStartupLocation = WindowStartupLocation.Manual;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this to execute a Show() call on a wpfWindow Performance cache window. Returns true
|
||||
/// if bPerformanceCache is true. This means that this Function did something to the window.
|
||||
/// </summary>
|
||||
/// <param name="wpfWindow">a WPF window object</param>
|
||||
/// <param name="bPerformanceCache">Pass in true, if this is a performance Cache window</param>
|
||||
/// <returns>true if bPerformanceCache is true, false otherwise</returns>
|
||||
public static bool ExecuteShowOnAHiddenWindow(Window wpfWindow, bool bPerformanceCache)
|
||||
{
|
||||
if (bPerformanceCache)
|
||||
{
|
||||
HideWPFWindow(wpfWindow);
|
||||
wpfWindow.Show();
|
||||
wpfWindow.Hide();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this in your WPFWindow's constructor. Returns true if bPerformanceCache is true.
|
||||
/// This means that this Function did something to the window.
|
||||
/// </summary>
|
||||
/// <param name="wpfWindow">a WPF window object</param>
|
||||
/// <param name="bPerformanceCache">Pass in true, if this is a performance Cache window</param>
|
||||
/// <returns>true if bPerformanceCache is true, false otherwise</returns>
|
||||
public static bool HiddenWindowConstructor(Window wpfWindow, bool bPerformanceCache)
|
||||
{
|
||||
if (bPerformanceCache)
|
||||
{
|
||||
HideWPFWindow(wpfWindow);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this from your WPFWindow's OnLoad Event. Returns true if bPerformanceCache is true.
|
||||
/// This means that this Function did something to the window.
|
||||
/// </summary>
|
||||
/// <param name="wpfWindow">a WPF window object</param>
|
||||
/// <param name="bPerformanceCache">Pass in true, if this is a performance Cache window</param>
|
||||
/// <returns>true if bPerformanceCache is true, false otherwise</returns>
|
||||
public static bool HiddenWindowOnLoad(Window wpfWindow, bool bPerformanceCache)
|
||||
{
|
||||
if (bPerformanceCache)
|
||||
{
|
||||
HideWPFWindow(wpfWindow);
|
||||
|
||||
// Add Message Hook for performanceCache WPForm * To make sure it is always invisible *
|
||||
WindowInteropHelper interop = new WindowInteropHelper(wpfWindow);
|
||||
HwndSource source = HwndSource.FromHwnd(interop.Handle);
|
||||
source.AddHook(new HwndSourceHook(MessageHook));
|
||||
s_hWndToWindowMap[interop.Handle] = wpfWindow;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this from your WPFWindow's Closing Event. Returns true if bPerformanceCache is true.
|
||||
/// This means that this Function did something to the window.
|
||||
/// </summary>
|
||||
/// <param name="wpfWindow">a WPF window object</param>
|
||||
/// <param name="bPerformanceCache">Pass in true, if this is a performance Cache window</param>
|
||||
/// <returns>true if bPerformanceCache is true, false otherwise</returns>
|
||||
public static bool HiddenWindowClosing(Window wpfWindow, bool bPerformanceCache)
|
||||
{
|
||||
if (s_hWndToWindowMap.ContainsValue(wpfWindow))
|
||||
{
|
||||
foreach (IntPtr hWnd in s_hWndToWindowMap.Keys)
|
||||
{
|
||||
if (s_hWndToWindowMap[hWnd] == wpfWindow)
|
||||
{
|
||||
s_hWndToWindowMap.Remove(hWnd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This Message Hook is for the Hidden wpfForm that we use for better performance,
|
||||
/// We want to make sure that it is never displayed *It can occur that explorer.exe can show it, without this hook*
|
||||
/// ~i.e. when explorer.exe crashes, and get's restarted
|
||||
/// </summary>
|
||||
private static IntPtr MessageHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
// Get the Proper WPF Object and make sure it is Hidden
|
||||
if (s_hWndToWindowMap.ContainsKey(hwnd))
|
||||
{
|
||||
Window wpfWindow = s_hWndToWindowMap[hwnd];
|
||||
if (wpfWindow != null)
|
||||
HideWPFWindow(wpfWindow);
|
||||
}
|
||||
|
||||
handled = false;
|
||||
return System.IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
GUILib/app.config
Normal file
3
GUILib/app.config
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
|
||||
Reference in New Issue
Block a user