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

285
GUILib/GUICommon.cs Normal file
View 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
View 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

Binary file not shown.

View 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
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;
}
}
}

106
GUILib/WPFHelper.cs Normal file
View 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
View 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
View File

@@ -0,0 +1,3 @@
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>