This commit is contained in:
2024-02-23 07:03:56 -05:00
commit 4a3813687a
937 changed files with 113251 additions and 0 deletions

View File

@@ -0,0 +1,111 @@
/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
/**************************************************************************\
Copyright Microsoft Corporation. All Rights Reserved.
\**************************************************************************/
namespace Standard
{
internal static partial class IID
{
/// <summary>IID_IEnumIDList</summary>
public const string EnumIdList = "000214F2-0000-0000-C000-000000000046";
/// <summary>IID_IEnumObjects</summary>
public const string EnumObjects = "2c1c7e2e-2d0e-4059-831e-1e6f82335c2e";
/// <summary>IID_IHTMLDocument2</summary>
public const string HtmlDocument2 = "332C4425-26CB-11D0-B483-00C04FD90119";
/// <summary>IID_IModalWindow</summary>
public const string ModalWindow = "b4db1657-70d7-485e-8e3e-6fcb5a5c1802";
/// <summary>IID_IObjectArray</summary>
public const string ObjectArray = "92CA9DCD-5622-4bba-A805-5E9F541BD8C9";
/// <summary>IID_IObjectCollection</summary>
public const string ObjectCollection = "5632b1a4-e38a-400a-928a-d4cd63230295";
/// <summary>IID_IPropertyNotifySink</summary>
public const string PropertyNotifySink = "9BFBBC02-EFF1-101A-84ED-00AA00341D07";
/// <summary>IID_IPropertyStore</summary>
public const string PropertyStore = "886d8eeb-8cf2-4446-8d02-cdba1dbdcf99";
/// <summary>IID_IServiceProvider</summary>
public const string ServiceProvider = "6d5140c1-7436-11ce-8034-00aa006009fa";
/// <summary>IID_IShellFolder</summary>
public const string ShellFolder = "000214E6-0000-0000-C000-000000000046";
/// <summary>IID_IShellLink</summary>
public const string ShellLink = "000214F9-0000-0000-C000-000000000046";
/// <summary>IID_IShellItem</summary>
public const string ShellItem = "43826d1e-e718-42ee-bc55-a1e261c37bfe";
/// <summary>IID_IShellItem2</summary>
public const string ShellItem2 = "7e9fb0d3-919f-4307-ab2e-9b1860310c93";
/// <summary>IID_IShellItemArray</summary>
public const string ShellItemArray = "B63EA76D-1F85-456F-A19C-48159EFA858B";
/// <summary>IID_ITaskbarList</summary>
public const string TaskbarList = "56FDF342-FD6D-11d0-958A-006097C9A090";
/// <summary>IID_ITaskbarList2</summary>
public const string TaskbarList2 = "602D4995-B13A-429b-A66E-1935E44F4317";
/// <summary>IID_IUnknown</summary>
public const string Unknown = "00000000-0000-0000-C000-000000000046";
#region Win7 IIDs
/// <summary>IID_IApplicationDestinations</summary>
public const string ApplicationDestinations = "12337d35-94c6-48a0-bce7-6a9c69d4d600";
/// <summary>IID_IApplicationDocumentLists</summary>
public const string ApplicationDocumentLists = "3c594f9f-9f30-47a1-979a-c9e83d3d0a06";
/// <summary>IID_ICustomDestinationList</summary>
public const string CustomDestinationList = "6332debf-87b5-4670-90c0-5e57b408a49e";
/// <summary>IID_IObjectWithAppUserModelID</summary>
public const string ObjectWithAppUserModelId = "36db0196-9665-46d1-9ba7-d3709eecf9ed";
/// <summary>IID_IObjectWithProgID</summary>
public const string ObjectWithProgId = "71e806fb-8dee-46fc-bf8c-7748a8a1ae13";
/// <summary>IID_ITaskbarList3</summary>
public const string TaskbarList3 = "ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf";
/// <summary>IID_ITaskbarList4</summary>
public const string TaskbarList4 = "c43dc798-95d1-4bea-9030-bb99e2983a1a";
#endregion
}
internal static partial class CLSID
{
public static T CoCreateInstance<T>(string clsid)
{
return (T)System.Activator.CreateInstance(System.Type.GetTypeFromCLSID(new System.Guid(clsid)));
}
/// <summary>CLSID_TaskbarList</summary>
/// <remarks>IID_ITaskbarList</remarks>
public const string TaskbarList = "56FDF344-FD6D-11d0-958A-006097C9A090";
/// <summary>CLSID_EnumerableObjectCollection</summary>
/// <remarks>IID_IEnumObjects.</remarks>
public const string EnumerableObjectCollection = "2d3468c1-36a7-43b6-ac24-d3f02fd9607a";
/// <summary>CLSID_ShellLink</summary>
/// <remarks>IID_IShellLink</remarks>
public const string ShellLink = "00021401-0000-0000-C000-000000000046";
#region Win7 CLSIDs
/// <summary>CLSID_DestinationList</summary>
/// <remarks>IID_ICustomDestinationList</remarks>
public const string DestinationList = "77f10cf0-3db5-4966-b520-b7c54fd35ed6";
/// <summary>CLSID_ApplicationDestinations</summary>
/// <remarks>IID_IApplicationDestinations</remarks>
public const string ApplicationDestinations = "86c14003-4d6b-4ef3-a7b4-0506663b2e68";
/// <summary>CLSID_ApplicationDocumentLists</summary>
/// <remarks>IID_IApplicationDocumentLists</remarks>
public const string ApplicationDocumentLists = "86bec222-30f2-47e0-9f25-60d11cd75c28";
#endregion
}
}

View File

@@ -0,0 +1,389 @@
/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
/**************************************************************************\
Copyright Microsoft Corporation. All Rights Reserved.
\**************************************************************************/
// Conditional to use more aggressive fail-fast behaviors when debugging.
#define DEV_DEBUG
// This file contains general utilities to aid in development.
// It is distinct from unit test Assert classes.
// Classes here generally shouldn't be exposed publicly since
// they're not particular to any library functionality.
// Because the classes here are internal, it's likely this file
// might be included in multiple assemblies.
namespace Standard
{
using System;
using System.Diagnostics;
using System.Threading;
/// <summary>A static class for verifying assumptions.</summary>
internal static class Assert
{
private static void _Break()
{
#if DEV_DEBUG
Debugger.Break();
#else
Debug.Assert(false);
#endif
}
/// <summary>A function signature for Assert.Evaluate.</summary>
public delegate void EvaluateFunction();
/// <summary>A function signature for Assert.Implies.</summary>
/// <returns>Returns the truth of a predicate.</returns>
public delegate bool ImplicationFunction();
/// <summary>
/// Executes the specified argument.
/// </summary>
/// <param name="argument">The function to execute.</param>
[Conditional("DEBUG")]
public static void Evaluate(EvaluateFunction argument)
{
IsNotNull(argument);
argument();
}
/// <summary>Obsolete: Use Standard.Assert.AreEqual instead of Assert.Equals</summary>
/// <typeparam name="T">The generic type to compare for equality.</typeparam>
/// <param name="expected">The first generic type data to compare. This is is the expected value.</param>
/// <param name="actual">The second generic type data to compare. This is the actual value.</param>
[
Obsolete("Use Assert.AreEqual instead of Assert.Equals", false),
Conditional("DEBUG")
]
public static void Equals<T>(T expected, T actual)
{
AreEqual(expected, actual);
}
/// <summary>
/// Verifies that two generic type data are equal. The assertion fails if they are not.
/// </summary>
/// <typeparam name="T">The generic type to compare for equality.</typeparam>
/// <param name="expected">The first generic type data to compare. This is is the expected value.</param>
/// <param name="actual">The second generic type data to compare. This is the actual value.</param>
/// <remarks>This breaks into the debugger in the case of a failed assertion.</remarks>
[Conditional("DEBUG")]
public static void AreEqual<T>(T expected, T actual)
{
if (null == expected)
{
// Two nulls are considered equal, regardless of type semantics.
if (null != actual && !actual.Equals(expected))
{
_Break();
}
}
else if (!expected.Equals(actual))
{
_Break();
}
}
/// <summary>
/// Verifies that two generic type data are not equal. The assertion fails if they are.
/// </summary>
/// <typeparam name="T">The generic type to compare for inequality.</typeparam>
/// <param name="notExpected">The first generic type data to compare. This is is the value that's not expected.</param>
/// <param name="actual">The second generic type data to compare. This is the actual value.</param>
/// <remarks>This breaks into the debugger in the case of a failed assertion.</remarks>
[Conditional("DEBUG")]
public static void AreNotEqual<T>(T notExpected, T actual)
{
if (null == notExpected)
{
// Two nulls are considered equal, regardless of type semantics.
if (null == actual || actual.Equals(notExpected))
{
_Break();
}
}
else if (notExpected.Equals(actual))
{
_Break();
}
}
/// <summary>
/// Verifies that if the specified condition is true, then so is the result.
/// The assertion fails if the condition is true but the result is false.
/// </summary>
/// <param name="condition">if set to <c>true</c> [condition].</param>
/// <param name="result">
/// A second Boolean statement. If the first was true then so must this be.
/// If the first statement was false then the value of this is ignored.
/// </param>
/// <remarks>This breaks into the debugger in the case of a failed assertion.</remarks>
[Conditional("DEBUG")]
public static void Implies(bool condition, bool result)
{
if (condition && !result)
{
_Break();
}
}
/// <summary>
/// Lazy evaluation overload. Verifies that if a condition is true, then so is a secondary value.
/// </summary>
/// <param name="condition">The conditional value.</param>
/// <param name="result">A function to be evaluated for truth if the condition argument is true.</param>
/// <remarks>
/// This overload only evaluates the result if the first condition is true.
/// </remarks>
[Conditional("DEBUG")]
public static void Implies(bool condition, ImplicationFunction result)
{
if (condition && !result())
{
_Break();
}
}
/// <summary>
/// Verifies that a string has content. I.e. it is not null and it is not empty.
/// </summary>
/// <param name="value">The string to verify.</param>
[Conditional("DEBUG")]
public static void IsNeitherNullNorEmpty(string value)
{
IsFalse(string.IsNullOrEmpty(value));
}
/// <summary>
/// Verifies that a string has content. I.e. it is not null and it is not purely whitespace.
/// </summary>
/// <param name="value">The string to verify.</param>
[Conditional("DEBUG")]
public static void IsNeitherNullNorWhitespace(string value)
{
if (string.IsNullOrEmpty(value))
{
_Break();
}
if (value.Trim().Length == 0)
{
_Break();
}
}
/// <summary>
/// Verifies the specified value is not null. The assertion fails if it is.
/// </summary>
/// <typeparam name="T">The generic reference type.</typeparam>
/// <param name="value">The value to check for nullness.</param>
/// <remarks>This breaks into the debugger in the case of a failed assertion.</remarks>
[Conditional("DEBUG")]
public static void IsNotNull<T>(T value) where T : class
{
if (null == value)
{
_Break();
}
}
[Conditional("DEBUG")]
public static void IsDefault<T>(T value) where T : struct
{
if (!value.Equals(default(T)))
{
Assert.Fail();
}
}
[Conditional("DEBUG")]
public static void IsNotDefault<T>(T value) where T : struct
{
if (value.Equals(default(T)))
{
Assert.Fail();
}
}
/// <summary>
/// Verifies that the specified condition is false. The assertion fails if it is true.
/// </summary>
/// <param name="condition">The expression that should be <c>false</c>.</param>
/// <remarks>This breaks into the debugger in the case of a failed assertion.</remarks>
[Conditional("DEBUG")]
public static void IsFalse(bool condition)
{
if (condition)
{
_Break();
}
}
/// <summary>
/// Verifies that the specified condition is false. The assertion fails if it is true.
/// </summary>
/// <param name="condition">The expression that should be <c>false</c>.</param>
/// <param name="message">The message to display if the condition is <c>true</c>.</param>
/// <remarks>This breaks into the debugger in the case of a failed assertion.</remarks>
[Conditional("DEBUG")]
public static void IsFalse(bool condition, string message)
{
if (condition)
{
_Break();
}
}
/// <summary>
/// Verifies that the specified condition is true. The assertion fails if it is not.
/// </summary>
/// <param name="condition">A condition that is expected to be <c>true</c>.</param>
/// <remarks>This breaks into the debugger in the case of a failed assertion.</remarks>
[Conditional("DEBUG")]
public static void IsTrue(bool condition)
{
if (!condition)
{
_Break();
}
}
/// <summary>
/// Verifies that the specified condition is true. The assertion fails if it is not.
/// </summary>
/// <param name="condition">A condition that is expected to be <c>true</c>.</param>
/// <param name="message">The message to write in case the condition is <c>false</c>.</param>
/// <remarks>This breaks into the debugger in the case of a failed assertion.</remarks>
[Conditional("DEBUG")]
public static void IsTrue(bool condition, string message)
{
if (!condition)
{
_Break();
}
}
/// <summary>
/// This line should never be executed. The assertion always fails.
/// </summary>
/// <remarks>This breaks into the debugger in the case of a failed assertion.</remarks>
[Conditional("DEBUG")]
public static void Fail()
{
_Break();
}
/// <summary>
/// This line should never be executed. The assertion always fails.
/// </summary>
/// <param name="message">The message to display if this function is executed.</param>
/// <remarks>This breaks into the debugger in the case of a failed assertion.</remarks>
[Conditional("DEBUG")]
public static void Fail(string message)
{
_Break();
}
/// <summary>
/// Verifies that the specified object is null. The assertion fails if it is not.
/// </summary>
/// <param name="item">The item to verify is null.</param>
[Conditional("DEBUG")]
public static void IsNull<T>(T item) where T : class
{
if (null != item)
{
_Break();
}
}
/// <summary>
/// Verifies that the specified value is within the expected range. The assertion fails if it isn't.
/// </summary>
/// <param name="lowerBoundInclusive">The lower bound inclusive value.</param>
/// <param name="value">The value to verify.</param>
/// <param name="upperBoundInclusive">The upper bound inclusive value.</param>
[Conditional("DEBUG")]
public static void BoundedDoubleInc(double lowerBoundInclusive, double value, double upperBoundInclusive)
{
if (value < lowerBoundInclusive || value > upperBoundInclusive)
{
_Break();
}
}
/// <summary>
/// Verifies that the specified value is within the expected range. The assertion fails if it isn't.
/// </summary>
/// <param name="lowerBoundInclusive">The lower bound inclusive value.</param>
/// <param name="value">The value to verify.</param>
/// <param name="upperBoundExclusive">The upper bound exclusive value.</param>
[Conditional("DEBUG")]
public static void BoundedInteger(int lowerBoundInclusive, int value, int upperBoundExclusive)
{
if (value < lowerBoundInclusive || value >= upperBoundExclusive)
{
_Break();
}
}
/// <summary>
/// Verify the current thread's apartment state is what's expected. The assertion fails if it isn't
/// </summary>
/// <param name="expectedState">
/// The expected apartment state for the current thread.
/// </param>
/// <remarks>This breaks into the debugger in the case of a failed assertion.</remarks>
[Conditional("DEBUG")]
public static void IsApartmentState(ApartmentState expectedState)
{
if (Thread.CurrentThread.GetApartmentState() != expectedState)
{
_Break();
}
}
[Conditional("DEBUG")]
public static void NullableIsNotNull<T>(T? value) where T : struct
{
if (null == value)
{
_Break();
}
}
[Conditional("DEBUG")]
public static void NullableIsNull<T>(T? value) where T : struct
{
if (null != value)
{
_Break();
}
}
[Conditional("DEBUG")]
public static void IsNotOnMainThread()
{
if (System.Windows.Application.Current.Dispatcher.CheckAccess())
{
_Break();
}
}
}
}

View File

@@ -0,0 +1,148 @@
/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
namespace Standard
{
using System;
using System.Diagnostics.CodeAnalysis;
/// <summary>
/// DoubleUtil uses fixed eps to provide fuzzy comparison functionality for doubles.
/// Note that FP noise is a big problem and using any of these compare
/// methods is not a complete solution, but rather the way to reduce
/// the probability of repeating unnecessary work.
/// </summary>
internal static class DoubleUtilities
{
/// <summary>
/// Epsilon - more or less random, more or less small number.
/// </summary>
private const double Epsilon = 0.00000153;
/// <summary>
/// AreClose returns whether or not two doubles are "close". That is, whether or
/// not they are within epsilon of each other.
/// There are plenty of ways for this to return false even for numbers which
/// are theoretically identical, so no code calling this should fail to work if this
/// returns false.
/// </summary>
/// <param name="value1">The first double to compare.</param>
/// <param name="value2">The second double to compare.</param>
/// <returns>The result of the AreClose comparision.</returns>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public static bool AreClose(double value1, double value2)
{
if (value1 == value2)
{
return true;
}
double delta = value1 - value2;
return (delta < Epsilon) && (delta > -Epsilon);
}
/// <summary>
/// LessThan returns whether or not the first double is less than the second double.
/// That is, whether or not the first is strictly less than *and* not within epsilon of
/// the other number.
/// There are plenty of ways for this to return false even for numbers which
/// are theoretically identical, so no code calling this should fail to work if this
/// returns false.
/// </summary>
/// <param name="value1">The first double to compare.</param>
/// <param name="value2">The second double to compare.</param>
/// <returns>The result of the LessThan comparision.</returns>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public static bool LessThan(double value1, double value2)
{
return (value1 < value2) && !AreClose(value1, value2);
}
/// <summary>
/// GreaterThan returns whether or not the first double is greater than the second double.
/// That is, whether or not the first is strictly greater than *and* not within epsilon of
/// the other number.
/// There are plenty of ways for this to return false even for numbers which
/// are theoretically identical, so no code calling this should fail to work if this
/// returns false.
/// </summary>
/// <param name="value1">The first double to compare.</param>
/// <param name="value2">The second double to compare.</param>
/// <returns>The result of the GreaterThan comparision.</returns>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public static bool GreaterThan(double value1, double value2)
{
return (value1 > value2) && !AreClose(value1, value2);
}
/// <summary>
/// LessThanOrClose returns whether or not the first double is less than or close to
/// the second double. That is, whether or not the first is strictly less than or within
/// epsilon of the other number.
/// There are plenty of ways for this to return false even for numbers which
/// are theoretically identical, so no code calling this should fail to work if this
/// returns false.
/// </summary>
/// <param name="value1">The first double to compare.</param>
/// <param name="value2">The second double to compare.</param>
/// <returns>The result of the LessThanOrClose comparision.</returns>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public static bool LessThanOrClose(double value1, double value2)
{
return (value1 < value2) || AreClose(value1, value2);
}
/// <summary>
/// GreaterThanOrClose returns whether or not the first double is greater than or close to
/// the second double. That is, whether or not the first is strictly greater than or within
/// epsilon of the other number.
/// There are plenty of ways for this to return false even for numbers which
/// are theoretically identical, so no code calling this should fail to work if this
/// returns false.
/// </summary>
/// <param name="value1">The first double to compare.</param>
/// <param name="value2">The second double to compare.</param>
/// <returns>The result of the GreaterThanOrClose comparision.</returns>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public static bool GreaterThanOrClose(double value1, double value2)
{
return (value1 > value2) || AreClose(value1, value2);
}
/// <summary>
/// Test to see if a double is a finite number (is not NaN or Infinity).
/// </summary>
/// <param name='value'>The value to test.</param>
/// <returns>Whether or not the value is a finite number.</returns>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public static bool IsFinite(double value)
{
return !double.IsNaN(value) && !double.IsInfinity(value);
}
/// <summary>
/// Test to see if a double a valid size value (is finite and > 0).
/// </summary>
/// <param name='value'>The value to test.</param>
/// <returns>Whether or not the value is a valid size value.</returns>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public static bool IsValidSize(double value)
{
return IsFinite(value) && GreaterThanOrClose(value, 0);
}
}
}

View File

@@ -0,0 +1,102 @@
/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
/**************************************************************************\
Copyright Microsoft Corporation. All Rights Reserved.
\**************************************************************************/
namespace Standard
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Windows;
using System.Windows.Media;
internal static class DpiHelper
{
private static Matrix _transformToDevice;
private static Matrix _transformToDip;
[SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
static DpiHelper()
{
using (SafeDC desktop = SafeDC.GetDesktop())
{
// Can get these in the static constructor. They shouldn't vary window to window,
// and changing the system DPI requires a restart.
int pixelsPerInchX = NativeMethods.GetDeviceCaps(desktop, DeviceCap.LOGPIXELSX);
int pixelsPerInchY = NativeMethods.GetDeviceCaps(desktop, DeviceCap.LOGPIXELSY);
_transformToDip = Matrix.Identity;
_transformToDip.Scale(96d / (double)pixelsPerInchX, 96d / (double)pixelsPerInchY);
_transformToDevice = Matrix.Identity;
_transformToDevice.Scale((double)pixelsPerInchX / 96d, (double)pixelsPerInchY / 96d);
}
}
/// <summary>
/// Convert a point in device independent pixels (1/96") to a point in the system coordinates.
/// </summary>
/// <param name="logicalPoint">A point in the logical coordinate system.</param>
/// <returns>Returns the parameter converted to the system's coordinates.</returns>
public static Point LogicalPixelsToDevice(Point logicalPoint)
{
return _transformToDevice.Transform(logicalPoint);
}
/// <summary>
/// Convert a point in system coordinates to a point in device independent pixels (1/96").
/// </summary>
/// <param name="logicalPoint">A point in the physical coordinate system.</param>
/// <returns>Returns the parameter converted to the device independent coordinate system.</returns>
public static Point DevicePixelsToLogical(Point devicePoint)
{
return _transformToDip.Transform(devicePoint);
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public static Rect LogicalRectToDevice(Rect logicalRectangle)
{
Point topLeft = LogicalPixelsToDevice(new Point(logicalRectangle.Left, logicalRectangle.Top));
Point bottomRight = LogicalPixelsToDevice(new Point(logicalRectangle.Right, logicalRectangle.Bottom));
return new Rect(topLeft, bottomRight);
}
public static Rect DeviceRectToLogical(Rect deviceRectangle)
{
Point topLeft = DevicePixelsToLogical(new Point(deviceRectangle.Left, deviceRectangle.Top));
Point bottomRight = DevicePixelsToLogical(new Point(deviceRectangle.Right, deviceRectangle.Bottom));
return new Rect(topLeft, bottomRight);
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public static Size LogicalSizeToDevice(Size logicalSize)
{
Point pt = LogicalPixelsToDevice(new Point(logicalSize.Width, logicalSize.Height));
return new Size { Width = pt.X, Height = pt.Y };
}
public static Size DeviceSizeToLogical(Size deviceSize)
{
Point pt = DevicePixelsToLogical(new Point(deviceSize.Width, deviceSize.Height));
return new Size(pt.X, pt.Y);
}
}
}

View File

@@ -0,0 +1,524 @@
/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
/**************************************************************************\
Copyright Microsoft Corporation. All Rights Reserved.
\**************************************************************************/
namespace Standard
{
using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
/// <summary>
/// Wrapper for common Win32 status codes.
/// </summary>
[StructLayout(LayoutKind.Explicit)]
internal struct Win32Error
{
[FieldOffset(0)]
private readonly int _value;
// NOTE: These public static field declarations are automatically
// picked up by (HRESULT's) ToString through reflection.
/// <summary>The operation completed successfully.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_SUCCESS = new Win32Error(0);
/// <summary>Incorrect function.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_INVALID_FUNCTION = new Win32Error(1);
/// <summary>The system cannot find the file specified.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_FILE_NOT_FOUND = new Win32Error(2);
/// <summary>The system cannot find the path specified.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_PATH_NOT_FOUND = new Win32Error(3);
/// <summary>The system cannot open the file.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_TOO_MANY_OPEN_FILES = new Win32Error(4);
/// <summary>Access is denied.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_ACCESS_DENIED = new Win32Error(5);
/// <summary>The handle is invalid.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_INVALID_HANDLE = new Win32Error(6);
/// <summary>Not enough storage is available to complete this operation.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_OUTOFMEMORY = new Win32Error(14);
/// <summary>There are no more files.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_NO_MORE_FILES = new Win32Error(18);
/// <summary>The process cannot access the file because it is being used by another process.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_SHARING_VIOLATION = new Win32Error(32);
/// <summary>The parameter is incorrect.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_INVALID_PARAMETER = new Win32Error(87);
/// <summary>The data area passed to a system call is too small.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_INSUFFICIENT_BUFFER = new Win32Error(122);
/// <summary>Cannot nest calls to LoadModule.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_NESTING_NOT_ALLOWED = new Win32Error(215);
/// <summary>Illegal operation attempted on a registry key that has been marked for deletion.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_KEY_DELETED = new Win32Error(1018);
/// <summary>Element not found.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_NOT_FOUND = new Win32Error(1168);
/// <summary>There was no match for the specified key in the index.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_NO_MATCH = new Win32Error(1169);
/// <summary>An invalid device was specified.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_BAD_DEVICE = new Win32Error(1200);
/// <summary>The operation was canceled by the user.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_CANCELLED = new Win32Error(1223);
/// <summary>The window class was already registered.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_CLASS_ALREADY_EXISTS = new Win32Error(1410);
/// <summary>The specified datatype is invalid.</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly Win32Error ERROR_INVALID_DATATYPE = new Win32Error(1804);
/// <summary>
/// Create a new Win32 error.
/// </summary>
/// <param name="i">The integer value of the error.</param>
public Win32Error(int i)
{
_value = i;
}
/// <summary>Performs HRESULT_FROM_WIN32 conversion.</summary>
/// <param name="error">The Win32 error being converted to an HRESULT.</param>
/// <returns>The equivilent HRESULT value.</returns>
public static explicit operator HRESULT(Win32Error error)
{
// #define __HRESULT_FROM_WIN32(x)
// ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)))
if (error._value <= 0)
{
return new HRESULT((uint)error._value);
}
return HRESULT.Make(true, Facility.Win32, error._value & 0x0000FFFF);
}
// Method version of the cast operation
/// <summary>Performs HRESULT_FROM_WIN32 conversion.</summary>
/// <param name="error">The Win32 error being converted to an HRESULT.</param>
/// <returns>The equivilent HRESULT value.</returns>
public HRESULT ToHRESULT()
{
return (HRESULT)this;
}
/// <summary>Performs the equivalent of Win32's GetLastError()</summary>
/// <returns>A Win32Error instance with the result of the native GetLastError</returns>
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
public static Win32Error GetLastError()
{
return new Win32Error(Marshal.GetLastWin32Error());
}
public override bool Equals(object obj)
{
try
{
return ((Win32Error)obj)._value == _value;
}
catch (InvalidCastException)
{
return false;
}
}
public override int GetHashCode()
{
return _value.GetHashCode();
}
/// <summary>
/// Compare two Win32 error codes for equality.
/// </summary>
/// <param name="errLeft">The first error code to compare.</param>
/// <param name="errRight">The second error code to compare.</param>
/// <returns>Whether the two error codes are the same.</returns>
public static bool operator ==(Win32Error errLeft, Win32Error errRight)
{
return errLeft._value == errRight._value;
}
/// <summary>
/// Compare two Win32 error codes for inequality.
/// </summary>
/// <param name="errLeft">The first error code to compare.</param>
/// <param name="errRight">The second error code to compare.</param>
/// <returns>Whether the two error codes are not the same.</returns>
public static bool operator !=(Win32Error errLeft, Win32Error errRight)
{
return !(errLeft == errRight);
}
}
internal enum Facility
{
/// <summary>FACILITY_NULL</summary>
Null = 0,
/// <summary>FACILITY_RPC</summary>
Rpc = 1,
/// <summary>FACILITY_DISPATCH</summary>
Dispatch = 2,
/// <summary>FACILITY_STORAGE</summary>
Storage = 3,
/// <summary>FACILITY_ITF</summary>
Itf = 4,
/// <summary>FACILITY_WIN32</summary>
Win32 = 7,
/// <summary>FACILITY_WINDOWS</summary>
Windows = 8,
/// <summary>FACILITY_CONTROL</summary>
Control = 10,
/// <summary>MSDN doced facility code for ESE errors.</summary>
Ese = 0xE5E,
/// <summary>FACILITY_WINCODEC (WIC)</summary>
WinCodec = 0x898,
}
/// <summary>Wrapper for HRESULT status codes.</summary>
[StructLayout(LayoutKind.Explicit)]
internal struct HRESULT
{
[FieldOffset(0)]
private readonly uint _value;
// NOTE: These public static field declarations are automatically
// picked up by ToString through reflection.
/// <summary>S_OK</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT S_OK = new HRESULT(0x00000000);
/// <summary>S_FALSE</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT S_FALSE = new HRESULT(0x00000001);
/// <summary>E_PENDING</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT E_PENDING = new HRESULT(0x8000000A);
/// <summary>E_NOTIMPL</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT E_NOTIMPL = new HRESULT(0x80004001);
/// <summary>E_NOINTERFACE</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT E_NOINTERFACE = new HRESULT(0x80004002);
/// <summary>E_POINTER</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT E_POINTER = new HRESULT(0x80004003);
/// <summary>E_ABORT</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT E_ABORT = new HRESULT(0x80004004);
/// <summary>E_FAIL</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT E_FAIL = new HRESULT(0x80004005);
/// <summary>E_UNEXPECTED</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT E_UNEXPECTED = new HRESULT(0x8000FFFF);
/// <summary>STG_E_INVALIDFUNCTION</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT STG_E_INVALIDFUNCTION = new HRESULT(0x80030001);
/// <summary>REGDB_E_CLASSNOTREG</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT REGDB_E_CLASSNOTREG = new HRESULT(0x80040154);
/// <summary>DESTS_E_NO_MATCHING_ASSOC_HANDLER. Win7 internal error code for Jump Lists.</summary>
/// <remarks>There is no Assoc Handler for the given item registered by the specified application.</remarks>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT DESTS_E_NO_MATCHING_ASSOC_HANDLER = new HRESULT(0x80040F03);
/// <summary>DESTS_E_NORECDOCS. Win7 internal error code for Jump Lists.</summary>
/// <remarks>The given item is excluded from the recent docs folder by the NoRecDocs bit on its registration.</remarks>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT DESTS_E_NORECDOCS = new HRESULT(0x80040F04);
/// <summary>DESTS_E_NOTALLCLEARED. Win7 internal error code for Jump Lists.</summary>
/// <remarks>Not all of the items were successfully cleared</remarks>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT DESTS_E_NOTALLCLEARED = new HRESULT(0x80040F05);
/// <summary>E_ACCESSDENIED</summary>
/// <remarks>Win32Error ERROR_ACCESS_DENIED.</remarks>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT E_ACCESSDENIED = new HRESULT(0x80070005);
/// <summary>E_OUTOFMEMORY</summary>
/// <remarks>Win32Error ERROR_OUTOFMEMORY.</remarks>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT E_OUTOFMEMORY = new HRESULT(0x8007000E);
/// <summary>E_INVALIDARG</summary>
/// <remarks>Win32Error ERROR_INVALID_PARAMETER.</remarks>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT E_INVALIDARG = new HRESULT(0x80070057);
/// <summary>INTSAFE_E_ARITHMETIC_OVERFLOW</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT INTSAFE_E_ARITHMETIC_OVERFLOW = new HRESULT(0x80070216);
/// <summary>COR_E_OBJECTDISPOSED</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT COR_E_OBJECTDISPOSED = new HRESULT(0x80131622);
/// <summary>WC_E_GREATERTHAN</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT WC_E_GREATERTHAN = new HRESULT(0xC00CEE23);
/// <summary>WC_E_SYNTAX</summary>
[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
public static readonly HRESULT WC_E_SYNTAX = new HRESULT(0xC00CEE2D);
/// <summary>
/// Create an HRESULT from an integer value.
/// </summary>
/// <param name="i"></param>
public HRESULT(uint i)
{
_value = i;
}
public static HRESULT Make(bool severe, Facility facility, int code)
{
// #define MAKE_HRESULT(sev,fac,code) \
// ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) )
// Severity has 1 bit reserved.
// bitness is enforced by the boolean parameter.
// Facility has 11 bits reserved (different than SCODES, which have 4 bits reserved)
// MSDN documentation incorrectly uses 12 bits for the ESE facility (e5e), so go ahead and let that one slide.
// And WIC also ignores it the documented size...
Assert.Implies((int)facility != (int)((int)facility & 0x1FF), facility == Facility.Ese || facility == Facility.WinCodec);
// Code has 4 bits reserved.
Assert.AreEqual(code, code & 0xFFFF);
return new HRESULT((uint)((severe ? (1 << 31) : 0) | ((int)facility << 16) | code));
}
/// <summary>
/// retrieve HRESULT_FACILITY
/// </summary>
public Facility Facility
{
get
{
return GetFacility((int)_value);
}
}
public static Facility GetFacility(int errorCode)
{
// #define HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff)
return (Facility)((errorCode >> 16) & 0x1fff);
}
/// <summary>
/// retrieve HRESULT_CODE
/// </summary>
public int Code
{
get
{
return GetCode((int)_value);
}
}
public static int GetCode(int error)
{
// #define HRESULT_CODE(hr) ((hr) & 0xFFFF)
return (int)(error & 0xFFFF);
}
#region Object class override members
/// <summary>
/// Get a string representation of this HRESULT.
/// </summary>
/// <returns></returns>
public override string ToString()
{
// Use reflection to try to name this HRESULT.
// This is expensive, but if someone's ever printing HRESULT strings then
// I think it's a fair guess that they're not in a performance critical area
// (e.g. printing exception strings).
// This is less error prone than trying to keep the list in the function.
// To properly add an HRESULT's name to the ToString table, just add the HRESULT
// like all the others above.
//
// CONSIDER: This data is static. It could be cached
// after first usage for fast lookup since the keys are unique.
//
foreach (FieldInfo publicStaticField in typeof(HRESULT).GetFields(BindingFlags.Static | BindingFlags.Public))
{
if (publicStaticField.FieldType == typeof(HRESULT))
{
var hr = (HRESULT)publicStaticField.GetValue(null);
if (hr == this)
{
return publicStaticField.Name;
}
}
}
// Try Win32 error codes also
if (Facility == Facility.Win32)
{
foreach (FieldInfo publicStaticField in typeof(Win32Error).GetFields(BindingFlags.Static | BindingFlags.Public))
{
if (publicStaticField.FieldType == typeof(Win32Error))
{
var error = (Win32Error)publicStaticField.GetValue(null);
if ((HRESULT)error == this)
{
return "HRESULT_FROM_WIN32(" + publicStaticField.Name + ")";
}
}
}
}
// If there's no good name for this HRESULT,
// return the string as readable hex (0x########) format.
return string.Format(CultureInfo.InvariantCulture, "0x{0:X8}", _value);
}
public override bool Equals(object obj)
{
try
{
return ((HRESULT)obj)._value == _value;
}
catch (InvalidCastException)
{
return false;
}
}
public override int GetHashCode()
{
return _value.GetHashCode();
}
#endregion
public static bool operator ==(HRESULT hrLeft, HRESULT hrRight)
{
return hrLeft._value == hrRight._value;
}
public static bool operator !=(HRESULT hrLeft, HRESULT hrRight)
{
return !(hrLeft == hrRight);
}
public bool Succeeded
{
get { return (int)_value >= 0; }
}
public bool Failed
{
get { return (int)_value < 0; }
}
public void ThrowIfFailed()
{
ThrowIfFailed(null);
}
[
SuppressMessage(
"Microsoft.Usage",
"CA2201:DoNotRaiseReservedExceptionTypes",
Justification="Only recreating Exceptions that were already raised."),
SuppressMessage(
"Microsoft.Security",
"CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")
]
public void ThrowIfFailed(string message)
{
if (Failed)
{
if (string.IsNullOrEmpty(message))
{
message = ToString();
}
#if DEBUG
else
{
message += " (" + ToString() + ")";
}
#endif
// Wow. Reflection in a throw call. Later on this may turn out to have been a bad idea.
// If you're throwing an exception I assume it's OK for me to take some time to give it back.
// I want to convert the HRESULT to a more appropriate exception type than COMException.
// Marshal.ThrowExceptionForHR does this for me, but the general call uses GetErrorInfo
// if it's set, and then ignores the HRESULT that I've provided. This makes it so this
// call works the first time but you get burned on the second. To avoid this, I use
// the overload that explicitly ignores the IErrorInfo.
// In addition, the function doesn't allow me to set the Message unless I go through
// the process of implementing an IErrorInfo and then use that. There's no stock
// implementations of IErrorInfo available and I don't think it's worth the maintenance
// overhead of doing it, nor would it have significant value over this approach.
Exception e = Marshal.GetExceptionForHR((int)_value, new IntPtr(-1));
Assert.IsNotNull(e);
// ArgumentNullException doesn't have the right constructor parameters,
// (nor does Win32Exception...)
// but E_POINTER gets mapped to NullReferenceException,
// so I don't think it will ever matter.
Assert.IsFalse(e is ArgumentNullException);
// If we're not getting anything better than a COMException from Marshal,
// then at least check the facility and attempt to do better ourselves.
if (e.GetType() == typeof(COMException))
{
switch (Facility)
{
case Facility.Win32:
e = new Win32Exception(Code, message);
break;
default:
e = new COMException(message, (int)_value);
break;
}
}
else
{
ConstructorInfo cons = e.GetType().GetConstructor(new[] { typeof(string) });
if (null != cons)
{
e = cons.Invoke(new object[] { message }) as Exception;
Assert.IsNotNull(e);
}
}
throw e;
}
}
/// <summary>
/// Convert the result of Win32 GetLastError() into a raised exception.
/// </summary>
public static void ThrowLastError()
{
((HRESULT)Win32Error.GetLastError()).ThrowIfFailed();
// Only expecting to call this when we're expecting a failed GetLastError()
Assert.Fail();
}
}
}

View File

@@ -0,0 +1,185 @@
/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
/**************************************************************************\
Copyright Microsoft Corporation. All Rights Reserved.
\**************************************************************************/
namespace Standard
{
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Threading;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
internal sealed class MessageWindow : DispatcherObject, IDisposable
{
// Alias this to a static so the wrapper doesn't get GC'd
private static readonly WndProc s_WndProc = new WndProc(_WndProc);
private static readonly Dictionary<IntPtr, MessageWindow> s_windowLookup = new Dictionary<IntPtr, MessageWindow>();
private WndProc _wndProcCallback;
private string _className;
private bool _isDisposed;
public IntPtr Handle { get; private set; }
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
public MessageWindow(CS classStyle, WS style, WS_EX exStyle, Rect location, string name, WndProc callback)
{
// A null callback means just use DefWindowProc.
_wndProcCallback = callback;
_className = "MessageWindowClass+" + Guid.NewGuid().ToString();
var wc = new WNDCLASSEX
{
cbSize = Marshal.SizeOf(typeof(WNDCLASSEX)),
style = classStyle,
lpfnWndProc = s_WndProc,
hInstance = NativeMethods.GetModuleHandle(null),
hbrBackground = NativeMethods.GetStockObject(StockObject.NULL_BRUSH),
lpszMenuName = "",
lpszClassName = _className,
};
NativeMethods.RegisterClassEx(ref wc);
GCHandle gcHandle = default(GCHandle);
try
{
gcHandle = GCHandle.Alloc(this);
IntPtr pinnedThisPtr = (IntPtr)gcHandle;
Handle = NativeMethods.CreateWindowEx(
exStyle,
_className,
name,
style,
(int)location.X,
(int)location.Y,
(int)location.Width,
(int)location.Height,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
pinnedThisPtr);
}
finally
{
gcHandle.Free();
}
}
~MessageWindow()
{
_Dispose(false, false);
}
public void Dispose()
{
_Dispose(true, false);
GC.SuppressFinalize(this);
}
// This isn't right if the Dispatcher has already started shutting down.
// It will wind up leaking the class ATOM...
[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "disposing")]
private void _Dispose(bool disposing, bool isHwndBeingDestroyed)
{
if (_isDisposed)
{
// Block against reentrancy.
return;
}
_isDisposed = true;
IntPtr hwnd = Handle;
string className = _className;
if (isHwndBeingDestroyed)
{
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (DispatcherOperationCallback)(arg => _DestroyWindow(IntPtr.Zero, className)));
}
else if (Handle != IntPtr.Zero)
{
if (CheckAccess())
{
_DestroyWindow(hwnd, className);
}
else
{
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (DispatcherOperationCallback)(arg => _DestroyWindow(hwnd, className)));
}
}
s_windowLookup.Remove(hwnd);
_className = null;
Handle = IntPtr.Zero;
}
[SuppressMessage("Microsoft.Usage", "CA1816:CallGCSuppressFinalizeCorrectly")]
private static IntPtr _WndProc(IntPtr hwnd, WM msg, IntPtr wParam, IntPtr lParam)
{
IntPtr ret = IntPtr.Zero;
MessageWindow hwndWrapper = null;
if (msg == WM.CREATE)
{
var createStruct = (CREATESTRUCT)Marshal.PtrToStructure(lParam, typeof(CREATESTRUCT));
GCHandle gcHandle = GCHandle.FromIntPtr(createStruct.lpCreateParams);
hwndWrapper = (MessageWindow)gcHandle.Target;
s_windowLookup.Add(hwnd, hwndWrapper);
}
else
{
if (!s_windowLookup.TryGetValue(hwnd, out hwndWrapper))
{
return NativeMethods.DefWindowProc(hwnd, msg, wParam, lParam);
}
}
Assert.IsNotNull(hwndWrapper);
WndProc callback = hwndWrapper._wndProcCallback;
if (callback != null)
{
ret = callback(hwnd, msg, wParam, lParam);
}
else
{
ret = NativeMethods.DefWindowProc(hwnd, msg, wParam, lParam);
}
if (msg == WM.NCDESTROY)
{
hwndWrapper._Dispose(true, true);
GC.SuppressFinalize(hwndWrapper);
}
return ret;
}
private static object _DestroyWindow(IntPtr hwnd, string className)
{
Utility.SafeDestroyWindow(ref hwnd);
NativeMethods.UnregisterClass(className, NativeMethods.GetModuleHandle(null));
return null;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,983 @@
/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
/**************************************************************************\
Copyright Microsoft Corporation. All Rights Reserved.
\**************************************************************************/
namespace Standard
{
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
#region Enums and Static Property Classes
/// <summary>ShellItem attribute flags. SIATTRIBFLAGS_*</summary>
internal enum SIATTRIBFLAGS
{
AND = 0x00000001,
OR = 0x00000002,
APPCOMPAT = 0x00000003,
}
internal enum APPDOCLISTTYPE
{
ADLT_RECENT = 0, // The recently used documents list
ADLT_FREQUENT, // The frequently used documents list
}
/// <summary>
/// Flags for SetTabProperties. STPF_*
/// </summary>
/// <remarks>The native enum was called STPFLAG.</remarks>
[Flags]
internal enum STPF
{
NONE = 0x00000000,
USEAPPTHUMBNAILALWAYS = 0x00000001,
USEAPPTHUMBNAILWHENACTIVE = 0x00000002,
USEAPPPEEKALWAYS = 0x00000004,
USEAPPPEEKWHENACTIVE = 0x00000008,
}
/// <summary>
/// Flags for Setting Taskbar Progress state. TBPF_*
/// </summary>
/// <remarks>
/// The native enum was called TBPFLAG.
/// </remarks>
internal enum TBPF
{
NOPROGRESS = 0x00000000,
INDETERMINATE = 0x00000001,
NORMAL = 0x00000002,
ERROR = 0x00000004,
PAUSED = 0x00000008,
}
/// <summary>
/// THUMBBUTTON mask. THB_*
/// </summary>
[Flags]
internal enum THB : uint
{
BITMAP = 0x0001,
ICON = 0x0002,
TOOLTIP = 0x0004,
FLAGS = 0x0008,
}
/// <summary>
/// THUMBBUTTON flags. THBF_*
/// </summary>
[Flags]
internal enum THBF : uint
{
ENABLED = 0x0000,
DISABLED = 0x0001,
DISMISSONCLICK = 0x0002,
NOBACKGROUND = 0x0004,
HIDDEN = 0x0008,
// Added post-beta
NONINTERACTIVE = 0x0010,
}
/// <summary>
/// GetPropertyStoreFlags. GPS_*.
/// </summary>
/// <remarks>
/// These are new for Vista, but are used in downlevel components
/// </remarks>
internal enum GPS
{
// If no flags are specified (GPS_DEFAULT), a read-only property store is returned that includes properties for the file or item.
// In the case that the shell item is a file, the property store contains:
// 1. properties about the file from the file system
// 2. properties from the file itself provided by the file's property handler, unless that file is offline,
// see GPS_OPENSLOWITEM
// 3. if requested by the file's property handler and supported by the file system, properties stored in the
// alternate property store.
//
// Non-file shell items should return a similar read-only store
//
// Specifying other GPS_ flags modifies the store that is returned
DEFAULT = 0x00000000,
HANDLERPROPERTIESONLY = 0x00000001, // only include properties directly from the file's property handler
READWRITE = 0x00000002, // Writable stores will only include handler properties
TEMPORARY = 0x00000004, // A read/write store that only holds properties for the lifetime of the IShellItem object
FASTPROPERTIESONLY = 0x00000008, // do not include any properties from the file's property handler (because the file's property handler will hit the disk)
OPENSLOWITEM = 0x00000010, // include properties from a file's property handler, even if it means retrieving the file from offline storage.
DELAYCREATION = 0x00000020, // delay the creation of the file's property handler until those properties are read, written, or enumerated
BESTEFFORT = 0x00000040, // For readonly stores, succeed and return all available properties, even if one or more sources of properties fails. Not valid with GPS_READWRITE.
NO_OPLOCK = 0x00000080, // some data sources protect the read property store with an oplock, this disables that
MASK_VALID = 0x000000FF,
}
/// <summary>
/// KNOWNDESTCATEGORY. KDC_*
/// </summary>
internal enum KDC
{
FREQUENT = 1,
RECENT,
}
// IShellFolder::GetAttributesOf flags
[Flags]
internal enum SFGAO : uint
{
/// <summary>Objects can be copied</summary>
/// <remarks>DROPEFFECT_COPY</remarks>
CANCOPY = 0x1,
/// <summary>Objects can be moved</summary>
/// <remarks>DROPEFFECT_MOVE</remarks>
CANMOVE = 0x2,
/// <summary>Objects can be linked</summary>
/// <remarks>
/// DROPEFFECT_LINK.
///
/// If this bit is set on an item in the shell folder, a
/// 'Create Shortcut' menu item will be added to the File
/// menu and context menus for the item. If the user selects
/// that command, your IContextMenu::InvokeCommand() will be called
/// with 'link'.
/// That flag will also be used to determine if 'Create Shortcut'
/// should be added when the item in your folder is dragged to another
/// folder.
/// </remarks>
CANLINK = 0x4,
/// <summary>supports BindToObject(IID_IStorage)</summary>
STORAGE = 0x00000008,
/// <summary>Objects can be renamed</summary>
CANRENAME = 0x00000010,
/// <summary>Objects can be deleted</summary>
CANDELETE = 0x00000020,
/// <summary>Objects have property sheets</summary>
HASPROPSHEET = 0x00000040,
// unused = 0x00000080,
/// <summary>Objects are drop target</summary>
DROPTARGET = 0x00000100,
CAPABILITYMASK = 0x00000177,
// unused = 0x00000200,
// unused = 0x00000400,
// unused = 0x00000800,
// unused = 0x00001000,
/// <summary>Object is encrypted (use alt color)</summary>
ENCRYPTED = 0x00002000,
/// <summary>'Slow' object</summary>
ISSLOW = 0x00004000,
/// <summary>Ghosted icon</summary>
GHOSTED = 0x00008000,
/// <summary>Shortcut (link)</summary>
LINK = 0x00010000,
/// <summary>Shared</summary>
SHARE = 0x00020000,
/// <summary>Read-only</summary>
READONLY = 0x00040000,
/// <summary> Hidden object</summary>
HIDDEN = 0x00080000,
DISPLAYATTRMASK = 0x000FC000,
/// <summary> May contain children with SFGAO_FILESYSTEM</summary>
FILESYSANCESTOR = 0x10000000,
/// <summary>Support BindToObject(IID_IShellFolder)</summary>
FOLDER = 0x20000000,
/// <summary>Is a win32 file system object (file/folder/root)</summary>
FILESYSTEM = 0x40000000,
/// <summary>May contain children with SFGAO_FOLDER (may be slow)</summary>
HASSUBFOLDER = 0x80000000,
CONTENTSMASK = 0x80000000,
/// <summary>Invalidate cached information (may be slow)</summary>
VALIDATE = 0x01000000,
/// <summary>Is this removeable media?</summary>
REMOVABLE = 0x02000000,
/// <summary> Object is compressed (use alt color)</summary>
COMPRESSED = 0x04000000,
/// <summary>Supports IShellFolder, but only implements CreateViewObject() (non-folder view)</summary>
BROWSABLE = 0x08000000,
/// <summary>Is a non-enumerated object (should be hidden)</summary>
NONENUMERATED = 0x00100000,
/// <summary>Should show bold in explorer tree</summary>
NEWCONTENT = 0x00200000,
/// <summary>Obsolete</summary>
CANMONIKER = 0x00400000,
/// <summary>Obsolete</summary>
HASSTORAGE = 0x00400000,
/// <summary>Supports BindToObject(IID_IStream)</summary>
STREAM = 0x00400000,
/// <summary>May contain children with SFGAO_STORAGE or SFGAO_STREAM</summary>
STORAGEANCESTOR = 0x00800000,
/// <summary>For determining storage capabilities, ie for open/save semantics</summary>
STORAGECAPMASK = 0x70C50008,
/// <summary>
/// Attributes that are masked out for PKEY_SFGAOFlags because they are considered
/// to cause slow calculations or lack context
/// (SFGAO_VALIDATE | SFGAO_ISSLOW | SFGAO_HASSUBFOLDER and others)
/// </summary>
PKEYSFGAOMASK = 0x81044000,
}
/// <summary>
/// IShellFolder::EnumObjects grfFlags bits. Also called SHCONT
/// </summary>
internal enum SHCONTF
{
CHECKING_FOR_CHILDREN = 0x0010, // hint that client is checking if (what) child items the folder contains - not all details (e.g. short file name) are needed
FOLDERS = 0x0020, // only want folders enumerated (SFGAO_FOLDER)
NONFOLDERS = 0x0040, // include non folders (items without SFGAO_FOLDER)
INCLUDEHIDDEN = 0x0080, // show items normally hidden (items with SFGAO_HIDDEN)
INIT_ON_FIRST_NEXT = 0x0100, // DEFUNCT - this is always assumed
NETPRINTERSRCH = 0x0200, // hint that client is looking for printers
SHAREABLE = 0x0400, // hint that client is looking sharable resources (local drives or hidden root shares)
STORAGE = 0x0800, // include all items with accessible storage and their ancestors
NAVIGATION_ENUM = 0x1000, // mark child folders to indicate that they should provide a "navigation" enumeration by default
FASTITEMS = 0x2000, // hint that client is only interested in items that can be enumerated quickly
FLATLIST = 0x4000, // enumerate items as flat list even if folder is stacked
ENABLE_ASYNC = 0x8000, // inform enumerator that client is listening for change notifications so enumerator does not need to be complete, items can be reported via change notifications
}
/// <summary>
/// IShellFolder::GetDisplayNameOf/SetNameOf uFlags. Also called SHGDNF.
/// </summary>
/// <remarks>
/// For compatibility with SIGDN, these bits must all sit in the LOW word.
/// </remarks>
[Flags]
internal enum SHGDN
{
SHGDN_NORMAL = 0x0000, // default (display purpose)
SHGDN_INFOLDER = 0x0001, // displayed under a folder (relative)
SHGDN_FOREDITING = 0x1000, // for in-place editing
SHGDN_FORADDRESSBAR = 0x4000, // UI friendly parsing name (remove ugly stuff)
SHGDN_FORPARSING = 0x8000, // parsing name for ParseDisplayName()
}
/// <summary>
/// SHELLITEMCOMPAREHINTF. SICHINT_*.
/// </summary>
internal enum SICHINT : uint
{
/// <summary>iOrder based on display in a folder view</summary>
DISPLAY = 0x00000000,
/// <summary>exact instance compare</summary>
ALLFIELDS = 0x80000000,
/// <summary>iOrder based on canonical name (better performance)</summary>
CANONICAL = 0x10000000,
TEST_FILESYSPATH_IF_NOT_EQUAL = 0x20000000,
};
/// <summary>
/// ShellItem enum. SIGDN_*.
/// </summary>
internal enum SIGDN : uint
{ // lower word (& with 0xFFFF)
NORMALDISPLAY = 0x00000000, // SHGDN_NORMAL
PARENTRELATIVEPARSING = 0x80018001, // SHGDN_INFOLDER | SHGDN_FORPARSING
DESKTOPABSOLUTEPARSING = 0x80028000, // SHGDN_FORPARSING
PARENTRELATIVEEDITING = 0x80031001, // SHGDN_INFOLDER | SHGDN_FOREDITING
DESKTOPABSOLUTEEDITING = 0x8004c000, // SHGDN_FORPARSING | SHGDN_FORADDRESSBAR
FILESYSPATH = 0x80058000, // SHGDN_FORPARSING
URL = 0x80068000, // SHGDN_FORPARSING
PARENTRELATIVEFORADDRESSBAR = 0x8007c001, // SHGDN_INFOLDER | SHGDN_FORPARSING | SHGDN_FORADDRESSBAR
PARENTRELATIVE = 0x80080001, // SHGDN_INFOLDER
}
/// <summary>
/// STR_GPS_*
/// </summary>
/// <remarks>
/// When requesting a property store through IShellFolder, you can specify the equivalent of
/// GPS_DEFAULT by passing in a null IBindCtx parameter.
///
/// You can specify the equivalent of GPS_READWRITE by passing a mode of STGM_READWRITE | STGM_EXCLUSIVE
/// in the bind context
///
/// Here are the string versions of GPS_ flags, passed to IShellFolder::BindToObject() via IBindCtx::RegisterObjectParam()
/// These flags are valid when requesting an IPropertySetStorage or IPropertyStore handler
///
/// The meaning of these flags are described above.
///
/// There is no STR_ equivalent for GPS_TEMPORARY because temporary property stores
/// are provided by IShellItem2 only -- not by the underlying IShellFolder.
/// </remarks>
internal static class STR_GPS
{
public const string HANDLERPROPERTIESONLY = "GPS_HANDLERPROPERTIESONLY";
public const string FASTPROPERTIESONLY = "GPS_FASTPROPERTIESONLY";
public const string OPENSLOWITEM = "GPS_OPENSLOWITEM";
public const string DELAYCREATION = "GPS_DELAYCREATION";
public const string BESTEFFORT = "GPS_BESTEFFORT";
public const string NO_OPLOCK = "GPS_NO_OPLOCK";
}
#endregion
#region Structs
[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Unicode)]
internal struct THUMBBUTTON
{
/// <summary>
/// WPARAM value for a THUMBBUTTON being clicked.
/// </summary>
public const int THBN_CLICKED = 0x1800;
public THB dwMask;
public uint iId;
public uint iBitmap;
public IntPtr hIcon;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szTip;
public THBF dwFlags;
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
internal struct PKEY
{
/// <summary>fmtid</summary>
private readonly Guid _fmtid;
/// <summary>pid</summary>
private readonly uint _pid;
public PKEY(Guid fmtid, uint pid)
{
_fmtid = fmtid;
_pid = pid;
}
/// <summary>PKEY_Title</summary>
public static readonly PKEY Title = new PKEY(new Guid("F29F85E0-4FF9-1068-AB91-08002B27B3D9"), 2);
/// <summary>PKEY_AppUserModel_ID</summary>
public static readonly PKEY AppUserModel_ID = new PKEY(new Guid("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3"), 5);
/// <summary>PKEY_AppUserModel_IsDestListSeparator</summary>
public static readonly PKEY AppUserModel_IsDestListSeparator = new PKEY(new Guid("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3"), 6);
/// <summary>PKEY_AppUserModel_RelaunchCommand</summary>
public static readonly PKEY AppUserModel_RelaunchCommand = new PKEY(new Guid("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3"), 2);
/// <summary>PKEY_AppUserModel_RelaunchDisplayNameResource</summary>
public static readonly PKEY AppUserModel_RelaunchDisplayNameResource = new PKEY(new Guid("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3"), 4);
/// <summary>PKEY_AppUserModel_RelaunchIconResource</summary>
public static readonly PKEY AppUserModel_RelaunchIconResource = new PKEY(new Guid("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3"), 3);
}
#endregion
#region Interfaces
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.EnumIdList),
]
internal interface IEnumIDList
{
[PreserveSig()]
HRESULT Next(uint celt, out IntPtr rgelt, out int pceltFetched);
[PreserveSig()]
HRESULT Skip(uint celt);
void Reset();
void Clone([Out, MarshalAs(UnmanagedType.Interface)] out IEnumIDList ppenum);
}
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.EnumObjects),
]
internal interface IEnumObjects
{
//[local]
// This signature might not work... Hopefully don't need this interface though.
void Next(uint celt, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.IUnknown, IidParameterIndex = 1, SizeParamIndex = 0)] object[] rgelt, [Out] out uint pceltFetched);
/*
[call_as(Next)] HRESULT RemoteNext(
[in] ULONG celt,
[in] REFIID riid,
[out, size_is(celt), length_is(*pceltFetched), iid_is(riid)] void **rgelt,
[out] ULONG *pceltFetched);
*/
void Skip(uint celt);
void Reset();
IEnumObjects Clone();
}
/// <summary>Unknown Object Array</summary>
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.ObjectArray),
]
internal interface IObjectArray
{
uint GetCount();
[return: MarshalAs(UnmanagedType.IUnknown)]
object GetAt([In] uint uiIndex, [In] ref Guid riid);
}
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.ObjectArray),
]
interface IObjectCollection : IObjectArray
{
#region IObjectArray redeclarations
new uint GetCount();
[return: MarshalAs(UnmanagedType.IUnknown)]
new object GetAt([In] uint uiIndex, [In] ref Guid riid);
#endregion
void AddObject([MarshalAs(UnmanagedType.IUnknown)] object punk);
void AddFromArray(IObjectArray poaSource);
void RemoveObjectAt(uint uiIndex);
void Clear();
}
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.PropertyStore)
]
internal interface IPropertyStore
{
uint GetCount();
PKEY GetAt(uint iProp);
void GetValue([In] ref PKEY pkey, [In, Out] PROPVARIANT pv);
void SetValue([In] ref PKEY pkey, PROPVARIANT pv);
void Commit();
}
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.ShellFolder),
]
internal interface IShellFolder
{
void ParseDisplayName(
[In] IntPtr hwnd,
[In] IBindCtx pbc,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszDisplayName,
[In, Out] ref int pchEaten,
[Out] out IntPtr ppidl,
[In, Out] ref uint pdwAttributes);
IEnumIDList EnumObjects(
[In] IntPtr hwnd,
[In] SHCONTF grfFlags);
// returns an instance of a sub-folder which is specified by the IDList (pidl).
// IShellFolder or derived interfaces
[return: MarshalAs(UnmanagedType.Interface)]
object BindToObject(
[In] IntPtr pidl,
[In] IBindCtx pbc,
[In] ref Guid riid);
// produces the same result as BindToObject()
[return: MarshalAs(UnmanagedType.Interface)]
object BindToStorage([In] IntPtr pidl, [In] IBindCtx pbc, [In] ref Guid riid);
// compares two IDLists and returns the result. The shell
// explorer always passes 0 as lParam, which indicates 'sort by name'.
// It should return 0 (as CODE of the scode), if two id indicates the
// same object; negative value if pidl1 should be placed before pidl2;
// positive value if pidl2 should be placed before pidl1.
// use the macro ResultFromShort() to extract the result comparison
// it deals with the casting and type conversion issues for you
[PreserveSig]
HRESULT CompareIDs([In] IntPtr lParam, [In] IntPtr pidl1, [In] IntPtr pidl2);
// creates a view object of the folder itself. The view
// object is a difference instance from the shell folder object.
// 'hwndOwner' can be used as the owner window of its dialog box or
// menu during the lifetime of the view object.
// This member function should always create a new
// instance which has only one reference count. The explorer may create
// more than one instances of view object from one shell folder object
// and treat them as separate instances.
// returns IShellView derived interface
[return: MarshalAs(UnmanagedType.Interface)]
object CreateViewObject([In] IntPtr hwndOwner, [In] ref Guid riid);
// returns the attributes of specified objects in that
// folder. 'cidl' and 'apidl' specifies objects. 'apidl' contains only
// simple IDLists. The explorer initializes *prgfInOut with a set of
// flags to be evaluated. The shell folder may optimize the operation
// by not returning unspecified flags.
void GetAttributesOf(
[In] uint cidl,
[In] IntPtr apidl,
[In, Out] ref SFGAO rgfInOut);
// creates a UI object to be used for specified objects.
// The shell explorer passes either IID_IDataObject (for transfer operation)
// or IID_IContextMenu (for context menu operation) as riid
// and many other interfaces
[return: MarshalAs(UnmanagedType.Interface)]
object GetUIObjectOf(
[In] IntPtr hwndOwner,
[In] uint cidl,
[In, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.SysInt, SizeParamIndex = 2)] IntPtr apidl,
[In] ref Guid riid,
[In, Out] ref uint rgfReserved);
// returns the display name of the specified object.
// If the ID contains the display name (in the locale character set),
// it returns the offset to the name. Otherwise, it returns a pointer
// to the display name string (UNICODE), which is allocated by the
// task allocator, or fills in a buffer.
// use the helper APIS StrRetToStr() or StrRetToBuf() to deal with the different
// forms of the STRRET structure
void GetDisplayNameOf([In] IntPtr pidl, [In] SHGDN uFlags, [Out] out IntPtr pName);
// sets the display name of the specified object.
// If it changes the ID as well, it returns the new ID which is
// alocated by the task allocator.
void SetNameOf([In] IntPtr hwnd,
[In] IntPtr pidl,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszName,
[In] SHGDN uFlags,
[Out] out IntPtr ppidlOut);
}
/// <summary>
/// Shell Namespace helper
/// </summary>
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.ShellItem),
]
internal interface IShellItem
{
[return: MarshalAs(UnmanagedType.Interface)]
object BindToHandler(IBindCtx pbc, [In] ref Guid bhid, [In] ref Guid riid);
IShellItem GetParent();
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetDisplayName(SIGDN sigdnName);
SFGAO GetAttributes(SFGAO sfgaoMask);
int Compare(IShellItem psi, SICHINT hint);
}
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.ShellItemArray),
]
internal interface IShellItemArray
{
[return: MarshalAs(UnmanagedType.Interface)]
object BindToHandler(IBindCtx pbc, [In] ref Guid rbhid, [In] ref Guid riid);
[return: MarshalAs(UnmanagedType.Interface)]
object GetPropertyStore(int flags, [In] ref Guid riid);
[return: MarshalAs(UnmanagedType.Interface)]
object GetPropertyDescriptionList([In] ref PKEY keyType, [In] ref Guid riid);
uint GetAttributes(SIATTRIBFLAGS dwAttribFlags, uint sfgaoMask);
uint GetCount();
IShellItem GetItemAt(uint dwIndex);
[return: MarshalAs(UnmanagedType.Interface)]
object EnumItems();
}
/// <summary>
/// Shell Namespace helper 2
/// </summary>
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.ShellItem2),
]
interface IShellItem2 : IShellItem
{
#region IShellItem redeclarations
[return: MarshalAs(UnmanagedType.Interface)]
new object BindToHandler([In] IBindCtx pbc, [In] ref Guid bhid, [In] ref Guid riid);
new IShellItem GetParent();
[return: MarshalAs(UnmanagedType.LPWStr)]
new string GetDisplayName(SIGDN sigdnName);
new SFGAO GetAttributes(SFGAO sfgaoMask);
new int Compare(IShellItem psi, SICHINT hint);
#endregion
[return: MarshalAs(UnmanagedType.Interface)]
object GetPropertyStore(
GPS flags,
[In] ref Guid riid);
[return: MarshalAs(UnmanagedType.Interface)]
object GetPropertyStoreWithCreateObject(
GPS flags,
[MarshalAs(UnmanagedType.IUnknown)] object punkCreateObject, // factory for low-rights creation of type ICreateObject
[In] ref Guid riid);
[return: MarshalAs(UnmanagedType.Interface)]
object GetPropertyStoreForKeys(
IntPtr rgKeys,
uint cKeys,
GPS flags,
[In] ref Guid riid);
[return: MarshalAs(UnmanagedType.Interface)]
object GetPropertyDescriptionList(
IntPtr keyType,
[In] ref Guid riid);
// Ensures any cached information in this item is up to date, or returns __HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) if the item does not exist.
void Update(IBindCtx pbc);
PROPVARIANT GetProperty(IntPtr key);
Guid GetCLSID(IntPtr key);
FILETIME GetFileTime(IntPtr key);
int GetInt32(IntPtr key);
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetString(IntPtr key);
uint GetUInt32(IntPtr key);
ulong GetUInt64(IntPtr key);
[return: MarshalAs(UnmanagedType.Bool)]
void GetBool(IntPtr key);
}
[
ComImport,
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.ShellLink),
]
internal interface IShellLinkW
{
void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, [In, Out] WIN32_FIND_DATAW pfd, SLGP fFlags);
void GetIDList(out IntPtr ppidl);
void SetIDList(IntPtr pidl);
void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxName);
void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
short GetHotKey();
void SetHotKey(short wHotKey);
uint GetShowCmd();
void SetShowCmd(uint iShowCmd);
void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon);
void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, uint dwReserved);
void Resolve(IntPtr hwnd, uint fFlags);
void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
}
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.TaskbarList),
]
internal interface ITaskbarList
{
/// <summary>
/// This function must be called first to validate use of other members.
/// </summary>
void HrInit();
/// <summary>
/// This function adds a tab for hwnd to the taskbar.
/// </summary>
/// <param name="hwnd">The HWND for which to add the tab.</param>
void AddTab(IntPtr hwnd);
/// <summary>
/// This function deletes a tab for hwnd from the taskbar.
/// </summary>
/// <param name="hwnd">The HWND for which the tab is to be deleted.</param>
void DeleteTab(IntPtr hwnd);
/// <summary>
/// This function activates the tab associated with hwnd on the taskbar.
/// </summary>
/// <param name="hwnd">The HWND for which the tab is to be actuvated.</param>
void ActivateTab(IntPtr hwnd);
/// <summary>
/// This function marks hwnd in the taskbar as the active tab.
/// </summary>
/// <param name="hwnd">The HWND to activate.</param>
void SetActiveAlt(IntPtr hwnd);
}
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.TaskbarList2),
]
internal interface ITaskbarList2 : ITaskbarList
{
#region ITaskbarList redeclaration
new void HrInit();
new void AddTab(IntPtr hwnd);
new void DeleteTab(IntPtr hwnd);
new void ActivateTab(IntPtr hwnd);
new void SetActiveAlt(IntPtr hwnd);
#endregion
/// <summary>
/// Marks a window as full-screen.
/// </summary>
/// <param name="hwnd">The handle of the window to be marked.</param>
/// <param name="fFullscreen">A Boolean value marking the desired full-screen status of the window.</param>
/// <remarks>
/// Setting the value of fFullscreen to true, the Shell treats this window as a full-screen window, and the taskbar
/// is moved to the bottom of the z-order when this window is active. Setting the value of fFullscreen to false
/// removes the full-screen marking, but <i>does not</i> cause the Shell to treat the window as though it were
/// definitely not full-screen. With a false fFullscreen value, the Shell depends on its automatic detection facility
/// to specify how the window should be treated, possibly still flagging the window as full-screen.
/// </remarks>
void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen);
}
// Used to remove items from the automatic destination lists created when apps or the system call SHAddToRecentDocs to report usage of a document.
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.ApplicationDestinations)
]
internal interface IApplicationDestinations
{
// Set the App User Model ID for the application removing destinations from its list. If an AppID is not provided
// via this method, the system will use a heuristically determined ID. This method must be called before
// RemoveDestination or RemoveAllDestinations.
void SetAppID([In, MarshalAs(UnmanagedType.LPWStr)] string pszAppID);
// Remove an IShellItem or an IShellLink from the automatic destination list
void RemoveDestination([MarshalAs(UnmanagedType.IUnknown)] object punk);
// Clear the frequent and recent destination lists for this application.
void RemoveAllDestinations();
}
/// <summary>
/// Allows an application to retrieve the most recent and frequent documents opened in that app, as reported via SHAddToRecentDocs
/// </summary>
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.ApplicationDocumentLists)
]
internal interface IApplicationDocumentLists
{
/// <summary>
/// Set the App User Model ID for the application retrieving this list. If an AppID is not provided via this method,
/// the system will use a heuristically determined ID. This method must be called before GetList.
/// </summary>
/// <param name="pszAppID">App Id.</param>
void SetAppID([MarshalAs(UnmanagedType.LPWStr)] string pszAppID);
/// <summary>
/// Retrieve an IEnumObjects or IObjectArray for IShellItems and/or IShellLinks.
/// Items may appear in both the frequent and recent lists.
/// </summary>
/// <param name="?"></param>
/// <returns></returns>
[return: MarshalAs(UnmanagedType.IUnknown)]
object GetList([In] APPDOCLISTTYPE listtype, [In] uint cItemsDesired, [In] ref Guid riid);
}
// Custom Destination List
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.CustomDestinationList)
]
internal interface ICustomDestinationList
{
void SetAppID([In, MarshalAs(UnmanagedType.LPWStr)] string pszAppID);
// Retrieve IObjectArray of IShellItems or IShellLinks that represent removed destinations
[return: MarshalAs(UnmanagedType.Interface)]
object BeginList(out uint pcMaxSlots, [In] ref Guid riid);
// PreserveSig because this will return custom errors when attempting to add unregistered ShellItems.
// Can't readily detect that case without just trying to append it.
[PreserveSig]
HRESULT AppendCategory([MarshalAs(UnmanagedType.LPWStr)] string pszCategory, IObjectArray poa);
void AppendKnownCategory(KDC category);
[PreserveSig]
HRESULT AddUserTasks(IObjectArray poa);
void CommitList();
// Retrieve IObjectCollection of IShellItems
[return: MarshalAs(UnmanagedType.Interface)]
object GetRemovedDestinations([In] ref Guid riid);
void DeleteList([MarshalAs(UnmanagedType.LPWStr)] string pszAppID);
void AbortList();
}
/// <summary>
/// Provides access to the App User Model ID on objects supporting this value.
/// </summary>
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.ObjectWithAppUserModelId)
]
internal interface IObjectWithAppUserModelId
{
void SetAppID([MarshalAs(UnmanagedType.LPWStr)] string pszAppID);
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetAppID();
};
/// <summary>
/// Provides access to the ProgID associated with an object
/// </summary>
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.ObjectWithProgId)
]
internal interface IObjectWithProgId
{
void SetProgID([MarshalAs(UnmanagedType.LPWStr)] string pszProgID);
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetProgID();
};
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.TaskbarList3),
]
internal interface ITaskbarList3 : ITaskbarList2
{
#region ITaskbarList2 redeclaration
#region ITaskbarList redeclaration
new void HrInit();
new void AddTab(IntPtr hwnd);
new void DeleteTab(IntPtr hwnd);
new void ActivateTab(IntPtr hwnd);
new void SetActiveAlt(IntPtr hwnd);
#endregion
new void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen);
#endregion
[PreserveSig]
HRESULT SetProgressValue(IntPtr hwnd, ulong ullCompleted, ulong ullTotal);
[PreserveSig]
HRESULT SetProgressState(IntPtr hwnd, TBPF tbpFlags);
[PreserveSig]
HRESULT RegisterTab(IntPtr hwndTab, IntPtr hwndMDI);
[PreserveSig]
HRESULT UnregisterTab(IntPtr hwndTab);
[PreserveSig]
HRESULT SetTabOrder(IntPtr hwndTab, IntPtr hwndInsertBefore);
[PreserveSig]
HRESULT SetTabActive(IntPtr hwndTab, IntPtr hwndMDI, uint dwReserved);
[PreserveSig]
HRESULT ThumbBarAddButtons(IntPtr hwnd, uint cButtons, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] THUMBBUTTON[] pButtons);
[PreserveSig]
HRESULT ThumbBarUpdateButtons(IntPtr hwnd, uint cButtons, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] THUMBBUTTON[] pButtons);
[PreserveSig]
HRESULT ThumbBarSetImageList(IntPtr hwnd, [MarshalAs(UnmanagedType.IUnknown)] object himl);
[PreserveSig]
HRESULT SetOverlayIcon(IntPtr hwnd, IntPtr hIcon, [MarshalAs(UnmanagedType.LPWStr)] string pszDescription);
[PreserveSig]
HRESULT SetThumbnailTooltip(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)] string pszTip);
// Using RefRECT to making passing NULL possible. Removes clipping from the HWND.
[PreserveSig]
HRESULT SetThumbnailClip(IntPtr hwnd, RefRECT prcClip);
}
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(IID.TaskbarList3),
]
internal interface ITaskbarList4 : ITaskbarList3
{
#region ITaskbarList3 redeclaration
#region ITaskbarList2 redeclaration
#region ITaskbarList redeclaration
new void HrInit();
new void AddTab(IntPtr hwnd);
new void DeleteTab(IntPtr hwnd);
new void ActivateTab(IntPtr hwnd);
new void SetActiveAlt(IntPtr hwnd);
#endregion
new void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen);
#endregion
[PreserveSig] new HRESULT SetProgressValue(IntPtr hwnd, ulong ullCompleted, ulong ullTotal);
[PreserveSig] new HRESULT SetProgressState(IntPtr hwnd, TBPF tbpFlags);
[PreserveSig] new HRESULT RegisterTab(IntPtr hwndTab, IntPtr hwndMDI);
[PreserveSig] new HRESULT UnregisterTab(IntPtr hwndTab);
[PreserveSig] new HRESULT SetTabOrder(IntPtr hwndTab, IntPtr hwndInsertBefore);
[PreserveSig] new HRESULT SetTabActive(IntPtr hwndTab, IntPtr hwndMDI, uint dwReserved);
[PreserveSig] new HRESULT ThumbBarAddButtons(IntPtr hwnd, uint cButtons, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] THUMBBUTTON[] pButtons);
[PreserveSig] new HRESULT ThumbBarUpdateButtons(IntPtr hwnd, uint cButtons, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] THUMBBUTTON[] pButtons);
[PreserveSig] new HRESULT ThumbBarSetImageList(IntPtr hwnd, [MarshalAs(UnmanagedType.IUnknown)] object himl);
[PreserveSig] new HRESULT SetOverlayIcon(IntPtr hwnd, IntPtr hIcon, [MarshalAs(UnmanagedType.LPWStr)] string pszDescription);
[PreserveSig] new HRESULT SetThumbnailTooltip(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)] string pszTip);
// Using RefRECT to making passing NULL possible. Removes clipping from the HWND.
[PreserveSig] new HRESULT SetThumbnailClip(IntPtr hwnd, RefRECT prcClip);
#endregion
void SetTabProperties(IntPtr hwndTab, STPF stpFlags);
}
#endregion
}

View File

@@ -0,0 +1,357 @@
/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
/**************************************************************************\
Copyright Microsoft Corporation. All Rights Reserved.
\**************************************************************************/
namespace Standard
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
// disambiguate with System.Runtime.InteropServices.STATSTG
using STATSTG = System.Runtime.InteropServices.ComTypes.STATSTG;
// All these methods return void. Does the standard marshaller convert them to HRESULTs?
/// <summary>
/// Wraps a managed stream instance into an interface pointer consumable by COM.
/// </summary>
internal sealed class ManagedIStream : IStream, IDisposable
{
private const int STGTY_STREAM = 2;
private const int STGM_READWRITE = 2;
private const int LOCK_EXCLUSIVE = 2;
private Stream _source;
/// <summary>
/// Initializes a new instance of the ManagedIStream class with the specified managed Stream object.
/// </summary>
/// <param name="source">
/// The stream that this IStream reference is wrapping.
/// </param>
public ManagedIStream(Stream source)
{
Verify.IsNotNull(source, "source");
_source = source;
}
private void _Validate()
{
if (null == _source)
{
throw new ObjectDisposedException("this");
}
}
// Comments are taken from MSDN IStream documentation.
#region IStream Members
/// <summary>
/// Creates a new stream object with its own seek pointer that
/// references the same bytes as the original stream.
/// </summary>
/// <param name="ppstm">
/// When this method returns, contains the new stream object. This parameter is passed uninitialized.
/// </param>
/// <remarks>
/// For more information, see the existing documentation for IStream::Clone in the MSDN library.
/// This class doesn't implement Clone. A COMException is thrown if it is used.
/// </remarks>
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Standard.HRESULT.ThrowIfFailed(System.String)")]
[Obsolete("The method is not implemented", true)]
public void Clone(out IStream ppstm)
{
ppstm = null;
HRESULT.STG_E_INVALIDFUNCTION.ThrowIfFailed("The method is not implemented.");
}
/// <summary>
/// Ensures that any changes made to a stream object that is open in transacted
/// mode are reflected in the parent storage.
/// </summary>
/// <param name="grfCommitFlags">
/// A value that controls how the changes for the stream object are committed.
/// </param>
/// <remarks>
/// For more information, see the existing documentation for IStream::Commit in the MSDN library.
/// </remarks>
public void Commit(int grfCommitFlags)
{
_Validate();
_source.Flush();
}
/// <summary>
/// Copies a specified number of bytes from the current seek pointer in the
/// stream to the current seek pointer in another stream.
/// </summary>
/// <param name="pstm">
/// A reference to the destination stream.
/// </param>
/// <param name="cb">
/// The number of bytes to copy from the source stream.
/// </param>
/// <param name="pcbRead">
/// On successful return, contains the actual number of bytes read from the source.
/// (Note the native signature is to a ULARGE_INTEGER*, so 64 bits are written
/// to this parameter on success.)
/// </param>
/// <param name="pcbWritten">
/// On successful return, contains the actual number of bytes written to the destination.
/// (Note the native signature is to a ULARGE_INTEGER*, so 64 bits are written
/// to this parameter on success.)
/// </param>
[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten)
{
Verify.IsNotNull(pstm, "pstm");
_Validate();
// Reasonbly sized buffer, don't try to copy large streams in bulk.
var buffer = new byte[4096];
long cbWritten = 0;
while (cbWritten < cb)
{
int cbRead = _source.Read(buffer, 0, buffer.Length);
if (0 == cbRead)
{
break;
}
// COM documentation is a bit vague here whether NULL is valid for the third parameter.
// Going to assume it is, as most implementations I've seen treat it as optional.
// It's possible this will break on some IStream implementations.
pstm.Write(buffer, cbRead, IntPtr.Zero);
cbWritten += cbRead;
}
if (IntPtr.Zero != pcbRead)
{
Marshal.WriteInt64(pcbRead, cbWritten);
}
if (IntPtr.Zero != pcbWritten)
{
Marshal.WriteInt64(pcbWritten, cbWritten);
}
}
/// <summary>
/// Restricts access to a specified range of bytes in the stream.
/// </summary>
/// <param name="libOffset">
/// The byte offset for the beginning of the range.
/// </param>
/// <param name="cb">
/// The length of the range, in bytes, to restrict.
/// </param>
/// <param name="dwLockType">
/// The requested restrictions on accessing the range.
/// </param>
/// <remarks>
/// For more information, see the existing documentation for IStream::LockRegion in the MSDN library.
/// This class doesn't implement LockRegion. A COMException is thrown if it is used.
/// </remarks>
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Standard.HRESULT.ThrowIfFailed(System.String)"), Obsolete("The method is not implemented", true)]
public void LockRegion(long libOffset, long cb, int dwLockType)
{
HRESULT.STG_E_INVALIDFUNCTION.ThrowIfFailed("The method is not implemented.");
}
/// <summary>
/// Reads a specified number of bytes from the stream object into memory starting at the current seek pointer.
/// </summary>
/// <param name="pv">
/// When this method returns, contains the data read from the stream. This parameter is passed uninitialized.
/// </param>
/// <param name="cb">
/// The number of bytes to read from the stream object.
/// </param>
/// <param name="pcbRead">
/// A pointer to a ULONG variable that receives the actual number of bytes read from the stream object.
/// </param>
/// <remarks>
/// For more information, see the existing documentation for ISequentialStream::Read in the MSDN library.
/// </remarks>
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
public void Read(byte[] pv, int cb, IntPtr pcbRead)
{
_Validate();
int cbRead = _source.Read(pv, 0, cb);
if (IntPtr.Zero != pcbRead)
{
Marshal.WriteInt32(pcbRead, cbRead);
}
}
/// <summary>
/// Discards all changes that have been made to a transacted stream since the last Commit call.
/// </summary>
/// <remarks>
/// This class doesn't implement Revert. A COMException is thrown if it is used.
/// </remarks>
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Standard.HRESULT.ThrowIfFailed(System.String)"), Obsolete("The method is not implemented", true)]
public void Revert()
{
HRESULT.STG_E_INVALIDFUNCTION.ThrowIfFailed("The method is not implemented.");
}
/// <summary>
/// Changes the seek pointer to a new location relative to the beginning of the
/// stream, to the end of the stream, or to the current seek pointer.
/// </summary>
/// <param name="dlibMove">
/// The displacement to add to dwOrigin.
/// </param>
/// <param name="dwOrigin">
/// The origin of the seek. The origin can be the beginning of the file, the current seek pointer, or the end of the file.
/// </param>
/// <param name="plibNewPosition">
/// On successful return, contains the offset of the seek pointer from the beginning of the stream.
/// (Note the native signature is to a ULARGE_INTEGER*, so 64 bits are written
/// to this parameter on success.)
/// </param>
/// <remarks>
/// For more information, see the existing documentation for IStream::Seek in the MSDN library.
/// </remarks>
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition)
{
_Validate();
long position = _source.Seek(dlibMove, (SeekOrigin)dwOrigin);
if (IntPtr.Zero != plibNewPosition)
{
Marshal.WriteInt64(plibNewPosition, position);
}
}
/// <summary>
/// Changes the size of the stream object.
/// </summary>
/// <param name="libNewSize">
/// The new size of the stream as a number of bytes.
/// </param>
/// <remarks>
/// For more information, see the existing documentation for IStream::SetSize in the MSDN library.
/// </remarks>
public void SetSize(long libNewSize)
{
_Validate();
_source.SetLength(libNewSize);
}
/// <summary>
/// Retrieves the STATSTG structure for this stream.
/// </summary>
/// <param name="pstatstg">
/// When this method returns, contains a STATSTG structure that describes this stream object.
/// This parameter is passed uninitialized.
/// </param>
/// <param name="grfStatFlag">
/// Members in the STATSTG structure that this method does not return, thus saving some memory allocation operations.
/// </param>
public void Stat(out STATSTG pstatstg, int grfStatFlag)
{
pstatstg = default(STATSTG);
_Validate();
pstatstg.type = STGTY_STREAM;
pstatstg.cbSize = _source.Length;
pstatstg.grfMode = STGM_READWRITE;
pstatstg.grfLocksSupported = LOCK_EXCLUSIVE;
}
/// <summary>
/// Removes the access restriction on a range of bytes previously restricted with the LockRegion method.
/// </summary>
/// <param name="libOffset">The byte offset for the beginning of the range.
/// </param>
/// <param name="cb">
/// The length, in bytes, of the range to restrict.
/// </param>
/// <param name="dwLockType">
/// The access restrictions previously placed on the range.
/// </param>
/// <remarks>
/// For more information, see the existing documentation for IStream::UnlockRegion in the MSDN library.
/// This class doesn't implement UnlockRegion. A COMException is thrown if it is used.
/// </remarks>
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Standard.HRESULT.ThrowIfFailed(System.String)")]
[Obsolete("The method is not implemented", true)]
public void UnlockRegion(long libOffset, long cb, int dwLockType)
{
HRESULT.STG_E_INVALIDFUNCTION.ThrowIfFailed("The method is not implemented.");
}
/// <summary>
/// Writes a specified number of bytes into the stream object starting at the current seek pointer.
/// </summary>
/// <param name="pv">
/// The buffer to write this stream to.
/// </param>
/// <param name="cb">
/// The number of bytes to write to the stream.
/// </param>
/// <param name="pcbWritten">
/// On successful return, contains the actual number of bytes written to the stream object.
/// If the caller sets this pointer to null, this method does not provide the actual number
/// of bytes written.
/// </param>
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
public void Write(byte[] pv, int cb, IntPtr pcbWritten)
{
_Validate();
_source.Write(pv, 0, cb);
if (IntPtr.Zero != pcbWritten)
{
Marshal.WriteInt32(pcbWritten, cb);
}
}
#endregion
#region IDisposable Members
/// <summary>
/// Releases resources controlled by this object.
/// </summary>
/// <remarks>
/// Dispose can be called multiple times, but trying to use the object
/// after it has been disposed will generally throw ObjectDisposedExceptions.
/// </remarks>
public void Dispose()
{
_source = null;
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,328 @@
/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
/**************************************************************************\
Copyright Microsoft Corporation. All Rights Reserved.
\**************************************************************************/
// This file contains general utilities to aid in development.
// Classes here generally shouldn't be exposed publicly since
// they're not particular to any library functionality.
// Because the classes here are internal, it's likely this file
// might be included in multiple assemblies.
namespace Standard
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Threading;
/// <summary>
/// A static class for retail validated assertions.
/// Instead of breaking into the debugger an exception is thrown.
/// </summary>
internal static class Verify
{
/// <summary>
/// Ensure that the current thread's apartment state is what's expected.
/// </summary>
/// <param name="requiredState">
/// The required apartment state for the current thread.
/// </param>
/// <param name="message">
/// The message string for the exception to be thrown if the state is invalid.
/// </param>
/// <exception cref="InvalidOperationException">
/// Thrown if the calling thread's apartment state is not the same as the requiredState.
/// </exception>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsApartmentState(ApartmentState requiredState, string message)
{
if (Thread.CurrentThread.GetApartmentState() != requiredState)
{
throw new InvalidOperationException(message);
}
}
/// <summary>
/// Ensure that an argument is neither null nor empty.
/// </summary>
/// <param name="value">The string to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[SuppressMessage("Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength")]
[DebuggerStepThrough]
public static void IsNeitherNullNorEmpty(string value, string name)
{
// catch caller errors, mixing up the parameters. Name should never be empty.
Assert.IsNeitherNullNorEmpty(name);
// Notice that ArgumentNullException and ArgumentException take the parameters in opposite order :P
const string errorMessage = "The parameter can not be either null or empty.";
if (null == value)
{
throw new ArgumentNullException(name, errorMessage);
}
if ("" == value)
{
throw new ArgumentException(errorMessage, name);
}
}
/// <summary>
/// Ensure that an argument is neither null nor does it consist only of whitespace.
/// </summary>
/// <param name="value">The string to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[SuppressMessage("Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength")]
[DebuggerStepThrough]
public static void IsNeitherNullNorWhitespace(string value, string name)
{
// catch caller errors, mixing up the parameters. Name should never be empty.
Assert.IsNeitherNullNorEmpty(name);
// Notice that ArgumentNullException and ArgumentException take the parameters in opposite order :P
const string errorMessage = "The parameter can not be either null or empty or consist only of white space characters.";
if (null == value)
{
throw new ArgumentNullException(name, errorMessage);
}
if ("" == value.Trim())
{
throw new ArgumentException(errorMessage, name);
}
}
/// <summary>Verifies that an argument is not null.</summary>
/// <typeparam name="T">Type of the object to validate. Must be a class.</typeparam>
/// <param name="obj">The object to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsNotDefault<T>(T obj, string name) where T : struct
{
if (default(T).Equals(obj))
{
throw new ArgumentException("The parameter must not be the default value.", name);
}
}
/// <summary>Verifies that an argument is not null.</summary>
/// <typeparam name="T">Type of the object to validate. Must be a class.</typeparam>
/// <param name="obj">The object to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsNotNull<T>(T obj, string name) where T : class
{
if (null == obj)
{
throw new ArgumentNullException(name);
}
}
/// <summary>Verifies that an argument is null.</summary>
/// <typeparam name="T">Type of the object to validate. Must be a class.</typeparam>
/// <param name="obj">The object to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsNull<T>(T obj, string name) where T : class
{
if (null != obj)
{
throw new ArgumentException("The parameter must be null.", name);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void PropertyIsNotNull<T>(T obj, string name) where T : class
{
if (null == obj)
{
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "The property {0} cannot be null at this time.", name));
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void PropertyIsNull<T>(T obj, string name) where T : class
{
if (null != obj)
{
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "The property {0} must be null at this time.", name));
}
}
/// <summary>
/// Verifies the specified statement is true. Throws an ArgumentException if it's not.
/// </summary>
/// <param name="statement">The statement to be verified as true.</param>
/// <param name="name">Name of the parameter to include in the ArgumentException.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsTrue(bool statement, string name)
{
if (!statement)
{
throw new ArgumentException("", name);
}
}
/// <summary>
/// Verifies the specified statement is true. Throws an ArgumentException if it's not.
/// </summary>
/// <param name="statement">The statement to be verified as true.</param>
/// <param name="name">Name of the parameter to include in the ArgumentException.</param>
/// <param name="message">The message to include in the ArgumentException.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsTrue(bool statement, string name, string message)
{
if (!statement)
{
throw new ArgumentException(message, name);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void AreEqual<T>(T expected, T actual, string parameterName, string message)
{
if (null == expected)
{
// Two nulls are considered equal, regardless of type semantics.
if (null != actual && !actual.Equals(expected))
{
throw new ArgumentException(message, parameterName);
}
}
else if (!expected.Equals(actual))
{
throw new ArgumentException(message, parameterName);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void AreNotEqual<T>(T notExpected, T actual, string parameterName, string message)
{
if (null == notExpected)
{
// Two nulls are considered equal, regardless of type semantics.
if (null == actual || actual.Equals(notExpected))
{
throw new ArgumentException(message, parameterName);
}
}
else if (notExpected.Equals(actual))
{
throw new ArgumentException(message, parameterName);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void UriIsAbsolute(Uri uri, string parameterName)
{
Verify.IsNotNull(uri, parameterName);
if (!uri.IsAbsoluteUri)
{
throw new ArgumentException("The URI must be absolute.", parameterName);
}
}
/// <summary>
/// Verifies that the specified value is within the expected range. The assertion fails if it isn't.
/// </summary>
/// <param name="lowerBoundInclusive">The lower bound inclusive value.</param>
/// <param name="value">The value to verify.</param>
/// <param name="upperBoundExclusive">The upper bound exclusive value.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void BoundedInteger(int lowerBoundInclusive, int value, int upperBoundExclusive, string parameterName)
{
if (value < lowerBoundInclusive || value >= upperBoundExclusive)
{
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The integer value must be bounded with [{0}, {1})", lowerBoundInclusive, upperBoundExclusive), parameterName);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void BoundedDoubleInc(double lowerBoundInclusive, double value, double upperBoundInclusive, string message, string parameter)
{
if (value < lowerBoundInclusive || value > upperBoundInclusive)
{
throw new ArgumentException(message, parameter);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void TypeSupportsInterface(Type type, Type interfaceType, string parameterName)
{
Assert.IsNeitherNullNorEmpty(parameterName);
Verify.IsNotNull(type, "type");
Verify.IsNotNull(interfaceType, "interfaceType");
if (type.GetInterface(interfaceType.Name) == null)
{
throw new ArgumentException("The type of this parameter does not support a required interface", parameterName);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void FileExists(string filePath, string parameterName)
{
Verify.IsNeitherNullNorEmpty(filePath, parameterName);
if (!File.Exists(filePath))
{
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "No file exists at \"{0}\"", filePath), parameterName);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
internal static void ImplementsInterface(object parameter, Type interfaceType, string parameterName)
{
Assert.IsNotNull(parameter);
Assert.IsNotNull(interfaceType);
Assert.IsTrue(interfaceType.IsInterface);
bool isImplemented = false;
foreach (var ifaceType in parameter.GetType().GetInterfaces())
{
if (ifaceType == interfaceType)
{
isImplemented = true;
break;
}
}
if (!isImplemented)
{
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The parameter must implement interface {0}.", interfaceType.ToString()), parameterName);
}
}
}
}

View File

@@ -0,0 +1,107 @@
/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
namespace Microsoft.Windows.Shell
{
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using Standard;
public static class SystemCommands
{
public static RoutedCommand CloseWindowCommand { get; private set; }
public static RoutedCommand MaximizeWindowCommand { get; private set; }
public static RoutedCommand MinimizeWindowCommand { get; private set; }
public static RoutedCommand RestoreWindowCommand { get; private set; }
public static RoutedCommand ShowSystemMenuCommand { get; private set; }
static SystemCommands()
{
CloseWindowCommand = new RoutedCommand("CloseWindow", typeof(SystemCommands));
MaximizeWindowCommand = new RoutedCommand("MaximizeWindow", typeof(SystemCommands));
MinimizeWindowCommand = new RoutedCommand("MinimizeWindow", typeof(SystemCommands));
RestoreWindowCommand = new RoutedCommand("RestoreWindow", typeof(SystemCommands));
ShowSystemMenuCommand = new RoutedCommand("ShowSystemMenu", typeof(SystemCommands));
}
private static void _PostSystemCommand(Window window, SC command)
{
IntPtr hwnd = new WindowInteropHelper(window).Handle;
if (hwnd == IntPtr.Zero || !NativeMethods.IsWindow(hwnd))
{
return;
}
NativeMethods.PostMessage(hwnd, WM.SYSCOMMAND, new IntPtr((int)command), IntPtr.Zero);
}
public static void CloseWindow(Window window)
{
Verify.IsNotNull(window, "window");
_PostSystemCommand(window, SC.CLOSE);
}
public static void MaximizeWindow(Window window)
{
Verify.IsNotNull(window, "window");
_PostSystemCommand(window, SC.MAXIMIZE);
}
public static void MinimizeWindow(Window window)
{
Verify.IsNotNull(window, "window");
_PostSystemCommand(window, SC.MINIMIZE);
}
public static void RestoreWindow(Window window)
{
Verify.IsNotNull(window, "window");
_PostSystemCommand(window, SC.RESTORE);
}
/// <summary>Display the system menu at a specified location.</summary>
/// <param name="screenLocation">The location to display the system menu, in logical screen coordinates.</param>
public static void ShowSystemMenu(Window window, Point screenLocation)
{
Verify.IsNotNull(window, "window");
ShowSystemMenuPhysicalCoordinates(window, DpiHelper.LogicalPixelsToDevice(screenLocation));
}
internal static void ShowSystemMenuPhysicalCoordinates(Window window, Point physicalScreenLocation)
{
const uint TPM_RETURNCMD = 0x0100;
const uint TPM_LEFTBUTTON = 0x0;
Verify.IsNotNull(window, "window");
IntPtr hwnd = new WindowInteropHelper(window).Handle;
if (hwnd == IntPtr.Zero || !NativeMethods.IsWindow(hwnd))
{
return;
}
IntPtr hmenu = NativeMethods.GetSystemMenu(hwnd, false);
uint cmd = NativeMethods.TrackPopupMenuEx(hmenu, TPM_LEFTBUTTON | TPM_RETURNCMD, (int)physicalScreenLocation.X, (int)physicalScreenLocation.Y, hwnd, IntPtr.Zero);
if (0 != cmd)
{
NativeMethods.PostMessage(hwnd, WM.SYSCOMMAND, new IntPtr(cmd), IntPtr.Zero);
}
}
}
}

View File

@@ -0,0 +1,573 @@
/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
/**************************************************************************\
Copyright Microsoft Corporation. All Rights Reserved.
\**************************************************************************/
namespace Microsoft.Windows.Shell
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Media;
using Standard;
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable")]
public class SystemParameters2 : INotifyPropertyChanged
{
private delegate void _SystemMetricUpdate(IntPtr wParam, IntPtr lParam);
[ThreadStatic]
private static SystemParameters2 _threadLocalSingleton;
private MessageWindow _messageHwnd;
private bool _isGlassEnabled;
private Color _glassColor;
private SolidColorBrush _glassColorBrush;
private Thickness _windowResizeBorderThickness;
private Thickness _windowNonClientFrameThickness;
private double _captionHeight;
private Size _smallIconSize;
private string _uxThemeName;
private string _uxThemeColor;
private bool _isHighContrast;
private CornerRadius _windowCornerRadius;
private Rect _captionButtonLocation;
private readonly Dictionary<WM, List<_SystemMetricUpdate>> _UpdateTable;
#region Initialization and Update Methods
// Most properties exposed here have a way of being queried directly
// and a way of being notified of updates via a window message.
// This region is a grouping of both, for each of the exposed properties.
private void _InitializeIsGlassEnabled()
{
IsGlassEnabled = NativeMethods.DwmIsCompositionEnabled();
}
private void _UpdateIsGlassEnabled(IntPtr wParam, IntPtr lParam)
{
// Neither the wParam or lParam are used in this case.
_InitializeIsGlassEnabled();
}
private void _InitializeGlassColor()
{
bool isOpaque;
uint color;
NativeMethods.DwmGetColorizationColor(out color, out isOpaque);
color |= isOpaque ? 0xFF000000 : 0;
WindowGlassColor = Utility.ColorFromArgbDword(color);
var glassBrush = new SolidColorBrush(WindowGlassColor);
glassBrush.Freeze();
WindowGlassBrush = glassBrush;
}
private void _UpdateGlassColor(IntPtr wParam, IntPtr lParam)
{
bool isOpaque = lParam != IntPtr.Zero;
uint color = unchecked((uint)(int)wParam.ToInt64());
color |= isOpaque ? 0xFF000000 : 0;
WindowGlassColor = Utility.ColorFromArgbDword(color);
var glassBrush = new SolidColorBrush(WindowGlassColor);
glassBrush.Freeze();
WindowGlassBrush = glassBrush;
}
private void _InitializeCaptionHeight()
{
Point ptCaption = new Point(0, NativeMethods.GetSystemMetrics(SM.CYCAPTION));
WindowCaptionHeight = DpiHelper.DevicePixelsToLogical(ptCaption).Y;
}
private void _UpdateCaptionHeight(IntPtr wParam, IntPtr lParam)
{
_InitializeCaptionHeight();
}
private void _InitializeWindowResizeBorderThickness()
{
Size frameSize = new Size(
NativeMethods.GetSystemMetrics(SM.CXSIZEFRAME),
NativeMethods.GetSystemMetrics(SM.CYSIZEFRAME));
Size frameSizeInDips = DpiHelper.DeviceSizeToLogical(frameSize);
WindowResizeBorderThickness = new Thickness(frameSizeInDips.Width, frameSizeInDips.Height, frameSizeInDips.Width, frameSizeInDips.Height);
}
private void _UpdateWindowResizeBorderThickness(IntPtr wParam, IntPtr lParam)
{
_InitializeWindowResizeBorderThickness();
}
private void _InitializeWindowNonClientFrameThickness()
{
Size frameSize = new Size(
NativeMethods.GetSystemMetrics(SM.CXSIZEFRAME),
NativeMethods.GetSystemMetrics(SM.CYSIZEFRAME));
Size frameSizeInDips = DpiHelper.DeviceSizeToLogical(frameSize);
int captionHeight = NativeMethods.GetSystemMetrics(SM.CYCAPTION);
double captionHeightInDips = DpiHelper.DevicePixelsToLogical(new Point(0, captionHeight)).Y;
WindowNonClientFrameThickness = new Thickness(frameSizeInDips.Width, frameSizeInDips.Height + captionHeightInDips, frameSizeInDips.Width, frameSizeInDips.Height);
}
private void _UpdateWindowNonClientFrameThickness(IntPtr wParam, IntPtr lParam)
{
_InitializeWindowNonClientFrameThickness();
}
private void _InitializeSmallIconSize()
{
SmallIconSize = new Size(
NativeMethods.GetSystemMetrics(SM.CXSMICON),
NativeMethods.GetSystemMetrics(SM.CYSMICON));
}
private void _UpdateSmallIconSize(IntPtr wParam, IntPtr lParam)
{
_InitializeSmallIconSize();
}
private void _LegacyInitializeCaptionButtonLocation()
{
// This calculation isn't quite right, but it's pretty close.
// I expect this is good enough for the scenarios where this is expected to be used.
int captionX = NativeMethods.GetSystemMetrics(SM.CXSIZE);
int captionY = NativeMethods.GetSystemMetrics(SM.CYSIZE);
int frameX = NativeMethods.GetSystemMetrics(SM.CXSIZEFRAME) + NativeMethods.GetSystemMetrics(SM.CXEDGE);
int frameY = NativeMethods.GetSystemMetrics(SM.CYSIZEFRAME) + NativeMethods.GetSystemMetrics(SM.CYEDGE);
Rect captionRect = new Rect(0, 0, captionX * 3, captionY);
captionRect.Offset(-frameX - captionRect.Width, frameY);
WindowCaptionButtonsLocation = captionRect;
}
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
private void _InitializeCaptionButtonLocation()
{
// There is a completely different way to do this on XP.
if (!Utility.IsOSVistaOrNewer || !NativeMethods.IsThemeActive())
{
_LegacyInitializeCaptionButtonLocation();
return;
}
var tbix = new TITLEBARINFOEX { cbSize = Marshal.SizeOf(typeof(TITLEBARINFOEX)) };
IntPtr lParam = Marshal.AllocHGlobal(tbix.cbSize);
try
{
Marshal.StructureToPtr(tbix, lParam, false);
// This might flash a window in the taskbar while being calculated.
// WM_GETTITLEBARINFOEX doesn't work correctly unless the window is visible while processing.
NativeMethods.ShowWindow(_messageHwnd.Handle, SW.SHOW);
NativeMethods.SendMessage(_messageHwnd.Handle, WM.GETTITLEBARINFOEX, IntPtr.Zero, lParam);
tbix = (TITLEBARINFOEX)Marshal.PtrToStructure(lParam, typeof(TITLEBARINFOEX));
}
finally
{
NativeMethods.ShowWindow(_messageHwnd.Handle, SW.HIDE);
Utility.SafeFreeHGlobal(ref lParam);
}
// TITLEBARINFOEX has information relative to the screen. We need to convert the containing rect
// to instead be relative to the top-right corner of the window.
RECT rcAllCaptionButtons = RECT.Union(tbix.rgrect_CloseButton, tbix.rgrect_MinimizeButton);
// For all known themes, the RECT for the maximize box shouldn't add anything to the union of the minimize and close boxes.
Assert.AreEqual(rcAllCaptionButtons, RECT.Union(rcAllCaptionButtons, tbix.rgrect_MaximizeButton));
RECT rcWindow = NativeMethods.GetWindowRect(_messageHwnd.Handle);
// Reorient the Top/Right to be relative to the top right edge of the Window.
var deviceCaptionLocation = new Rect(
rcAllCaptionButtons.Left - rcWindow.Width - rcWindow.Left,
rcAllCaptionButtons.Top - rcWindow.Top,
rcAllCaptionButtons.Width,
rcAllCaptionButtons.Height);
Rect logicalCaptionLocation = DpiHelper.DeviceRectToLogical(deviceCaptionLocation);
WindowCaptionButtonsLocation = logicalCaptionLocation;
}
private void _UpdateCaptionButtonLocation(IntPtr wParam, IntPtr lParam)
{
_InitializeCaptionButtonLocation();
}
private void _InitializeHighContrast()
{
HIGHCONTRAST hc = NativeMethods.SystemParameterInfo_GetHIGHCONTRAST();
HighContrast = (hc.dwFlags & HCF.HIGHCONTRASTON) != 0;
}
private void _UpdateHighContrast(IntPtr wParam, IntPtr lParam)
{
_InitializeHighContrast();
}
private void _InitializeThemeInfo()
{
if (!NativeMethods.IsThemeActive())
{
UxThemeName = "Classic";
UxThemeColor = "";
return;
}
string name;
string color;
string size;
NativeMethods.GetCurrentThemeName(out name, out color, out size);
// Consider whether this is the most useful way to expose this...
UxThemeName = System.IO.Path.GetFileNameWithoutExtension(name);
UxThemeColor = color;
}
private void _UpdateThemeInfo(IntPtr wParam, IntPtr lParam)
{
_InitializeThemeInfo();
}
private void _InitializeWindowCornerRadius()
{
// The radius of window corners isn't exposed as a true system parameter.
// It instead is a logical size that we're approximating based on the current theme.
// There aren't any known variations based on theme color.
Assert.IsNeitherNullNorEmpty(UxThemeName);
// These radii are approximate. The way WPF does rounding is different than how
// rounded-rectangle HRGNs are created, which is also different than the actual
// round corners on themed Windows. For now we're not exposing anything to
// mitigate the differences.
var cornerRadius = default(CornerRadius);
// This list is known to be incomplete and very much not future-proof.
// On XP there are at least a couple of shipped themes that this won't catch,
// "Zune" and "Royale", but WPF doesn't know about these either.
// If a new theme was to replace Aero, then this will fall back on "classic" behaviors.
// This isn't ideal, but it's not the end of the world. WPF will generally have problems anyways.
switch (UxThemeName.ToUpperInvariant())
{
case "LUNA":
cornerRadius = new CornerRadius(6, 6, 0, 0);
break;
case "AERO":
// Aero has two cases. One with glass and one without...
if (NativeMethods.DwmIsCompositionEnabled())
{
cornerRadius = new CornerRadius(8);
}
else
{
cornerRadius = new CornerRadius(6, 6, 0, 0);
}
break;
case "CLASSIC":
case "ZUNE":
case "ROYALE":
default:
cornerRadius = new CornerRadius(0);
break;
}
WindowCornerRadius = cornerRadius;
}
private void _UpdateWindowCornerRadius(IntPtr wParam, IntPtr lParam)
{
// Neither the wParam or lParam are used in this case.
_InitializeWindowCornerRadius();
}
#endregion
/// <summary>
/// Private constructor. The public way to access this class is through the static Current property.
/// </summary>
private SystemParameters2()
{
// This window gets used for calculations about standard caption button locations
// so it has WS_OVERLAPPEDWINDOW as a style to give it normal caption buttons.
// This window may be shown during calculations of caption bar information, so create it at a location that's likely offscreen.
_messageHwnd = new MessageWindow((CS)0, WS.OVERLAPPEDWINDOW | WS.DISABLED, (WS_EX)0, new Rect(-16000, -16000, 100, 100), "", _WndProc);
_messageHwnd.Dispatcher.ShutdownStarted += (sender, e) => Utility.SafeDispose(ref _messageHwnd);
// Fixup the default values of the DPs.
_InitializeIsGlassEnabled();
_InitializeGlassColor();
_InitializeCaptionHeight();
_InitializeWindowNonClientFrameThickness();
_InitializeWindowResizeBorderThickness();
_InitializeCaptionButtonLocation();
_InitializeSmallIconSize();
_InitializeHighContrast();
_InitializeThemeInfo();
// WindowCornerRadius isn't exposed by true system parameters, so it requires the theme to be initialized first.
_InitializeWindowCornerRadius();
_UpdateTable = new Dictionary<WM, List<_SystemMetricUpdate>>
{
{ WM.THEMECHANGED,
new List<_SystemMetricUpdate>
{
_UpdateThemeInfo,
_UpdateHighContrast,
_UpdateWindowCornerRadius,
_UpdateCaptionButtonLocation, } },
{ WM.SETTINGCHANGE,
new List<_SystemMetricUpdate>
{
_UpdateCaptionHeight,
_UpdateWindowResizeBorderThickness,
_UpdateSmallIconSize,
_UpdateHighContrast,
_UpdateWindowNonClientFrameThickness,
_UpdateCaptionButtonLocation, } },
{ WM.DWMNCRENDERINGCHANGED, new List<_SystemMetricUpdate> { _UpdateIsGlassEnabled } },
{ WM.DWMCOMPOSITIONCHANGED, new List<_SystemMetricUpdate> { _UpdateIsGlassEnabled } },
{ WM.DWMCOLORIZATIONCOLORCHANGED, new List<_SystemMetricUpdate> { _UpdateGlassColor } },
};
}
public static SystemParameters2 Current
{
get
{
if (_threadLocalSingleton == null)
{
_threadLocalSingleton = new SystemParameters2();
}
return _threadLocalSingleton;
}
}
private IntPtr _WndProc(IntPtr hwnd, WM msg, IntPtr wParam, IntPtr lParam)
{
// Don't do this if called within the SystemParameters2 constructor
if (_UpdateTable != null)
{
List<_SystemMetricUpdate> handlers;
if (_UpdateTable.TryGetValue(msg, out handlers))
{
Assert.IsNotNull(handlers);
foreach (var handler in handlers)
{
handler(wParam, lParam);
}
}
}
return NativeMethods.DefWindowProc(hwnd, msg, wParam, lParam);
}
public bool IsGlassEnabled
{
get
{
// return _isGlassEnabled;
// It turns out there may be some lag between someone asking this
// and the window getting updated. It's not too expensive, just always do the check.
return NativeMethods.DwmIsCompositionEnabled();
}
private set
{
if (value != _isGlassEnabled)
{
_isGlassEnabled = value;
_NotifyPropertyChanged("IsGlassEnabled");
}
}
}
public Color WindowGlassColor
{
get { return _glassColor; }
private set
{
if (value != _glassColor)
{
_glassColor = value;
_NotifyPropertyChanged("WindowGlassColor");
}
}
}
public SolidColorBrush WindowGlassBrush
{
get { return _glassColorBrush; }
private set
{
Assert.IsNotNull(value);
Assert.IsTrue(value.IsFrozen);
if (_glassColorBrush == null || value.Color != _glassColorBrush.Color)
{
_glassColorBrush = value;
_NotifyPropertyChanged("WindowGlassBrush");
}
}
}
public Thickness WindowResizeBorderThickness
{
get { return _windowResizeBorderThickness; }
private set
{
if (value != _windowResizeBorderThickness)
{
_windowResizeBorderThickness = value;
_NotifyPropertyChanged("WindowResizeBorderThickness");
}
}
}
public Thickness WindowNonClientFrameThickness
{
get { return _windowNonClientFrameThickness; }
private set
{
if (value != _windowNonClientFrameThickness)
{
_windowNonClientFrameThickness = value;
_NotifyPropertyChanged("WindowNonClientFrameThickness");
}
}
}
public double WindowCaptionHeight
{
get { return _captionHeight; }
private set
{
if (value != _captionHeight)
{
_captionHeight = value;
_NotifyPropertyChanged("WindowCaptionHeight");
}
}
}
public Size SmallIconSize
{
get { return new Size(_smallIconSize.Width, _smallIconSize.Height); }
private set
{
if (value != _smallIconSize)
{
_smallIconSize = value;
_NotifyPropertyChanged("SmallIconSize");
}
}
}
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Ux")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ux")]
public string UxThemeName
{
get { return _uxThemeName; }
private set
{
if (value != _uxThemeName)
{
_uxThemeName = value;
_NotifyPropertyChanged("UxThemeName");
}
}
}
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Ux")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ux")]
public string UxThemeColor
{
get { return _uxThemeColor; }
private set
{
if (value != _uxThemeColor)
{
_uxThemeColor = value;
_NotifyPropertyChanged("UxThemeColor");
}
}
}
public bool HighContrast
{
get { return _isHighContrast; }
private set
{
if (value != _isHighContrast)
{
_isHighContrast = value;
_NotifyPropertyChanged("HighContrast");
}
}
}
public CornerRadius WindowCornerRadius
{
get { return _windowCornerRadius; }
private set
{
if (value != _windowCornerRadius)
{
_windowCornerRadius = value;
_NotifyPropertyChanged("WindowCornerRadius");
}
}
}
public Rect WindowCaptionButtonsLocation
{
get { return _captionButtonLocation; }
private set
{
if (value != _captionButtonLocation)
{
_captionButtonLocation = value;
_NotifyPropertyChanged("WindowCaptionButtonsLocation");
}
}
}
#region INotifyPropertyChanged Members
private void _NotifyPropertyChanged(string propertyName)
{
Assert.IsNeitherNullNorEmpty(propertyName);
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
}

View File

@@ -0,0 +1,267 @@
/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
/**************************************************************************\
Copyright Microsoft Corporation. All Rights Reserved.
\**************************************************************************/
namespace Microsoft.Windows.Shell
{
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Windows;
using System.Windows.Data;
using Standard;
public class WindowChrome : Freezable
{
private struct _SystemParameterBoundProperty
{
public string SystemParameterPropertyName { get; set; }
public DependencyProperty DependencyProperty { get; set; }
}
// Named property available for fully extending the glass frame.
public static Thickness GlassFrameCompleteThickness { get { return new Thickness(-1); } }
#region Attached Properties
public static readonly DependencyProperty WindowChromeProperty = DependencyProperty.RegisterAttached(
"WindowChrome",
typeof(WindowChrome),
typeof(WindowChrome),
new PropertyMetadata(null, _OnChromeChanged));
private static void _OnChromeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// The different design tools handle drawing outside their custom window objects differently.
// Rather than try to support this concept in the design surface let the designer draw its own
// chrome anyways.
// There's certainly room for improvement here.
if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(d))
{
return;
}
var window = (Window)d;
var newChrome = (WindowChrome)e.NewValue;
Assert.IsNotNull(window);
// Update the ChromeWorker with this new object.
// If there isn't currently a worker associated with the Window then assign a new one.
// There can be a many:1 relationship of to Window to WindowChrome objects, but a 1:1 for a Window and a WindowChromeWorker.
WindowChromeWorker chromeWorker = WindowChromeWorker.GetWindowChromeWorker(window);
if (chromeWorker == null)
{
chromeWorker = new WindowChromeWorker();
WindowChromeWorker.SetWindowChromeWorker(window, chromeWorker);
}
chromeWorker.SetWindowChrome(newChrome);
}
[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
public static WindowChrome GetWindowChrome(Window window)
{
Verify.IsNotNull(window, "window");
return (WindowChrome)window.GetValue(WindowChromeProperty);
}
[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
public static void SetWindowChrome(Window window, WindowChrome chrome)
{
Verify.IsNotNull(window, "window");
window.SetValue(WindowChromeProperty, chrome);
}
public static readonly DependencyProperty IsHitTestVisibleInChromeProperty = DependencyProperty.RegisterAttached(
"IsHitTestVisibleInChrome",
typeof(bool),
typeof(WindowChrome),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));
[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
public static bool GetIsHitTestVisibleInChrome(IInputElement inputElement)
{
Verify.IsNotNull(inputElement, "inputElement");
var dobj = inputElement as DependencyObject;
if (dobj == null)
{
throw new ArgumentException("The element must be a DependencyObject", "inputElement");
}
return (bool)dobj.GetValue(IsHitTestVisibleInChromeProperty);
}
[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
public static void SetIsHitTestVisibleInChrome(IInputElement inputElement, bool hitTestVisible)
{
Verify.IsNotNull(inputElement, "inputElement");
var dobj = inputElement as DependencyObject;
if (dobj == null)
{
throw new ArgumentException("The element must be a DependencyObject", "inputElement");
}
dobj.SetValue(IsHitTestVisibleInChromeProperty, hitTestVisible);
}
#endregion
#region Dependency Properties
public static readonly DependencyProperty CaptionHeightProperty = DependencyProperty.Register(
"CaptionHeight",
typeof(double),
typeof(WindowChrome),
new PropertyMetadata(
0d,
(d, e) => ((WindowChrome)d)._OnPropertyChangedThatRequiresRepaint()),
value => (double)value >= 0d);
/// <summary>The extent of the top of the window to treat as the caption.</summary>
public double CaptionHeight
{
get { return (double)GetValue(CaptionHeightProperty); }
set { SetValue(CaptionHeightProperty, value); }
}
public static readonly DependencyProperty ResizeBorderThicknessProperty = DependencyProperty.Register(
"ResizeBorderThickness",
typeof(Thickness),
typeof(WindowChrome),
new PropertyMetadata(default(Thickness)),
(value) => Utility.IsThicknessNonNegative((Thickness)value));
public Thickness ResizeBorderThickness
{
get { return (Thickness)GetValue(ResizeBorderThicknessProperty); }
set { SetValue(ResizeBorderThicknessProperty, value); }
}
public static readonly DependencyProperty GlassFrameThicknessProperty = DependencyProperty.Register(
"GlassFrameThickness",
typeof(Thickness),
typeof(WindowChrome),
new PropertyMetadata(
default(Thickness),
(d, e) => ((WindowChrome)d)._OnPropertyChangedThatRequiresRepaint(),
(d, o) => _CoerceGlassFrameThickness((Thickness)o)));
private static object _CoerceGlassFrameThickness(Thickness thickness)
{
// If it's explicitly set, but set to a thickness with at least one negative side then
// coerce the value to the stock GlassFrameCompleteThickness.
if (!Utility.IsThicknessNonNegative(thickness))
{
return GlassFrameCompleteThickness;
}
return thickness;
}
public Thickness GlassFrameThickness
{
get { return (Thickness)GetValue(GlassFrameThicknessProperty); }
set { SetValue(GlassFrameThicknessProperty, value); }
}
public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register(
"CornerRadius",
typeof(CornerRadius),
typeof(WindowChrome),
new PropertyMetadata(
default(CornerRadius),
(d, e) => ((WindowChrome)d)._OnPropertyChangedThatRequiresRepaint()),
(value) => Utility.IsCornerRadiusValid((CornerRadius)value));
public CornerRadius CornerRadius
{
get { return (CornerRadius)GetValue(CornerRadiusProperty); }
set { SetValue(CornerRadiusProperty, value); }
}
#region ShowSystemMenu
/// <summary>
/// Gets or sets the ShowSystemMenu property. This dependency property
/// indicates if the system menu should be shown at right click on the caption.
/// </summary>
public bool ShowSystemMenu
{
get;
set;
}
#endregion
#endregion
protected override Freezable CreateInstanceCore()
{
return new WindowChrome();
}
private static readonly List<_SystemParameterBoundProperty> _BoundProperties = new List<_SystemParameterBoundProperty>
{
new _SystemParameterBoundProperty { DependencyProperty = CornerRadiusProperty, SystemParameterPropertyName = "WindowCornerRadius" },
new _SystemParameterBoundProperty { DependencyProperty = CaptionHeightProperty, SystemParameterPropertyName = "WindowCaptionHeight" },
new _SystemParameterBoundProperty { DependencyProperty = ResizeBorderThicknessProperty, SystemParameterPropertyName = "WindowResizeBorderThickness" },
new _SystemParameterBoundProperty { DependencyProperty = GlassFrameThicknessProperty, SystemParameterPropertyName = "WindowNonClientFrameThickness" },
};
public WindowChrome()
{
// Effective default values for some of these properties are set to be bindings
// that set them to system defaults.
// A more correct way to do this would be to Coerce the value iff the source of the DP was the default value.
// Unfortunately with the current property system we can't detect whether the value being applied at the time
// of the coersion is the default.
foreach (var bp in _BoundProperties)
{
// This list must be declared after the DP's are assigned.
Assert.IsNotNull(bp.DependencyProperty);
BindingOperations.SetBinding(
this,
bp.DependencyProperty,
new Binding
{
Source = SystemParameters2.Current,
Path = new PropertyPath(bp.SystemParameterPropertyName),
Mode = BindingMode.OneWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
});
}
}
private void _OnPropertyChangedThatRequiresRepaint()
{
var handler = PropertyChangedThatRequiresRepaint;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
internal event EventHandler PropertyChangedThatRequiresRepaint;
}
}

File diff suppressed because it is too large Load Diff