diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AssemblyVersionInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AssemblyVersionInfo.cs index 73fd3191..c6ea985d 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AssemblyVersionInfo.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AssemblyVersionInfo.cs @@ -21,7 +21,7 @@ internal static class _XceedVersionInfo { [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string BaseVersion = "3.3"; + public const string BaseVersion = "3.4"; [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] public const string Version = BaseVersion + ".0.0"; diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/Theme.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/Theme.xaml index 83b47b28..0bbf9bac 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/Theme.xaml +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/Theme.xaml @@ -1161,8 +1161,9 @@ + - - + + + + - + - + + + + - + - - @@ -1880,7 +1888,8 @@ FontWeight="Bold" Margin="0,3,0,4" > - - + + + + + + diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Brushes.baml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Brushes.baml deleted file mode 100644 index 6e1c9b10..00000000 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Brushes.baml and /dev/null differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/GeneratedInternalTypeHelper.g.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/GeneratedInternalTypeHelper.g.cs deleted file mode 100644 index c65238fb..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/GeneratedInternalTypeHelper.g.cs +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Theme.baml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Theme.baml deleted file mode 100644 index 6727bc1a..00000000 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Theme.baml and /dev/null differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Aero.csproj.FileListAbsolute.txt b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Aero.csproj.FileListAbsolute.txt deleted file mode 100644 index ca7da23f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Aero.csproj.FileListAbsolute.txt +++ /dev/null @@ -1,23 +0,0 @@ -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Debug\Xceed.Wpf.AvalonDock.Themes.Aero.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Debug\Xceed.Wpf.AvalonDock.Themes.Aero.pdb -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Debug\Xceed.Wpf.AvalonDock.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Debug\Xceed.Wpf.AvalonDock.pdb -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Debug\de\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Debug\es\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Debug\fr\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Debug\hu\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Debug\it\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Debug\pt-BR\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Debug\ro\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Debug\ru\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Debug\sv\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Debug\zh-Hans\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Debug\Xceed.Wpf.AvalonDock.Themes.Aero.csprojResolveAssemblyReference.cache -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Debug\GeneratedInternalTypeHelper.g.cs -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Debug\Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.cache -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Debug\Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.lref -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Debug\Brushes.baml -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Debug\Theme.baml -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Debug\Xceed.Wpf.AvalonDock.Themes.Aero.g.resources -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Debug\Xceed.Wpf.AvalonDock.Themes.Aero.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Debug\Xceed.Wpf.AvalonDock.Themes.Aero.pdb diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Aero.g.resources b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Aero.g.resources deleted file mode 100644 index a2ba5ff5..00000000 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Aero.g.resources and /dev/null differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.i.lref b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.i.lref deleted file mode 100644 index 161cff3a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.i.lref +++ /dev/null @@ -1,5 +0,0 @@ -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Debug\GeneratedInternalTypeHelper.g.i.cs - -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\Brushes.xaml;; -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\Theme.xaml;; - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.lref b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.lref deleted file mode 100644 index b21b8ca9..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.lref +++ /dev/null @@ -1,5 +0,0 @@ -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Debug\GeneratedInternalTypeHelper.g.cs - -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\Brushes.xaml;; -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\Theme.xaml;; - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Brushes.baml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Brushes.baml index 16b4ecd6..f2fc70fd 100644 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Brushes.baml and b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Brushes.baml differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Theme.baml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Theme.baml index c40581ec..7558b5b0 100644 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Theme.baml and b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Theme.baml differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Xceed.Wpf.AvalonDock.Themes.Aero.csproj.FileListAbsolute.txt b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Xceed.Wpf.AvalonDock.Themes.Aero.csproj.FileListAbsolute.txt index a4b763bc..38d68938 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Xceed.Wpf.AvalonDock.Themes.Aero.csproj.FileListAbsolute.txt +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Xceed.Wpf.AvalonDock.Themes.Aero.csproj.FileListAbsolute.txt @@ -1,23 +1,23 @@ -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\Xceed.Wpf.AvalonDock.Themes.Aero.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\Xceed.Wpf.AvalonDock.Themes.Aero.pdb -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\Xceed.Wpf.AvalonDock.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\Xceed.Wpf.AvalonDock.pdb -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\de\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\es\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\fr\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\hu\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\it\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\pt-BR\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\ro\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\ru\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\sv\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\zh-Hans\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Xceed.Wpf.AvalonDock.Themes.Aero.csprojResolveAssemblyReference.cache -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\GeneratedInternalTypeHelper.g.cs -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.cache -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.lref -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Brushes.baml -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Theme.baml -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Xceed.Wpf.AvalonDock.Themes.Aero.g.resources -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Xceed.Wpf.AvalonDock.Themes.Aero.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Xceed.Wpf.AvalonDock.Themes.Aero.pdb +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\Xceed.Wpf.AvalonDock.Themes.Aero.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\Xceed.Wpf.AvalonDock.Themes.Aero.pdb +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\Xceed.Wpf.AvalonDock.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\Xceed.Wpf.AvalonDock.pdb +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\de\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\es\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\fr\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\hu\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\it\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\pt-BR\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\ro\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\ru\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\sv\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\bin\Release\zh-Hans\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Xceed.Wpf.AvalonDock.Themes.Aero.csprojResolveAssemblyReference.cache +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\GeneratedInternalTypeHelper.g.cs +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.cache +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.lref +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Brushes.baml +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Theme.baml +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Xceed.Wpf.AvalonDock.Themes.Aero.g.resources +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Xceed.Wpf.AvalonDock.Themes.Aero.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\Xceed.Wpf.AvalonDock.Themes.Aero.pdb diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Xceed.Wpf.AvalonDock.Themes.Aero.g.resources b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Xceed.Wpf.AvalonDock.Themes.Aero.g.resources index 62d2180e..9216728b 100644 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Xceed.Wpf.AvalonDock.Themes.Aero.g.resources and b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Xceed.Wpf.AvalonDock.Themes.Aero.g.resources differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.i.lref b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.i.lref deleted file mode 100644 index 6775f037..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.i.lref +++ /dev/null @@ -1,5 +0,0 @@ -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\GeneratedInternalTypeHelper.g.i.cs - -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\Brushes.xaml;; -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\Theme.xaml;; - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.lref b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.lref index 0b92f121..556f4e24 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.lref +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Release/Xceed.Wpf.AvalonDock.Themes.Aero_MarkupCompile.lref @@ -1,5 +1,5 @@ -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\GeneratedInternalTypeHelper.g.cs +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\obj\Release\GeneratedInternalTypeHelper.g.cs -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\Brushes.xaml;; -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\Theme.xaml;; +FD:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\Brushes.xaml;; +FD:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Aero\Theme.xaml;; diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/AssemblyVersionInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/AssemblyVersionInfo.cs index 73fd3191..c6ea985d 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/AssemblyVersionInfo.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/AssemblyVersionInfo.cs @@ -21,7 +21,7 @@ internal static class _XceedVersionInfo { [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string BaseVersion = "3.3"; + public const string BaseVersion = "3.4"; [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] public const string Version = BaseVersion + ".0.0"; diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/Theme.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/Theme.xaml index dbe90ad5..1027b5d7 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/Theme.xaml +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/Theme.xaml @@ -1185,8 +1185,9 @@ + - @@ -1209,12 +1209,24 @@ - + + + + - + + + + + + + - + + + + - - - - + - - @@ -1944,7 +1955,8 @@ FontWeight="Bold" Margin="0,3,0,4" > - - + + + + + + diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Brushes.baml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Brushes.baml deleted file mode 100644 index 2a3b1522..00000000 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Brushes.baml and /dev/null differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Theme.baml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Theme.baml deleted file mode 100644 index e6a5e3c5..00000000 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Theme.baml and /dev/null differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Metro.csproj.FileListAbsolute.txt b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Metro.csproj.FileListAbsolute.txt deleted file mode 100644 index 180f1b72..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Metro.csproj.FileListAbsolute.txt +++ /dev/null @@ -1,22 +0,0 @@ -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Debug\Xceed.Wpf.AvalonDock.Themes.Metro.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Debug\Xceed.Wpf.AvalonDock.Themes.Metro.pdb -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Debug\Xceed.Wpf.AvalonDock.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Debug\Xceed.Wpf.AvalonDock.pdb -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Debug\de\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Debug\es\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Debug\fr\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Debug\hu\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Debug\it\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Debug\pt-BR\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Debug\ro\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Debug\ru\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Debug\sv\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Debug\zh-Hans\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Debug\Xceed.Wpf.AvalonDock.Themes.Metro.csprojResolveAssemblyReference.cache -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Debug\Brushes.baml -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Debug\Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.cache -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Debug\Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.lref -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Debug\Theme.baml -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Debug\Xceed.Wpf.AvalonDock.Themes.Metro.g.resources -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Debug\Xceed.Wpf.AvalonDock.Themes.Metro.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Debug\Xceed.Wpf.AvalonDock.Themes.Metro.pdb diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Metro.g.resources b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Metro.g.resources deleted file mode 100644 index da03029f..00000000 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Metro.g.resources and /dev/null differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.i.lref b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.i.lref deleted file mode 100644 index 86b39b7f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.i.lref +++ /dev/null @@ -1,4 +0,0 @@ - - -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\Theme.xaml;; - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.lref b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.lref deleted file mode 100644 index 86b39b7f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Debug/Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.lref +++ /dev/null @@ -1,4 +0,0 @@ - - -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\Theme.xaml;; - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Theme.baml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Theme.baml index f45809ce..7c3c5841 100644 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Theme.baml and b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Theme.baml differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Xceed.Wpf.AvalonDock.Themes.Metro.csproj.FileListAbsolute.txt b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Xceed.Wpf.AvalonDock.Themes.Metro.csproj.FileListAbsolute.txt index e6591c21..0c30339b 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Xceed.Wpf.AvalonDock.Themes.Metro.csproj.FileListAbsolute.txt +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Xceed.Wpf.AvalonDock.Themes.Metro.csproj.FileListAbsolute.txt @@ -1,22 +1,22 @@ -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\Xceed.Wpf.AvalonDock.Themes.Metro.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\Xceed.Wpf.AvalonDock.Themes.Metro.pdb -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\Xceed.Wpf.AvalonDock.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\Xceed.Wpf.AvalonDock.pdb -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\de\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\es\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\fr\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\hu\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\it\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\pt-BR\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\ro\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\ru\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\sv\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\zh-Hans\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Xceed.Wpf.AvalonDock.Themes.Metro.csprojResolveAssemblyReference.cache -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Brushes.baml -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.cache -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.lref -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Theme.baml -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Xceed.Wpf.AvalonDock.Themes.Metro.g.resources -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Xceed.Wpf.AvalonDock.Themes.Metro.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Xceed.Wpf.AvalonDock.Themes.Metro.pdb +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\Xceed.Wpf.AvalonDock.Themes.Metro.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\Xceed.Wpf.AvalonDock.Themes.Metro.pdb +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\Xceed.Wpf.AvalonDock.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\Xceed.Wpf.AvalonDock.pdb +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\de\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\es\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\fr\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\hu\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\it\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\pt-BR\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\ro\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\ru\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\sv\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\bin\Release\zh-Hans\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Xceed.Wpf.AvalonDock.Themes.Metro.csprojResolveAssemblyReference.cache +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Brushes.baml +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.cache +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.lref +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Theme.baml +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Xceed.Wpf.AvalonDock.Themes.Metro.g.resources +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Xceed.Wpf.AvalonDock.Themes.Metro.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\obj\Release\Xceed.Wpf.AvalonDock.Themes.Metro.pdb diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Xceed.Wpf.AvalonDock.Themes.Metro.g.resources b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Xceed.Wpf.AvalonDock.Themes.Metro.g.resources index 62744a87..9f250192 100644 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Xceed.Wpf.AvalonDock.Themes.Metro.g.resources and b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Xceed.Wpf.AvalonDock.Themes.Metro.g.resources differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.i.lref b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.i.lref deleted file mode 100644 index 86b39b7f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.i.lref +++ /dev/null @@ -1,4 +0,0 @@ - - -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\Theme.xaml;; - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.lref b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.lref index 86b39b7f..a99d42b4 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.lref +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/obj/Release/Xceed.Wpf.AvalonDock.Themes.Metro_MarkupCompile.lref @@ -1,4 +1,4 @@  -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\Theme.xaml;; +FD:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.Metro\Theme.xaml;; diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/AssemblyVersionInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/AssemblyVersionInfo.cs index 73fd3191..c6ea985d 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/AssemblyVersionInfo.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/AssemblyVersionInfo.cs @@ -21,7 +21,7 @@ internal static class _XceedVersionInfo { [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string BaseVersion = "3.3"; + public const string BaseVersion = "3.4"; [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] public const string Version = BaseVersion + ".0.0"; diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/Theme.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/Theme.xaml index f06a4ef0..d7d484db 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/Theme.xaml +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/Theme.xaml @@ -1279,8 +1279,9 @@ + - @@ -1303,12 +1303,24 @@ - + + + + - + + + + + + + - + + + + - - - - + - - @@ -2084,7 +2095,8 @@ FontWeight="Bold" Margin="0,3,0,4" > - - + + + + + + diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Brushes.baml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Brushes.baml deleted file mode 100644 index 1cda146e..00000000 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Brushes.baml and /dev/null differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Theme.baml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Theme.baml deleted file mode 100644 index 21afb581..00000000 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Theme.baml and /dev/null differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Xceed.Wpf.AvalonDock.Themes.VS2010.csproj.FileListAbsolute.txt b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Xceed.Wpf.AvalonDock.Themes.VS2010.csproj.FileListAbsolute.txt deleted file mode 100644 index 970ae804..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Xceed.Wpf.AvalonDock.Themes.VS2010.csproj.FileListAbsolute.txt +++ /dev/null @@ -1,22 +0,0 @@ -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Debug\Xceed.Wpf.AvalonDock.Themes.VS2010.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Debug\Xceed.Wpf.AvalonDock.Themes.VS2010.pdb -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Debug\Xceed.Wpf.AvalonDock.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Debug\Xceed.Wpf.AvalonDock.pdb -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Debug\de\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Debug\es\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Debug\fr\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Debug\hu\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Debug\it\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Debug\pt-BR\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Debug\ro\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Debug\ru\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Debug\sv\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Debug\zh-Hans\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Debug\Xceed.Wpf.AvalonDock.Themes.VS2010.csprojResolveAssemblyReference.cache -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Debug\Brushes.baml -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Debug\Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.cache -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Debug\Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.lref -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Debug\Theme.baml -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Debug\Xceed.Wpf.AvalonDock.Themes.VS2010.g.resources -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Debug\Xceed.Wpf.AvalonDock.Themes.VS2010.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Debug\Xceed.Wpf.AvalonDock.Themes.VS2010.pdb diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Xceed.Wpf.AvalonDock.Themes.VS2010.g.resources b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Xceed.Wpf.AvalonDock.Themes.VS2010.g.resources deleted file mode 100644 index f3507144..00000000 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Xceed.Wpf.AvalonDock.Themes.VS2010.g.resources and /dev/null differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.i.lref b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.i.lref deleted file mode 100644 index f4e6c70b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.i.lref +++ /dev/null @@ -1,4 +0,0 @@ - - -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\Theme.xaml;; - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.lref b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.lref deleted file mode 100644 index f4e6c70b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Debug/Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.lref +++ /dev/null @@ -1,4 +0,0 @@ - - -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\Theme.xaml;; - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Theme.baml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Theme.baml index bc6c6783..c7159e9f 100644 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Theme.baml and b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Theme.baml differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Xceed.Wpf.AvalonDock.Themes.VS2010.csproj.FileListAbsolute.txt b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Xceed.Wpf.AvalonDock.Themes.VS2010.csproj.FileListAbsolute.txt index 31cc14f3..1b504512 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Xceed.Wpf.AvalonDock.Themes.VS2010.csproj.FileListAbsolute.txt +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Xceed.Wpf.AvalonDock.Themes.VS2010.csproj.FileListAbsolute.txt @@ -1,22 +1,22 @@ -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\Xceed.Wpf.AvalonDock.Themes.VS2010.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\Xceed.Wpf.AvalonDock.Themes.VS2010.pdb -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\Xceed.Wpf.AvalonDock.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\Xceed.Wpf.AvalonDock.pdb -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\de\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\es\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\fr\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\hu\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\it\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\pt-BR\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\ro\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\ru\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\sv\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\zh-Hans\Xceed.Wpf.AvalonDock.resources.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Xceed.Wpf.AvalonDock.Themes.VS2010.csprojResolveAssemblyReference.cache -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Brushes.baml -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.cache -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.lref -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Theme.baml -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Xceed.Wpf.AvalonDock.Themes.VS2010.g.resources -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Xceed.Wpf.AvalonDock.Themes.VS2010.dll -D:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Xceed.Wpf.AvalonDock.Themes.VS2010.pdb +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\Xceed.Wpf.AvalonDock.Themes.VS2010.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\Xceed.Wpf.AvalonDock.Themes.VS2010.pdb +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\Xceed.Wpf.AvalonDock.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\Xceed.Wpf.AvalonDock.pdb +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\de\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\es\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\fr\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\hu\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\it\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\pt-BR\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\ro\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\ru\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\sv\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\bin\Release\zh-Hans\Xceed.Wpf.AvalonDock.resources.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Xceed.Wpf.AvalonDock.Themes.VS2010.csprojResolveAssemblyReference.cache +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Brushes.baml +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.cache +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.lref +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Theme.baml +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Xceed.Wpf.AvalonDock.Themes.VS2010.g.resources +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Xceed.Wpf.AvalonDock.Themes.VS2010.dll +D:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\obj\Release\Xceed.Wpf.AvalonDock.Themes.VS2010.pdb diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Xceed.Wpf.AvalonDock.Themes.VS2010.g.resources b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Xceed.Wpf.AvalonDock.Themes.VS2010.g.resources index 0962fd37..91044a8c 100644 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Xceed.Wpf.AvalonDock.Themes.VS2010.g.resources and b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Xceed.Wpf.AvalonDock.Themes.VS2010.g.resources differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.i.lref b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.i.lref deleted file mode 100644 index f4e6c70b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.i.lref +++ /dev/null @@ -1,4 +0,0 @@ - - -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\Theme.xaml;; - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.lref b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.lref index f4e6c70b..5885ecd8 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.lref +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/obj/Release/Xceed.Wpf.AvalonDock.Themes.VS2010_MarkupCompile.lref @@ -1,4 +1,4 @@  -FD:\Dev\ExtendedWPFToolkit\Release\3.3.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\Theme.xaml;; +FD:\Dev\ExtendedWPFToolkit\Release\3.4.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock.Themes.VS2010\Theme.xaml;; diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/AssemblyVersionInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/AssemblyVersionInfo.cs index 73fd3191..c6ea985d 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/AssemblyVersionInfo.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/AssemblyVersionInfo.cs @@ -21,7 +21,7 @@ internal static class _XceedVersionInfo { [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string BaseVersion = "3.3"; + public const string BaseVersion = "3.4"; [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] public const string Version = BaseVersion + ".0.0"; diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Commands/RelayCommand.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Commands/RelayCommand.cs index c82ac802..8be365f9 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Commands/RelayCommand.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Commands/RelayCommand.cs @@ -15,57 +15,60 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Input; namespace Xceed.Wpf.AvalonDock.Commands { - internal class RelayCommand : ICommand - { - #region Fields - - readonly Action _execute; - readonly Predicate _canExecute; + internal class RelayCommand : ICommand + { + #region Fields - #endregion // Fields + private readonly Action _execute; + private readonly Predicate _canExecute; - #region Constructors + #endregion // Fields - public RelayCommand(Action execute) - : this(execute, null) - { - } + #region Constructors - public RelayCommand(Action execute, Predicate canExecute) - { - if (execute == null) - throw new ArgumentNullException("execute"); + public RelayCommand( Action execute ) + : this( execute, null ) + { + } - _execute = execute; - _canExecute = canExecute; - } - #endregion // Constructors + public RelayCommand( Action execute, Predicate canExecute ) + { + if( execute == null ) + throw new ArgumentNullException( "execute" ); - #region ICommand Members + _execute = execute; + _canExecute = canExecute; + } + #endregion // Constructors - public bool CanExecute(object parameter) - { - return _canExecute == null ? true : _canExecute(parameter); - } + #region ICommand Members - public event EventHandler CanExecuteChanged - { - add { CommandManager.RequerySuggested += value; } - remove { CommandManager.RequerySuggested -= value; } - } + public bool CanExecute( object parameter ) + { + return _canExecute == null ? true : _canExecute( parameter ); + } - public void Execute(object parameter) - { - _execute(parameter); - } + public event EventHandler CanExecuteChanged + { + add + { + CommandManager.RequerySuggested += value; + } + remove + { + CommandManager.RequerySuggested -= value; + } + } - #endregion // ICommand Members + public void Execute( object parameter ) + { + _execute( parameter ); } + + #endregion // ICommand Members + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneControlOverlayArea.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneControlOverlayArea.cs index 90274cc6..89586bc8 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneControlOverlayArea.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneControlOverlayArea.cs @@ -14,30 +14,33 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; -using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Controls { - public class AnchorablePaneControlOverlayArea : OverlayArea - { - internal AnchorablePaneControlOverlayArea( - IOverlayWindow overlayWindow, - LayoutAnchorablePaneControl anchorablePaneControl) - : base(overlayWindow) - { + public class AnchorablePaneControlOverlayArea : OverlayArea + { + #region Members + + private LayoutAnchorablePaneControl _anchorablePaneControl; + + #endregion - _anchorablePaneControl = anchorablePaneControl; - base.SetScreenDetectionArea(new Rect( - _anchorablePaneControl.PointToScreenDPI(new Point()), - _anchorablePaneControl.TransformActualSizeToAncestor())); + #region constructors - } + internal AnchorablePaneControlOverlayArea( + IOverlayWindow overlayWindow, + LayoutAnchorablePaneControl anchorablePaneControl ) + : base( overlayWindow ) + { + + _anchorablePaneControl = anchorablePaneControl; + base.SetScreenDetectionArea( new Rect( + _anchorablePaneControl.PointToScreenDPI( new Point() ), + _anchorablePaneControl.TransformActualSizeToAncestor() ) ); - LayoutAnchorablePaneControl _anchorablePaneControl; } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneDropTarget.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneDropTarget.cs index a17a47c4..75e83b10 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneDropTarget.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneDropTarget.cs @@ -14,323 +14,330 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows; using System.Windows.Media; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Controls { - internal class AnchorablePaneDropTarget : DropTarget + internal class AnchorablePaneDropTarget : DropTarget + { + #region Members + + private LayoutAnchorablePaneControl _targetPane; + int _tabIndex = -1; + + #endregion + + #region Constructors + + internal AnchorablePaneDropTarget( LayoutAnchorablePaneControl paneControl, Rect detectionRect, DropTargetType type ) + : base( paneControl, detectionRect, type ) { - internal AnchorablePaneDropTarget(LayoutAnchorablePaneControl paneControl, Rect detectionRect, DropTargetType type) - : base(paneControl, detectionRect, type) - { - _targetPane = paneControl; - } + _targetPane = paneControl; + } - internal AnchorablePaneDropTarget(LayoutAnchorablePaneControl paneControl, Rect detectionRect, DropTargetType type, int tabIndex) - : base(paneControl, detectionRect, type) - { - _targetPane = paneControl; - _tabIndex = tabIndex; - } + internal AnchorablePaneDropTarget( LayoutAnchorablePaneControl paneControl, Rect detectionRect, DropTargetType type, int tabIndex ) + : base( paneControl, detectionRect, type ) + { + _targetPane = paneControl; + _tabIndex = tabIndex; + } + #endregion - LayoutAnchorablePaneControl _targetPane; + #region Overrides - int _tabIndex = -1; + protected override void Drop( LayoutAnchorableFloatingWindow floatingWindow ) + { + ILayoutAnchorablePane targetModel = _targetPane.Model as ILayoutAnchorablePane; + LayoutAnchorable anchorableActive = floatingWindow.Descendents().OfType().FirstOrDefault(); + + switch( Type ) + { + case DropTargetType.AnchorablePaneDockBottom: + #region DropTargetType.AnchorablePaneDockBottom + { + var parentModel = targetModel.Parent as ILayoutGroup; + var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup; + int insertToIndex = parentModel.IndexOfChild( targetModel ); + + if( parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Vertical && + parentModel.ChildrenCount == 1 ) + parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Vertical; + + if( parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Vertical ) + { + var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; + if( layoutAnchorablePaneGroup != null && + ( layoutAnchorablePaneGroup.Children.Count == 1 || + layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Vertical ) ) + { + var anchorablesToMove = layoutAnchorablePaneGroup.Children.ToArray(); + for( int i = 0; i < anchorablesToMove.Length; i++ ) + parentModel.InsertChildAt( insertToIndex + 1 + i, anchorablesToMove[ i ] ); + } + else + parentModel.InsertChildAt( insertToIndex + 1, floatingWindow.RootPanel ); + } + else + { + var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement; + var newOrientedPanel = new LayoutAnchorablePaneGroup() + { + Orientation = System.Windows.Controls.Orientation.Vertical, + DockWidth = targetModelAsPositionableElement.DockWidth, + DockHeight = targetModelAsPositionableElement.DockHeight, + }; + + parentModel.InsertChildAt( insertToIndex, newOrientedPanel ); + newOrientedPanel.Children.Add( targetModel ); + newOrientedPanel.Children.Add( floatingWindow.RootPanel ); + + } + } + break; + #endregion + case DropTargetType.AnchorablePaneDockTop: + #region DropTargetType.AnchorablePaneDockTop + { + var parentModel = targetModel.Parent as ILayoutGroup; + var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup; + int insertToIndex = parentModel.IndexOfChild( targetModel ); + + if( parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Vertical && + parentModel.ChildrenCount == 1 ) + parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Vertical; + + if( parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Vertical ) + { + var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; + if( layoutAnchorablePaneGroup != null && + ( layoutAnchorablePaneGroup.Children.Count == 1 || + layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Vertical ) ) + { + var anchorablesToMove = layoutAnchorablePaneGroup.Children.ToArray(); + for( int i = 0; i < anchorablesToMove.Length; i++ ) + parentModel.InsertChildAt( insertToIndex + i, anchorablesToMove[ i ] ); + } + else + parentModel.InsertChildAt( insertToIndex, floatingWindow.RootPanel ); + } + else + { + var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement; + var newOrientedPanel = new LayoutAnchorablePaneGroup() + { + Orientation = System.Windows.Controls.Orientation.Vertical, + DockWidth = targetModelAsPositionableElement.DockWidth, + DockHeight = targetModelAsPositionableElement.DockHeight, + }; + + parentModel.InsertChildAt( insertToIndex, newOrientedPanel ); + //the floating window must be added after the target modal as it could be raise a CollectGarbage call + newOrientedPanel.Children.Add( targetModel ); + newOrientedPanel.Children.Insert( 0, floatingWindow.RootPanel ); - protected override void Drop(LayoutAnchorableFloatingWindow floatingWindow) - { - ILayoutAnchorablePane targetModel = _targetPane.Model as ILayoutAnchorablePane; - LayoutAnchorable anchorableActive = floatingWindow.Descendents().OfType().FirstOrDefault(); + } + } + break; + #endregion + case DropTargetType.AnchorablePaneDockLeft: + #region DropTargetType.AnchorablePaneDockLeft + { + var parentModel = targetModel.Parent as ILayoutGroup; + var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup; + int insertToIndex = parentModel.IndexOfChild( targetModel ); + + if( parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Horizontal && + parentModel.ChildrenCount == 1 ) + parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Horizontal; + + if( parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Horizontal ) + { + var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; + if( layoutAnchorablePaneGroup != null && + ( layoutAnchorablePaneGroup.Children.Count == 1 || + layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Horizontal ) ) + { + var anchorablesToMove = layoutAnchorablePaneGroup.Children.ToArray(); + for( int i = 0; i < anchorablesToMove.Length; i++ ) + parentModel.InsertChildAt( insertToIndex + i, anchorablesToMove[ i ] ); + } + else + parentModel.InsertChildAt( insertToIndex, floatingWindow.RootPanel ); + } + else + { + var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement; + var newOrientedPanel = new LayoutAnchorablePaneGroup() + { + Orientation = System.Windows.Controls.Orientation.Horizontal, + DockWidth = targetModelAsPositionableElement.DockWidth, + DockHeight = targetModelAsPositionableElement.DockHeight, + }; + + parentModel.InsertChildAt( insertToIndex, newOrientedPanel ); + //the floating window must be added after the target modal as it could be raise a CollectGarbage call + newOrientedPanel.Children.Add( targetModel ); + newOrientedPanel.Children.Insert( 0, floatingWindow.RootPanel ); - switch (Type) + } + } + break; + #endregion + case DropTargetType.AnchorablePaneDockRight: + #region DropTargetType.AnchorablePaneDockRight + { + var parentModel = targetModel.Parent as ILayoutGroup; + var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup; + int insertToIndex = parentModel.IndexOfChild( targetModel ); + + if( parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Horizontal && + parentModel.ChildrenCount == 1 ) + parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Horizontal; + + if( parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Horizontal ) { - case DropTargetType.AnchorablePaneDockBottom: - #region DropTargetType.AnchorablePaneDockBottom - { - var parentModel = targetModel.Parent as ILayoutGroup; - var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup; - int insertToIndex = parentModel.IndexOfChild(targetModel); - - if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Vertical && - parentModel.ChildrenCount == 1) - parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Vertical; - - if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Vertical) - { - var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; - if (layoutAnchorablePaneGroup != null && - (layoutAnchorablePaneGroup.Children.Count == 1 || - layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Vertical)) - { - var anchorablesToMove = layoutAnchorablePaneGroup.Children.ToArray(); - for (int i = 0; i < anchorablesToMove.Length; i++) - parentModel.InsertChildAt(insertToIndex + 1 + i, anchorablesToMove[i]); - } - else - parentModel.InsertChildAt(insertToIndex + 1, floatingWindow.RootPanel); - } - else - { - var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement; - var newOrientedPanel = new LayoutAnchorablePaneGroup() - { - Orientation = System.Windows.Controls.Orientation.Vertical, - DockWidth = targetModelAsPositionableElement.DockWidth, - DockHeight = targetModelAsPositionableElement.DockHeight, - }; - - parentModel.InsertChildAt(insertToIndex, newOrientedPanel); - newOrientedPanel.Children.Add(targetModel); - newOrientedPanel.Children.Add(floatingWindow.RootPanel); - - } - } - break; - #endregion - case DropTargetType.AnchorablePaneDockTop: - #region DropTargetType.AnchorablePaneDockTop - { - var parentModel = targetModel.Parent as ILayoutGroup; - var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup; - int insertToIndex = parentModel.IndexOfChild(targetModel); - - if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Vertical && - parentModel.ChildrenCount == 1) - parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Vertical; - - if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Vertical) - { - var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; - if (layoutAnchorablePaneGroup != null && - (layoutAnchorablePaneGroup.Children.Count == 1 || - layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Vertical)) - { - var anchorablesToMove = layoutAnchorablePaneGroup.Children.ToArray(); - for (int i = 0; i < anchorablesToMove.Length; i++) - parentModel.InsertChildAt(insertToIndex + i, anchorablesToMove[i]); - } - else - parentModel.InsertChildAt(insertToIndex, floatingWindow.RootPanel); - } - else - { - var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement; - var newOrientedPanel = new LayoutAnchorablePaneGroup() - { - Orientation = System.Windows.Controls.Orientation.Vertical, - DockWidth = targetModelAsPositionableElement.DockWidth, - DockHeight = targetModelAsPositionableElement.DockHeight, - }; - - parentModel.InsertChildAt(insertToIndex, newOrientedPanel); - //the floating window must be added after the target modal as it could be raise a CollectGarbage call - newOrientedPanel.Children.Add(targetModel); - newOrientedPanel.Children.Insert(0, floatingWindow.RootPanel); - - } - } - break; - #endregion - case DropTargetType.AnchorablePaneDockLeft: - #region DropTargetType.AnchorablePaneDockLeft - { - var parentModel = targetModel.Parent as ILayoutGroup; - var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup; - int insertToIndex = parentModel.IndexOfChild(targetModel); - - if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Horizontal && - parentModel.ChildrenCount == 1) - parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Horizontal; - - if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Horizontal) - { - var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; - if (layoutAnchorablePaneGroup != null && - (layoutAnchorablePaneGroup.Children.Count == 1 || - layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Horizontal)) - { - var anchorablesToMove = layoutAnchorablePaneGroup.Children.ToArray(); - for (int i = 0; i < anchorablesToMove.Length; i++) - parentModel.InsertChildAt(insertToIndex + i, anchorablesToMove[i]); - } - else - parentModel.InsertChildAt(insertToIndex, floatingWindow.RootPanel); - } - else - { - var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement; - var newOrientedPanel = new LayoutAnchorablePaneGroup() - { - Orientation = System.Windows.Controls.Orientation.Horizontal, - DockWidth = targetModelAsPositionableElement.DockWidth, - DockHeight = targetModelAsPositionableElement.DockHeight, - }; - - parentModel.InsertChildAt(insertToIndex, newOrientedPanel); - //the floating window must be added after the target modal as it could be raise a CollectGarbage call - newOrientedPanel.Children.Add(targetModel); - newOrientedPanel.Children.Insert(0, floatingWindow.RootPanel); - - } - } - break; - #endregion - case DropTargetType.AnchorablePaneDockRight: - #region DropTargetType.AnchorablePaneDockRight - { - var parentModel = targetModel.Parent as ILayoutGroup; - var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup; - int insertToIndex = parentModel.IndexOfChild(targetModel); - - if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Horizontal && - parentModel.ChildrenCount == 1) - parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Horizontal; - - if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Horizontal) - { - var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; - if (layoutAnchorablePaneGroup != null && - (layoutAnchorablePaneGroup.Children.Count == 1 || - layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Horizontal)) - { - var anchorablesToMove = layoutAnchorablePaneGroup.Children.ToArray(); - for (int i = 0; i < anchorablesToMove.Length; i++) - parentModel.InsertChildAt(insertToIndex + 1 + i, anchorablesToMove[i]); - } - else - parentModel.InsertChildAt(insertToIndex + 1, floatingWindow.RootPanel); - } - else - { - var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement; - var newOrientedPanel = new LayoutAnchorablePaneGroup() - { - Orientation = System.Windows.Controls.Orientation.Horizontal, - DockWidth = targetModelAsPositionableElement.DockWidth, - DockHeight = targetModelAsPositionableElement.DockHeight, - }; - - parentModel.InsertChildAt(insertToIndex, newOrientedPanel); - newOrientedPanel.Children.Add(targetModel); - newOrientedPanel.Children.Add(floatingWindow.RootPanel); - - } - } - break; - #endregion - - - case DropTargetType.AnchorablePaneDockInside: - #region DropTargetType.AnchorablePaneDockInside - { - var paneModel = targetModel as LayoutAnchorablePane; - var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; - - int i = _tabIndex == -1 ? 0 : _tabIndex; - foreach (var anchorableToImport in - layoutAnchorablePaneGroup.Descendents().OfType().ToArray()) - { - paneModel.Children.Insert(i, anchorableToImport); - i++; - } - - } - break; - #endregion + var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; + if( layoutAnchorablePaneGroup != null && + ( layoutAnchorablePaneGroup.Children.Count == 1 || + layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Horizontal ) ) + { + var anchorablesToMove = layoutAnchorablePaneGroup.Children.ToArray(); + for( int i = 0; i < anchorablesToMove.Length; i++ ) + parentModel.InsertChildAt( insertToIndex + 1 + i, anchorablesToMove[ i ] ); + } + else + parentModel.InsertChildAt( insertToIndex + 1, floatingWindow.RootPanel ); + } + else + { + var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement; + var newOrientedPanel = new LayoutAnchorablePaneGroup() + { + Orientation = System.Windows.Controls.Orientation.Horizontal, + DockWidth = targetModelAsPositionableElement.DockWidth, + DockHeight = targetModelAsPositionableElement.DockHeight, + }; + + parentModel.InsertChildAt( insertToIndex, newOrientedPanel ); + newOrientedPanel.Children.Add( targetModel ); + newOrientedPanel.Children.Add( floatingWindow.RootPanel ); + + } + } + break; + #endregion + + case DropTargetType.AnchorablePaneDockInside: + #region DropTargetType.AnchorablePaneDockInside + { + var paneModel = targetModel as LayoutAnchorablePane; + var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; + int i = _tabIndex == -1 ? 0 : _tabIndex; + foreach( var anchorableToImport in + layoutAnchorablePaneGroup.Descendents().OfType().ToArray() ) + { + paneModel.Children.Insert( i, anchorableToImport ); + i++; } - anchorableActive.IsActive = true; + } + break; + #endregion + - base.Drop(floatingWindow); - } + } - public override System.Windows.Media.Geometry GetPreviewPath(OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindowModel) - { - //var anchorablePaneDropTarget = target as AnchorablePaneDropTarget; - var anchorableFloatingWindowModel = floatingWindowModel as LayoutAnchorableFloatingWindow; - var layoutAnchorablePane = anchorableFloatingWindowModel.RootPanel as ILayoutPositionableElement; - var layoutAnchorablePaneWithActualSize = anchorableFloatingWindowModel.RootPanel as ILayoutPositionableElementWithActualSize; + anchorableActive.IsActive = true; + + base.Drop( floatingWindow ); + } - switch (Type) + public override System.Windows.Media.Geometry GetPreviewPath( OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindowModel ) + { + //var anchorablePaneDropTarget = target as AnchorablePaneDropTarget; + var anchorableFloatingWindowModel = floatingWindowModel as LayoutAnchorableFloatingWindow; + var layoutAnchorablePane = anchorableFloatingWindowModel.RootPanel as ILayoutPositionableElement; + var layoutAnchorablePaneWithActualSize = anchorableFloatingWindowModel.RootPanel as ILayoutPositionableElementWithActualSize; + + switch( Type ) + { + case DropTargetType.AnchorablePaneDockBottom: + { + var targetScreenRect = TargetElement.GetScreenArea(); + targetScreenRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + + targetScreenRect.Offset( 0.0, targetScreenRect.Height / 2.0 ); + targetScreenRect.Height /= 2.0; + + return new RectangleGeometry( targetScreenRect ); + } + case DropTargetType.AnchorablePaneDockTop: + { + var targetScreenRect = TargetElement.GetScreenArea(); + targetScreenRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + + targetScreenRect.Height /= 2.0; + + return new RectangleGeometry( targetScreenRect ); + } + case DropTargetType.AnchorablePaneDockLeft: + { + var targetScreenRect = TargetElement.GetScreenArea(); + targetScreenRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + + targetScreenRect.Width /= 2.0; + + return new RectangleGeometry( targetScreenRect ); + } + case DropTargetType.AnchorablePaneDockRight: + { + var targetScreenRect = TargetElement.GetScreenArea(); + targetScreenRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + + targetScreenRect.Offset( targetScreenRect.Width / 2.0, 0.0 ); + targetScreenRect.Width /= 2.0; + + return new RectangleGeometry( targetScreenRect ); + } + case DropTargetType.AnchorablePaneDockInside: + { + var targetScreenRect = TargetElement.GetScreenArea(); + targetScreenRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + + if( _tabIndex == -1 ) + { + return new RectangleGeometry( targetScreenRect ); + } + else { - case DropTargetType.AnchorablePaneDockBottom: - { - var targetScreenRect = TargetElement.GetScreenArea(); - targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - - targetScreenRect.Offset(0.0, targetScreenRect.Height / 2.0); - targetScreenRect.Height /= 2.0; - - return new RectangleGeometry(targetScreenRect); - } - case DropTargetType.AnchorablePaneDockTop: - { - var targetScreenRect = TargetElement.GetScreenArea(); - targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - - targetScreenRect.Height /= 2.0; - - return new RectangleGeometry(targetScreenRect); - } - case DropTargetType.AnchorablePaneDockLeft: - { - var targetScreenRect = TargetElement.GetScreenArea(); - targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - - targetScreenRect.Width /= 2.0; - - return new RectangleGeometry(targetScreenRect); - } - case DropTargetType.AnchorablePaneDockRight: - { - var targetScreenRect = TargetElement.GetScreenArea(); - targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - - targetScreenRect.Offset(targetScreenRect.Width / 2.0, 0.0); - targetScreenRect.Width /= 2.0; - - return new RectangleGeometry(targetScreenRect); - } - case DropTargetType.AnchorablePaneDockInside: - { - var targetScreenRect = TargetElement.GetScreenArea(); - targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - - if (_tabIndex == -1) - { - return new RectangleGeometry(targetScreenRect); - } - else - { - var translatedDetectionRect = new Rect(DetectionRects[0].TopLeft, DetectionRects[0].BottomRight); - translatedDetectionRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - var pathFigure = new PathFigure(); - pathFigure.StartPoint = targetScreenRect.TopLeft; - pathFigure.Segments.Add(new LineSegment() { Point = new Point(targetScreenRect.Left, translatedDetectionRect.Top) }); - pathFigure.Segments.Add(new LineSegment() { Point = translatedDetectionRect.TopLeft }); - pathFigure.Segments.Add(new LineSegment() { Point = translatedDetectionRect.BottomLeft }); - pathFigure.Segments.Add(new LineSegment() { Point = translatedDetectionRect.BottomRight }); - pathFigure.Segments.Add(new LineSegment() { Point = translatedDetectionRect.TopRight }); - pathFigure.Segments.Add(new LineSegment() { Point = new Point(targetScreenRect.Right, translatedDetectionRect.Top) }); - pathFigure.Segments.Add(new LineSegment() { Point = targetScreenRect.TopRight }); - pathFigure.IsClosed = true; - pathFigure.IsFilled = true; - pathFigure.Freeze(); - return new PathGeometry(new PathFigure[] { pathFigure }); - } - } + var translatedDetectionRect = new Rect( DetectionRects[ 0 ].TopLeft, DetectionRects[ 0 ].BottomRight ); + translatedDetectionRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + var pathFigure = new PathFigure(); + pathFigure.StartPoint = targetScreenRect.TopLeft; + pathFigure.Segments.Add( new LineSegment() { Point = new Point( targetScreenRect.Left, translatedDetectionRect.Top ) } ); + pathFigure.Segments.Add( new LineSegment() { Point = translatedDetectionRect.TopLeft } ); + pathFigure.Segments.Add( new LineSegment() { Point = translatedDetectionRect.BottomLeft } ); + pathFigure.Segments.Add( new LineSegment() { Point = translatedDetectionRect.BottomRight } ); + pathFigure.Segments.Add( new LineSegment() { Point = translatedDetectionRect.TopRight } ); + pathFigure.Segments.Add( new LineSegment() { Point = new Point( targetScreenRect.Right, translatedDetectionRect.Top ) } ); + pathFigure.Segments.Add( new LineSegment() { Point = targetScreenRect.TopRight } ); + pathFigure.IsClosed = true; + pathFigure.IsFilled = true; + pathFigure.Freeze(); + return new PathGeometry( new PathFigure[] { pathFigure } ); } + } + } - return null; - } + return null; } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneTabPanel.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneTabPanel.cs index c4c4787e..00ee5fff 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneTabPanel.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneTabPanel.cs @@ -15,93 +15,98 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows.Controls; using System.Windows; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Controls { - public class AnchorablePaneTabPanel : Panel + public class AnchorablePaneTabPanel : Panel + { + #region Constructors + + public AnchorablePaneTabPanel() + { + this.FlowDirection = System.Windows.FlowDirection.LeftToRight; + } + + #endregion + + #region Overrides + + protected override Size MeasureOverride( Size availableSize ) { - public AnchorablePaneTabPanel() + double totWidth = 0; + double maxHeight = 0; + var visibleChildren = Children.Cast().Where( ch => ch.Visibility != System.Windows.Visibility.Collapsed ); + foreach( FrameworkElement child in visibleChildren ) + { + child.Measure( new Size( double.PositiveInfinity, availableSize.Height ) ); + totWidth += child.DesiredSize.Width; + maxHeight = Math.Max( maxHeight, child.DesiredSize.Height ); + } + + if( totWidth > availableSize.Width ) + { + double childFinalDesideredWidth = availableSize.Width / visibleChildren.Count(); + foreach( FrameworkElement child in visibleChildren ) { - FlowDirection = System.Windows.FlowDirection.LeftToRight; + child.Measure( new Size( childFinalDesideredWidth, availableSize.Height ) ); } + } + + return new Size( Math.Min( availableSize.Width, totWidth ), maxHeight ); + } + + protected override Size ArrangeOverride( Size finalSize ) + { + var visibleChildren = Children.Cast().Where( ch => ch.Visibility != System.Windows.Visibility.Collapsed ); - protected override Size MeasureOverride(Size availableSize) + double finalWidth = finalSize.Width; + double desideredWidth = visibleChildren.Sum( ch => ch.DesiredSize.Width ); + double offsetX = 0.0; + + if( finalWidth > desideredWidth ) + { + foreach( FrameworkElement child in visibleChildren ) { - double totWidth = 0; - double maxHeight = 0; - var visibleChildren = Children.Cast().Where(ch => ch.Visibility != System.Windows.Visibility.Collapsed); - foreach (FrameworkElement child in visibleChildren) - { - child.Measure(new Size(double.PositiveInfinity, availableSize.Height)); - totWidth += child.DesiredSize.Width; - maxHeight = Math.Max(maxHeight, child.DesiredSize.Height); - } - - if (totWidth > availableSize.Width) - { - double childFinalDesideredWidth = availableSize.Width / visibleChildren.Count(); - foreach (FrameworkElement child in visibleChildren) - { - child.Measure(new Size(childFinalDesideredWidth, availableSize.Height)); - } - } - - return new Size(Math.Min(availableSize.Width, totWidth), maxHeight); - } + double childFinalWidth = child.DesiredSize.Width; + child.Arrange( new Rect( offsetX, 0, childFinalWidth, finalSize.Height ) ); - protected override Size ArrangeOverride(Size finalSize) + offsetX += childFinalWidth; + } + } + else + { + double childFinalWidth = finalWidth / visibleChildren.Count(); + foreach( FrameworkElement child in visibleChildren ) { - var visibleChildren = Children.Cast().Where(ch => ch.Visibility != System.Windows.Visibility.Collapsed); - - - double finalWidth = finalSize.Width; - double desideredWidth = visibleChildren.Sum(ch => ch.DesiredSize.Width); - double offsetX = 0.0; - - if (finalWidth > desideredWidth) - { - foreach (FrameworkElement child in visibleChildren) - { - double childFinalWidth = child.DesiredSize.Width ; - child.Arrange(new Rect(offsetX, 0, childFinalWidth, finalSize.Height)); - - offsetX += childFinalWidth; - } - } - else - { - double childFinalWidth = finalWidth / visibleChildren.Count(); - foreach (FrameworkElement child in visibleChildren) - { - child.Arrange(new Rect(offsetX, 0, childFinalWidth, finalSize.Height)); - - offsetX += childFinalWidth; - } - } - - return finalSize; + child.Arrange( new Rect( offsetX, 0, childFinalWidth, finalSize.Height ) ); + + offsetX += childFinalWidth; } + } - protected override void OnMouseLeave(System.Windows.Input.MouseEventArgs e) - { - if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed && - LayoutAnchorableTabItem.IsDraggingItem()) - { - var contentModel = LayoutAnchorableTabItem.GetDraggingItem().Model as LayoutAnchorable; - var manager = contentModel.Root.Manager; - LayoutAnchorableTabItem.ResetDraggingItem(); + return finalSize; + } - manager.StartDraggingFloatingWindowForContent(contentModel); - } + protected override void OnMouseLeave( System.Windows.Input.MouseEventArgs e ) + { + if( e.LeftButton == System.Windows.Input.MouseButtonState.Pressed && + LayoutAnchorableTabItem.IsDraggingItem() ) + { + var contentModel = LayoutAnchorableTabItem.GetDraggingItem().Model as LayoutAnchorable; + var manager = contentModel.Root.Manager; + LayoutAnchorableTabItem.ResetDraggingItem(); - base.OnMouseLeave(e); - } + manager.StartDraggingFloatingWindowForContent( contentModel ); + } + + base.OnMouseLeave( e ); } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneTitle.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneTitle.cs index bf11271b..a4c5c481 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneTitle.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AnchorablePaneTitle.cs @@ -14,10 +14,7 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows.Controls; using System.Windows; using System.Windows.Input; @@ -25,165 +22,191 @@ using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Controls { + public class AnchorablePaneTitle : Control + { + #region Members - public class AnchorablePaneTitle : Control + private bool _isMouseDown = false; + + #endregion + + #region Constructors + + static AnchorablePaneTitle() { - static AnchorablePaneTitle() - { - IsHitTestVisibleProperty.OverrideMetadata(typeof(AnchorablePaneTitle), new FrameworkPropertyMetadata(true)); - FocusableProperty.OverrideMetadata(typeof(AnchorablePaneTitle), new FrameworkPropertyMetadata(false)); - DefaultStyleKeyProperty.OverrideMetadata(typeof(AnchorablePaneTitle), new FrameworkPropertyMetadata(typeof(AnchorablePaneTitle))); - } + IsHitTestVisibleProperty.OverrideMetadata( typeof( AnchorablePaneTitle ), new FrameworkPropertyMetadata( true ) ); + FocusableProperty.OverrideMetadata( typeof( AnchorablePaneTitle ), new FrameworkPropertyMetadata( false ) ); + DefaultStyleKeyProperty.OverrideMetadata( typeof( AnchorablePaneTitle ), new FrameworkPropertyMetadata( typeof( AnchorablePaneTitle ) ) ); + } + public AnchorablePaneTitle() + { + } - public AnchorablePaneTitle() - { + #endregion - } + #region Properties - #region Model + #region Model - /// - /// Model Dependency Property - /// - public static readonly DependencyProperty ModelProperty = - DependencyProperty.Register("Model", typeof(LayoutAnchorable), typeof(AnchorablePaneTitle), - new FrameworkPropertyMetadata((LayoutAnchorable)null, new PropertyChangedCallback(_OnModelChanged))); + /// + /// Model Dependency Property + /// + public static readonly DependencyProperty ModelProperty = DependencyProperty.Register( "Model", typeof( LayoutAnchorable ), typeof( AnchorablePaneTitle ), + new FrameworkPropertyMetadata( ( LayoutAnchorable )null, new PropertyChangedCallback( _OnModelChanged ) ) ); - /// - /// Gets or sets the Model property. This dependency property - /// indicates model attached to this view. - /// - public LayoutAnchorable Model - { - get { return (LayoutAnchorable)GetValue(ModelProperty); } - set { SetValue(ModelProperty, value); } - } + /// + /// Gets or sets the Model property. This dependency property + /// indicates model attached to this view. + /// + public LayoutAnchorable Model + { + get + { + return ( LayoutAnchorable )GetValue( ModelProperty ); + } + set + { + SetValue( ModelProperty, value ); + } + } - static void _OnModelChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) - { - ((AnchorablePaneTitle)sender).OnModelChanged(e); - } + private static void _OnModelChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) + { + ( ( AnchorablePaneTitle )sender ).OnModelChanged( e ); + } - /// - /// Provides derived classes an opportunity to handle changes to the Model property. - /// - protected virtual void OnModelChanged(DependencyPropertyChangedEventArgs e) - { - if (Model != null) - SetLayoutItem(Model.Root.Manager.GetLayoutItemFromModel(Model)); - else - SetLayoutItem(null); - } + /// + /// Provides derived classes an opportunity to handle changes to the Model property. + /// + protected virtual void OnModelChanged( DependencyPropertyChangedEventArgs e ) + { + if( Model != null ) + { + this.SetLayoutItem( Model.Root.Manager.GetLayoutItemFromModel( Model ) ); + } + else + { + this.SetLayoutItem( null ); + } + } - #endregion + #endregion + #region LayoutItem - #region LayoutItem + /// + /// LayoutItem Read-Only Dependency Property + /// + private static readonly DependencyPropertyKey LayoutItemPropertyKey = DependencyProperty.RegisterReadOnly( "LayoutItem", typeof( LayoutItem ), typeof( AnchorablePaneTitle ), + new FrameworkPropertyMetadata( ( LayoutItem )null ) ); - /// - /// LayoutItem Read-Only Dependency Property - /// - private static readonly DependencyPropertyKey LayoutItemPropertyKey - = DependencyProperty.RegisterReadOnly("LayoutItem", typeof(LayoutItem), typeof(AnchorablePaneTitle), - new FrameworkPropertyMetadata((LayoutItem)null)); + public static readonly DependencyProperty LayoutItemProperty = LayoutItemPropertyKey.DependencyProperty; - public static readonly DependencyProperty LayoutItemProperty - = LayoutItemPropertyKey.DependencyProperty; + /// + /// Gets the LayoutItem property. This dependency property + /// indicates the LayoutItem attached to this tag item. + /// + public LayoutItem LayoutItem + { + get + { + return ( LayoutItem )GetValue( LayoutItemProperty ); + } + } - /// - /// Gets the LayoutItem property. This dependency property - /// indicates the LayoutItem attached to this tag item. - /// - public LayoutItem LayoutItem - { - get { return (LayoutItem)GetValue(LayoutItemProperty); } - } + /// + /// Provides a secure method for setting the LayoutItem property. + /// This dependency property indicates the LayoutItem attached to this tag item. + /// + /// The new value for the property. + protected void SetLayoutItem( LayoutItem value ) + { + this.SetValue( LayoutItemPropertyKey, value ); + } - /// - /// Provides a secure method for setting the LayoutItem property. - /// This dependency property indicates the LayoutItem attached to this tag item. - /// - /// The new value for the property. - protected void SetLayoutItem(LayoutItem value) - { - SetValue(LayoutItemPropertyKey, value); - } + #endregion - #endregion + #endregion + #region Overrides - private void OnHide() - { - Model.Hide(); - } + protected override void OnMouseMove( System.Windows.Input.MouseEventArgs e ) + { + if( e.LeftButton != MouseButtonState.Pressed ) + { + _isMouseDown = false; + } - private void OnToggleAutoHide() - { - Model.ToggleAutoHide(); - } + base.OnMouseMove( e ); + } - protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e) + protected override void OnMouseLeave( System.Windows.Input.MouseEventArgs e ) + { + base.OnMouseLeave( e ); + + if( _isMouseDown && e.LeftButton == MouseButtonState.Pressed ) + { + var pane = this.FindVisualAncestor(); + if( pane != null ) { - if (e.LeftButton != MouseButtonState.Pressed) - { - _isMouseDown = false; - } + var paneModel = pane.Model as LayoutAnchorablePane; + var manager = paneModel.Root.Manager; - base.OnMouseMove(e); + manager.StartDraggingFloatingWindowForPane( paneModel ); } + } - protected override void OnMouseLeave(System.Windows.Input.MouseEventArgs e) - { - base.OnMouseLeave(e); - - if (_isMouseDown && e.LeftButton == MouseButtonState.Pressed) - { - var pane = this.FindVisualAncestor(); - if (pane != null) - { - var paneModel = pane.Model as LayoutAnchorablePane; - var manager = paneModel.Root.Manager; + _isMouseDown = false; + } - manager.StartDraggingFloatingWindowForPane(paneModel); - } - } + protected override void OnMouseLeftButtonDown( System.Windows.Input.MouseButtonEventArgs e ) + { + base.OnMouseLeftButtonDown( e ); - _isMouseDown = false; + if( !e.Handled ) + { + bool attachFloatingWindow = false; + var parentFloatingWindow = Model.FindParent(); + if( parentFloatingWindow != null ) + { + attachFloatingWindow = parentFloatingWindow.Descendents().OfType().Count() == 1; } - bool _isMouseDown = false; - protected override void OnMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e) + if( attachFloatingWindow ) { - base.OnMouseLeftButtonDown(e); - - if (!e.Handled) - { - bool attachFloatingWindow = false; - var parentFloatingWindow = Model.FindParent(); - if (parentFloatingWindow != null) - { - attachFloatingWindow = parentFloatingWindow.Descendents().OfType().Count() == 1; - } - - if (attachFloatingWindow) - { - //the pane is hosted inside a floating window that contains only an anchorable pane so drag the floating window itself - var floatingWndControl = Model.Root.Manager.FloatingWindows.Single(fwc => fwc.Model == parentFloatingWindow); - floatingWndControl.AttachDrag(false); - } - else - _isMouseDown = true;//normal drag - } + //the pane is hosted inside a floating window that contains only an anchorable pane so drag the floating window itself + var floatingWndControl = Model.Root.Manager.FloatingWindows.Single( fwc => fwc.Model == parentFloatingWindow ); + floatingWndControl.AttachDrag( false ); } + else + _isMouseDown = true;//normal drag + } + } - protected override void OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e) - { - _isMouseDown = false; - base.OnMouseLeftButtonUp(e); + protected override void OnMouseLeftButtonUp( System.Windows.Input.MouseButtonEventArgs e ) + { + _isMouseDown = false; + base.OnMouseLeftButtonUp( e ); - if (Model != null) - Model.IsActive = true;//FocusElementManager.SetFocusOnLastElement(Model); - } + if( Model != null ) + Model.IsActive = true;//FocusElementManager.SetFocusOnLastElement(Model); } + + #endregion + + #region Private Methods + + private void OnHide() + { + this.Model.Hide(); + } + + private void OnToggleAutoHide() + { + this.Model.ToggleAutoHide(); + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AutoHideWindowManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AutoHideWindowManager.cs index 30618533..33260c23 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AutoHideWindowManager.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AutoHideWindowManager.cs @@ -15,76 +15,82 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Threading; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Controls { - class AutoHideWindowManager + internal class AutoHideWindowManager + { + #region Members + + private DockingManager _manager; + private WeakReference _currentAutohiddenAnchor = null; + private DispatcherTimer _closeTimer = null; + + #endregion + + #region Constructors + + internal AutoHideWindowManager( DockingManager manager ) + { + _manager = manager; + this.SetupCloseTimer(); + } + + #endregion + + #region Private Methods + + public void ShowAutoHideWindow( LayoutAnchorControl anchor ) + { + if( _currentAutohiddenAnchor.GetValueOrDefault() != anchor ) + { + StopCloseTimer(); + _currentAutohiddenAnchor = new WeakReference( anchor ); + _manager.AutoHideWindow.Show( anchor ); + StartCloseTimer(); + } + } + + public void HideAutoWindow( LayoutAnchorControl anchor = null ) + { + if( anchor == null || + anchor == _currentAutohiddenAnchor.GetValueOrDefault() ) + { + StopCloseTimer(); + } + else + System.Diagnostics.Debug.Assert( false ); + } + + private void SetupCloseTimer() { - DockingManager _manager; - - internal AutoHideWindowManager(DockingManager manager) - { - _manager = manager; - SetupCloseTimer(); - } - - - WeakReference _currentAutohiddenAnchor = null; - - public void ShowAutoHideWindow(LayoutAnchorControl anchor) - { - if( _currentAutohiddenAnchor.GetValueOrDefault() != anchor ) - { - StopCloseTimer(); - _currentAutohiddenAnchor = new WeakReference( anchor ); - _manager.AutoHideWindow.Show( anchor ); - StartCloseTimer(); - } - } - - public void HideAutoWindow(LayoutAnchorControl anchor = null) - { - if (anchor == null || - anchor == _currentAutohiddenAnchor.GetValueOrDefault()) - { - StopCloseTimer(); - } - else - System.Diagnostics.Debug.Assert(false); - } - - DispatcherTimer _closeTimer = null; - void SetupCloseTimer() - { - _closeTimer = new DispatcherTimer(DispatcherPriority.Background); - _closeTimer.Interval = TimeSpan.FromMilliseconds(1500); - _closeTimer.Tick += (s, e) => - { - if (_manager.AutoHideWindow.IsWin32MouseOver || - ((LayoutAnchorable)_manager.AutoHideWindow.Model).IsActive || - _manager.AutoHideWindow.IsResizing) - return; - - StopCloseTimer(); - }; - } - - void StartCloseTimer() - { - _closeTimer.Start(); - - } - - void StopCloseTimer() - { - _closeTimer.Stop(); - _manager.AutoHideWindow.Hide(); - _currentAutohiddenAnchor = null; - } + _closeTimer = new DispatcherTimer( DispatcherPriority.Background ); + _closeTimer.Interval = TimeSpan.FromMilliseconds( 1500 ); + _closeTimer.Tick += ( s, e ) => + { + if( _manager.AutoHideWindow.IsWin32MouseOver || + ( ( LayoutAnchorable )_manager.AutoHideWindow.Model ).IsActive || + _manager.AutoHideWindow.IsResizing ) + return; + + StopCloseTimer(); + }; } + + private void StartCloseTimer() + { + _closeTimer.Start(); + } + + private void StopCloseTimer() + { + _closeTimer.Stop(); + _manager.AutoHideWindow.Hide(); + _currentAutohiddenAnchor = null; + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/BindingHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/BindingHelper.cs index e04049e1..b31b35b7 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/BindingHelper.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/BindingHelper.cs @@ -15,9 +15,6 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; using System.ComponentModel; using System.Windows.Data; @@ -25,31 +22,35 @@ using System.Windows.Threading; namespace Xceed.Wpf.AvalonDock.Controls { - class BindingHelper + internal class BindingHelper + { + #region Methods + + public static void RebindInactiveBindings( DependencyObject dependencyObject ) { - public static void RebindInactiveBindings(DependencyObject dependencyObject) + foreach( PropertyDescriptor property in TypeDescriptor.GetProperties( dependencyObject.GetType() ) ) + { + var dpd = DependencyPropertyDescriptor.FromProperty( property ); + if( dpd != null ) { - foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(dependencyObject.GetType())) + BindingExpressionBase binding = BindingOperations.GetBindingExpressionBase( dependencyObject, dpd.DependencyProperty ); + if( binding != null ) + { + //if (property.Name == "DataContext" || binding.HasError || binding.Status != BindingStatus.Active) { - var dpd = DependencyPropertyDescriptor.FromProperty(property); - if (dpd != null) - { - BindingExpressionBase binding = BindingOperations.GetBindingExpressionBase(dependencyObject, dpd.DependencyProperty); - if (binding != null) - { - //if (property.Name == "DataContext" || binding.HasError || binding.Status != BindingStatus.Active) - { - // Ensure that no pending calls are in the dispatcher queue - Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.SystemIdle, (Action)delegate - { - // Remove and add the binding to re-trigger the binding error - dependencyObject.ClearValue(dpd.DependencyProperty); - BindingOperations.SetBinding(dependencyObject, dpd.DependencyProperty, binding.ParentBindingBase); - }); - } - } - } + // Ensure that no pending calls are in the dispatcher queue + Dispatcher.CurrentDispatcher.BeginInvoke( DispatcherPriority.SystemIdle, ( Action )delegate + { + // Remove and add the binding to re-trigger the binding error + dependencyObject.ClearValue( dpd.DependencyProperty ); + BindingOperations.SetBinding( dependencyObject, dpd.DependencyProperty, binding.ParentBindingBase ); + } ); } + } } + } } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/ContextMenuEx.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/ContextMenuEx.cs index 3bffa602..c5d9274e 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/ContextMenuEx.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/ContextMenuEx.cs @@ -14,39 +14,39 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Controls; using System.Windows.Data; -using System.Windows; namespace Xceed.Wpf.AvalonDock.Controls { - public class ContextMenuEx : ContextMenu - { - static ContextMenuEx() - { - } + public class ContextMenuEx : ContextMenu + { + #region Constructors - public ContextMenuEx() - { + static ContextMenuEx() + { + } - } + public ContextMenuEx() + { + } - protected override System.Windows.DependencyObject GetContainerForItemOverride() - { - return new MenuItemEx(); - } + #endregion - protected override void OnOpened(System.Windows.RoutedEventArgs e) - { - BindingOperations.GetBindingExpression(this, ItemsSourceProperty).UpdateTarget(); + #region Overrides - base.OnOpened(e); - } + protected override System.Windows.DependencyObject GetContainerForItemOverride() + { + return new MenuItemEx(); + } + protected override void OnOpened( System.Windows.RoutedEventArgs e ) + { + BindingOperations.GetBindingExpression( this, ItemsSourceProperty ).UpdateTarget(); + base.OnOpened( e ); } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DockingManagerDropTarget.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DockingManagerDropTarget.cs index ab773a3f..415cdf49 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DockingManagerDropTarget.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DockingManagerDropTarget.cs @@ -15,234 +15,245 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows; using System.Windows.Media; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Controls { - internal class DockingManagerDropTarget : DropTarget + internal class DockingManagerDropTarget : DropTarget + { + #region Members + + private DockingManager _manager; + + #endregion + + #region Constructors + + internal DockingManagerDropTarget( DockingManager manager, Rect detectionRect, DropTargetType type ) + : base( manager, detectionRect, type ) { - internal DockingManagerDropTarget(DockingManager manager, Rect detectionRect, DropTargetType type) - : base(manager, detectionRect, type) - { - _manager = manager; - } + _manager = manager; + } + + #endregion - DockingManager _manager; + #region Overrides - protected override void Drop(LayoutAnchorableFloatingWindow floatingWindow) - { - switch (Type) + protected override void Drop( LayoutAnchorableFloatingWindow floatingWindow ) + { + switch( Type ) + { + case DropTargetType.DockingManagerDockLeft: + #region DropTargetType.DockingManagerDockLeft + { + if( _manager.Layout.RootPanel.Orientation != System.Windows.Controls.Orientation.Horizontal && + _manager.Layout.RootPanel.Children.Count == 1 ) + _manager.Layout.RootPanel.Orientation = System.Windows.Controls.Orientation.Horizontal; + + if( _manager.Layout.RootPanel.Orientation == System.Windows.Controls.Orientation.Horizontal ) { - case DropTargetType.DockingManagerDockLeft: - #region DropTargetType.DockingManagerDockLeft - { - if (_manager.Layout.RootPanel.Orientation != System.Windows.Controls.Orientation.Horizontal && - _manager.Layout.RootPanel.Children.Count == 1) - _manager.Layout.RootPanel.Orientation = System.Windows.Controls.Orientation.Horizontal; - - if (_manager.Layout.RootPanel.Orientation == System.Windows.Controls.Orientation.Horizontal) - { - var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; - if (layoutAnchorablePaneGroup != null && - layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Horizontal) - { - var childrenToTransfer = layoutAnchorablePaneGroup.Children.ToArray(); - for (int i = 0; i < childrenToTransfer.Length; i++) - _manager.Layout.RootPanel.Children.Insert(i, childrenToTransfer[i]); - } - else - _manager.Layout.RootPanel.Children.Insert(0, floatingWindow.RootPanel); - } - else - { - var newOrientedPanel = new LayoutPanel() - { - Orientation = System.Windows.Controls.Orientation.Horizontal - }; - - newOrientedPanel.Children.Add(floatingWindow.RootPanel); - newOrientedPanel.Children.Add(_manager.Layout.RootPanel); - - _manager.Layout.RootPanel = newOrientedPanel; - } - } - break; - #endregion - case DropTargetType.DockingManagerDockRight: - #region DropTargetType.DockingManagerDockRight - { - if (_manager.Layout.RootPanel.Orientation != System.Windows.Controls.Orientation.Horizontal && - _manager.Layout.RootPanel.Children.Count == 1) - _manager.Layout.RootPanel.Orientation = System.Windows.Controls.Orientation.Horizontal; - - if (_manager.Layout.RootPanel.Orientation == System.Windows.Controls.Orientation.Horizontal) - { - var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; - if (layoutAnchorablePaneGroup != null && - layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Horizontal) - { - var childrenToTransfer = layoutAnchorablePaneGroup.Children.ToArray(); - for (int i = 0; i < childrenToTransfer.Length; i++) - _manager.Layout.RootPanel.Children.Add(childrenToTransfer[i]); - } - else - _manager.Layout.RootPanel.Children.Add(floatingWindow.RootPanel); - } - else - { - var newOrientedPanel = new LayoutPanel() - { - Orientation = System.Windows.Controls.Orientation.Horizontal - }; - - newOrientedPanel.Children.Add(_manager.Layout.RootPanel); - newOrientedPanel.Children.Add(floatingWindow.RootPanel); - - _manager.Layout.RootPanel = newOrientedPanel; - } - } - break; - #endregion - case DropTargetType.DockingManagerDockTop: - #region DropTargetType.DockingManagerDockTop - { - if (_manager.Layout.RootPanel.Orientation != System.Windows.Controls.Orientation.Vertical && - _manager.Layout.RootPanel.Children.Count == 1) - _manager.Layout.RootPanel.Orientation = System.Windows.Controls.Orientation.Vertical; - - if (_manager.Layout.RootPanel.Orientation == System.Windows.Controls.Orientation.Vertical) - { - var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; - if (layoutAnchorablePaneGroup != null && - layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Vertical) - { - var childrenToTransfer = layoutAnchorablePaneGroup.Children.ToArray(); - for (int i = 0; i < childrenToTransfer.Length; i++) - _manager.Layout.RootPanel.Children.Insert(i, childrenToTransfer[i]); - } - else - _manager.Layout.RootPanel.Children.Insert(0, floatingWindow.RootPanel); - } - else - { - var newOrientedPanel = new LayoutPanel() - { - Orientation = System.Windows.Controls.Orientation.Vertical - }; - - newOrientedPanel.Children.Add(floatingWindow.RootPanel); - newOrientedPanel.Children.Add(_manager.Layout.RootPanel); - - _manager.Layout.RootPanel = newOrientedPanel; - } - } - break; - #endregion - case DropTargetType.DockingManagerDockBottom: - #region DropTargetType.DockingManagerDockBottom - { - if (_manager.Layout.RootPanel.Orientation != System.Windows.Controls.Orientation.Vertical && - _manager.Layout.RootPanel.Children.Count == 1) - _manager.Layout.RootPanel.Orientation = System.Windows.Controls.Orientation.Vertical; - - if (_manager.Layout.RootPanel.Orientation == System.Windows.Controls.Orientation.Vertical) - { - var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; - if (layoutAnchorablePaneGroup != null && - layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Vertical) - { - var childrenToTransfer = layoutAnchorablePaneGroup.Children.ToArray(); - for (int i = 0; i < childrenToTransfer.Length; i++) - _manager.Layout.RootPanel.Children.Add(childrenToTransfer[i]); - - } - else - _manager.Layout.RootPanel.Children.Add(floatingWindow.RootPanel); - } - else - { - var newOrientedPanel = new LayoutPanel() - { - Orientation = System.Windows.Controls.Orientation.Vertical - }; - - newOrientedPanel.Children.Add(_manager.Layout.RootPanel); - newOrientedPanel.Children.Add(floatingWindow.RootPanel); - - _manager.Layout.RootPanel = newOrientedPanel; - } - } - break; - #endregion + var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; + if( layoutAnchorablePaneGroup != null && + layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Horizontal ) + { + var childrenToTransfer = layoutAnchorablePaneGroup.Children.ToArray(); + for( int i = 0; i < childrenToTransfer.Length; i++ ) + _manager.Layout.RootPanel.Children.Insert( i, childrenToTransfer[ i ] ); + } + else + _manager.Layout.RootPanel.Children.Insert( 0, floatingWindow.RootPanel ); } + else + { + var newOrientedPanel = new LayoutPanel() + { + Orientation = System.Windows.Controls.Orientation.Horizontal + }; + newOrientedPanel.Children.Add( floatingWindow.RootPanel ); + newOrientedPanel.Children.Add( _manager.Layout.RootPanel ); - base.Drop(floatingWindow); - } + _manager.Layout.RootPanel = newOrientedPanel; + } + } + break; + #endregion + case DropTargetType.DockingManagerDockRight: + #region DropTargetType.DockingManagerDockRight + { + if( _manager.Layout.RootPanel.Orientation != System.Windows.Controls.Orientation.Horizontal && + _manager.Layout.RootPanel.Children.Count == 1 ) + _manager.Layout.RootPanel.Orientation = System.Windows.Controls.Orientation.Horizontal; + + if( _manager.Layout.RootPanel.Orientation == System.Windows.Controls.Orientation.Horizontal ) + { + var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; + if( layoutAnchorablePaneGroup != null && + layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Horizontal ) + { + var childrenToTransfer = layoutAnchorablePaneGroup.Children.ToArray(); + for( int i = 0; i < childrenToTransfer.Length; i++ ) + _manager.Layout.RootPanel.Children.Add( childrenToTransfer[ i ] ); + } + else + _manager.Layout.RootPanel.Children.Add( floatingWindow.RootPanel ); + } + else + { + var newOrientedPanel = new LayoutPanel() + { + Orientation = System.Windows.Controls.Orientation.Horizontal + }; - public override System.Windows.Media.Geometry GetPreviewPath(OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindowModel) - { - var anchorableFloatingWindowModel = floatingWindowModel as LayoutAnchorableFloatingWindow; - var layoutAnchorablePane = anchorableFloatingWindowModel.RootPanel as ILayoutPositionableElement; - var layoutAnchorablePaneWithActualSize = anchorableFloatingWindowModel.RootPanel as ILayoutPositionableElementWithActualSize; + newOrientedPanel.Children.Add( floatingWindow.RootPanel ); + newOrientedPanel.Children.Insert( 0, _manager.Layout.RootPanel ); - var targetScreenRect = TargetElement.GetScreenArea(); - switch (Type) + _manager.Layout.RootPanel = newOrientedPanel; + } + } + break; + #endregion + case DropTargetType.DockingManagerDockTop: + #region DropTargetType.DockingManagerDockTop + { + if( _manager.Layout.RootPanel.Orientation != System.Windows.Controls.Orientation.Vertical && + _manager.Layout.RootPanel.Children.Count == 1 ) + _manager.Layout.RootPanel.Orientation = System.Windows.Controls.Orientation.Vertical; + + if( _manager.Layout.RootPanel.Orientation == System.Windows.Controls.Orientation.Vertical ) { - case DropTargetType.DockingManagerDockLeft: - { - var desideredWidth = layoutAnchorablePane.DockWidth.IsAbsolute ? layoutAnchorablePane.DockWidth.Value : layoutAnchorablePaneWithActualSize.ActualWidth; - var previewBoxRect = new Rect( - targetScreenRect.Left - overlayWindow.Left, - targetScreenRect.Top - overlayWindow.Top, - Math.Min(desideredWidth, targetScreenRect.Width / 2.0), - targetScreenRect.Height); - - return new RectangleGeometry(previewBoxRect); - } - case DropTargetType.DockingManagerDockTop: - { - var desideredHeight = layoutAnchorablePane.DockHeight.IsAbsolute ? layoutAnchorablePane.DockHeight.Value : layoutAnchorablePaneWithActualSize.ActualHeight; - var previewBoxRect = new Rect( - targetScreenRect.Left - overlayWindow.Left, - targetScreenRect.Top - overlayWindow.Top, - targetScreenRect.Width, - Math.Min(desideredHeight, targetScreenRect.Height / 2.0)); - - return new RectangleGeometry(previewBoxRect); - } - case DropTargetType.DockingManagerDockRight: - { - var desideredWidth = layoutAnchorablePane.DockWidth.IsAbsolute ? layoutAnchorablePane.DockWidth.Value : layoutAnchorablePaneWithActualSize.ActualWidth; - var previewBoxRect = new Rect( - targetScreenRect.Right - overlayWindow.Left - Math.Min(desideredWidth, targetScreenRect.Width / 2.0), - targetScreenRect.Top - overlayWindow.Top, - Math.Min(desideredWidth, targetScreenRect.Width / 2.0), - targetScreenRect.Height); - - return new RectangleGeometry(previewBoxRect); - } - case DropTargetType.DockingManagerDockBottom: - { - var desideredHeight = layoutAnchorablePane.DockHeight.IsAbsolute ? layoutAnchorablePane.DockHeight.Value : layoutAnchorablePaneWithActualSize.ActualHeight; - var previewBoxRect = new Rect( - targetScreenRect.Left - overlayWindow.Left, - targetScreenRect.Bottom - overlayWindow.Top - Math.Min(desideredHeight, targetScreenRect.Height / 2.0), - targetScreenRect.Width, - Math.Min(desideredHeight, targetScreenRect.Height / 2.0)); - - return new RectangleGeometry(previewBoxRect); - } + var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; + if( layoutAnchorablePaneGroup != null && + layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Vertical ) + { + var childrenToTransfer = layoutAnchorablePaneGroup.Children.ToArray(); + for( int i = 0; i < childrenToTransfer.Length; i++ ) + _manager.Layout.RootPanel.Children.Insert( i, childrenToTransfer[ i ] ); + } + else + _manager.Layout.RootPanel.Children.Insert( 0, floatingWindow.RootPanel ); } + else + { + var newOrientedPanel = new LayoutPanel() + { + Orientation = System.Windows.Controls.Orientation.Vertical + }; + newOrientedPanel.Children.Add( floatingWindow.RootPanel ); + newOrientedPanel.Children.Add( _manager.Layout.RootPanel ); - throw new InvalidOperationException(); - } + _manager.Layout.RootPanel = newOrientedPanel; + } + } + break; + #endregion + case DropTargetType.DockingManagerDockBottom: + #region DropTargetType.DockingManagerDockBottom + { + if( _manager.Layout.RootPanel.Orientation != System.Windows.Controls.Orientation.Vertical && + _manager.Layout.RootPanel.Children.Count == 1 ) + _manager.Layout.RootPanel.Orientation = System.Windows.Controls.Orientation.Vertical; + + if( _manager.Layout.RootPanel.Orientation == System.Windows.Controls.Orientation.Vertical ) + { + var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; + if( layoutAnchorablePaneGroup != null && + layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Vertical ) + { + var childrenToTransfer = layoutAnchorablePaneGroup.Children.ToArray(); + for( int i = 0; i < childrenToTransfer.Length; i++ ) + _manager.Layout.RootPanel.Children.Add( childrenToTransfer[ i ] ); + + } + else + _manager.Layout.RootPanel.Children.Add( floatingWindow.RootPanel ); + } + else + { + var newOrientedPanel = new LayoutPanel() + { + Orientation = System.Windows.Controls.Orientation.Vertical + }; + + newOrientedPanel.Children.Add( floatingWindow.RootPanel ); + newOrientedPanel.Children.Insert( 0, _manager.Layout.RootPanel ); + + _manager.Layout.RootPanel = newOrientedPanel; + } + } + break; + #endregion + } + + + base.Drop( floatingWindow ); + } + + public override System.Windows.Media.Geometry GetPreviewPath( OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindowModel ) + { + var anchorableFloatingWindowModel = floatingWindowModel as LayoutAnchorableFloatingWindow; + var layoutAnchorablePane = anchorableFloatingWindowModel.RootPanel as ILayoutPositionableElement; + var layoutAnchorablePaneWithActualSize = anchorableFloatingWindowModel.RootPanel as ILayoutPositionableElementWithActualSize; + + var targetScreenRect = TargetElement.GetScreenArea(); + + switch( Type ) + { + case DropTargetType.DockingManagerDockLeft: + { + var desideredWidth = layoutAnchorablePane.DockWidth.IsAbsolute ? layoutAnchorablePane.DockWidth.Value : layoutAnchorablePaneWithActualSize.ActualWidth; + var previewBoxRect = new Rect( + targetScreenRect.Left - overlayWindow.Left, + targetScreenRect.Top - overlayWindow.Top, + Math.Min( desideredWidth, targetScreenRect.Width / 2.0 ), + targetScreenRect.Height ); + + return new RectangleGeometry( previewBoxRect ); + } + case DropTargetType.DockingManagerDockTop: + { + var desideredHeight = layoutAnchorablePane.DockHeight.IsAbsolute ? layoutAnchorablePane.DockHeight.Value : layoutAnchorablePaneWithActualSize.ActualHeight; + var previewBoxRect = new Rect( + targetScreenRect.Left - overlayWindow.Left, + targetScreenRect.Top - overlayWindow.Top, + targetScreenRect.Width, + Math.Min( desideredHeight, targetScreenRect.Height / 2.0 ) ); + + return new RectangleGeometry( previewBoxRect ); + } + case DropTargetType.DockingManagerDockRight: + { + var desideredWidth = layoutAnchorablePane.DockWidth.IsAbsolute ? layoutAnchorablePane.DockWidth.Value : layoutAnchorablePaneWithActualSize.ActualWidth; + var previewBoxRect = new Rect( + targetScreenRect.Right - overlayWindow.Left - Math.Min( desideredWidth, targetScreenRect.Width / 2.0 ), + targetScreenRect.Top - overlayWindow.Top, + Math.Min( desideredWidth, targetScreenRect.Width / 2.0 ), + targetScreenRect.Height ); + + return new RectangleGeometry( previewBoxRect ); + } + case DropTargetType.DockingManagerDockBottom: + { + var desideredHeight = layoutAnchorablePane.DockHeight.IsAbsolute ? layoutAnchorablePane.DockHeight.Value : layoutAnchorablePaneWithActualSize.ActualHeight; + var previewBoxRect = new Rect( + targetScreenRect.Left - overlayWindow.Left, + targetScreenRect.Bottom - overlayWindow.Top - Math.Min( desideredHeight, targetScreenRect.Height / 2.0 ), + targetScreenRect.Width, + Math.Min( desideredHeight, targetScreenRect.Height / 2.0 ) ); + + return new RectangleGeometry( previewBoxRect ); + } + } + + + throw new InvalidOperationException(); } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DockingManagerOverlayArea.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DockingManagerOverlayArea.cs index 0192c7fe..90091192 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DockingManagerOverlayArea.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DockingManagerOverlayArea.cs @@ -14,27 +14,30 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; namespace Xceed.Wpf.AvalonDock.Controls { - public class DockingManagerOverlayArea : OverlayArea - { - internal DockingManagerOverlayArea(IOverlayWindow overlayWindow, DockingManager manager) - : base(overlayWindow) - { - _manager = manager; + public class DockingManagerOverlayArea : OverlayArea + { + #region Members + + private DockingManager _manager; - base.SetScreenDetectionArea(new Rect( - _manager.PointToScreenDPI(new Point()), - _manager.TransformActualSizeToAncestor())); - } + #endregion - DockingManager _manager; + #region Constructors + internal DockingManagerOverlayArea( IOverlayWindow overlayWindow, DockingManager manager ) + : base( overlayWindow ) + { + _manager = manager; + + base.SetScreenDetectionArea( new Rect( + _manager.PointToScreenDPI( new Point() ), + _manager.TransformActualSizeToAncestor() ) ); } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneControlOverlayArea.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneControlOverlayArea.cs index 0069ae84..6f427b03 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneControlOverlayArea.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneControlOverlayArea.cs @@ -14,31 +14,29 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; namespace Xceed.Wpf.AvalonDock.Controls { - public class DocumentPaneControlOverlayArea : OverlayArea - { - + public class DocumentPaneControlOverlayArea : OverlayArea + { + #region Members - internal DocumentPaneControlOverlayArea( - IOverlayWindow overlayWindow, - LayoutDocumentPaneControl documentPaneControl) - : base(overlayWindow) - { - _documentPaneControl = documentPaneControl; - base.SetScreenDetectionArea(new Rect( - _documentPaneControl.PointToScreenDPI(new Point()), - _documentPaneControl.TransformActualSizeToAncestor())); - } + private LayoutDocumentPaneControl _documentPaneControl; - LayoutDocumentPaneControl _documentPaneControl; + #endregion + #region Constructors + internal DocumentPaneControlOverlayArea( + IOverlayWindow overlayWindow, + LayoutDocumentPaneControl documentPaneControl ) + : base( overlayWindow ) + { + _documentPaneControl = documentPaneControl; + base.SetScreenDetectionArea( new Rect( _documentPaneControl.PointToScreenDPI( new Point() ), _documentPaneControl.TransformActualSizeToAncestor() ) ); } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneDropAsAnchorableTarget.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneDropAsAnchorableTarget.cs index fbe700c7..5d86257d 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneDropAsAnchorableTarget.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneDropAsAnchorableTarget.cs @@ -15,263 +15,271 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows; using System.Windows.Media; -using System.Diagnostics; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Controls { - internal class DocumentPaneDropAsAnchorableTarget : DropTarget - { - internal DocumentPaneDropAsAnchorableTarget(LayoutDocumentPaneControl paneControl, Rect detectionRect, DropTargetType type) - : base(paneControl, detectionRect, type) - { - _targetPane = paneControl; - } + internal class DocumentPaneDropAsAnchorableTarget : DropTarget + { + #region Members - internal DocumentPaneDropAsAnchorableTarget(LayoutDocumentPaneControl paneControl, Rect detectionRect, DropTargetType type, int tabIndex) - : base(paneControl, detectionRect, type) - { - _targetPane = paneControl; - _tabIndex = tabIndex; - } + private LayoutDocumentPaneControl _targetPane; + int _tabIndex = -1; + #endregion - LayoutDocumentPaneControl _targetPane; + #region Constructors - int _tabIndex = -1; + internal DocumentPaneDropAsAnchorableTarget( LayoutDocumentPaneControl paneControl, Rect detectionRect, DropTargetType type ) + : base( paneControl, detectionRect, type ) + { + _targetPane = paneControl; + } - protected override void Drop(LayoutAnchorableFloatingWindow floatingWindow) - { - ILayoutDocumentPane targetModel = _targetPane.Model as ILayoutDocumentPane; - LayoutDocumentPaneGroup parentGroup; - LayoutPanel parentGroupPanel; - FindParentLayoutDocumentPane(targetModel, out parentGroup, out parentGroupPanel); + internal DocumentPaneDropAsAnchorableTarget( LayoutDocumentPaneControl paneControl, Rect detectionRect, DropTargetType type, int tabIndex ) + : base( paneControl, detectionRect, type ) + { + _targetPane = paneControl; + _tabIndex = tabIndex; + } - switch (Type) - { - case DropTargetType.DocumentPaneDockAsAnchorableBottom: - #region DropTargetType.DocumentPaneDockAsAnchorableBottom - { - if (parentGroupPanel != null && - parentGroupPanel.ChildrenCount == 1) - parentGroupPanel.Orientation = System.Windows.Controls.Orientation.Vertical; - - if (parentGroupPanel != null && - parentGroupPanel.Orientation == System.Windows.Controls.Orientation.Vertical) - { - parentGroupPanel.Children.Insert( - parentGroupPanel.IndexOfChild(parentGroup != null ? parentGroup : targetModel) + 1, - floatingWindow.RootPanel); - } - else if (parentGroupPanel != null) - { - var newParentPanel = new LayoutPanel() { Orientation = System.Windows.Controls.Orientation.Vertical }; - parentGroupPanel.ReplaceChild(parentGroup != null ? parentGroup : targetModel, newParentPanel); - newParentPanel.Children.Add(parentGroup != null ? parentGroup : targetModel); - newParentPanel.Children.Add(floatingWindow.RootPanel); - } - else - { - throw new NotImplementedException(); - } - - - } - break; - #endregion - case DropTargetType.DocumentPaneDockAsAnchorableTop: - #region DropTargetType.DocumentPaneDockAsAnchorableTop - { - if (parentGroupPanel != null && - parentGroupPanel.ChildrenCount == 1) - parentGroupPanel.Orientation = System.Windows.Controls.Orientation.Vertical; - - if (parentGroupPanel != null && - parentGroupPanel.Orientation == System.Windows.Controls.Orientation.Vertical) - { - parentGroupPanel.Children.Insert( - parentGroupPanel.IndexOfChild(parentGroup != null ? parentGroup : targetModel), - floatingWindow.RootPanel); - } - else if (parentGroupPanel != null) - { - var newParentPanel = new LayoutPanel() { Orientation = System.Windows.Controls.Orientation.Vertical }; - parentGroupPanel.ReplaceChild(parentGroup != null ? parentGroup : targetModel, newParentPanel); - newParentPanel.Children.Add(parentGroup != null ? parentGroup : targetModel); - newParentPanel.Children.Insert(0, floatingWindow.RootPanel); - } - else - { - throw new NotImplementedException(); - } - - } - break; - #endregion - case DropTargetType.DocumentPaneDockAsAnchorableLeft: - #region DropTargetType.DocumentPaneDockAsAnchorableLeft - { - if (parentGroupPanel != null && - parentGroupPanel.ChildrenCount == 1) - parentGroupPanel.Orientation = System.Windows.Controls.Orientation.Horizontal; - - if (parentGroupPanel != null && - parentGroupPanel.Orientation == System.Windows.Controls.Orientation.Horizontal) - { - parentGroupPanel.Children.Insert( - parentGroupPanel.IndexOfChild(parentGroup != null ? parentGroup : targetModel), - floatingWindow.RootPanel); - } - else if (parentGroupPanel != null) - { - var newParentPanel = new LayoutPanel() { Orientation = System.Windows.Controls.Orientation.Horizontal }; - parentGroupPanel.ReplaceChild(parentGroup != null ? parentGroup : targetModel, newParentPanel); - newParentPanel.Children.Add(parentGroup != null ? parentGroup : targetModel); - newParentPanel.Children.Insert(0, floatingWindow.RootPanel); - } - else - { - throw new NotImplementedException(); - } - } - break; - #endregion - case DropTargetType.DocumentPaneDockAsAnchorableRight: - #region DropTargetType.DocumentPaneDockAsAnchorableRight - { - if (parentGroupPanel != null && - parentGroupPanel.ChildrenCount == 1) - parentGroupPanel.Orientation = System.Windows.Controls.Orientation.Horizontal; - - if (parentGroupPanel != null && - parentGroupPanel.Orientation == System.Windows.Controls.Orientation.Horizontal) - { - parentGroupPanel.Children.Insert( - parentGroupPanel.IndexOfChild(parentGroup != null ? parentGroup : targetModel) + 1, - floatingWindow.RootPanel); - } - else if (parentGroupPanel != null) - { - var newParentPanel = new LayoutPanel() { Orientation = System.Windows.Controls.Orientation.Horizontal }; - parentGroupPanel.ReplaceChild(parentGroup != null ? parentGroup : targetModel, newParentPanel); - newParentPanel.Children.Add(parentGroup != null ? parentGroup : targetModel); - newParentPanel.Children.Add(floatingWindow.RootPanel); - } - else - { - throw new NotImplementedException(); - } - } - break; - #endregion - } + #endregion - base.Drop(floatingWindow); - } + #region Overrides - public override System.Windows.Media.Geometry GetPreviewPath(OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindowModel) - { - Rect targetScreenRect; - ILayoutDocumentPane targetModel = _targetPane.Model as ILayoutDocumentPane; - var manager = targetModel.Root.Manager; - - //ILayoutDocumentPane targetModel = _targetPane.Model as ILayoutDocumentPane; - LayoutDocumentPaneGroup parentGroup; - LayoutPanel parentGroupPanel; - if (!FindParentLayoutDocumentPane(targetModel, out parentGroup, out parentGroupPanel)) - return null; - - //if (targetModel.Parent is LayoutDocumentPaneGroup) - //{ - // var parentGroup = targetModel.Parent as LayoutDocumentPaneGroup; - // var documentPaneGroupControl = manager.FindLogicalChildren().First(d => d.Model == parentGroup); - // targetScreenRect = documentPaneGroupControl.GetScreenArea(); - //} - //else - //{ - // var documentPaneControl = manager.FindLogicalChildren().First(d => d.Model == targetModel); - // targetScreenRect = documentPaneControl.GetScreenArea(); - //} - - //var parentPanel = targetModel.FindParent(); - var documentPaneControl = manager.FindLogicalChildren().OfType().First(d => parentGroup != null ? d.Model == parentGroup : d.Model == parentGroupPanel) as FrameworkElement; - targetScreenRect = documentPaneControl.GetScreenArea(); - - switch (Type) + protected override void Drop( LayoutAnchorableFloatingWindow floatingWindow ) + { + ILayoutDocumentPane targetModel = _targetPane.Model as ILayoutDocumentPane; + LayoutDocumentPaneGroup parentGroup; + LayoutPanel parentGroupPanel; + FindParentLayoutDocumentPane( targetModel, out parentGroup, out parentGroupPanel ); + + switch( Type ) + { + case DropTargetType.DocumentPaneDockAsAnchorableBottom: + #region DropTargetType.DocumentPaneDockAsAnchorableBottom + { + if( parentGroupPanel != null && + parentGroupPanel.ChildrenCount == 1 ) + parentGroupPanel.Orientation = System.Windows.Controls.Orientation.Vertical; + + if( parentGroupPanel != null && + parentGroupPanel.Orientation == System.Windows.Controls.Orientation.Vertical ) { - case DropTargetType.DocumentPaneDockAsAnchorableBottom: - { - targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - targetScreenRect.Offset(0.0, targetScreenRect.Height - targetScreenRect.Height / 3.0); - targetScreenRect.Height /= 3.0; - return new RectangleGeometry(targetScreenRect); - } - case DropTargetType.DocumentPaneDockAsAnchorableTop: - { - targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - targetScreenRect.Height /= 3.0; - return new RectangleGeometry(targetScreenRect); - } - case DropTargetType.DocumentPaneDockAsAnchorableRight: - { - targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - targetScreenRect.Offset(targetScreenRect.Width - targetScreenRect.Width / 3.0, 0.0); - targetScreenRect.Width /= 3.0; - return new RectangleGeometry(targetScreenRect); - } - case DropTargetType.DocumentPaneDockAsAnchorableLeft: - { - targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - targetScreenRect.Width /= 3.0; - return new RectangleGeometry(targetScreenRect); - } + parentGroupPanel.Children.Insert( + parentGroupPanel.IndexOfChild( parentGroup != null ? parentGroup : targetModel ) + 1, + floatingWindow.RootPanel ); + } + else if( parentGroupPanel != null ) + { + var newParentPanel = new LayoutPanel() { Orientation = System.Windows.Controls.Orientation.Vertical }; + parentGroupPanel.ReplaceChild( parentGroup != null ? parentGroup : targetModel, newParentPanel ); + newParentPanel.Children.Add( parentGroup != null ? parentGroup : targetModel ); + newParentPanel.Children.Add( floatingWindow.RootPanel ); + } + else + { + throw new NotImplementedException(); } - - return null; - } - - bool FindParentLayoutDocumentPane(ILayoutDocumentPane documentPane, out LayoutDocumentPaneGroup containerPaneGroup, out LayoutPanel containerPanel) - { - containerPaneGroup = null; - containerPanel = null; + } + break; + #endregion + case DropTargetType.DocumentPaneDockAsAnchorableTop: + #region DropTargetType.DocumentPaneDockAsAnchorableTop + { + if( parentGroupPanel != null && + parentGroupPanel.ChildrenCount == 1 ) + parentGroupPanel.Orientation = System.Windows.Controls.Orientation.Vertical; - if (documentPane.Parent is LayoutPanel) + if( parentGroupPanel != null && + parentGroupPanel.Orientation == System.Windows.Controls.Orientation.Vertical ) + { + parentGroupPanel.Children.Insert( + parentGroupPanel.IndexOfChild( parentGroup != null ? parentGroup : targetModel ), + floatingWindow.RootPanel ); + } + else if( parentGroupPanel != null ) { - containerPaneGroup = null; - containerPanel = documentPane.Parent as LayoutPanel; - return true; + var newParentPanel = new LayoutPanel() { Orientation = System.Windows.Controls.Orientation.Vertical }; + parentGroupPanel.ReplaceChild( parentGroup != null ? parentGroup : targetModel, newParentPanel ); + newParentPanel.Children.Add( parentGroup != null ? parentGroup : targetModel ); + newParentPanel.Children.Insert( 0, floatingWindow.RootPanel ); } - else if (documentPane.Parent is LayoutDocumentPaneGroup) + else { - var currentDocumentPaneGroup = documentPane.Parent as LayoutDocumentPaneGroup; - while (!(currentDocumentPaneGroup.Parent is LayoutPanel)) - { - currentDocumentPaneGroup = currentDocumentPaneGroup.Parent as LayoutDocumentPaneGroup; + throw new NotImplementedException(); + } - if (currentDocumentPaneGroup == null) - break; - } + } + break; + #endregion + case DropTargetType.DocumentPaneDockAsAnchorableLeft: + #region DropTargetType.DocumentPaneDockAsAnchorableLeft + { + if( parentGroupPanel != null && + parentGroupPanel.ChildrenCount == 1 ) + parentGroupPanel.Orientation = System.Windows.Controls.Orientation.Horizontal; + + if( parentGroupPanel != null && + parentGroupPanel.Orientation == System.Windows.Controls.Orientation.Horizontal ) + { + parentGroupPanel.Children.Insert( + parentGroupPanel.IndexOfChild( parentGroup != null ? parentGroup : targetModel ), + floatingWindow.RootPanel ); + } + else if( parentGroupPanel != null ) + { + var newParentPanel = new LayoutPanel() { Orientation = System.Windows.Controls.Orientation.Horizontal }; + parentGroupPanel.ReplaceChild( parentGroup != null ? parentGroup : targetModel, newParentPanel ); + newParentPanel.Children.Add( parentGroup != null ? parentGroup : targetModel ); + newParentPanel.Children.Insert( 0, floatingWindow.RootPanel ); + } + else + { + throw new NotImplementedException(); + } + } + break; + #endregion + case DropTargetType.DocumentPaneDockAsAnchorableRight: + #region DropTargetType.DocumentPaneDockAsAnchorableRight + { + if( parentGroupPanel != null && + parentGroupPanel.ChildrenCount == 1 ) + parentGroupPanel.Orientation = System.Windows.Controls.Orientation.Horizontal; + + if( parentGroupPanel != null && + parentGroupPanel.Orientation == System.Windows.Controls.Orientation.Horizontal ) + { + parentGroupPanel.Children.Insert( + parentGroupPanel.IndexOfChild( parentGroup != null ? parentGroup : targetModel ) + 1, + floatingWindow.RootPanel ); + } + else if( parentGroupPanel != null ) + { + var newParentPanel = new LayoutPanel() { Orientation = System.Windows.Controls.Orientation.Horizontal }; + parentGroupPanel.ReplaceChild( parentGroup != null ? parentGroup : targetModel, newParentPanel ); + newParentPanel.Children.Add( parentGroup != null ? parentGroup : targetModel ); + newParentPanel.Children.Add( floatingWindow.RootPanel ); + } + else + { + throw new NotImplementedException(); + } + } + break; + #endregion + } - if (currentDocumentPaneGroup == null) - return false; + base.Drop( floatingWindow ); + } - containerPaneGroup = currentDocumentPaneGroup; - containerPanel = currentDocumentPaneGroup.Parent as LayoutPanel; - return true; - } + public override System.Windows.Media.Geometry GetPreviewPath( OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindowModel ) + { + Rect targetScreenRect; + ILayoutDocumentPane targetModel = _targetPane.Model as ILayoutDocumentPane; + var manager = targetModel.Root.Manager; + + //ILayoutDocumentPane targetModel = _targetPane.Model as ILayoutDocumentPane; + LayoutDocumentPaneGroup parentGroup; + LayoutPanel parentGroupPanel; + if( !FindParentLayoutDocumentPane( targetModel, out parentGroup, out parentGroupPanel ) ) + return null; + + //if (targetModel.Parent is LayoutDocumentPaneGroup) + //{ + // var parentGroup = targetModel.Parent as LayoutDocumentPaneGroup; + // var documentPaneGroupControl = manager.FindLogicalChildren().First(d => d.Model == parentGroup); + // targetScreenRect = documentPaneGroupControl.GetScreenArea(); + //} + //else + //{ + // var documentPaneControl = manager.FindLogicalChildren().First(d => d.Model == targetModel); + // targetScreenRect = documentPaneControl.GetScreenArea(); + //} + + //var parentPanel = targetModel.FindParent(); + var documentPaneControl = manager.FindLogicalChildren().OfType().First( d => parentGroup != null ? d.Model == parentGroup : d.Model == parentGroupPanel ) as FrameworkElement; + targetScreenRect = documentPaneControl.GetScreenArea(); + + switch( Type ) + { + case DropTargetType.DocumentPaneDockAsAnchorableBottom: + { + targetScreenRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + targetScreenRect.Offset( 0.0, targetScreenRect.Height - targetScreenRect.Height / 3.0 ); + targetScreenRect.Height /= 3.0; + return new RectangleGeometry( targetScreenRect ); + } + case DropTargetType.DocumentPaneDockAsAnchorableTop: + { + targetScreenRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + targetScreenRect.Height /= 3.0; + return new RectangleGeometry( targetScreenRect ); + } + case DropTargetType.DocumentPaneDockAsAnchorableRight: + { + targetScreenRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + targetScreenRect.Offset( targetScreenRect.Width - targetScreenRect.Width / 3.0, 0.0 ); + targetScreenRect.Width /= 3.0; + return new RectangleGeometry( targetScreenRect ); + } + case DropTargetType.DocumentPaneDockAsAnchorableLeft: + { + targetScreenRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + targetScreenRect.Width /= 3.0; + return new RectangleGeometry( targetScreenRect ); + } + } + + return null; + } - return false; + #endregion + #region Private Methods + private bool FindParentLayoutDocumentPane( ILayoutDocumentPane documentPane, out LayoutDocumentPaneGroup containerPaneGroup, out LayoutPanel containerPanel ) + { + containerPaneGroup = null; + containerPanel = null; + + if( documentPane.Parent is LayoutPanel ) + { + containerPaneGroup = null; + containerPanel = documentPane.Parent as LayoutPanel; + return true; + } + else if( documentPane.Parent is LayoutDocumentPaneGroup ) + { + var currentDocumentPaneGroup = documentPane.Parent as LayoutDocumentPaneGroup; + while( !( currentDocumentPaneGroup.Parent is LayoutPanel ) ) + { + currentDocumentPaneGroup = currentDocumentPaneGroup.Parent as LayoutDocumentPaneGroup; + if( currentDocumentPaneGroup == null ) + break; } + if( currentDocumentPaneGroup == null ) + return false; + + containerPaneGroup = currentDocumentPaneGroup; + containerPanel = currentDocumentPaneGroup.Parent as LayoutPanel; + return true; + } + + return false; + + + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneDropTarget.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneDropTarget.cs index 3d1026c1..2df4f018 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneDropTarget.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneDropTarget.cs @@ -14,490 +14,500 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows; using System.Windows.Media; -using System.Diagnostics; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Controls { - internal class DocumentPaneDropTarget : DropTarget + internal class DocumentPaneDropTarget : DropTarget + { + #region Members + + private LayoutDocumentPaneControl _targetPane; + private int _tabIndex = -1; + + #endregion + + #region Constructors + + internal DocumentPaneDropTarget( LayoutDocumentPaneControl paneControl, Rect detectionRect, DropTargetType type ) + : base( paneControl, detectionRect, type ) { - internal DocumentPaneDropTarget(LayoutDocumentPaneControl paneControl, Rect detectionRect, DropTargetType type) - : base(paneControl, detectionRect, type) - { - _targetPane = paneControl; - } + _targetPane = paneControl; + } + + internal DocumentPaneDropTarget( LayoutDocumentPaneControl paneControl, Rect detectionRect, DropTargetType type, int tabIndex ) + : base( paneControl, detectionRect, type ) + { + _targetPane = paneControl; + _tabIndex = tabIndex; + } + + #endregion + + #region Overrides + + protected override void Drop( LayoutDocumentFloatingWindow floatingWindow ) + { + ILayoutDocumentPane targetModel = _targetPane.Model as ILayoutDocumentPane; + + switch( Type ) + { + case DropTargetType.DocumentPaneDockBottom: + #region DropTargetType.DocumentPaneDockBottom + { + var newLayoutDocumentPane = new LayoutDocumentPane( floatingWindow.RootDocument ); + var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; + + if( parentModel == null ) + { + var parentContainer = targetModel.Parent as ILayoutContainer; + var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Vertical }; + parentContainer.ReplaceChild( targetModel, newParentModel ); + newParentModel.Children.Add( targetModel as LayoutDocumentPane ); + newParentModel.Children.Add( newLayoutDocumentPane ); + } + else + { + var manager = parentModel.Root.Manager; + if( !manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Vertical ) + { + parentModel.Orientation = System.Windows.Controls.Orientation.Vertical; + int targetPaneIndex = parentModel.IndexOfChild( targetModel ); + parentModel.Children.Insert( targetPaneIndex + 1, newLayoutDocumentPane ); + } + else + { + LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); + newChildGroup.Orientation = System.Windows.Controls.Orientation.Vertical; + parentModel.ReplaceChild( targetModel, newChildGroup ); + newChildGroup.Children.Add( targetModel ); + newChildGroup.Children.Add( newLayoutDocumentPane ); + } + + } + } + break; + #endregion + case DropTargetType.DocumentPaneDockTop: + #region DropTargetType.DocumentPaneDockTop + { + var newLayoutDocumentPane = new LayoutDocumentPane( floatingWindow.RootDocument ); + var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; + + if( parentModel == null ) + { + var parentContainer = targetModel.Parent as ILayoutContainer; + var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Vertical }; + parentContainer.ReplaceChild( targetModel, newParentModel ); + newParentModel.Children.Add( targetModel as LayoutDocumentPane ); + newParentModel.Children.Insert( 0, newLayoutDocumentPane ); + } + else + { + var manager = parentModel.Root.Manager; + if( !manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Vertical ) + { + parentModel.Orientation = System.Windows.Controls.Orientation.Vertical; + int targetPaneIndex = parentModel.IndexOfChild( targetModel ); + parentModel.Children.Insert( targetPaneIndex, newLayoutDocumentPane ); + } + else + { + LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); + newChildGroup.Orientation = System.Windows.Controls.Orientation.Vertical; + parentModel.ReplaceChild( targetModel, newChildGroup ); + newChildGroup.Children.Add( newLayoutDocumentPane ); + newChildGroup.Children.Add( targetModel ); + } + + } + } + break; + #endregion + case DropTargetType.DocumentPaneDockLeft: + #region DropTargetType.DocumentPaneDockLeft + { + var newLayoutDocumentPane = new LayoutDocumentPane( floatingWindow.RootDocument ); + var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; + + if( parentModel == null ) + { + var parentContainer = targetModel.Parent as ILayoutContainer; + var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Horizontal }; + parentContainer.ReplaceChild( targetModel, newParentModel ); + newParentModel.Children.Add( targetModel ); + newParentModel.Children.Insert( 0, newLayoutDocumentPane ); + } + else + { + var manager = parentModel.Root.Manager; + if( !manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Horizontal ) + { + parentModel.Orientation = System.Windows.Controls.Orientation.Horizontal; + int targetPaneIndex = parentModel.IndexOfChild( targetModel ); + parentModel.Children.Insert( targetPaneIndex, newLayoutDocumentPane ); + } + else + { + LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); + newChildGroup.Orientation = System.Windows.Controls.Orientation.Horizontal; + parentModel.ReplaceChild( targetModel, newChildGroup ); + newChildGroup.Children.Add( newLayoutDocumentPane ); + newChildGroup.Children.Add( targetModel ); + } + } + } + break; + #endregion + case DropTargetType.DocumentPaneDockRight: + #region DropTargetType.DocumentPaneDockRight + { + var newLayoutDocumentPane = new LayoutDocumentPane( floatingWindow.RootDocument ); + var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; + + if( parentModel == null ) + { + var parentContainer = targetModel.Parent as ILayoutContainer; + var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Horizontal }; + parentContainer.ReplaceChild( targetModel, newParentModel ); + newParentModel.Children.Add( targetModel as LayoutDocumentPane ); + newParentModel.Children.Add( newLayoutDocumentPane ); + } + else + { + var manager = parentModel.Root.Manager; + if( !manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Horizontal ) + { + parentModel.Orientation = System.Windows.Controls.Orientation.Horizontal; + int targetPaneIndex = parentModel.IndexOfChild( targetModel ); + parentModel.Children.Insert( targetPaneIndex + 1, newLayoutDocumentPane ); + } + else + { + LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); + newChildGroup.Orientation = System.Windows.Controls.Orientation.Horizontal; + parentModel.ReplaceChild( targetModel, newChildGroup ); + newChildGroup.Children.Add( targetModel ); + newChildGroup.Children.Add( newLayoutDocumentPane ); + } + + } + } + break; + #endregion + + case DropTargetType.DocumentPaneDockInside: + #region DropTargetType.DocumentPaneDockInside + { + var paneModel = targetModel as LayoutDocumentPane; + var sourceModel = floatingWindow.RootDocument; + + int i = 0; + if( _tabIndex != -1 ) + { + i = _tabIndex; + } + else + { + var previousIndex = 0; + var previousContainer = ( ( ILayoutPreviousContainer )sourceModel ).PreviousContainer; + if( object.ReferenceEquals( previousContainer, targetModel ) && ( sourceModel.PreviousContainerIndex != -1 ) ) + { + previousIndex = sourceModel.PreviousContainerIndex; + } + + i = previousIndex; + } + sourceModel.IsActive = false; + paneModel.Children.Insert( i, sourceModel ); + sourceModel.IsActive = true; + } + break; + #endregion - internal DocumentPaneDropTarget(LayoutDocumentPaneControl paneControl, Rect detectionRect, DropTargetType type, int tabIndex) - : base(paneControl, detectionRect, type) - { - _targetPane = paneControl; - _tabIndex = tabIndex; - } + } - LayoutDocumentPaneControl _targetPane; + base.Drop( floatingWindow ); + } - int _tabIndex = -1; + protected override void Drop( LayoutAnchorableFloatingWindow floatingWindow ) + { + ILayoutDocumentPane targetModel = _targetPane.Model as ILayoutDocumentPane; - protected override void Drop(LayoutDocumentFloatingWindow floatingWindow) - { - ILayoutDocumentPane targetModel = _targetPane.Model as ILayoutDocumentPane; + switch( Type ) + { + case DropTargetType.DocumentPaneDockBottom: + #region DropTargetType.DocumentPaneDockBottom + { + var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; + var newLayoutDocumentPane = new LayoutDocumentPane(); - switch (Type) + if( parentModel == null ) + { + var parentContainer = targetModel.Parent as ILayoutContainer; + var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Vertical }; + parentContainer.ReplaceChild( targetModel, newParentModel ); + newParentModel.Children.Add( targetModel as LayoutDocumentPane ); + newParentModel.Children.Add( newLayoutDocumentPane ); + } + else { - case DropTargetType.DocumentPaneDockBottom: - #region DropTargetType.DocumentPaneDockBottom - { - var newLayoutDocumentPane = new LayoutDocumentPane(floatingWindow.RootDocument); - var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; - - if (parentModel == null) - { - var parentContainer = targetModel.Parent as ILayoutContainer; - var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Vertical}; - parentContainer.ReplaceChild(targetModel, newParentModel); - newParentModel.Children.Add(targetModel as LayoutDocumentPane); - newParentModel.Children.Add(newLayoutDocumentPane); - } - else - { - var manager = parentModel.Root.Manager; - if (!manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Vertical) - { - parentModel.Orientation = System.Windows.Controls.Orientation.Vertical; - int targetPaneIndex = parentModel.IndexOfChild(targetModel); - parentModel.Children.Insert(targetPaneIndex + 1, newLayoutDocumentPane); - } - else - { - LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); - newChildGroup.Orientation = System.Windows.Controls.Orientation.Vertical; - parentModel.ReplaceChild(targetModel, newChildGroup); - newChildGroup.Children.Add(targetModel); - newChildGroup.Children.Add(newLayoutDocumentPane); - } - - } - } - break; - #endregion - case DropTargetType.DocumentPaneDockTop: - #region DropTargetType.DocumentPaneDockTop - { - var newLayoutDocumentPane = new LayoutDocumentPane(floatingWindow.RootDocument); - var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; - - if (parentModel == null) - { - var parentContainer = targetModel.Parent as ILayoutContainer; - var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Vertical }; - parentContainer.ReplaceChild(targetModel, newParentModel); - newParentModel.Children.Add(targetModel as LayoutDocumentPane); - newParentModel.Children.Insert(0, newLayoutDocumentPane); - } - else - { - var manager = parentModel.Root.Manager; - if (!manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Vertical) - { - parentModel.Orientation = System.Windows.Controls.Orientation.Vertical; - int targetPaneIndex = parentModel.IndexOfChild(targetModel); - parentModel.Children.Insert(targetPaneIndex, newLayoutDocumentPane); - } - else - { - LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); - newChildGroup.Orientation = System.Windows.Controls.Orientation.Vertical; - parentModel.ReplaceChild(targetModel, newChildGroup); - newChildGroup.Children.Add(newLayoutDocumentPane); - newChildGroup.Children.Add(targetModel); - } - - } - } - break; - #endregion - case DropTargetType.DocumentPaneDockLeft: - #region DropTargetType.DocumentPaneDockLeft - { - var newLayoutDocumentPane = new LayoutDocumentPane(floatingWindow.RootDocument); - var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; - - if (parentModel == null) - { - var parentContainer = targetModel.Parent as ILayoutContainer; - var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Horizontal }; - parentContainer.ReplaceChild(targetModel, newParentModel); - newParentModel.Children.Add(targetModel); - newParentModel.Children.Insert(0, newLayoutDocumentPane); - } - else - { - var manager = parentModel.Root.Manager; - if (!manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Horizontal) - { - parentModel.Orientation = System.Windows.Controls.Orientation.Horizontal; - int targetPaneIndex = parentModel.IndexOfChild(targetModel); - parentModel.Children.Insert(targetPaneIndex, newLayoutDocumentPane); - } - else - { - LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); - newChildGroup.Orientation = System.Windows.Controls.Orientation.Horizontal; - parentModel.ReplaceChild(targetModel, newChildGroup); - newChildGroup.Children.Add(newLayoutDocumentPane); - newChildGroup.Children.Add(targetModel); - } - } - } - break; - #endregion - case DropTargetType.DocumentPaneDockRight: - #region DropTargetType.DocumentPaneDockRight - { - var newLayoutDocumentPane = new LayoutDocumentPane(floatingWindow.RootDocument); - var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; - - if (parentModel == null) - { - var parentContainer = targetModel.Parent as ILayoutContainer; - var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Horizontal }; - parentContainer.ReplaceChild(targetModel, newParentModel); - newParentModel.Children.Add(targetModel as LayoutDocumentPane); - newParentModel.Children.Add(newLayoutDocumentPane); - } - else - { - var manager = parentModel.Root.Manager; - if (!manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Horizontal) - { - parentModel.Orientation = System.Windows.Controls.Orientation.Horizontal; - int targetPaneIndex = parentModel.IndexOfChild(targetModel); - parentModel.Children.Insert(targetPaneIndex + 1, newLayoutDocumentPane); - } - else - { - LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); - newChildGroup.Orientation = System.Windows.Controls.Orientation.Horizontal; - parentModel.ReplaceChild(targetModel, newChildGroup); - newChildGroup.Children.Add(targetModel); - newChildGroup.Children.Add(newLayoutDocumentPane); - } - - } - } - break; - #endregion - - case DropTargetType.DocumentPaneDockInside: - #region DropTargetType.DocumentPaneDockInside - { - var paneModel = targetModel as LayoutDocumentPane; - var sourceModel = floatingWindow.RootDocument; - - int i = 0; - if( _tabIndex != -1 ) - { - i = _tabIndex; - } - else - { - var previousContainer = ((ILayoutPreviousContainer)sourceModel).PreviousContainer; - if( object.ReferenceEquals( previousContainer, targetModel ) && (sourceModel.PreviousContainerIndex != -1) ) - { - i = sourceModel.PreviousContainerIndex; - } - } - sourceModel.IsActive = false; - paneModel.Children.Insert(i, sourceModel); - sourceModel.IsActive = true; - } - break; - #endregion + var manager = parentModel.Root.Manager; + if( !manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Vertical ) + { + parentModel.Orientation = System.Windows.Controls.Orientation.Vertical; + int targetPaneIndex = parentModel.IndexOfChild( targetModel ); + parentModel.Children.Insert( targetPaneIndex + 1, newLayoutDocumentPane ); + } + else + { + LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); + newChildGroup.Orientation = System.Windows.Controls.Orientation.Vertical; + parentModel.ReplaceChild( targetModel, newChildGroup ); + newChildGroup.Children.Add( targetModel ); + newChildGroup.Children.Add( newLayoutDocumentPane ); + } + } + foreach( var cntToTransfer in floatingWindow.RootPanel.Descendents().OfType().ToArray() ) + newLayoutDocumentPane.Children.Add( cntToTransfer ); + } + break; + #endregion + case DropTargetType.DocumentPaneDockTop: + #region DropTargetType.DocumentPaneDockTop + { + var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; + var newLayoutDocumentPane = new LayoutDocumentPane(); + + if( parentModel == null ) + { + var parentContainer = targetModel.Parent as ILayoutContainer; + var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Vertical }; + parentContainer.ReplaceChild( targetModel, newParentModel ); + newParentModel.Children.Add( newLayoutDocumentPane ); + newParentModel.Children.Add( targetModel as LayoutDocumentPane ); + } + else + { + var manager = parentModel.Root.Manager; + if( !manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Vertical ) + { + parentModel.Orientation = System.Windows.Controls.Orientation.Vertical; + int targetPaneIndex = parentModel.IndexOfChild( targetModel ); + parentModel.Children.Insert( targetPaneIndex, newLayoutDocumentPane ); + } + else + { + LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); + newChildGroup.Orientation = System.Windows.Controls.Orientation.Vertical; + parentModel.ReplaceChild( targetModel, newChildGroup ); + newChildGroup.Children.Add( newLayoutDocumentPane ); + newChildGroup.Children.Add( targetModel ); + } } - base.Drop(floatingWindow); - } + foreach( var cntToTransfer in floatingWindow.RootPanel.Descendents().OfType().ToArray() ) + newLayoutDocumentPane.Children.Add( cntToTransfer ); - protected override void Drop(LayoutAnchorableFloatingWindow floatingWindow) - { - ILayoutDocumentPane targetModel = _targetPane.Model as ILayoutDocumentPane; + } + break; + #endregion + case DropTargetType.DocumentPaneDockLeft: + #region DropTargetType.DocumentPaneDockLeft + { + var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; + var newLayoutDocumentPane = new LayoutDocumentPane(); - switch (Type) + if( parentModel == null ) { - case DropTargetType.DocumentPaneDockBottom: - #region DropTargetType.DocumentPaneDockBottom - { - var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; - var newLayoutDocumentPane = new LayoutDocumentPane(); - - if (parentModel == null) - { - var parentContainer = targetModel.Parent as ILayoutContainer; - var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Vertical }; - parentContainer.ReplaceChild(targetModel, newParentModel); - newParentModel.Children.Add(targetModel as LayoutDocumentPane); - newParentModel.Children.Add(newLayoutDocumentPane); - } - else - { - var manager = parentModel.Root.Manager; - if (!manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Vertical) - { - parentModel.Orientation = System.Windows.Controls.Orientation.Vertical; - int targetPaneIndex = parentModel.IndexOfChild(targetModel); - parentModel.Children.Insert(targetPaneIndex + 1, newLayoutDocumentPane); - } - else - { - LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); - newChildGroup.Orientation = System.Windows.Controls.Orientation.Vertical; - parentModel.ReplaceChild(targetModel, newChildGroup); - newChildGroup.Children.Add(targetModel); - newChildGroup.Children.Add(newLayoutDocumentPane); - } - } - - foreach (var cntToTransfer in floatingWindow.RootPanel.Descendents().OfType().ToArray()) - newLayoutDocumentPane.Children.Add(cntToTransfer); - - } - break; - #endregion - case DropTargetType.DocumentPaneDockTop: - #region DropTargetType.DocumentPaneDockTop - { - var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; - var newLayoutDocumentPane = new LayoutDocumentPane(); - - if (parentModel == null) - { - var parentContainer = targetModel.Parent as ILayoutContainer; - var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Vertical }; - parentContainer.ReplaceChild(targetModel, newParentModel); - newParentModel.Children.Add(newLayoutDocumentPane); - newParentModel.Children.Add(targetModel as LayoutDocumentPane); - } - else - { - var manager = parentModel.Root.Manager; - if (!manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Vertical) - { - parentModel.Orientation = System.Windows.Controls.Orientation.Vertical; - int targetPaneIndex = parentModel.IndexOfChild(targetModel); - parentModel.Children.Insert(targetPaneIndex, newLayoutDocumentPane); - } - else - { - LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); - newChildGroup.Orientation = System.Windows.Controls.Orientation.Vertical; - parentModel.ReplaceChild(targetModel, newChildGroup); - newChildGroup.Children.Add(newLayoutDocumentPane); - newChildGroup.Children.Add(targetModel); - } - } - - foreach (var cntToTransfer in floatingWindow.RootPanel.Descendents().OfType().ToArray()) - newLayoutDocumentPane.Children.Add(cntToTransfer); - - } - break; - #endregion - case DropTargetType.DocumentPaneDockLeft: - #region DropTargetType.DocumentPaneDockLeft - { - var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; - var newLayoutDocumentPane = new LayoutDocumentPane(); - - if (parentModel == null) - { - var parentContainer = targetModel.Parent as ILayoutContainer; - var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Horizontal }; - parentContainer.ReplaceChild(targetModel, newParentModel); - newParentModel.Children.Add(newLayoutDocumentPane); - newParentModel.Children.Add(targetModel as LayoutDocumentPane); - } - else - { - var manager = parentModel.Root.Manager; - if (!manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Horizontal) - { - parentModel.Orientation = System.Windows.Controls.Orientation.Horizontal; - int targetPaneIndex = parentModel.IndexOfChild(targetModel); - parentModel.Children.Insert(targetPaneIndex, newLayoutDocumentPane); - } - else - { - LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); - newChildGroup.Orientation = System.Windows.Controls.Orientation.Horizontal; - parentModel.ReplaceChild(targetModel, newChildGroup); - newChildGroup.Children.Add(newLayoutDocumentPane); - newChildGroup.Children.Add(targetModel); - } - - } - - foreach (var cntToTransfer in floatingWindow.RootPanel.Descendents().OfType().ToArray()) - newLayoutDocumentPane.Children.Add(cntToTransfer); - - } - break; - #endregion - case DropTargetType.DocumentPaneDockRight: - #region DropTargetType.DocumentPaneDockRight - { - var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; - var newLayoutDocumentPane = new LayoutDocumentPane(); - - if (parentModel == null) - { - var parentContainer = targetModel.Parent as ILayoutContainer; - var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Horizontal }; - parentContainer.ReplaceChild(targetModel, newParentModel); - newParentModel.Children.Add(targetModel as LayoutDocumentPane); - newParentModel.Children.Add(newLayoutDocumentPane); - } - else - { - var manager = parentModel.Root.Manager; - if (!manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Horizontal) - { - parentModel.Orientation = System.Windows.Controls.Orientation.Horizontal; - int targetPaneIndex = parentModel.IndexOfChild(targetModel); - parentModel.Children.Insert(targetPaneIndex + 1, newLayoutDocumentPane); - } - else - { - LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); - newChildGroup.Orientation = System.Windows.Controls.Orientation.Horizontal; - parentModel.ReplaceChild(targetModel, newChildGroup); - newChildGroup.Children.Add(targetModel); - newChildGroup.Children.Add(newLayoutDocumentPane); - } - } - - foreach (var cntToTransfer in floatingWindow.RootPanel.Descendents().OfType().ToArray()) - newLayoutDocumentPane.Children.Add(cntToTransfer); - - } - break; - #endregion - case DropTargetType.DocumentPaneDockInside: - #region DropTargetType.DocumentPaneDockInside - { - var paneModel = targetModel as LayoutDocumentPane; - var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; - - bool checkPreviousContainer = true; - int i = 0; - if( _tabIndex != -1 ) - { - i = _tabIndex; - checkPreviousContainer = false; - } - LayoutAnchorable anchorableToActivate = null; - - foreach (var anchorableToImport in layoutAnchorablePaneGroup.Descendents().OfType().ToArray()) - { - if( checkPreviousContainer ) - { - var previousContainer = ((ILayoutPreviousContainer)anchorableToImport).PreviousContainer; - if( object.ReferenceEquals( previousContainer, targetModel ) && (anchorableToImport.PreviousContainerIndex != -1) ) - { - i = anchorableToImport.PreviousContainerIndex; - } - checkPreviousContainer = false; - } - - paneModel.Children.Insert(i, anchorableToImport); - i++; - anchorableToActivate = anchorableToImport; - } - - anchorableToActivate.IsActive = true; - } - break; - #endregion + var parentContainer = targetModel.Parent as ILayoutContainer; + var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Horizontal }; + parentContainer.ReplaceChild( targetModel, newParentModel ); + newParentModel.Children.Add( newLayoutDocumentPane ); + newParentModel.Children.Add( targetModel as LayoutDocumentPane ); } + else + { + var manager = parentModel.Root.Manager; + if( !manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Horizontal ) + { + parentModel.Orientation = System.Windows.Controls.Orientation.Horizontal; + int targetPaneIndex = parentModel.IndexOfChild( targetModel ); + parentModel.Children.Insert( targetPaneIndex, newLayoutDocumentPane ); + } + else + { + LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); + newChildGroup.Orientation = System.Windows.Controls.Orientation.Horizontal; + parentModel.ReplaceChild( targetModel, newChildGroup ); + newChildGroup.Children.Add( newLayoutDocumentPane ); + newChildGroup.Children.Add( targetModel ); + } + + } + + foreach( var cntToTransfer in floatingWindow.RootPanel.Descendents().OfType().ToArray() ) + newLayoutDocumentPane.Children.Add( cntToTransfer ); - base.Drop(floatingWindow); - } + } + break; + #endregion + case DropTargetType.DocumentPaneDockRight: + #region DropTargetType.DocumentPaneDockRight + { + var parentModel = targetModel.Parent as LayoutDocumentPaneGroup; + var newLayoutDocumentPane = new LayoutDocumentPane(); - public override System.Windows.Media.Geometry GetPreviewPath(OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindowModel) - { - switch (Type) + if( parentModel == null ) { - case DropTargetType.DocumentPaneDockInside: - { - var targetScreenRect = TargetElement.GetScreenArea(); - targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - - if (_tabIndex == -1) - { - return new RectangleGeometry(targetScreenRect); - } - else - { - var translatedDetectionRect = new Rect(DetectionRects[0].TopLeft, DetectionRects[0].BottomRight); - translatedDetectionRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - - var pathFigure = new PathFigure(); - pathFigure.StartPoint = targetScreenRect.BottomRight; - pathFigure.Segments.Add(new LineSegment() { Point = new Point(targetScreenRect.Right, translatedDetectionRect.Bottom) }); - pathFigure.Segments.Add(new LineSegment() { Point = translatedDetectionRect.BottomRight }); - pathFigure.Segments.Add(new LineSegment() { Point = translatedDetectionRect.TopRight }); - pathFigure.Segments.Add(new LineSegment() { Point = translatedDetectionRect.TopLeft }); - pathFigure.Segments.Add(new LineSegment() { Point = translatedDetectionRect.BottomLeft }); - pathFigure.Segments.Add(new LineSegment() { Point = new Point(targetScreenRect.Left, translatedDetectionRect.Bottom) }); - pathFigure.Segments.Add(new LineSegment() { Point = targetScreenRect.BottomLeft }); - pathFigure.IsClosed = true; - pathFigure.IsFilled = true; - pathFigure.Freeze(); - return new PathGeometry(new PathFigure[] { pathFigure }); - } - } - case DropTargetType.DocumentPaneDockBottom: - { - var targetScreenRect = TargetElement.GetScreenArea(); - targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - targetScreenRect.Offset(0.0, targetScreenRect.Height / 2.0); - targetScreenRect.Height /= 2.0; - return new RectangleGeometry(targetScreenRect); - } - case DropTargetType.DocumentPaneDockTop: - { - var targetScreenRect = TargetElement.GetScreenArea(); - targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - targetScreenRect.Height /= 2.0; - return new RectangleGeometry(targetScreenRect); - } - case DropTargetType.DocumentPaneDockLeft: - { - var targetScreenRect = TargetElement.GetScreenArea(); - targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - targetScreenRect.Width /= 2.0; - return new RectangleGeometry(targetScreenRect); - } - case DropTargetType.DocumentPaneDockRight: - { - var targetScreenRect = TargetElement.GetScreenArea(); - targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - targetScreenRect.Offset(targetScreenRect.Width / 2.0, 0.0); - targetScreenRect.Width /= 2.0; - return new RectangleGeometry(targetScreenRect); - } + var parentContainer = targetModel.Parent as ILayoutContainer; + var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Horizontal }; + parentContainer.ReplaceChild( targetModel, newParentModel ); + newParentModel.Children.Add( targetModel as LayoutDocumentPane ); + newParentModel.Children.Add( newLayoutDocumentPane ); + } + else + { + var manager = parentModel.Root.Manager; + if( !manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Horizontal ) + { + parentModel.Orientation = System.Windows.Controls.Orientation.Horizontal; + int targetPaneIndex = parentModel.IndexOfChild( targetModel ); + parentModel.Children.Insert( targetPaneIndex + 1, newLayoutDocumentPane ); + } + else + { + LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup(); + newChildGroup.Orientation = System.Windows.Controls.Orientation.Horizontal; + parentModel.ReplaceChild( targetModel, newChildGroup ); + newChildGroup.Children.Add( targetModel ); + newChildGroup.Children.Add( newLayoutDocumentPane ); + } + } + + foreach( var cntToTransfer in floatingWindow.RootPanel.Descendents().OfType().ToArray() ) + newLayoutDocumentPane.Children.Add( cntToTransfer ); + + } + break; + #endregion + case DropTargetType.DocumentPaneDockInside: + #region DropTargetType.DocumentPaneDockInside + { + var paneModel = targetModel as LayoutDocumentPane; + var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; + + bool checkPreviousContainer = true; + int i = 0; + if( _tabIndex != -1 ) + { + i = _tabIndex; + checkPreviousContainer = false; + } + LayoutAnchorable anchorableToActivate = null; + + foreach( var anchorableToImport in layoutAnchorablePaneGroup.Descendents().OfType().ToArray() ) + { + if( checkPreviousContainer ) + { + var previousContainer = ( ( ILayoutPreviousContainer )anchorableToImport ).PreviousContainer; + if( object.ReferenceEquals( previousContainer, targetModel ) && ( anchorableToImport.PreviousContainerIndex != -1 ) ) + { + i = anchorableToImport.PreviousContainerIndex; + } + checkPreviousContainer = false; + } + + anchorableToImport.SetCanCloseInternal( true ); + + paneModel.Children.Insert( i, anchorableToImport ); + i++; + anchorableToActivate = anchorableToImport; } - return null; - } + anchorableToActivate.IsActive = true; + } + break; + #endregion + } + base.Drop( floatingWindow ); } + + public override System.Windows.Media.Geometry GetPreviewPath( OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindowModel ) + { + switch( Type ) + { + case DropTargetType.DocumentPaneDockInside: + { + var targetScreenRect = TargetElement.GetScreenArea(); + targetScreenRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + + if( _tabIndex == -1 ) + { + return new RectangleGeometry( targetScreenRect ); + } + else + { + var translatedDetectionRect = new Rect( DetectionRects[ 0 ].TopLeft, DetectionRects[ 0 ].BottomRight ); + translatedDetectionRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + + var pathFigure = new PathFigure(); + pathFigure.StartPoint = targetScreenRect.BottomRight; + pathFigure.Segments.Add( new LineSegment() { Point = new Point( targetScreenRect.Right, translatedDetectionRect.Bottom ) } ); + pathFigure.Segments.Add( new LineSegment() { Point = translatedDetectionRect.BottomRight } ); + pathFigure.Segments.Add( new LineSegment() { Point = translatedDetectionRect.TopRight } ); + pathFigure.Segments.Add( new LineSegment() { Point = translatedDetectionRect.TopLeft } ); + pathFigure.Segments.Add( new LineSegment() { Point = translatedDetectionRect.BottomLeft } ); + pathFigure.Segments.Add( new LineSegment() { Point = new Point( targetScreenRect.Left, translatedDetectionRect.Bottom ) } ); + pathFigure.Segments.Add( new LineSegment() { Point = targetScreenRect.BottomLeft } ); + pathFigure.IsClosed = true; + pathFigure.IsFilled = true; + pathFigure.Freeze(); + return new PathGeometry( new PathFigure[] { pathFigure } ); + } + } + case DropTargetType.DocumentPaneDockBottom: + { + var targetScreenRect = TargetElement.GetScreenArea(); + targetScreenRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + targetScreenRect.Offset( 0.0, targetScreenRect.Height / 2.0 ); + targetScreenRect.Height /= 2.0; + return new RectangleGeometry( targetScreenRect ); + } + case DropTargetType.DocumentPaneDockTop: + { + var targetScreenRect = TargetElement.GetScreenArea(); + targetScreenRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + targetScreenRect.Height /= 2.0; + return new RectangleGeometry( targetScreenRect ); + } + case DropTargetType.DocumentPaneDockLeft: + { + var targetScreenRect = TargetElement.GetScreenArea(); + targetScreenRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + targetScreenRect.Width /= 2.0; + return new RectangleGeometry( targetScreenRect ); + } + case DropTargetType.DocumentPaneDockRight: + { + var targetScreenRect = TargetElement.GetScreenArea(); + targetScreenRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + targetScreenRect.Offset( targetScreenRect.Width / 2.0, 0.0 ); + targetScreenRect.Width /= 2.0; + return new RectangleGeometry( targetScreenRect ); + } + } + + return null; + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneGroupDropTarget.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneGroupDropTarget.cs index 91eb732e..85812499 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneGroupDropTarget.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneGroupDropTarget.cs @@ -14,92 +14,101 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows; using System.Windows.Media; -using System.Diagnostics; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Controls { - internal class DocumentPaneGroupDropTarget : DropTarget + internal class DocumentPaneGroupDropTarget : DropTarget + { + #region Constructors + + internal DocumentPaneGroupDropTarget( LayoutDocumentPaneGroupControl paneControl, Rect detectionRect, DropTargetType type ) + : base( paneControl, detectionRect, type ) { - internal DocumentPaneGroupDropTarget(LayoutDocumentPaneGroupControl paneControl, Rect detectionRect, DropTargetType type) - : base(paneControl, detectionRect, type) - { - _targetPane = paneControl; - } + _targetPane = paneControl; + } - LayoutDocumentPaneGroupControl _targetPane; + #endregion - protected override void Drop(LayoutDocumentFloatingWindow floatingWindow) - { - ILayoutPane targetModel = _targetPane.Model as ILayoutPane; + #region Members - switch (Type) - { - case DropTargetType.DocumentPaneGroupDockInside: - #region DropTargetType.DocumentPaneGroupDockInside - { - var paneGroupModel = targetModel as LayoutDocumentPaneGroup; - var paneModel = paneGroupModel.Children[0] as LayoutDocumentPane; - var sourceModel = floatingWindow.RootDocument; - - paneModel.Children.Insert(0, sourceModel); - } - break; - #endregion - } - base.Drop(floatingWindow); - } + private LayoutDocumentPaneGroupControl _targetPane; - protected override void Drop(LayoutAnchorableFloatingWindow floatingWindow) - { - ILayoutPane targetModel = _targetPane.Model as ILayoutPane; + #endregion - switch (Type) - { - case DropTargetType.DocumentPaneGroupDockInside: - #region DropTargetType.DocumentPaneGroupDockInside - { - var paneGroupModel = targetModel as LayoutDocumentPaneGroup; - var paneModel = paneGroupModel.Children[0] as LayoutDocumentPane; - var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; - - int i = 0; - foreach (var anchorableToImport in layoutAnchorablePaneGroup.Descendents().OfType().ToArray()) - { - paneModel.Children.Insert(i, anchorableToImport); - i++; - } - } - break; - #endregion - } + #region Overrides - base.Drop(floatingWindow); - } + protected override void Drop( LayoutDocumentFloatingWindow floatingWindow ) + { + ILayoutPane targetModel = _targetPane.Model as ILayoutPane; + + switch( Type ) + { + case DropTargetType.DocumentPaneGroupDockInside: + #region DropTargetType.DocumentPaneGroupDockInside + { + var paneGroupModel = targetModel as LayoutDocumentPaneGroup; + var paneModel = paneGroupModel.Children[ 0 ] as LayoutDocumentPane; + var sourceModel = floatingWindow.RootDocument; + + paneModel.Children.Insert( 0, sourceModel ); + } + break; + #endregion + } + base.Drop( floatingWindow ); + } - public override System.Windows.Media.Geometry GetPreviewPath(OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindowModel) - { - switch (Type) + protected override void Drop( LayoutAnchorableFloatingWindow floatingWindow ) + { + ILayoutPane targetModel = _targetPane.Model as ILayoutPane; + + switch( Type ) + { + case DropTargetType.DocumentPaneGroupDockInside: + #region DropTargetType.DocumentPaneGroupDockInside + { + var paneGroupModel = targetModel as LayoutDocumentPaneGroup; + var paneModel = paneGroupModel.Children[ 0 ] as LayoutDocumentPane; + var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup; + + int i = 0; + foreach( var anchorableToImport in layoutAnchorablePaneGroup.Descendents().OfType().ToArray() ) { - case DropTargetType.DocumentPaneGroupDockInside: - #region DropTargetType.DocumentPaneGroupDockInside - { - var targetScreenRect = TargetElement.GetScreenArea(); - targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top); - - return new RectangleGeometry(targetScreenRect); - } - #endregion + anchorableToImport.SetCanCloseInternal( true ); + + paneModel.Children.Insert( i, anchorableToImport ); + i++; } + } + break; + #endregion + } - return null; - } + base.Drop( floatingWindow ); + } + public override System.Windows.Media.Geometry GetPreviewPath( OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindowModel ) + { + switch( Type ) + { + case DropTargetType.DocumentPaneGroupDockInside: + #region DropTargetType.DocumentPaneGroupDockInside + { + var targetScreenRect = TargetElement.GetScreenArea(); + targetScreenRect.Offset( -overlayWindow.Left, -overlayWindow.Top ); + + return new RectangleGeometry( targetScreenRect ); + } + #endregion + } + + return null; } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneTabPanel.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneTabPanel.cs index a869f7c5..1bacd43e 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneTabPanel.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DocumentPaneTabPanel.cs @@ -15,92 +15,97 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows.Controls; using System.Windows; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Controls { - public class DocumentPaneTabPanel : Panel + public class DocumentPaneTabPanel : Panel + { + #region Constructors + + public DocumentPaneTabPanel() { - public DocumentPaneTabPanel() - { - FlowDirection = System.Windows.FlowDirection.LeftToRight; - } + this.FlowDirection = System.Windows.FlowDirection.LeftToRight; + } - protected override Size MeasureOverride(Size availableSize) - { - var visibleChildren = Children.Cast().Where(ch => ch.Visibility != System.Windows.Visibility.Collapsed); + #endregion - Size desideredSize = new Size(); - foreach (FrameworkElement child in Children) - { - child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); - desideredSize.Width += child.DesiredSize.Width; + #region Overrides - desideredSize.Height = Math.Max(desideredSize.Height, child.DesiredSize.Height); - } + protected override Size MeasureOverride( Size availableSize ) + { + var visibleChildren = Children.Cast().Where( ch => ch.Visibility != System.Windows.Visibility.Collapsed ); - return new Size(Math.Min(desideredSize.Width, availableSize.Width), desideredSize.Height); - } + Size desideredSize = new Size(); + foreach( FrameworkElement child in Children ) + { + child.Measure( new Size( double.PositiveInfinity, double.PositiveInfinity ) ); + desideredSize.Width += child.DesiredSize.Width; + + desideredSize.Height = Math.Max( desideredSize.Height, child.DesiredSize.Height ); + } + + return new Size( Math.Min( desideredSize.Width, availableSize.Width ), desideredSize.Height ); + } - protected override Size ArrangeOverride(Size finalSize) + protected override Size ArrangeOverride( Size finalSize ) + { + var visibleChildren = Children.Cast().Where( ch => ch.Visibility != System.Windows.Visibility.Collapsed ); + var offset = 0.0; + var skipAllOthers = false; + foreach( TabItem doc in visibleChildren ) + { + var layoutContent = doc.Content as LayoutContent; + if( skipAllOthers || offset + doc.DesiredSize.Width > finalSize.Width ) { - var visibleChildren = Children.Cast().Where( ch => ch.Visibility != System.Windows.Visibility.Collapsed ); - var offset = 0.0; - var skipAllOthers = false; - foreach( TabItem doc in visibleChildren ) + if( layoutContent.IsSelected && !doc.IsVisible ) { - var layoutContent = doc.Content as LayoutContent; - if( skipAllOthers || offset + doc.DesiredSize.Width > finalSize.Width ) - { - if( layoutContent.IsSelected && !doc.IsVisible ) - { - var parentContainer = layoutContent.Parent as ILayoutContainer; - var parentSelector = layoutContent.Parent as ILayoutContentSelector; - var parentPane = layoutContent.Parent as ILayoutPane; - int contentIndex = parentSelector.IndexOf( layoutContent ); - if( contentIndex > 0 && - parentContainer.ChildrenCount > 1 ) - { - parentPane.MoveChild( contentIndex, 0 ); - parentSelector.SelectedContentIndex = 0; - return ArrangeOverride( finalSize ); - } - } - doc.Visibility = System.Windows.Visibility.Hidden; - skipAllOthers = true; - } - else + var parentContainer = layoutContent.Parent as ILayoutContainer; + var parentSelector = layoutContent.Parent as ILayoutContentSelector; + var parentPane = layoutContent.Parent as ILayoutPane; + int contentIndex = parentSelector.IndexOf( layoutContent ); + if( contentIndex > 0 && + parentContainer.ChildrenCount > 1 ) { - doc.Visibility = System.Windows.Visibility.Visible; - doc.Arrange( new Rect( offset, 0.0, doc.DesiredSize.Width, finalSize.Height ) ); - offset += doc.ActualWidth + doc.Margin.Left + doc.Margin.Right; + parentPane.MoveChild( contentIndex, 0 ); + parentSelector.SelectedContentIndex = 0; + return ArrangeOverride( finalSize ); } } - return finalSize; - + doc.Visibility = System.Windows.Visibility.Hidden; + skipAllOthers = true; + } + else + { + doc.Visibility = System.Windows.Visibility.Visible; + doc.Arrange( new Rect( offset, 0.0, doc.DesiredSize.Width, finalSize.Height ) ); + offset += doc.ActualWidth + doc.Margin.Left + doc.Margin.Right; } + } + return finalSize; + } - protected override void OnMouseLeave(System.Windows.Input.MouseEventArgs e) - { - //if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed && - // LayoutDocumentTabItem.IsDraggingItem()) - //{ - // var contentModel = LayoutDocumentTabItem.GetDraggingItem().Model; - // var manager = contentModel.Root.Manager; - // LayoutDocumentTabItem.ResetDraggingItem(); - // System.Diagnostics.Trace.WriteLine("OnMouseLeave()"); + protected override void OnMouseLeave( System.Windows.Input.MouseEventArgs e ) + { + //if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed && + // LayoutDocumentTabItem.IsDraggingItem()) + //{ + // var contentModel = LayoutDocumentTabItem.GetDraggingItem().Model; + // var manager = contentModel.Root.Manager; + // LayoutDocumentTabItem.ResetDraggingItem(); + // System.Diagnostics.Trace.WriteLine("OnMouseLeave()"); - // manager.StartDraggingFloatingWindowForContent(contentModel); - //} + // manager.StartDraggingFloatingWindowForContent(contentModel); + //} - base.OnMouseLeave(e); - } + base.OnMouseLeave( e ); } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DragService.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DragService.cs index 206e0927..1a533575 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DragService.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DragService.cs @@ -14,177 +14,188 @@ ***********************************************************************************/ -using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Windows.Input; using System.Windows; -using System.Diagnostics; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Controls { - class DragService + internal class DragService + { + #region Members + + private DockingManager _manager; + private LayoutFloatingWindowControl _floatingWindow; + private List _overlayWindowHosts = new List(); + private IOverlayWindowHost _currentHost; + private IOverlayWindow _currentWindow; + private List _currentWindowAreas = new List(); + private IDropTarget _currentDropTarget; + + #endregion + + #region Public Methods + + public DragService( LayoutFloatingWindowControl floatingWindow ) { - DockingManager _manager; - LayoutFloatingWindowControl _floatingWindow; + _floatingWindow = floatingWindow; + _manager = floatingWindow.Model.Root.Manager; - public DragService(LayoutFloatingWindowControl floatingWindow) - { - _floatingWindow = floatingWindow; - _manager = floatingWindow.Model.Root.Manager; + GetOverlayWindowHosts(); + } + + public void UpdateMouseLocation( Point dragPosition ) + { + var floatingWindowModel = _floatingWindow.Model as LayoutFloatingWindow; + + var newHost = _overlayWindowHosts.FirstOrDefault( oh => oh.HitTest( dragPosition ) ); - GetOverlayWindowHosts(); + if( _currentHost != null || _currentHost != newHost ) + { + //is mouse still inside current overlay window host? + if( ( _currentHost != null && !_currentHost.HitTest( dragPosition ) ) || + _currentHost != newHost ) + { + //esit drop target + if( _currentDropTarget != null ) + _currentWindow.DragLeave( _currentDropTarget ); + _currentDropTarget = null; + + //exit area + _currentWindowAreas.ForEach( a => + _currentWindow.DragLeave( a ) ); + _currentWindowAreas.Clear(); + + //hide current overlay window + if( _currentWindow != null ) + _currentWindow.DragLeave( _floatingWindow ); + if( _currentHost != null ) + _currentHost.HideOverlayWindow(); + _currentHost = null; } - List _overlayWindowHosts = new List(); - void GetOverlayWindowHosts() + if( _currentHost != newHost ) + { + _currentHost = newHost; + _currentWindow = _currentHost.ShowOverlayWindow( _floatingWindow ); + _currentWindow.DragEnter( _floatingWindow ); + } + } + + if( _currentHost == null ) + return; + + if( _currentDropTarget != null && + !_currentDropTarget.HitTest( dragPosition ) ) + { + _currentWindow.DragLeave( _currentDropTarget ); + _currentDropTarget = null; + } + + List areasToRemove = new List(); + _currentWindowAreas.ForEach( a => + { + //is mouse still inside this area? + if( !a.DetectionRect.Contains( dragPosition ) ) { - _overlayWindowHosts.AddRange(_manager.GetFloatingWindowsByZOrder().OfType().Where(fw => fw != _floatingWindow && fw.IsVisible)); - _overlayWindowHosts.Add(_manager); + _currentWindow.DragLeave( a ); + areasToRemove.Add( a ); } + } ); + + areasToRemove.ForEach( a => + _currentWindowAreas.Remove( a ) ); + + + var areasToAdd = + _currentHost.GetDropAreas( _floatingWindow ).Where( cw => !_currentWindowAreas.Contains( cw ) && cw.DetectionRect.Contains( dragPosition ) ).ToList(); + + _currentWindowAreas.AddRange( areasToAdd ); - IOverlayWindowHost _currentHost; - IOverlayWindow _currentWindow; - List _currentWindowAreas = new List(); - IDropTarget _currentDropTarget; + areasToAdd.ForEach( a => + _currentWindow.DragEnter( a ) ); - public void UpdateMouseLocation(Point dragPosition) + if( _currentDropTarget == null ) + { + _currentWindowAreas.ForEach( wa => { - var floatingWindowModel = _floatingWindow.Model as LayoutFloatingWindow; - - var newHost = _overlayWindowHosts.FirstOrDefault(oh => oh.HitTest(dragPosition)); - - if (_currentHost != null || _currentHost != newHost) - { - //is mouse still inside current overlay window host? - if ((_currentHost != null && !_currentHost.HitTest(dragPosition)) || - _currentHost != newHost) - { - //esit drop target - if (_currentDropTarget != null) - _currentWindow.DragLeave(_currentDropTarget); - _currentDropTarget = null; - - //exit area - _currentWindowAreas.ForEach(a => - _currentWindow.DragLeave(a)); - _currentWindowAreas.Clear(); - - //hide current overlay window - if (_currentWindow != null) - _currentWindow.DragLeave(_floatingWindow); - if (_currentHost != null) - _currentHost.HideOverlayWindow(); - _currentHost = null; - } - - if (_currentHost != newHost) - { - _currentHost = newHost; - _currentWindow = _currentHost.ShowOverlayWindow(_floatingWindow); - _currentWindow.DragEnter(_floatingWindow); - } - } - - if (_currentHost == null) - return; - - if (_currentDropTarget != null && - !_currentDropTarget.HitTest(dragPosition)) - { - _currentWindow.DragLeave(_currentDropTarget); - _currentDropTarget = null; - } - - List areasToRemove = new List(); - _currentWindowAreas.ForEach(a => - { - //is mouse still inside this area? - if (!a.DetectionRect.Contains(dragPosition)) - { - _currentWindow.DragLeave(a); - areasToRemove.Add(a); - } - }); - - areasToRemove.ForEach(a => - _currentWindowAreas.Remove(a)); - - - var areasToAdd = - _currentHost.GetDropAreas(_floatingWindow).Where(cw => !_currentWindowAreas.Contains(cw) && cw.DetectionRect.Contains(dragPosition)).ToList(); - - _currentWindowAreas.AddRange(areasToAdd); - - areasToAdd.ForEach(a => - _currentWindow.DragEnter(a)); - - if (_currentDropTarget == null) - { - _currentWindowAreas.ForEach(wa => - { - if (_currentDropTarget != null) - return; - - _currentDropTarget = _currentWindow.GetTargets().FirstOrDefault(dt => dt.HitTest(dragPosition)); - if (_currentDropTarget != null) - { - _currentWindow.DragEnter(_currentDropTarget); - return; - } - }); - } + if( _currentDropTarget != null ) + return; + + _currentDropTarget = _currentWindow.GetTargets().FirstOrDefault( dt => dt.HitTest( dragPosition ) ); + if( _currentDropTarget != null ) + { + _currentWindow.DragEnter( _currentDropTarget ); + return; + } + } ); + } - } + } - public void Drop(Point dropLocation, out bool dropHandled) - { - dropHandled = false; + public void Drop( Point dropLocation, out bool dropHandled ) + { + dropHandled = false; - UpdateMouseLocation(dropLocation); + UpdateMouseLocation( dropLocation ); - var floatingWindowModel = _floatingWindow.Model as LayoutFloatingWindow; - var root = floatingWindowModel.Root; + var floatingWindowModel = _floatingWindow.Model as LayoutFloatingWindow; + var root = floatingWindowModel.Root; - if (_currentHost != null) - _currentHost.HideOverlayWindow(); + if( _currentHost != null ) + _currentHost.HideOverlayWindow(); - if (_currentDropTarget != null) - { - _currentWindow.DragDrop(_currentDropTarget); - root.CollectGarbage(); - dropHandled = true; - } + if( _currentDropTarget != null ) + { + _currentWindow.DragDrop( _currentDropTarget ); + root.CollectGarbage(); + dropHandled = true; + } - _currentWindowAreas.ForEach(a => _currentWindow.DragLeave(a)); + _currentWindowAreas.ForEach( a => _currentWindow.DragLeave( a ) ); - if (_currentDropTarget != null) - _currentWindow.DragLeave(_currentDropTarget); - if (_currentWindow != null) - _currentWindow.DragLeave(_floatingWindow); - _currentWindow = null; + if( _currentDropTarget != null ) + _currentWindow.DragLeave( _currentDropTarget ); + if( _currentWindow != null ) + _currentWindow.DragLeave( _floatingWindow ); + _currentWindow = null; - _currentHost = null; - } + _currentHost = null; + } - internal void Abort() - { - var floatingWindowModel = _floatingWindow.Model as LayoutFloatingWindow; - - _currentWindowAreas.ForEach(a => _currentWindow.DragLeave(a)); - - if (_currentDropTarget != null) - _currentWindow.DragLeave(_currentDropTarget); - if (_currentWindow != null) - _currentWindow.DragLeave(_floatingWindow); - _currentWindow = null; - if (_currentHost != null) - _currentHost.HideOverlayWindow(); - _currentHost = null; - } + #endregion + + #region Internal Methods + + internal void Abort() + { + var floatingWindowModel = _floatingWindow.Model as LayoutFloatingWindow; + + _currentWindowAreas.ForEach( a => _currentWindow.DragLeave( a ) ); + + if( _currentDropTarget != null ) + _currentWindow.DragLeave( _currentDropTarget ); + if( _currentWindow != null ) + _currentWindow.DragLeave( _floatingWindow ); + _currentWindow = null; + if( _currentHost != null ) + _currentHost.HideOverlayWindow(); + _currentHost = null; + } + + #endregion + + #region Private Methods + + private void GetOverlayWindowHosts() + { + _overlayWindowHosts.AddRange( _manager.GetFloatingWindowsByZOrder().OfType().Where( fw => fw != _floatingWindow && fw.IsVisible ) ); + _overlayWindowHosts.Add( _manager ); } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropArea.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropArea.cs index f5f998c5..7cc2f647 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropArea.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropArea.cs @@ -14,64 +14,78 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; namespace Xceed.Wpf.AvalonDock.Controls { - public enum DropAreaType + public enum DropAreaType + { + DockingManager, + DocumentPane, + DocumentPaneGroup, + AnchorablePane, + } + + + public interface IDropArea + { + Rect DetectionRect { - DockingManager, + get; + } + DropAreaType Type + { + get; + } + } - DocumentPane, + public class DropArea : IDropArea where T : FrameworkElement + { + #region Members - DocumentPaneGroup, + private Rect _detectionRect; + private DropAreaType _type; + private T _element; - AnchorablePane, + #endregion + #region Constructors + + internal DropArea( T areaElement, DropAreaType type ) + { + _element = areaElement; + _detectionRect = areaElement.GetScreenArea(); + _type = type; } + #endregion - public interface IDropArea + #region Properties + + public Rect DetectionRect { - Rect DetectionRect { get; } - DropAreaType Type { get; } - } + get + { + return _detectionRect; + } + } - public class DropArea : IDropArea where T : FrameworkElement + public DropAreaType Type { - internal DropArea(T areaElement, DropAreaType type) - { - _element = areaElement; - _detectionRect = areaElement.GetScreenArea(); - _type = type; - } - - Rect _detectionRect; - - public Rect DetectionRect - { - get { return _detectionRect; } - } - - DropAreaType _type; - - public DropAreaType Type - { - get { return _type; } - } - - T _element; - public T AreaElement - { - get - { - return _element; - } - } + get + { + return _type; + } + } + public T AreaElement + { + get + { + return _element; + } } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropDownButton.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropDownButton.cs index 02f7ade4..e4ae9a12 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropDownButton.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropDownButton.cs @@ -14,119 +14,136 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Controls.Primitives; using System.Windows; using System.Windows.Controls; -using System.Windows.Data; -using System.Diagnostics; namespace Xceed.Wpf.AvalonDock.Controls { - public class DropDownButton : ToggleButton + public class DropDownButton : ToggleButton + { + #region Constructors + + public DropDownButton() { - public DropDownButton() - { - this.Unloaded += new RoutedEventHandler(DropDownButton_Unloaded); - } - - #region DropDownContextMenu - - /// - /// DropDownContextMenu Dependency Property - /// - public static readonly DependencyProperty DropDownContextMenuProperty = - DependencyProperty.Register("DropDownContextMenu", typeof(ContextMenu), typeof(DropDownButton), - new FrameworkPropertyMetadata((ContextMenu)null, - new PropertyChangedCallback(OnDropDownContextMenuChanged))); - - /// - /// Gets or sets the DropDownContextMenu property. This dependency property - /// indicates drop down menu to show up when user click on an anchorable menu pin. - /// - public ContextMenu DropDownContextMenu - { - get { return (ContextMenu)GetValue(DropDownContextMenuProperty); } - set { SetValue(DropDownContextMenuProperty, value); } - } - - /// - /// Handles changes to the DropDownContextMenu property. - /// - private static void OnDropDownContextMenuChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DropDownButton)d).OnDropDownContextMenuChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the DropDownContextMenu property. - /// - protected virtual void OnDropDownContextMenuChanged(DependencyPropertyChangedEventArgs e) - { - var oldContextMenu = e.OldValue as ContextMenu; - if (oldContextMenu != null && IsChecked.GetValueOrDefault()) - oldContextMenu.Closed -= new RoutedEventHandler(OnContextMenuClosed); - } - - #endregion - - #region DropDownContextMenuDataContext - - /// - /// DropDownContextMenuDataContext Dependency Property - /// - public static readonly DependencyProperty DropDownContextMenuDataContextProperty = - DependencyProperty.Register("DropDownContextMenuDataContext", typeof(object), typeof(DropDownButton), - new FrameworkPropertyMetadata((object)null)); - - /// - /// Gets or sets the DropDownContextMenuDataContext property. This dependency property - /// indicates data context to set for drop down context menu. - /// - public object DropDownContextMenuDataContext - { - get { return (object)GetValue(DropDownContextMenuDataContextProperty); } - set { SetValue(DropDownContextMenuDataContextProperty, value); } - } - - #endregion - - protected override void OnClick() - { - if (DropDownContextMenu != null) - { - //IsChecked = true; - DropDownContextMenu.PlacementTarget = this; - DropDownContextMenu.Placement = PlacementMode.Bottom; - DropDownContextMenu.DataContext = DropDownContextMenuDataContext; - DropDownContextMenu.Closed += new RoutedEventHandler(OnContextMenuClosed); - DropDownContextMenu.IsOpen = true; - } - - base.OnClick(); - } - - void OnContextMenuClosed(object sender, RoutedEventArgs e) - { - //Debug.Assert(IsChecked.GetValueOrDefault()); - var ctxMenu = sender as ContextMenu; - ctxMenu.Closed -= new RoutedEventHandler(OnContextMenuClosed); - IsChecked = false; - } - - void DropDownButton_Unloaded(object sender, RoutedEventArgs e) - { - // When changing theme, Unloaded event is called, erasing the DropDownContextMenu. - // Prevent this on theme changes. - if( this.IsLoaded ) - { - DropDownContextMenu = null; - } - } + this.Unloaded += new RoutedEventHandler( DropDownButton_Unloaded ); + } + + #endregion + + #region Properties + + #region DropDownContextMenu + /// + /// DropDownContextMenu Dependency Property + /// + public static readonly DependencyProperty DropDownContextMenuProperty = DependencyProperty.Register( "DropDownContextMenu", typeof( ContextMenu ), typeof( DropDownButton ), + new FrameworkPropertyMetadata( ( ContextMenu )null, new PropertyChangedCallback( OnDropDownContextMenuChanged ) ) ); + /// + /// Gets or sets the DropDownContextMenu property. This dependency property + /// indicates drop down menu to show up when user click on an anchorable menu pin. + /// + public ContextMenu DropDownContextMenu + { + get + { + return ( ContextMenu )GetValue( DropDownContextMenuProperty ); + } + set + { + SetValue( DropDownContextMenuProperty, value ); + } + } + + /// + /// Handles changes to the DropDownContextMenu property. + /// + private static void OnDropDownContextMenuChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( DropDownButton )d ).OnDropDownContextMenuChanged( e ); } + + /// + /// Provides derived classes an opportunity to handle changes to the DropDownContextMenu property. + /// + protected virtual void OnDropDownContextMenuChanged( DependencyPropertyChangedEventArgs e ) + { + var oldContextMenu = e.OldValue as ContextMenu; + if( oldContextMenu != null && IsChecked.GetValueOrDefault() ) + oldContextMenu.Closed -= new RoutedEventHandler( OnContextMenuClosed ); + } + + #endregion + + #region DropDownContextMenuDataContext + + /// + /// DropDownContextMenuDataContext Dependency Property + /// + public static readonly DependencyProperty DropDownContextMenuDataContextProperty = DependencyProperty.Register( "DropDownContextMenuDataContext", typeof( object ), typeof( DropDownButton ), + new FrameworkPropertyMetadata( ( object )null ) ); + + /// + /// Gets or sets the DropDownContextMenuDataContext property. This dependency property + /// indicates data context to set for drop down context menu. + /// + public object DropDownContextMenuDataContext + { + get + { + return ( object )GetValue( DropDownContextMenuDataContextProperty ); + } + set + { + SetValue( DropDownContextMenuDataContextProperty, value ); + } + } + + #endregion + + #endregion + + #region Overrides + + protected override void OnClick() + { + if( DropDownContextMenu != null ) + { + //IsChecked = true; + DropDownContextMenu.PlacementTarget = this; + DropDownContextMenu.Placement = PlacementMode.Bottom; + DropDownContextMenu.DataContext = DropDownContextMenuDataContext; + DropDownContextMenu.Closed += new RoutedEventHandler( OnContextMenuClosed ); + DropDownContextMenu.IsOpen = true; + } + + base.OnClick(); + } + + #endregion + + #region Private Methods + + private void OnContextMenuClosed( object sender, RoutedEventArgs e ) + { + //Debug.Assert(IsChecked.GetValueOrDefault()); + var ctxMenu = sender as ContextMenu; + ctxMenu.Closed -= new RoutedEventHandler( OnContextMenuClosed ); + IsChecked = false; + } + + private void DropDownButton_Unloaded( object sender, RoutedEventArgs e ) + { + // When changing theme, Unloaded event is called, erasing the DropDownContextMenu. + // Prevent this on theme changes. + if( this.IsLoaded ) + { + DropDownContextMenu = null; + } + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropDownControlArea.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropDownControlArea.cs index 01aa6b29..ee848287 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropDownControlArea.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropDownControlArea.cs @@ -14,105 +14,116 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; -using System.Windows.Media; -using System.Windows.Input; -using System.Diagnostics; namespace Xceed.Wpf.AvalonDock.Controls { - public class DropDownControlArea : UserControl + public class DropDownControlArea : UserControl + { + #region Constructors + + //static DropDownControlArea() + //{ + // //IsHitTestVisibleProperty.OverrideMetadata(typeof(DropDownControlArea), new FrameworkPropertyMetadata(true)); + //} + + public DropDownControlArea() { - //static DropDownControlArea() - //{ - // //IsHitTestVisibleProperty.OverrideMetadata(typeof(DropDownControlArea), new FrameworkPropertyMetadata(true)); - //} + } - public DropDownControlArea() - { + #endregion - } + #region Properties - #region DropDownContextMenu + #region DropDownContextMenu - /// - /// DropDownContextMenu Dependency Property - /// - public static readonly DependencyProperty DropDownContextMenuProperty = - DependencyProperty.Register("DropDownContextMenu", typeof(ContextMenu), typeof(DropDownControlArea), - new FrameworkPropertyMetadata((ContextMenu)null)); + /// + /// DropDownContextMenu Dependency Property + /// + public static readonly DependencyProperty DropDownContextMenuProperty = DependencyProperty.Register( "DropDownContextMenu", typeof( ContextMenu ), typeof( DropDownControlArea ), + new FrameworkPropertyMetadata( ( ContextMenu )null ) ); - /// - /// Gets or sets the DropDownContextMenu property. This dependency property - /// indicates context menu to show when a right click is detected over the area occpied by the control. - /// - public ContextMenu DropDownContextMenu - { - get { return (ContextMenu)GetValue(DropDownContextMenuProperty); } - set { SetValue(DropDownContextMenuProperty, value); } - } + /// + /// Gets or sets the DropDownContextMenu property. This dependency property + /// indicates context menu to show when a right click is detected over the area occpied by the control. + /// + public ContextMenu DropDownContextMenu + { + get + { + return ( ContextMenu )GetValue( DropDownContextMenuProperty ); + } + set + { + SetValue( DropDownContextMenuProperty, value ); + } + } - #endregion + #endregion - #region DropDownContextMenuDataContext + #region DropDownContextMenuDataContext - /// - /// DropDownContextMenuDataContext Dependency Property - /// - public static readonly DependencyProperty DropDownContextMenuDataContextProperty = - DependencyProperty.Register("DropDownContextMenuDataContext", typeof(object), typeof(DropDownControlArea), - new FrameworkPropertyMetadata((object)null)); + /// + /// DropDownContextMenuDataContext Dependency Property + /// + public static readonly DependencyProperty DropDownContextMenuDataContextProperty = DependencyProperty.Register( "DropDownContextMenuDataContext", typeof( object ), typeof( DropDownControlArea ), + new FrameworkPropertyMetadata( ( object )null ) ); - /// - /// Gets or sets the DropDownContextMenuDataContext property. This dependency property - /// indicates data context to attach when context menu is shown. - /// - public object DropDownContextMenuDataContext - { - get { return (object)GetValue(DropDownContextMenuDataContextProperty); } - set { SetValue(DropDownContextMenuDataContextProperty, value); } - } + /// + /// Gets or sets the DropDownContextMenuDataContext property. This dependency property + /// indicates data context to attach when context menu is shown. + /// + public object DropDownContextMenuDataContext + { + get + { + return ( object )GetValue( DropDownContextMenuDataContextProperty ); + } + set + { + SetValue( DropDownContextMenuDataContextProperty, value ); + } + } - #endregion + #endregion - protected override void OnMouseRightButtonDown(System.Windows.Input.MouseButtonEventArgs e) - { - base.OnMouseRightButtonDown(e); + #endregion + #region Overrides - } + protected override void OnMouseRightButtonDown( System.Windows.Input.MouseButtonEventArgs e ) + { + base.OnMouseRightButtonDown( e ); + } + + protected override void OnPreviewMouseRightButtonUp( System.Windows.Input.MouseButtonEventArgs e ) + { + base.OnPreviewMouseRightButtonUp( e ); - protected override void OnPreviewMouseRightButtonUp(System.Windows.Input.MouseButtonEventArgs e) + if( !e.Handled ) + { + if( DropDownContextMenu != null ) { - base.OnPreviewMouseRightButtonUp(e); - - if (!e.Handled) - { - if (DropDownContextMenu != null) - { - DropDownContextMenu.PlacementTarget = null; - DropDownContextMenu.Placement = PlacementMode.MousePoint; - DropDownContextMenu.DataContext = DropDownContextMenuDataContext; - DropDownContextMenu.IsOpen = true; - // e.Handled = true; - } - } + DropDownContextMenu.PlacementTarget = null; + DropDownContextMenu.Placement = PlacementMode.MousePoint; + DropDownContextMenu.DataContext = DropDownContextMenuDataContext; + DropDownContextMenu.IsOpen = true; + // e.Handled = true; } + } + } + //protected override System.Windows.Media.HitTestResult HitTestCore(System.Windows.Media.PointHitTestParameters hitTestParameters) + //{ + // var hitResult = base.HitTestCore(hitTestParameters); + // if (hitResult == null) + // return new PointHitTestResult(this, hitTestParameters.HitPoint); - //protected override System.Windows.Media.HitTestResult HitTestCore(System.Windows.Media.PointHitTestParameters hitTestParameters) - //{ - // var hitResult = base.HitTestCore(hitTestParameters); - // if (hitResult == null) - // return new PointHitTestResult(this, hitTestParameters.HitPoint); + // return hitResult; + //} - // return hitResult; - //} - } + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTarget.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTarget.cs index d0f42b48..5177c483 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTarget.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTarget.cs @@ -17,7 +17,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows; using System.Windows.Media; using Xceed.Wpf.AvalonDock.Layout; @@ -25,91 +24,117 @@ using System.Windows.Threading; namespace Xceed.Wpf.AvalonDock.Controls { - internal abstract class DropTarget : DropTargetBase, IDropTarget where T : FrameworkElement - { - protected DropTarget(T targetElement, Rect detectionRect, DropTargetType type) - { - _targetElement = targetElement; - _detectionRect = new Rect[] { detectionRect }; - _type = type; - } + internal abstract class DropTarget : DropTargetBase, IDropTarget where T : FrameworkElement + { + #region Members - protected DropTarget(T targetElement, IEnumerable detectionRects, DropTargetType type) - { - _targetElement = targetElement; - _detectionRect = detectionRects.ToArray(); - _type = type; - } + private Rect[] _detectionRect; + private T _targetElement; + private DropTargetType _type; - Rect[] _detectionRect; + #endregion - public Rect[] DetectionRects - { - get { return _detectionRect; } - } + #region Constructors + protected DropTarget( T targetElement, Rect detectionRect, DropTargetType type ) + { + _targetElement = targetElement; + _detectionRect = new Rect[] { detectionRect }; + _type = type; + } - T _targetElement; - public T TargetElement - { - get { return _targetElement; } - } + protected DropTarget( T targetElement, IEnumerable detectionRects, DropTargetType type ) + { + _targetElement = targetElement; + _detectionRect = detectionRects.ToArray(); + _type = type; + } - DropTargetType _type; + #endregion - public DropTargetType Type - { - get { return _type; } - } + #region Properties - protected virtual void Drop(LayoutAnchorableFloatingWindow floatingWindow) - { } + public Rect[] DetectionRects + { + get + { + return _detectionRect; + } + } - protected virtual void Drop(LayoutDocumentFloatingWindow floatingWindow) - { } + public T TargetElement + { + get + { + return _targetElement; + } + } + public DropTargetType Type + { + get + { + return _type; + } + } - public void Drop(LayoutFloatingWindow floatingWindow) - { - var root = floatingWindow.Root; - var currentActiveContent = floatingWindow.Root.ActiveContent; - var fwAsAnchorable = floatingWindow as LayoutAnchorableFloatingWindow; + #endregion - if (fwAsAnchorable != null) - { - this.Drop(fwAsAnchorable); - } - else - { - var fwAsDocument = floatingWindow as LayoutDocumentFloatingWindow; - this.Drop(fwAsDocument); - } + #region Overrides - Dispatcher.BeginInvoke(new Action(() => - { - currentActiveContent.IsSelected = false; - currentActiveContent.IsActive = false; - currentActiveContent.IsActive = true; - }), DispatcherPriority.Background); - } + protected virtual void Drop( LayoutAnchorableFloatingWindow floatingWindow ) + { + } - public virtual bool HitTest(Point dragPoint) - { - return _detectionRect.Any(dr => dr.Contains(dragPoint)); - } + protected virtual void Drop( LayoutDocumentFloatingWindow floatingWindow ) + { + } - public abstract Geometry GetPreviewPath(OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindow); + #endregion + #region Public Methods + public void Drop( LayoutFloatingWindow floatingWindow ) + { + var root = floatingWindow.Root; + var currentActiveContent = floatingWindow.Root.ActiveContent; + var fwAsAnchorable = floatingWindow as LayoutAnchorableFloatingWindow; + + if( fwAsAnchorable != null ) + { + this.Drop( fwAsAnchorable ); + } + else + { + var fwAsDocument = floatingWindow as LayoutDocumentFloatingWindow; + this.Drop( fwAsDocument ); + } + + Dispatcher.BeginInvoke( new Action( () => + { + currentActiveContent.IsSelected = false; + currentActiveContent.IsActive = false; + currentActiveContent.IsActive = true; + } ), DispatcherPriority.Background ); + } - public void DragEnter() - { - SetIsDraggingOver(TargetElement, true); - } + public virtual bool HitTest( Point dragPoint ) + { + return _detectionRect.Any( dr => dr.Contains( dragPoint ) ); + } - public void DragLeave() - { - SetIsDraggingOver(TargetElement, false); - } + public abstract Geometry GetPreviewPath( OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindow ); + + public void DragEnter() + { + SetIsDraggingOver( TargetElement, true ); + } + + public void DragLeave() + { + SetIsDraggingOver( TargetElement, false ); } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTargetBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTargetBase.cs index fa793370..b19b3a77 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTargetBase.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTargetBase.cs @@ -14,43 +14,42 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; namespace Xceed.Wpf.AvalonDock.Controls { - abstract class DropTargetBase : DependencyObject + abstract class DropTargetBase : DependencyObject + { + #region Properties + + #region IsDraggingOver + + /// + /// IsDraggingOver Attached Dependency Property + /// + public static readonly DependencyProperty IsDraggingOverProperty = DependencyProperty.RegisterAttached( "IsDraggingOver", typeof( bool ), typeof( DropTargetBase ), + new FrameworkPropertyMetadata( ( bool )false ) ); + + /// + /// Gets the IsDraggingOver property. This dependency property + /// indicates if user is dragging a window over the target element. + /// + public static bool GetIsDraggingOver( DependencyObject d ) { - #region IsDraggingOver - - /// - /// IsDraggingOver Attached Dependency Property - /// - public static readonly DependencyProperty IsDraggingOverProperty = - DependencyProperty.RegisterAttached("IsDraggingOver", typeof(bool), typeof(DropTargetBase), - new FrameworkPropertyMetadata((bool)false)); - - /// - /// Gets the IsDraggingOver property. This dependency property - /// indicates if user is dragging a window over the target element. - /// - public static bool GetIsDraggingOver(DependencyObject d) - { - return (bool)d.GetValue(IsDraggingOverProperty); - } - - /// - /// Sets the IsDraggingOver property. This dependency property - /// indicates if user is dragging away a window from the target element. - /// - public static void SetIsDraggingOver(DependencyObject d, bool value) - { - d.SetValue(IsDraggingOverProperty, value); - } - - #endregion + return ( bool )d.GetValue( IsDraggingOverProperty ); } + + /// + /// Sets the IsDraggingOver property. This dependency property + /// indicates if user is dragging away a window from the target element. + /// + public static void SetIsDraggingOver( DependencyObject d, bool value ) + { + d.SetValue( IsDraggingOverProperty, value ); + } + + #endregion + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTargetType.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTargetType.cs index 67839074..20226c1d 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTargetType.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTargetType.cs @@ -14,37 +14,32 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - namespace Xceed.Wpf.AvalonDock.Controls { - public enum DropTargetType - { - DockingManagerDockLeft, - DockingManagerDockTop, - DockingManagerDockRight, - DockingManagerDockBottom, - - DocumentPaneDockLeft, - DocumentPaneDockTop, - DocumentPaneDockRight, - DocumentPaneDockBottom, - DocumentPaneDockInside, - - DocumentPaneGroupDockInside, - - AnchorablePaneDockLeft, - AnchorablePaneDockTop, - AnchorablePaneDockRight, - AnchorablePaneDockBottom, - AnchorablePaneDockInside, - - DocumentPaneDockAsAnchorableLeft, - DocumentPaneDockAsAnchorableTop, - DocumentPaneDockAsAnchorableRight, - DocumentPaneDockAsAnchorableBottom, - } + public enum DropTargetType + { + DockingManagerDockLeft, + DockingManagerDockTop, + DockingManagerDockRight, + DockingManagerDockBottom, + + DocumentPaneDockLeft, + DocumentPaneDockTop, + DocumentPaneDockRight, + DocumentPaneDockBottom, + DocumentPaneDockInside, + + DocumentPaneGroupDockInside, + + AnchorablePaneDockLeft, + AnchorablePaneDockTop, + AnchorablePaneDockRight, + AnchorablePaneDockBottom, + AnchorablePaneDockInside, + + DocumentPaneDockAsAnchorableLeft, + DocumentPaneDockAsAnchorableTop, + DocumentPaneDockAsAnchorableRight, + DocumentPaneDockAsAnchorableBottom, + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Extentions.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Extentions.cs index 4d4fc5c6..6d62cd8b 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Extentions.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Extentions.cs @@ -14,107 +14,103 @@ ***********************************************************************************/ -using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows; using System.Windows.Media; using System.Windows.Media.Media3D; -using System.Runtime.InteropServices; namespace Xceed.Wpf.AvalonDock.Controls { - public static class Extentions + public static class Extentions + { + public static IEnumerable FindVisualChildren( this DependencyObject depObj ) where T : DependencyObject { - public static IEnumerable FindVisualChildren(this DependencyObject depObj) where T : DependencyObject + if( depObj != null ) + { + for( int i = 0; i < VisualTreeHelper.GetChildrenCount( depObj ); i++ ) { - if (depObj != null) - { - for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) - { - DependencyObject child = VisualTreeHelper.GetChild(depObj, i); - if (child != null && child is T) - { - yield return (T)child; - } - - foreach (T childOfChild in FindVisualChildren(child)) - { - yield return childOfChild; - } - } - } + DependencyObject child = VisualTreeHelper.GetChild( depObj, i ); + if( child != null && child is T ) + { + yield return ( T )child; + } + + foreach( T childOfChild in FindVisualChildren( child ) ) + { + yield return childOfChild; + } } + } + } - public static IEnumerable FindLogicalChildren(this DependencyObject depObj) where T : DependencyObject + public static IEnumerable FindLogicalChildren( this DependencyObject depObj ) where T : DependencyObject + { + if( depObj != null ) + { + foreach( DependencyObject child in LogicalTreeHelper.GetChildren( depObj ).OfType() ) { - if (depObj != null) - { - foreach (DependencyObject child in LogicalTreeHelper.GetChildren(depObj).OfType()) - { - if (child != null && child is T) - { - yield return (T)child; - } - - foreach (T childOfChild in FindLogicalChildren(child)) - { - yield return childOfChild; - } - } - } + if( child != null && child is T ) + { + yield return ( T )child; + } + + foreach( T childOfChild in FindLogicalChildren( child ) ) + { + yield return childOfChild; + } } + } + } - public static DependencyObject FindVisualTreeRoot(this DependencyObject initial) - { - DependencyObject current = initial; - DependencyObject result = initial; - - while (current != null) - { - result = current; - if (current is Visual || current is Visual3D) - { - current = VisualTreeHelper.GetParent(current); - } - else - { - // If we're in Logical Land then we must walk - // up the logical tree until we find a - // Visual/Visual3D to get us back to Visual Land. - current = LogicalTreeHelper.GetParent(current); - } - } - - return result; - } + public static DependencyObject FindVisualTreeRoot( this DependencyObject initial ) + { + DependencyObject current = initial; + DependencyObject result = initial; - public static T FindVisualAncestor(this DependencyObject dependencyObject) where T : class + while( current != null ) + { + result = current; + if( current is Visual || current is Visual3D ) { - DependencyObject target = dependencyObject; - do - { - target = VisualTreeHelper.GetParent(target); - } - while (target != null && !(target is T)); - return target as T; + current = VisualTreeHelper.GetParent( current ); } - - public static T FindLogicalAncestor(this DependencyObject dependencyObject) where T : class + else { - DependencyObject target = dependencyObject; - do - { - var current = target; - target = LogicalTreeHelper.GetParent(target); - if (target == null) - target = VisualTreeHelper.GetParent(current); - - } - while (target != null && !(target is T)); - return target as T; + // If we're in Logical Land then we must walk + // up the logical tree until we find a + // Visual/Visual3D to get us back to Visual Land. + current = LogicalTreeHelper.GetParent( current ); } + } + return result; + } + + public static T FindVisualAncestor( this DependencyObject dependencyObject ) where T : class + { + DependencyObject target = dependencyObject; + do + { + target = VisualTreeHelper.GetParent( target ); + } + while( target != null && !( target is T ) ); + return target as T; + } + + public static T FindLogicalAncestor( this DependencyObject dependencyObject ) where T : class + { + DependencyObject target = dependencyObject; + do + { + var current = target; + target = LogicalTreeHelper.GetParent( target ); + if( target == null ) + target = VisualTreeHelper.GetParent( current ); + + } + while( target != null && !( target is T ) ); + return target as T; } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/FocusElementManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/FocusElementManager.cs index 768cff72..11d388bc 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/FocusElementManager.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/FocusElementManager.cs @@ -17,7 +17,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows.Input; using System.Windows.Interop; using System.Windows; @@ -28,241 +27,246 @@ using System.Windows.Threading; namespace Xceed.Wpf.AvalonDock.Controls { - internal static class FocusElementManager - { - #region Focus Management - static List _managers = new List(); - internal static void SetupFocusManagement(DockingManager manager) - { - if (_managers.Count == 0) - { - //InputManager.Current.EnterMenuMode += new EventHandler(InputManager_EnterMenuMode); - //InputManager.Current.LeaveMenuMode += new EventHandler(InputManager_LeaveMenuMode); - _windowHandler = new WindowHookHandler(); - _windowHandler.FocusChanged += new EventHandler(WindowFocusChanging); - //_windowHandler.Activate += new EventHandler(WindowActivating); - _windowHandler.Attach(); - - if (Application.Current != null) - Application.Current.Exit += new ExitEventHandler(Current_Exit); - } + internal static class FocusElementManager + { + #region Member - manager.PreviewGotKeyboardFocus += new KeyboardFocusChangedEventHandler(manager_PreviewGotKeyboardFocus); - _managers.Add(manager); - } + private static List _managers = new List(); + private static FullWeakDictionary _modelFocusedElement = new FullWeakDictionary(); + private static WeakDictionary _modelFocusedWindowHandle = new WeakDictionary(); + private static WeakReference _lastFocusedElement; + private static WindowHookHandler _windowHandler = null; + private static DispatcherOperation _setFocusAsyncOperation; + private static WeakReference _lastFocusedElementBeforeEnterMenuMode = null; - internal static void FinalizeFocusManagement(DockingManager manager) - { - manager.PreviewGotKeyboardFocus -= new KeyboardFocusChangedEventHandler(manager_PreviewGotKeyboardFocus); - _managers.Remove(manager); + #endregion - if (_managers.Count == 0) - { - //InputManager.Current.EnterMenuMode -= new EventHandler(InputManager_EnterMenuMode); - //InputManager.Current.LeaveMenuMode -= new EventHandler(InputManager_LeaveMenuMode); - if (_windowHandler != null) - { - _windowHandler.FocusChanged -= new EventHandler(WindowFocusChanging); - //_windowHandler.Activate -= new EventHandler(WindowActivating); - _windowHandler.Detach(); - _windowHandler = null; - } - } + #region Internal Methods - } + internal static void SetupFocusManagement( DockingManager manager ) + { + if( _managers.Count == 0 ) + { + //InputManager.Current.EnterMenuMode += new EventHandler(InputManager_EnterMenuMode); + //InputManager.Current.LeaveMenuMode += new EventHandler(InputManager_LeaveMenuMode); + _windowHandler = new WindowHookHandler(); + _windowHandler.FocusChanged += new EventHandler( WindowFocusChanging ); + //_windowHandler.Activate += new EventHandler(WindowActivating); + _windowHandler.Attach(); + + if( Application.Current != null ) + Application.Current.Exit += new ExitEventHandler( Current_Exit ); + } + + manager.PreviewGotKeyboardFocus += new KeyboardFocusChangedEventHandler( manager_PreviewGotKeyboardFocus ); + _managers.Add( manager ); + } - private static void Current_Exit(object sender, ExitEventArgs e) + internal static void FinalizeFocusManagement( DockingManager manager ) + { + manager.PreviewGotKeyboardFocus -= new KeyboardFocusChangedEventHandler( manager_PreviewGotKeyboardFocus ); + _managers.Remove( manager ); + + if( _managers.Count == 0 ) + { + //InputManager.Current.EnterMenuMode -= new EventHandler(InputManager_EnterMenuMode); + //InputManager.Current.LeaveMenuMode -= new EventHandler(InputManager_LeaveMenuMode); + if( _windowHandler != null ) { - Application.Current.Exit -= new ExitEventHandler(Current_Exit); - if (_windowHandler != null) - { - _windowHandler.FocusChanged -= new EventHandler(WindowFocusChanging); - //_windowHandler.Activate -= new EventHandler(WindowActivating); - _windowHandler.Detach(); - _windowHandler = null; - } + _windowHandler.FocusChanged -= new EventHandler( WindowFocusChanging ); + //_windowHandler.Activate -= new EventHandler(WindowActivating); + _windowHandler.Detach(); + _windowHandler = null; } + } - static void manager_PreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) - { - var focusedElement = e.NewFocus as Visual; - if (focusedElement != null && - !(focusedElement is LayoutAnchorableTabItem || focusedElement is LayoutDocumentTabItem)) - //Avoid tracking focus for elements like this - { - var parentAnchorable = focusedElement.FindVisualAncestor(); - if (parentAnchorable != null) - { - _modelFocusedElement[parentAnchorable.Model] = e.NewFocus; - } - else - { - var parentDocument = focusedElement.FindVisualAncestor(); - if (parentDocument != null) - { - _modelFocusedElement[parentDocument.Model] = e.NewFocus; - } - } - } - } + } - static FullWeakDictionary _modelFocusedElement = new FullWeakDictionary(); - static WeakDictionary _modelFocusedWindowHandle = new WeakDictionary(); + /// + /// Get the input element that was focused before user left the layout element + /// + /// Element to look for + /// Input element + internal static IInputElement GetLastFocusedElement( ILayoutElement model ) + { + IInputElement objectWithFocus; + if( _modelFocusedElement.GetValue( model, out objectWithFocus ) ) + return objectWithFocus; - /// - /// Get the input element that was focused before user left the layout element - /// - /// Element to look for - /// Input element - internal static IInputElement GetLastFocusedElement(ILayoutElement model) - { - IInputElement objectWithFocus; - if (_modelFocusedElement.GetValue(model, out objectWithFocus)) - return objectWithFocus; + return null; + } - return null; - } + /// + /// Get the last window handle focused before user left the element passed as argument + /// + /// + /// + internal static IntPtr GetLastWindowHandle( ILayoutElement model ) + { + IntPtr handleWithFocus; + if( _modelFocusedWindowHandle.GetValue( model, out handleWithFocus ) ) + return handleWithFocus; - /// - /// Get the last window handle focused before user left the element passed as argument - /// - /// - /// - internal static IntPtr GetLastWindowHandle(ILayoutElement model) - { - IntPtr handleWithFocus; - if (_modelFocusedWindowHandle.GetValue(model, out handleWithFocus)) - return handleWithFocus; + return IntPtr.Zero; + } - return IntPtr.Zero; - } - static WeakReference _lastFocusedElement; + /// + /// Given a layout element tries to set the focus of the keyword where it was before user moved to another element + /// + /// + internal static void SetFocusOnLastElement( ILayoutElement model ) + { + bool focused = false; + IInputElement objectToFocus; + if( _modelFocusedElement.GetValue( model, out objectToFocus ) ) + { + focused = objectToFocus == Keyboard.Focus( objectToFocus ); + } - /// - /// Given a layout element tries to set the focus of the keyword where it was before user moved to another element - /// - /// - internal static void SetFocusOnLastElement(ILayoutElement model) - { - bool focused = false; - IInputElement objectToFocus; - if (_modelFocusedElement.GetValue(model, out objectToFocus)) - { - focused = objectToFocus == Keyboard.Focus(objectToFocus); - } + IntPtr handleToFocus; + if( _modelFocusedWindowHandle.GetValue( model, out handleToFocus ) ) + focused = IntPtr.Zero != Win32Helper.SetFocus( handleToFocus ); - IntPtr handleToFocus; - if (_modelFocusedWindowHandle.GetValue(model, out handleToFocus)) - focused = IntPtr.Zero != Win32Helper.SetFocus(handleToFocus); + if( focused ) + { + _lastFocusedElement = new WeakReference( model ); + } - if (focused) - { - _lastFocusedElement = new WeakReference(model); - } + } - } + #endregion - static WindowHookHandler _windowHandler = null; + #region Private Methods - static void WindowFocusChanging(object sender, FocusChangeEventArgs e) + private static void Current_Exit( object sender, ExitEventArgs e ) + { + Application.Current.Exit -= new ExitEventHandler( Current_Exit ); + if( _windowHandler != null ) + { + _windowHandler.FocusChanged -= new EventHandler( WindowFocusChanging ); + //_windowHandler.Activate -= new EventHandler(WindowActivating); + _windowHandler.Detach(); + _windowHandler = null; + } + } + + private static void manager_PreviewGotKeyboardFocus( object sender, KeyboardFocusChangedEventArgs e ) + { + var focusedElement = e.NewFocus as Visual; + if( focusedElement != null && + !( focusedElement is LayoutAnchorableTabItem || focusedElement is LayoutDocumentTabItem ) ) + //Avoid tracking focus for elements like this + { + var parentAnchorable = focusedElement.FindVisualAncestor(); + if( parentAnchorable != null ) { - foreach (var manager in _managers) - { - var hostContainingFocusedHandle = manager.FindLogicalChildren().FirstOrDefault(hw => Win32Helper.IsChild(hw.Handle, e.GotFocusWinHandle)); - - if (hostContainingFocusedHandle != null) - { - var parentAnchorable = hostContainingFocusedHandle.FindVisualAncestor(); - if (parentAnchorable != null) - { - _modelFocusedWindowHandle[parentAnchorable.Model] = e.GotFocusWinHandle; - if (parentAnchorable.Model != null) - parentAnchorable.Model.IsActive = true; - } - else - { - var parentDocument = hostContainingFocusedHandle.FindVisualAncestor(); - if (parentDocument != null) - { - _modelFocusedWindowHandle[parentDocument.Model] = e.GotFocusWinHandle; - if (parentDocument.Model != null) - parentDocument.Model.IsActive = true; - } - } - } - } + _modelFocusedElement[ parentAnchorable.Model ] = e.NewFocus; + } + else + { + var parentDocument = focusedElement.FindVisualAncestor(); + if( parentDocument != null ) + { + _modelFocusedElement[ parentDocument.Model ] = e.NewFocus; + } } + } + } - static DispatcherOperation _setFocusAsyncOperation; + private static void WindowFocusChanging( object sender, FocusChangeEventArgs e ) + { + foreach( var manager in _managers ) + { + var hostContainingFocusedHandle = manager.FindLogicalChildren().FirstOrDefault( hw => Win32Helper.IsChild( hw.Handle, e.GotFocusWinHandle ) ); - static void WindowActivating(object sender, WindowActivateEventArgs e) + if( hostContainingFocusedHandle != null ) { - if (Keyboard.FocusedElement == null && - _lastFocusedElement != null && - _lastFocusedElement.IsAlive) + var parentAnchorable = hostContainingFocusedHandle.FindVisualAncestor(); + if( parentAnchorable != null ) + { + _modelFocusedWindowHandle[ parentAnchorable.Model ] = e.GotFocusWinHandle; + if( parentAnchorable.Model != null ) + parentAnchorable.Model.IsActive = true; + } + else + { + var parentDocument = hostContainingFocusedHandle.FindVisualAncestor(); + if( parentDocument != null ) { - var elementToSetFocus = _lastFocusedElement.Target as ILayoutElement; - if (elementToSetFocus != null) - { - var manager = elementToSetFocus.Root.Manager; - if (manager == null) - return; - - IntPtr parentHwnd; - if (!manager.GetParentWindowHandle(out parentHwnd)) - return; - - if (e.HwndActivating != parentHwnd) - return; - - _setFocusAsyncOperation = Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => - { - try - { - SetFocusOnLastElement(elementToSetFocus); - } - finally - { - _setFocusAsyncOperation = null; - } - }), DispatcherPriority.Input); - } + _modelFocusedWindowHandle[ parentDocument.Model ] = e.GotFocusWinHandle; + if( parentDocument.Model != null ) + parentDocument.Model.IsActive = true; } + } } + } + } - - static WeakReference _lastFocusedElementBeforeEnterMenuMode = null; - static void InputManager_EnterMenuMode(object sender, EventArgs e) + private static void WindowActivating( object sender, WindowActivateEventArgs e ) + { + if( Keyboard.FocusedElement == null && + _lastFocusedElement != null && + _lastFocusedElement.IsAlive ) + { + var elementToSetFocus = _lastFocusedElement.Target as ILayoutElement; + if( elementToSetFocus != null ) { - if (Keyboard.FocusedElement == null) - return; + var manager = elementToSetFocus.Root.Manager; + if( manager == null ) + return; + + IntPtr parentHwnd; + if( !manager.GetParentWindowHandle( out parentHwnd ) ) + return; + + if( e.HwndActivating != parentHwnd ) + return; - var lastfocusDepObj = Keyboard.FocusedElement as DependencyObject; - if (lastfocusDepObj.FindLogicalAncestor() == null) + _setFocusAsyncOperation = Dispatcher.CurrentDispatcher.BeginInvoke( new Action( () => + { + try { - _lastFocusedElementBeforeEnterMenuMode = null; - return; + SetFocusOnLastElement( elementToSetFocus ); } - - _lastFocusedElementBeforeEnterMenuMode = new WeakReference(Keyboard.FocusedElement); - } - static void InputManager_LeaveMenuMode(object sender, EventArgs e) - { - if (_lastFocusedElementBeforeEnterMenuMode != null && - _lastFocusedElementBeforeEnterMenuMode.IsAlive) + finally { - var lastFocusedInputElement = _lastFocusedElementBeforeEnterMenuMode.GetValueOrDefault(); - if (lastFocusedInputElement != null) - { - if (lastFocusedInputElement != Keyboard.Focus(lastFocusedInputElement)) - Debug.WriteLine("Unable to activate the element"); - } + _setFocusAsyncOperation = null; } + } ), DispatcherPriority.Input ); } + } + } - #endregion + private static void InputManager_EnterMenuMode( object sender, EventArgs e ) + { + if( Keyboard.FocusedElement == null ) + return; + + var lastfocusDepObj = Keyboard.FocusedElement as DependencyObject; + if( lastfocusDepObj.FindLogicalAncestor() == null ) + { + _lastFocusedElementBeforeEnterMenuMode = null; + return; + } + _lastFocusedElementBeforeEnterMenuMode = new WeakReference( Keyboard.FocusedElement ); } + private static void InputManager_LeaveMenuMode( object sender, EventArgs e ) + { + if( _lastFocusedElementBeforeEnterMenuMode != null && + _lastFocusedElementBeforeEnterMenuMode.IsAlive ) + { + var lastFocusedInputElement = _lastFocusedElementBeforeEnterMenuMode.GetValueOrDefault(); + if( lastFocusedInputElement != null ) + { + if( lastFocusedInputElement != Keyboard.Focus( lastFocusedInputElement ) ) + Debug.WriteLine( "Unable to activate the element" ); + } + } + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/FullWeakDictionary.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/FullWeakDictionary.cs index 4fbf4b60..c483acfa 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/FullWeakDictionary.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/FullWeakDictionary.cs @@ -16,91 +16,101 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Xceed.Wpf.AvalonDock.Controls { - class FullWeakDictionary where K : class + internal class FullWeakDictionary where K : class + { + #region Members + + private List _keys = new List(); + private List _values = new List(); + + #endregion + + #region Constructors + + public FullWeakDictionary() { - public FullWeakDictionary() - {} + } - List _keys = new List(); - List _values = new List(); + #endregion - public V this[K key] - { - get - { - V valueToReturn; - if (!GetValue(key, out valueToReturn)) - throw new ArgumentException(); - return valueToReturn; - } - set - { - SetValue(key, value); - } - } + #region Public Methods - public bool ContainsKey(K key) - { - CollectGarbage(); - return -1 != _keys.FindIndex(k => k.GetValueOrDefault() == key); - } + public V this[ K key ] + { + get + { + V valueToReturn; + if( !GetValue( key, out valueToReturn ) ) + throw new ArgumentException(); + return valueToReturn; + } + set + { + SetValue( key, value ); + } + } - public void SetValue(K key, V value) - { - CollectGarbage(); - int vIndex = _keys.FindIndex(k => k.GetValueOrDefault() == key); - if (vIndex > -1) - _values[vIndex] = new WeakReference(value); - else - { - _values.Add(new WeakReference(value)); - _keys.Add(new WeakReference(key)); - } - } + public bool ContainsKey( K key ) + { + CollectGarbage(); + return -1 != _keys.FindIndex( k => k.GetValueOrDefault() == key ); + } - public bool GetValue(K key, out V value) - { - CollectGarbage(); - int vIndex = _keys.FindIndex(k => k.GetValueOrDefault() == key); - value = default(V); - if (vIndex == -1) - return false; - value = _values[vIndex].GetValueOrDefault(); - return true; - } + public void SetValue( K key, V value ) + { + CollectGarbage(); + int vIndex = _keys.FindIndex( k => k.GetValueOrDefault() == key ); + if( vIndex > -1 ) + _values[ vIndex ] = new WeakReference( value ); + else + { + _values.Add( new WeakReference( value ) ); + _keys.Add( new WeakReference( key ) ); + } + } + public bool GetValue( K key, out V value ) + { + CollectGarbage(); + int vIndex = _keys.FindIndex( k => k.GetValueOrDefault() == key ); + value = default( V ); + if( vIndex == -1 ) + return false; + value = _values[ vIndex ].GetValueOrDefault(); + return true; + } - void CollectGarbage() - { - int vIndex = 0; - - do - { - vIndex = _keys.FindIndex(vIndex, k => !k.IsAlive); - if (vIndex >= 0) - { - _keys.RemoveAt(vIndex); - _values.RemoveAt(vIndex); - } - } - while (vIndex >= 0); - - vIndex = 0; - do - { - vIndex = _values.FindIndex(vIndex, v => !v.IsAlive); - if (vIndex >= 0) - { - _values.RemoveAt(vIndex); - _keys.RemoveAt(vIndex); - } - } - while (vIndex >= 0); + void CollectGarbage() + { + int vIndex = 0; + + do + { + vIndex = _keys.FindIndex( vIndex, k => !k.IsAlive ); + if( vIndex >= 0 ) + { + _keys.RemoveAt( vIndex ); + _values.RemoveAt( vIndex ); } + } + while( vIndex >= 0 ); + + vIndex = 0; + do + { + vIndex = _values.FindIndex( vIndex, v => !v.IsAlive ); + if( vIndex >= 0 ) + { + _values.RemoveAt( vIndex ); + _keys.RemoveAt( vIndex ); + } + } + while( vIndex >= 0 ); } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IDropTarget.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IDropTarget.cs index a437a10f..2610304b 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IDropTarget.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IDropTarget.cs @@ -14,28 +14,35 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; using System.Windows.Media; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Controls { - internal interface IDropTarget + internal interface IDropTarget + { + #region Properties + + DropTargetType Type { - Geometry GetPreviewPath(OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindow); + get; + } - bool HitTest(Point dragPoint); + #endregion - DropTargetType Type { get; } + #region Methods - void Drop(LayoutFloatingWindow floatingWindow); + Geometry GetPreviewPath( OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindow ); - void DragEnter(); + bool HitTest( Point dragPoint ); - void DragLeave(); - } + void Drop( LayoutFloatingWindow floatingWindow ); + + void DragEnter(); + + void DragLeave(); + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindow.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindow.cs index 1eba29e8..e623f12c 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindow.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindow.cs @@ -14,25 +14,22 @@ ***********************************************************************************/ -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Xceed.Wpf.AvalonDock.Controls { - internal interface IOverlayWindow - { - IEnumerable GetTargets(); + internal interface IOverlayWindow + { + IEnumerable GetTargets(); - void DragEnter(LayoutFloatingWindowControl floatingWindow); - void DragLeave(LayoutFloatingWindowControl floatingWindow); + void DragEnter( LayoutFloatingWindowControl floatingWindow ); + void DragLeave( LayoutFloatingWindowControl floatingWindow ); - void DragEnter(IDropArea area); - void DragLeave(IDropArea area); + void DragEnter( IDropArea area ); + void DragLeave( IDropArea area ); - void DragEnter(IDropTarget target); - void DragLeave(IDropTarget target); - void DragDrop(IDropTarget target); - } + void DragEnter( IDropTarget target ); + void DragLeave( IDropTarget target ); + void DragDrop( IDropTarget target ); + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindowArea.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindowArea.cs index fcafbf1b..22331abb 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindowArea.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindowArea.cs @@ -14,16 +14,15 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; namespace Xceed.Wpf.AvalonDock.Controls { - internal interface IOverlayWindowArea + internal interface IOverlayWindowArea + { + Rect ScreenDetectionArea { - Rect ScreenDetectionArea { get; } + get; } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindowDropTarget.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindowDropTarget.cs index aca2dba6..450519c6 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindowDropTarget.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindowDropTarget.cs @@ -14,18 +14,20 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; namespace Xceed.Wpf.AvalonDock.Controls { - interface IOverlayWindowDropTarget + interface IOverlayWindowDropTarget + { + Rect ScreenDetectionArea { - Rect ScreenDetectionArea { get; } + get; + } - OverlayWindowDropTargetType Type { get; } + OverlayWindowDropTargetType Type + { + get; } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindowHost.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindowHost.cs index f32ecffa..9e58e7a5 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindowHost.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/IOverlayWindowHost.cs @@ -14,24 +14,32 @@ ***********************************************************************************/ -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; namespace Xceed.Wpf.AvalonDock.Controls { - internal interface IOverlayWindowHost + internal interface IOverlayWindowHost + { + #region Properties + + DockingManager Manager { - bool HitTest(Point dragPoint); + get; + } - IOverlayWindow ShowOverlayWindow(LayoutFloatingWindowControl draggingWindow); + #endregion - void HideOverlayWindow(); + #region Methods - IEnumerable GetDropAreas(LayoutFloatingWindowControl draggingWindow); + bool HitTest( Point dragPoint ); - DockingManager Manager { get; } - } + IOverlayWindow ShowOverlayWindow( LayoutFloatingWindowControl draggingWindow ); + + void HideOverlayWindow(); + + IEnumerable GetDropAreas( LayoutFloatingWindowControl draggingWindow ); + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorControl.cs index d247f9e2..fdb45068 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorControl.cs @@ -24,13 +24,21 @@ namespace Xceed.Wpf.AvalonDock.Controls { public class LayoutAnchorControl : Control, ILayoutControl { + #region Members + + private LayoutAnchorable _model; + private DispatcherTimer _openUpTimer = null; + + #endregion + + #region Constructors + static LayoutAnchorControl() { DefaultStyleKeyProperty.OverrideMetadata( typeof( LayoutAnchorControl ), new FrameworkPropertyMetadata( typeof( LayoutAnchorControl ) ) ); Control.IsHitTestVisibleProperty.AddOwner( typeof( LayoutAnchorControl ), new FrameworkPropertyMetadata( true ) ); } - internal LayoutAnchorControl( LayoutAnchorable model ) { _model = model; @@ -40,7 +48,61 @@ namespace Xceed.Wpf.AvalonDock.Controls SetSide( _model.FindParent().Side ); } - void _model_IsSelectedChanged( object sender, EventArgs e ) + #endregion + + #region Properties + + #region Model + + public ILayoutElement Model + { + get + { + return _model; + } + } + + #endregion + + #region Side + + /// + /// Side Read-Only Dependency Property + /// + private static readonly DependencyPropertyKey SidePropertyKey = DependencyProperty.RegisterReadOnly( "Side", typeof( AnchorSide ), typeof( LayoutAnchorControl ), + new FrameworkPropertyMetadata( ( AnchorSide )AnchorSide.Left ) ); + + public static readonly DependencyProperty SideProperty = SidePropertyKey.DependencyProperty; + + /// + /// Gets the Side property. This dependency property + /// indicates the anchor side of the control. + /// + public AnchorSide Side + { + get + { + return ( AnchorSide )GetValue( SideProperty ); + } + } + + /// + /// Provides a secure method for setting the Side property. + /// This dependency property indicates the anchor side of the control. + /// + /// The new value for the property. + protected void SetSide( AnchorSide value ) + { + SetValue( SidePropertyKey, value ); + } + + #endregion + + #endregion + + #region Private Methods + + private void _model_IsSelectedChanged( object sender, EventArgs e ) { if( !_model.IsAutoHidden ) _model.IsSelectedChanged -= new EventHandler( _model_IsSelectedChanged ); @@ -51,7 +113,7 @@ namespace Xceed.Wpf.AvalonDock.Controls } } - void _model_IsActiveChanged( object sender, EventArgs e ) + private void _model_IsActiveChanged( object sender, EventArgs e ) { if( !_model.IsAutoHidden ) _model.IsActiveChanged -= new EventHandler( _model_IsActiveChanged ); @@ -59,16 +121,18 @@ namespace Xceed.Wpf.AvalonDock.Controls _model.Root.Manager.ShowAutoHideWindow( this ); } - LayoutAnchorable _model; - - public ILayoutElement Model + private void _openUpTimer_Tick( object sender, EventArgs e ) { - get - { - return _model; - } + _openUpTimer.Tick -= new EventHandler( _openUpTimer_Tick ); + _openUpTimer.Stop(); + _openUpTimer = null; + _model.Root.Manager.ShowAutoHideWindow( this ); } + #endregion + + #region Overrides + //protected override void OnVisualParentChanged(DependencyObject oldParent) //{ // base.OnVisualParentChanged(oldParent); @@ -110,9 +174,6 @@ namespace Xceed.Wpf.AvalonDock.Controls } } - - DispatcherTimer _openUpTimer = null; - protected override void OnMouseEnter( System.Windows.Input.MouseEventArgs e ) { base.OnMouseEnter( e ); @@ -126,14 +187,6 @@ namespace Xceed.Wpf.AvalonDock.Controls } } - void _openUpTimer_Tick( object sender, EventArgs e ) - { - _openUpTimer.Tick -= new EventHandler( _openUpTimer_Tick ); - _openUpTimer.Stop(); - _openUpTimer = null; - _model.Root.Manager.ShowAutoHideWindow( this ); - } - protected override void OnMouseLeave( System.Windows.Input.MouseEventArgs e ) { if( _openUpTimer != null ) @@ -146,41 +199,6 @@ namespace Xceed.Wpf.AvalonDock.Controls } - #region Side - - /// - /// Side Read-Only Dependency Property - /// - private static readonly DependencyPropertyKey SidePropertyKey - = DependencyProperty.RegisterReadOnly( "Side", typeof( AnchorSide ), typeof( LayoutAnchorControl ), - new FrameworkPropertyMetadata( ( AnchorSide )AnchorSide.Left ) ); - - public static readonly DependencyProperty SideProperty - = SidePropertyKey.DependencyProperty; - - /// - /// Gets the Side property. This dependency property - /// indicates the anchor side of the control. - /// - public AnchorSide Side - { - get - { - return ( AnchorSide )GetValue( SideProperty ); - } - } - - /// - /// Provides a secure method for setting the Side property. - /// This dependency property indicates the anchor side of the control. - /// - /// The new value for the property. - protected void SetSide( AnchorSide value ) - { - SetValue( SidePropertyKey, value ); - } - #endregion - } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorGroupControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorGroupControl.cs index d8829b63..bea7877c 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorGroupControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorGroupControl.cs @@ -14,10 +14,7 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows.Controls; using System.Collections.ObjectModel; using Xceed.Wpf.AvalonDock.Layout; @@ -25,75 +22,95 @@ using System.Windows; namespace Xceed.Wpf.AvalonDock.Controls { - public class LayoutAnchorGroupControl : Control, ILayoutControl + public class LayoutAnchorGroupControl : Control, ILayoutControl + { + #region Members + + private ObservableCollection _childViews = new ObservableCollection(); + private LayoutAnchorGroup _model; + + #endregion + + #region Constructors + + static LayoutAnchorGroupControl() { - static LayoutAnchorGroupControl() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(LayoutAnchorGroupControl), new FrameworkPropertyMetadata(typeof(LayoutAnchorGroupControl))); - } + DefaultStyleKeyProperty.OverrideMetadata( typeof( LayoutAnchorGroupControl ), new FrameworkPropertyMetadata( typeof( LayoutAnchorGroupControl ) ) ); + } + internal LayoutAnchorGroupControl( LayoutAnchorGroup model ) + { + _model = model; + CreateChildrenViews(); - internal LayoutAnchorGroupControl(LayoutAnchorGroup model) - { - _model = model; - CreateChildrenViews(); + _model.Children.CollectionChanged += ( s, e ) => OnModelChildrenCollectionChanged( e ); + } - _model.Children.CollectionChanged += (s, e) => OnModelChildrenCollectionChanged(e); - } + #endregion - private void CreateChildrenViews() - { - var manager = _model.Root.Manager; - foreach (var childModel in _model.Children) - { - _childViews.Add(new LayoutAnchorControl(childModel) { Template = manager.AnchorTemplate }); - } - } + #region Properties - private void OnModelChildrenCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) - { - if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace) - { - if (e.OldItems != null) - { - { - foreach (var childModel in e.OldItems) - _childViews.Remove(_childViews.First(cv => cv.Model == childModel)); - } - } - } - - if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset) - _childViews.Clear(); - - if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace) - { - if (e.NewItems != null) - { - var manager = _model.Root.Manager; - int insertIndex = e.NewStartingIndex; - foreach (LayoutAnchorable childModel in e.NewItems) - { - _childViews.Insert(insertIndex++, new LayoutAnchorControl(childModel) { Template = manager.AnchorTemplate }); - } - } - } - } + public ObservableCollection Children + { + get + { + return _childViews; + } + } + + public ILayoutElement Model + { + get + { + return _model; + } + } - ObservableCollection _childViews = new ObservableCollection(); + #endregion - public ObservableCollection Children + #region Private Methods + + private void CreateChildrenViews() + { + var manager = _model.Root.Manager; + foreach( var childModel in _model.Children ) + { + _childViews.Add( new LayoutAnchorControl( childModel ) { Template = manager.AnchorTemplate } ); + } + } + + private void OnModelChildrenCollectionChanged( System.Collections.Specialized.NotifyCollectionChangedEventArgs e ) + { + if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) + { + if( e.OldItems != null ) { - get { return _childViews; } + { + foreach( var childModel in e.OldItems ) + _childViews.Remove( _childViews.First( cv => cv.Model == childModel ) ); + } } + } + if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset ) + _childViews.Clear(); - LayoutAnchorGroup _model; - public ILayoutElement Model + if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) + { + if( e.NewItems != null ) { - get { return _model; } + var manager = _model.Root.Manager; + int insertIndex = e.NewStartingIndex; + foreach( LayoutAnchorable childModel in e.NewItems ) + { + _childViews.Insert( insertIndex++, new LayoutAnchorControl( childModel ) { Template = manager.AnchorTemplate } ); + } } + } } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorSideControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorSideControl.cs index 5a0c6e8f..76b8e207 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorSideControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorSideControl.cs @@ -25,12 +25,21 @@ namespace Xceed.Wpf.AvalonDock.Controls { public class LayoutAnchorSideControl : Control, ILayoutControl { + #region Members + + private LayoutAnchorSide _model = null; + private ObservableCollection _childViews = new ObservableCollection(); + + + #endregion + + #region Constructors + static LayoutAnchorSideControl() { DefaultStyleKeyProperty.OverrideMetadata( typeof( LayoutAnchorSideControl ), new FrameworkPropertyMetadata( typeof( LayoutAnchorSideControl ) ) ); } - internal LayoutAnchorSideControl( LayoutAnchorSide model ) { if( model == null ) @@ -46,42 +55,12 @@ namespace Xceed.Wpf.AvalonDock.Controls UpdateSide(); } - private void CreateChildrenViews() - { - var manager = _model.Root.Manager; - foreach( var childModel in _model.Children ) - { - _childViews.Add( manager.CreateUIElementForModel( childModel ) as LayoutAnchorGroupControl ); - } - } + #endregion - private void OnModelChildrenCollectionChanged( System.Collections.Specialized.NotifyCollectionChangedEventArgs e ) - { - if( e.OldItems != null && - ( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) ) - { - foreach( var childModel in e.OldItems ) - _childViews.Remove( _childViews.First( cv => cv.Model == childModel ) ); - } + #region Properties - if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset ) - _childViews.Clear(); + #region Model - if( e.NewItems != null && - ( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) ) - { - var manager = _model.Root.Manager; - int insertIndex = e.NewStartingIndex; - foreach( LayoutAnchorGroup childModel in e.NewItems ) - { - _childViews.Insert( insertIndex++, manager.CreateUIElementForModel( childModel ) as LayoutAnchorGroupControl ); - } - } - } - - LayoutAnchorSide _model = null; public ILayoutElement Model { get @@ -90,7 +69,9 @@ namespace Xceed.Wpf.AvalonDock.Controls } } - ObservableCollection _childViews = new ObservableCollection(); + #endregion + + #region Children public ObservableCollection Children { @@ -100,36 +81,17 @@ namespace Xceed.Wpf.AvalonDock.Controls } } - void UpdateSide() - { - switch( _model.Side ) - { - case AnchorSide.Left: - SetIsLeftSide( true ); - break; - case AnchorSide.Top: - SetIsTopSide( true ); - break; - case AnchorSide.Right: - SetIsRightSide( true ); - break; - case AnchorSide.Bottom: - SetIsBottomSide( true ); - break; - } - } + #endregion #region IsLeftSide /// /// IsLeftSide Read-Only Dependency Property /// - private static readonly DependencyPropertyKey IsLeftSidePropertyKey - = DependencyProperty.RegisterReadOnly( "IsLeftSide", typeof( bool ), typeof( LayoutAnchorSideControl ), + private static readonly DependencyPropertyKey IsLeftSidePropertyKey = DependencyProperty.RegisterReadOnly( "IsLeftSide", typeof( bool ), typeof( LayoutAnchorSideControl ), new FrameworkPropertyMetadata( ( bool )false ) ); - public static readonly DependencyProperty IsLeftSideProperty - = IsLeftSidePropertyKey.DependencyProperty; + public static readonly DependencyProperty IsLeftSideProperty = IsLeftSidePropertyKey.DependencyProperty; /// /// Gets the IsLeftSide property. This dependency property @@ -160,12 +122,10 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// IsTopSide Read-Only Dependency Property /// - private static readonly DependencyPropertyKey IsTopSidePropertyKey - = DependencyProperty.RegisterReadOnly( "IsTopSide", typeof( bool ), typeof( LayoutAnchorSideControl ), + private static readonly DependencyPropertyKey IsTopSidePropertyKey = DependencyProperty.RegisterReadOnly( "IsTopSide", typeof( bool ), typeof( LayoutAnchorSideControl ), new FrameworkPropertyMetadata( ( bool )false ) ); - public static readonly DependencyProperty IsTopSideProperty - = IsTopSidePropertyKey.DependencyProperty; + public static readonly DependencyProperty IsTopSideProperty = IsTopSidePropertyKey.DependencyProperty; /// /// Gets the IsTopSide property. This dependency property @@ -196,12 +156,10 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// IsRightSide Read-Only Dependency Property /// - private static readonly DependencyPropertyKey IsRightSidePropertyKey - = DependencyProperty.RegisterReadOnly( "IsRightSide", typeof( bool ), typeof( LayoutAnchorSideControl ), + private static readonly DependencyPropertyKey IsRightSidePropertyKey = DependencyProperty.RegisterReadOnly( "IsRightSide", typeof( bool ), typeof( LayoutAnchorSideControl ), new FrameworkPropertyMetadata( ( bool )false ) ); - public static readonly DependencyProperty IsRightSideProperty - = IsRightSidePropertyKey.DependencyProperty; + public static readonly DependencyProperty IsRightSideProperty = IsRightSidePropertyKey.DependencyProperty; /// /// Gets the IsRightSide property. This dependency property @@ -232,12 +190,10 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// IsBottomSide Read-Only Dependency Property /// - private static readonly DependencyPropertyKey IsBottomSidePropertyKey - = DependencyProperty.RegisterReadOnly( "IsBottomSide", typeof( bool ), typeof( LayoutAnchorSideControl ), + private static readonly DependencyPropertyKey IsBottomSidePropertyKey = DependencyProperty.RegisterReadOnly( "IsBottomSide", typeof( bool ), typeof( LayoutAnchorSideControl ), new FrameworkPropertyMetadata( ( bool )false ) ); - public static readonly DependencyProperty IsBottomSideProperty - = IsBottomSidePropertyKey.DependencyProperty; + public static readonly DependencyProperty IsBottomSideProperty = IsBottomSidePropertyKey.DependencyProperty; /// /// Gets the IsBottomSide property. This dependency property @@ -263,5 +219,69 @@ namespace Xceed.Wpf.AvalonDock.Controls #endregion + #endregion + + #region Overrides + + + #endregion + + #region Private Methods + + private void CreateChildrenViews() + { + var manager = _model.Root.Manager; + foreach( var childModel in _model.Children ) + { + _childViews.Add( manager.CreateUIElementForModel( childModel ) as LayoutAnchorGroupControl ); + } + } + + private void OnModelChildrenCollectionChanged( System.Collections.Specialized.NotifyCollectionChangedEventArgs e ) + { + if( e.OldItems != null && + ( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) ) + { + foreach( var childModel in e.OldItems ) + _childViews.Remove( _childViews.First( cv => cv.Model == childModel ) ); + } + + if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset ) + _childViews.Clear(); + + if( e.NewItems != null && + ( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) ) + { + var manager = _model.Root.Manager; + int insertIndex = e.NewStartingIndex; + foreach( LayoutAnchorGroup childModel in e.NewItems ) + { + _childViews.Insert( insertIndex++, manager.CreateUIElementForModel( childModel ) as LayoutAnchorGroupControl ); + } + } + } + + private void UpdateSide() + { + switch( _model.Side ) + { + case AnchorSide.Left: + SetIsLeftSide( true ); + break; + case AnchorSide.Top: + SetIsTopSide( true ); + break; + case AnchorSide.Right: + SetIsRightSide( true ); + break; + case AnchorSide.Bottom: + SetIsBottomSide( true ); + break; + } + } + + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableControl.cs index f4bd9a32..80ebc8b8 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableControl.cs @@ -22,6 +22,8 @@ namespace Xceed.Wpf.AvalonDock.Controls { public class LayoutAnchorableControl : Control { + #region Constructors + static LayoutAnchorableControl() { DefaultStyleKeyProperty.OverrideMetadata( typeof( LayoutAnchorableControl ), new FrameworkPropertyMetadata( typeof( LayoutAnchorableControl ) ) ); @@ -33,16 +35,17 @@ namespace Xceed.Wpf.AvalonDock.Controls //SetBinding(FlowDirectionProperty, new Binding("Model.Root.Manager.FlowDirection") { Source = this }); } + #endregion + + #region Properties #region Model /// /// Model Dependency Property /// - public static readonly DependencyProperty ModelProperty = - DependencyProperty.Register( "Model", typeof( LayoutAnchorable ), typeof( LayoutAnchorableControl ), - new FrameworkPropertyMetadata( ( LayoutAnchorable )null, - new PropertyChangedCallback( OnModelChanged ) ) ); + public static readonly DependencyProperty ModelProperty = DependencyProperty.Register( "Model", typeof( LayoutAnchorable ), typeof( LayoutAnchorableControl ), + new FrameworkPropertyMetadata( ( LayoutAnchorable )null, new PropertyChangedCallback( OnModelChanged ) ) ); /// /// Gets or sets the Model property. This dependency property @@ -112,12 +115,10 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// LayoutItem Read-Only Dependency Property /// - private static readonly DependencyPropertyKey LayoutItemPropertyKey - = DependencyProperty.RegisterReadOnly( "LayoutItem", typeof( LayoutItem ), typeof( LayoutAnchorableControl ), + private static readonly DependencyPropertyKey LayoutItemPropertyKey = DependencyProperty.RegisterReadOnly( "LayoutItem", typeof( LayoutItem ), typeof( LayoutAnchorableControl ), new FrameworkPropertyMetadata( ( LayoutItem )null ) ); - public static readonly DependencyProperty LayoutItemProperty - = LayoutItemPropertyKey.DependencyProperty; + public static readonly DependencyProperty LayoutItemProperty = LayoutItemPropertyKey.DependencyProperty; /// /// Gets the LayoutItem property. This dependency property @@ -143,6 +144,9 @@ namespace Xceed.Wpf.AvalonDock.Controls #endregion + #endregion + + #region Overrides protected override void OnGotKeyboardFocus( System.Windows.Input.KeyboardFocusChangedEventArgs e ) { @@ -153,5 +157,6 @@ namespace Xceed.Wpf.AvalonDock.Controls } + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs index a6746b40..5bd804cf 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs @@ -17,17 +17,11 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows; -using System.Runtime.InteropServices; -using System.Windows.Interop; -using System.Windows.Controls; using System.Windows.Data; -using System.Windows.Media; using System.Windows.Input; using Xceed.Wpf.AvalonDock.Layout; using Xceed.Wpf.AvalonDock.Converters; -using System.Diagnostics; using System.Windows.Controls.Primitives; using Xceed.Wpf.AvalonDock.Commands; using Microsoft.Windows.Shell; @@ -36,12 +30,21 @@ namespace Xceed.Wpf.AvalonDock.Controls { public class LayoutAnchorableFloatingWindowControl : LayoutFloatingWindowControl, IOverlayWindowHost { + #region Members + + private LayoutAnchorableFloatingWindow _model; + private OverlayWindow _overlayWindow = null; + private List _dropAreas = null; + + #endregion + + #region Constructors + static LayoutAnchorableFloatingWindowControl() { DefaultStyleKeyProperty.OverrideMetadata( typeof( LayoutAnchorableFloatingWindowControl ), new FrameworkPropertyMetadata( typeof( LayoutAnchorableFloatingWindowControl ) ) ); } - internal LayoutAnchorableFloatingWindowControl( LayoutAnchorableFloatingWindow model ) : base( model ) { @@ -51,33 +54,17 @@ namespace Xceed.Wpf.AvalonDock.Controls UpdateThemeResources(); } - internal override void UpdateThemeResources( Xceed.Wpf.AvalonDock.Themes.Theme oldTheme = null ) - { - base.UpdateThemeResources( oldTheme ); - - if( _overlayWindow != null ) - _overlayWindow.UpdateThemeResources( oldTheme ); - } - - LayoutAnchorableFloatingWindow _model; + #endregion - public override ILayoutElement Model - { - get - { - return _model; - } - } + #region Properties #region SingleContentLayoutItem /// /// SingleContentLayoutItem Dependency Property /// - public static readonly DependencyProperty SingleContentLayoutItemProperty = - DependencyProperty.Register( "SingleContentLayoutItem", typeof( LayoutItem ), typeof( LayoutAnchorableFloatingWindowControl ), - new FrameworkPropertyMetadata( ( LayoutItem )null, - new PropertyChangedCallback( OnSingleContentLayoutItemChanged ) ) ); + public static readonly DependencyProperty SingleContentLayoutItemProperty = DependencyProperty.Register( "SingleContentLayoutItem", typeof( LayoutItem ), typeof( LayoutAnchorableFloatingWindowControl ), + new FrameworkPropertyMetadata( ( LayoutItem )null, new PropertyChangedCallback( OnSingleContentLayoutItemChanged ) ) ); /// /// Gets or sets the SingleContentLayoutItem property. This dependency property @@ -112,7 +99,17 @@ namespace Xceed.Wpf.AvalonDock.Controls #endregion + #endregion + #region Overrides + + public override ILayoutElement Model + { + get + { + return _model; + } + } protected override void OnInitialized( EventArgs e ) { @@ -139,89 +136,6 @@ namespace Xceed.Wpf.AvalonDock.Controls _model.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler( _model_PropertyChanged ); } - - void _model_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e ) - { - if( e.PropertyName == "RootPanel" && - _model.RootPanel == null ) - { - InternalClose(); - } - } - - - bool IOverlayWindowHost.HitTest( Point dragPoint ) - { - Rect detectionRect = new Rect( this.PointToScreenDPIWithoutFlowDirection( new Point() ), this.TransformActualSizeToAncestor() ); - return detectionRect.Contains( dragPoint ); - } - - DockingManager IOverlayWindowHost.Manager - { - get - { - return _model.Root.Manager; - } - } - - OverlayWindow _overlayWindow = null; - void CreateOverlayWindow() - { - if( _overlayWindow == null ) - _overlayWindow = new OverlayWindow( this ); - Rect rectWindow = new Rect( this.PointToScreenDPIWithoutFlowDirection( new Point() ), this.TransformActualSizeToAncestor() ); - _overlayWindow.Left = rectWindow.Left; - _overlayWindow.Top = rectWindow.Top; - _overlayWindow.Width = rectWindow.Width; - _overlayWindow.Height = rectWindow.Height; - } - - IOverlayWindow IOverlayWindowHost.ShowOverlayWindow( LayoutFloatingWindowControl draggingWindow ) - { - CreateOverlayWindow(); - _overlayWindow.Owner = draggingWindow; - _overlayWindow.EnableDropTargets(); - _overlayWindow.Show(); - - return _overlayWindow; - } - - void IOverlayWindowHost.HideOverlayWindow() - { - _dropAreas = null; - _overlayWindow.Owner = null; - _overlayWindow.HideDropTargets(); - } - - List _dropAreas = null; - IEnumerable IOverlayWindowHost.GetDropAreas( LayoutFloatingWindowControl draggingWindow ) - { - if( _dropAreas != null ) - return _dropAreas; - - _dropAreas = new List(); - - if( draggingWindow.Model is LayoutDocumentFloatingWindow ) - return _dropAreas; - - var rootVisual = ( Content as FloatingWindowContentHost ).RootVisual; - - foreach( var areaHost in rootVisual.FindVisualChildren() ) - { - _dropAreas.Add( new DropArea( - areaHost, - DropAreaType.AnchorablePane ) ); - } - foreach( var areaHost in rootVisual.FindVisualChildren() ) - { - _dropAreas.Add( new DropArea( - areaHost, - DropAreaType.DocumentPane ) ); - } - - return _dropAreas; - } - protected override void OnClosed( EventArgs e ) { var root = Model.Root; @@ -283,7 +197,41 @@ namespace Xceed.Wpf.AvalonDock.Controls return base.FilterMessage( hwnd, msg, wParam, lParam, ref handled ); } - bool OpenContextMenu() + internal override void UpdateThemeResources( Xceed.Wpf.AvalonDock.Themes.Theme oldTheme = null ) + { + base.UpdateThemeResources( oldTheme ); + + if( _overlayWindow != null ) + { + _overlayWindow.UpdateThemeResources( oldTheme ); + } + } + + #endregion + + #region Private Methods + + private void _model_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e ) + { + if( e.PropertyName == "RootPanel" && + _model.RootPanel == null ) + { + InternalClose(); + } + } + + private void CreateOverlayWindow() + { + if( _overlayWindow == null ) + _overlayWindow = new OverlayWindow( this ); + Rect rectWindow = new Rect( this.PointToScreenDPIWithoutFlowDirection( new Point() ), this.TransformActualSizeToAncestor() ); + _overlayWindow.Left = rectWindow.Left; + _overlayWindow.Top = rectWindow.Top; + _overlayWindow.Width = rectWindow.Width; + _overlayWindow.Height = rectWindow.Height; + } + + private bool OpenContextMenu() { var ctxMenu = _model.Root.Manager.AnchorableContextMenu; if( ctxMenu != null && SingleContentLayoutItem != null ) @@ -298,7 +246,7 @@ namespace Xceed.Wpf.AvalonDock.Controls return false; } - bool IsContextMenuOpen() + private bool IsContextMenuOpen() { var ctxMenu = _model.Root.Manager.AnchorableContextMenu; if( ctxMenu != null && SingleContentLayoutItem != null ) @@ -309,7 +257,12 @@ namespace Xceed.Wpf.AvalonDock.Controls return false; } + #endregion + + #region Commands + #region HideWindowCommand + public ICommand HideWindowCommand { get; @@ -417,6 +370,72 @@ namespace Xceed.Wpf.AvalonDock.Controls anchorableLayoutItem.CloseCommand.Execute( parameter ); } } + + #endregion + + #endregion + + #region IOverlayWindowHost + + bool IOverlayWindowHost.HitTest( Point dragPoint ) + { + Rect detectionRect = new Rect( this.PointToScreenDPIWithoutFlowDirection( new Point() ), this.TransformActualSizeToAncestor() ); + return detectionRect.Contains( dragPoint ); + } + + DockingManager IOverlayWindowHost.Manager + { + get + { + return _model.Root.Manager; + } + } + + IOverlayWindow IOverlayWindowHost.ShowOverlayWindow( LayoutFloatingWindowControl draggingWindow ) + { + CreateOverlayWindow(); + _overlayWindow.Owner = draggingWindow; + _overlayWindow.EnableDropTargets(); + _overlayWindow.Show(); + + return _overlayWindow; + } + + void IOverlayWindowHost.HideOverlayWindow() + { + _dropAreas = null; + _overlayWindow.Owner = null; + _overlayWindow.HideDropTargets(); + } + + IEnumerable IOverlayWindowHost.GetDropAreas( LayoutFloatingWindowControl draggingWindow ) + { + if( _dropAreas != null ) + return _dropAreas; + + _dropAreas = new List(); + + if( draggingWindow.Model is LayoutDocumentFloatingWindow ) + return _dropAreas; + + var rootVisual = ( Content as FloatingWindowContentHost ).RootVisual; + + foreach( var areaHost in rootVisual.FindVisualChildren() ) + { + _dropAreas.Add( new DropArea( + areaHost, + DropAreaType.AnchorablePane ) ); + } + foreach( var areaHost in rootVisual.FindVisualChildren() ) + { + _dropAreas.Add( new DropArea( + areaHost, + DropAreaType.DocumentPane ) ); + } + + return _dropAreas; + } + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableItem.cs index b94e03c7..9d68940f 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableItem.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableItem.cs @@ -15,9 +15,6 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using Xceed.Wpf.AvalonDock.Layout; using System.Windows.Input; using System.Windows; @@ -26,341 +23,370 @@ using System.Windows.Data; namespace Xceed.Wpf.AvalonDock.Controls { - public class LayoutAnchorableItem : LayoutItem + public class LayoutAnchorableItem : LayoutItem + { + #region Members + + private LayoutAnchorable _anchorable; + private ICommand _defaultHideCommand; + private ICommand _defaultAutoHideCommand; + private ICommand _defaultDockCommand; + private ReentrantFlag _visibilityReentrantFlag = new ReentrantFlag(); + + #endregion + + #region Constructors + + internal LayoutAnchorableItem() { - LayoutAnchorable _anchorable; - internal LayoutAnchorableItem() - { + } - } + #endregion - internal override void Attach(LayoutContent model) - { - _anchorable = model as LayoutAnchorable; - _anchorable.IsVisibleChanged += new EventHandler(_anchorable_IsVisibleChanged); + #region Properties - base.Attach(model); - } + #region HideCommand - internal override void Detach() - { - _anchorable.IsVisibleChanged -= new EventHandler(_anchorable_IsVisibleChanged); - _anchorable = null; - base.Detach(); - } + /// + /// HideCommand Dependency Property + /// + public static readonly DependencyProperty HideCommandProperty = DependencyProperty.Register( "HideCommand", typeof( ICommand ), typeof( LayoutAnchorableItem ), + new FrameworkPropertyMetadata( null, new PropertyChangedCallback( OnHideCommandChanged ), new CoerceValueCallback( CoerceHideCommandValue ) ) ); - protected override void Close() - { - if( (_anchorable.Root != null) && (_anchorable.Root.Manager != null) ) - { - var dockingManager = _anchorable.Root.Manager; - dockingManager._ExecuteCloseCommand( _anchorable ); - } - } + /// + /// Gets or sets the HideCommand property. This dependency property + /// indicates the command to execute when an anchorable is hidden. + /// + public ICommand HideCommand + { + get + { + return ( ICommand )GetValue( HideCommandProperty ); + } + set + { + SetValue( HideCommandProperty, value ); + } + } - ICommand _defaultHideCommand; - ICommand _defaultAutoHideCommand; - ICommand _defaultDockCommand; + /// + /// Handles changes to the HideCommand property. + /// + private static void OnHideCommandChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( LayoutAnchorableItem )d ).OnHideCommandChanged( e ); + } - protected override void InitDefaultCommands() - { - _defaultHideCommand = new RelayCommand((p) => ExecuteHideCommand(p), (p) => CanExecuteHideCommand(p)); - _defaultAutoHideCommand = new RelayCommand((p) => ExecuteAutoHideCommand(p), (p) => CanExecuteAutoHideCommand(p)); - _defaultDockCommand = new RelayCommand((p) => ExecuteDockCommand(p), (p) => CanExecuteDockCommand(p)); + /// + /// Provides derived classes an opportunity to handle changes to the HideCommand property. + /// + protected virtual void OnHideCommandChanged( DependencyPropertyChangedEventArgs e ) + { + } - base.InitDefaultCommands(); - } + /// + /// Coerces the HideCommand value. + /// + private static object CoerceHideCommandValue( DependencyObject d, object value ) + { + return value; + } - protected override void ClearDefaultBindings() - { - if (HideCommand == _defaultHideCommand) - BindingOperations.ClearBinding(this, HideCommandProperty); - if (AutoHideCommand == _defaultAutoHideCommand) - BindingOperations.ClearBinding(this, AutoHideCommandProperty); - if (DockCommand == _defaultDockCommand) - BindingOperations.ClearBinding(this, DockCommandProperty); - - base.ClearDefaultBindings(); - } + private bool CanExecuteHideCommand( object parameter ) + { + if( LayoutElement == null ) + return false; + return _anchorable.CanHide; + } - protected override void SetDefaultBindings() - { - if (HideCommand == null) - HideCommand = _defaultHideCommand; - if (AutoHideCommand == null) - AutoHideCommand = _defaultAutoHideCommand; - if (DockCommand == null) - DockCommand = _defaultDockCommand; - - Visibility = _anchorable.IsVisible ? Visibility.Visible : System.Windows.Visibility.Hidden; - base.SetDefaultBindings(); - } + private void ExecuteHideCommand( object parameter ) + { + if( _anchorable != null && _anchorable.Root != null && _anchorable.Root.Manager != null ) + _anchorable.Root.Manager._ExecuteHideCommand( _anchorable ); + } + #endregion - #region HideCommand + #region AutoHideCommand - /// - /// HideCommand Dependency Property - /// - public static readonly DependencyProperty HideCommandProperty = - DependencyProperty.Register("HideCommand", typeof(ICommand), typeof(LayoutAnchorableItem), - new FrameworkPropertyMetadata(null, - new PropertyChangedCallback(OnHideCommandChanged), - new CoerceValueCallback(CoerceHideCommandValue))); + /// + /// AutoHideCommand Dependency Property + /// + public static readonly DependencyProperty AutoHideCommandProperty = DependencyProperty.Register( "AutoHideCommand", typeof( ICommand ), typeof( LayoutAnchorableItem ), + new FrameworkPropertyMetadata( null, new PropertyChangedCallback( OnAutoHideCommandChanged ), new CoerceValueCallback( CoerceAutoHideCommandValue ) ) ); - /// - /// Gets or sets the HideCommand property. This dependency property - /// indicates the command to execute when an anchorable is hidden. - /// - public ICommand HideCommand - { - get { return (ICommand)GetValue(HideCommandProperty); } - set { SetValue(HideCommandProperty, value); } - } + /// + /// Gets or sets the AutoHideCommand property. This dependency property + /// indicates the command to execute when user click the auto hide button. + /// + /// By default this command toggles auto hide state for an anchorable. + public ICommand AutoHideCommand + { + get + { + return ( ICommand )GetValue( AutoHideCommandProperty ); + } + set + { + SetValue( AutoHideCommandProperty, value ); + } + } - /// - /// Handles changes to the HideCommand property. - /// - private static void OnHideCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((LayoutAnchorableItem)d).OnHideCommandChanged(e); - } + /// + /// Handles changes to the AutoHideCommand property. + /// + private static void OnAutoHideCommandChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( LayoutAnchorableItem )d ).OnAutoHideCommandChanged( e ); + } - /// - /// Provides derived classes an opportunity to handle changes to the HideCommand property. - /// - protected virtual void OnHideCommandChanged(DependencyPropertyChangedEventArgs e) - { - } + /// + /// Provides derived classes an opportunity to handle changes to the AutoHideCommand property. + /// + protected virtual void OnAutoHideCommandChanged( DependencyPropertyChangedEventArgs e ) + { + } - /// - /// Coerces the HideCommand value. - /// - private static object CoerceHideCommandValue(DependencyObject d, object value) - { - return value; - } + /// + /// Coerces the AutoHideCommand value. + /// + private static object CoerceAutoHideCommandValue( DependencyObject d, object value ) + { + return value; + } + private bool CanExecuteAutoHideCommand( object parameter ) + { + if( LayoutElement == null ) + return false; - private bool CanExecuteHideCommand(object parameter) - { - if (LayoutElement == null) - return false; - return _anchorable.CanHide; - } + if( LayoutElement.FindParent() != null ) + return false;//is floating - private void ExecuteHideCommand(object parameter) - { - if (_anchorable != null && _anchorable.Root != null && _anchorable.Root.Manager != null) - _anchorable.Root.Manager._ExecuteHideCommand(_anchorable); - } + return _anchorable.CanAutoHide; + } - #endregion - - #region AutoHideCommand - - /// - /// AutoHideCommand Dependency Property - /// - public static readonly DependencyProperty AutoHideCommandProperty = - DependencyProperty.Register("AutoHideCommand", typeof(ICommand), typeof(LayoutAnchorableItem), - new FrameworkPropertyMetadata(null, - new PropertyChangedCallback(OnAutoHideCommandChanged), - new CoerceValueCallback(CoerceAutoHideCommandValue))); - - /// - /// Gets or sets the AutoHideCommand property. This dependency property - /// indicates the command to execute when user click the auto hide button. - /// - /// By default this command toggles auto hide state for an anchorable. - public ICommand AutoHideCommand - { - get { return (ICommand)GetValue(AutoHideCommandProperty); } - set { SetValue(AutoHideCommandProperty, value); } - } + private void ExecuteAutoHideCommand( object parameter ) + { + if( _anchorable != null && _anchorable.Root != null && _anchorable.Root.Manager != null ) + _anchorable.Root.Manager._ExecuteAutoHideCommand( _anchorable ); + } - /// - /// Handles changes to the AutoHideCommand property. - /// - private static void OnAutoHideCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((LayoutAnchorableItem)d).OnAutoHideCommandChanged(e); - } + #endregion - /// - /// Provides derived classes an opportunity to handle changes to the AutoHideCommand property. - /// - protected virtual void OnAutoHideCommandChanged(DependencyPropertyChangedEventArgs e) - { - } + #region DockCommand - /// - /// Coerces the AutoHideCommand value. - /// - private static object CoerceAutoHideCommandValue(DependencyObject d, object value) - { - return value; - } + /// + /// DockCommand Dependency Property + /// + public static readonly DependencyProperty DockCommandProperty = DependencyProperty.Register( "DockCommand", typeof( ICommand ), typeof( LayoutAnchorableItem ), + new FrameworkPropertyMetadata( null, new PropertyChangedCallback( OnDockCommandChanged ), new CoerceValueCallback( CoerceDockCommandValue ) ) ); - private bool CanExecuteAutoHideCommand(object parameter) - { - if (LayoutElement == null) - return false; + /// + /// Gets or sets the DockCommand property. This dependency property + /// indicates the command to execute when user click the Dock button. + /// + /// By default this command moves the anchorable inside the container pane which previously hosted the object. + public ICommand DockCommand + { + get + { + return ( ICommand )GetValue( DockCommandProperty ); + } + set + { + SetValue( DockCommandProperty, value ); + } + } - if (LayoutElement.FindParent() != null) - return false;//is floating + /// + /// Handles changes to the DockCommand property. + /// + private static void OnDockCommandChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( LayoutAnchorableItem )d ).OnDockCommandChanged( e ); + } - return _anchorable.CanAutoHide; - } + /// + /// Provides derived classes an opportunity to handle changes to the DockCommand property. + /// + protected virtual void OnDockCommandChanged( DependencyPropertyChangedEventArgs e ) + { + } - private void ExecuteAutoHideCommand(object parameter) - { - if (_anchorable != null && _anchorable.Root != null && _anchorable.Root.Manager != null) - _anchorable.Root.Manager._ExecuteAutoHideCommand(_anchorable); - } + /// + /// Coerces the DockCommand value. + /// + private static object CoerceDockCommandValue( DependencyObject d, object value ) + { + return value; + } - #endregion - - #region DockCommand - - /// - /// DockCommand Dependency Property - /// - public static readonly DependencyProperty DockCommandProperty = - DependencyProperty.Register("DockCommand", typeof(ICommand), typeof(LayoutAnchorableItem), - new FrameworkPropertyMetadata(null, - new PropertyChangedCallback(OnDockCommandChanged), - new CoerceValueCallback(CoerceDockCommandValue))); - - /// - /// Gets or sets the DockCommand property. This dependency property - /// indicates the command to execute when user click the Dock button. - /// - /// By default this command moves the anchorable inside the container pane which previously hosted the object. - public ICommand DockCommand - { - get { return (ICommand)GetValue(DockCommandProperty); } - set { SetValue(DockCommandProperty, value); } - } + private bool CanExecuteDockCommand( object parameter ) + { + if( LayoutElement == null ) + return false; + return LayoutElement.FindParent() != null; + } - /// - /// Handles changes to the DockCommand property. - /// - private static void OnDockCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((LayoutAnchorableItem)d).OnDockCommandChanged(e); - } + private void ExecuteDockCommand( object parameter ) + { + LayoutElement.Root.Manager._ExecuteDockCommand( _anchorable ); + } - /// - /// Provides derived classes an opportunity to handle changes to the DockCommand property. - /// - protected virtual void OnDockCommandChanged(DependencyPropertyChangedEventArgs e) - { - } + #endregion - /// - /// Coerces the DockCommand value. - /// - private static object CoerceDockCommandValue(DependencyObject d, object value) - { - return value; - } + #region CanHide - private bool CanExecuteDockCommand(object parameter) - { - if (LayoutElement == null) - return false; - return LayoutElement.FindParent() != null; - } + /// + /// CanHide Dependency Property + /// + public static readonly DependencyProperty CanHideProperty = DependencyProperty.Register( "CanHide", typeof( bool ), typeof( LayoutAnchorableItem ), new FrameworkPropertyMetadata( ( bool )true, + new PropertyChangedCallback( OnCanHideChanged ) ) ); - private void ExecuteDockCommand(object parameter) - { - LayoutElement.Root.Manager._ExecuteDockCommand(_anchorable); - } + /// + /// Gets or sets the CanHide property. This dependency property + /// indicates if user can hide the anchorable item. + /// + public bool CanHide + { + get + { + return ( bool )GetValue( CanHideProperty ); + } + set + { + SetValue( CanHideProperty, value ); + } + } - #endregion + /// + /// Handles changes to the CanHide property. + /// + private static void OnCanHideChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( LayoutAnchorableItem )d ).OnCanHideChanged( e ); + } - #region Visibility - ReentrantFlag _visibilityReentrantFlag = new ReentrantFlag(); + /// + /// Provides derived classes an opportunity to handle changes to the CanHide property. + /// + protected virtual void OnCanHideChanged( DependencyPropertyChangedEventArgs e ) + { + if( _anchorable != null ) + _anchorable.CanHide = ( bool )e.NewValue; + } - protected override void OnVisibilityChanged() - { - if (_anchorable != null && _anchorable.Root != null) - { - if (_visibilityReentrantFlag.CanEnter) - { - using (_visibilityReentrantFlag.Enter()) - { - if (Visibility == System.Windows.Visibility.Hidden) - _anchorable.Hide(false); - else if (Visibility == System.Windows.Visibility.Visible) - _anchorable.Show(); - } - } - } - - base.OnVisibilityChanged(); - } + #endregion + #endregion - void _anchorable_IsVisibleChanged(object sender, EventArgs e) - { - if (_anchorable != null && _anchorable.Root != null) - { - if (_visibilityReentrantFlag.CanEnter) - { - using (_visibilityReentrantFlag.Enter()) - { - if (_anchorable.IsVisible) - Visibility = Visibility.Visible; - else - Visibility = Visibility.Hidden; - } - } - } - } + #region Overrides - #endregion + internal override void Attach( LayoutContent model ) + { + _anchorable = model as LayoutAnchorable; + _anchorable.IsVisibleChanged += new EventHandler( _anchorable_IsVisibleChanged ); - #region CanHide + base.Attach( model ); + } - /// - /// CanHide Dependency Property - /// - public static readonly DependencyProperty CanHideProperty = - DependencyProperty.Register("CanHide", typeof(bool), typeof(LayoutAnchorableItem), - new FrameworkPropertyMetadata((bool)true, - new PropertyChangedCallback(OnCanHideChanged))); + internal override void Detach() + { + _anchorable.IsVisibleChanged -= new EventHandler( _anchorable_IsVisibleChanged ); + _anchorable = null; + base.Detach(); + } - /// - /// Gets or sets the CanHide property. This dependency property - /// indicates if user can hide the anchorable item. - /// - public bool CanHide - { - get { return (bool)GetValue(CanHideProperty); } - set { SetValue(CanHideProperty, value); } - } + protected override void Close() + { + if( ( _anchorable.Root != null ) && ( _anchorable.Root.Manager != null ) ) + { + var dockingManager = _anchorable.Root.Manager; + dockingManager._ExecuteCloseCommand( _anchorable ); + } + } + + protected override void InitDefaultCommands() + { + _defaultHideCommand = new RelayCommand( ( p ) => ExecuteHideCommand( p ), ( p ) => CanExecuteHideCommand( p ) ); + _defaultAutoHideCommand = new RelayCommand( ( p ) => ExecuteAutoHideCommand( p ), ( p ) => CanExecuteAutoHideCommand( p ) ); + _defaultDockCommand = new RelayCommand( ( p ) => ExecuteDockCommand( p ), ( p ) => CanExecuteDockCommand( p ) ); + + base.InitDefaultCommands(); + } + + protected override void ClearDefaultBindings() + { + if( HideCommand == _defaultHideCommand ) + BindingOperations.ClearBinding( this, HideCommandProperty ); + if( AutoHideCommand == _defaultAutoHideCommand ) + BindingOperations.ClearBinding( this, AutoHideCommandProperty ); + if( DockCommand == _defaultDockCommand ) + BindingOperations.ClearBinding( this, DockCommandProperty ); + + base.ClearDefaultBindings(); + } + + protected override void SetDefaultBindings() + { + if( HideCommand == null ) + HideCommand = _defaultHideCommand; + if( AutoHideCommand == null ) + AutoHideCommand = _defaultAutoHideCommand; + if( DockCommand == null ) + DockCommand = _defaultDockCommand; + + Visibility = _anchorable.IsVisible ? Visibility.Visible : System.Windows.Visibility.Hidden; + base.SetDefaultBindings(); + } - /// - /// Handles changes to the CanHide property. - /// - private static void OnCanHideChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + protected override void OnVisibilityChanged() + { + if( _anchorable != null && _anchorable.Root != null ) + { + if( _visibilityReentrantFlag.CanEnter ) { - ((LayoutAnchorableItem)d).OnCanHideChanged(e); + using( _visibilityReentrantFlag.Enter() ) + { + if( Visibility == System.Windows.Visibility.Hidden ) + _anchorable.Hide( false ); + else if( Visibility == System.Windows.Visibility.Visible ) + _anchorable.Show(); + } } + } - /// - /// Provides derived classes an opportunity to handle changes to the CanHide property. - /// - protected virtual void OnCanHideChanged(DependencyPropertyChangedEventArgs e) + base.OnVisibilityChanged(); + } + + #endregion + + #region Private Methods + + private void _anchorable_IsVisibleChanged( object sender, EventArgs e ) + { + if( _anchorable != null && _anchorable.Root != null ) + { + if( _visibilityReentrantFlag.CanEnter ) { - if (_anchorable != null) - _anchorable.CanHide = (bool)e.NewValue; + using( _visibilityReentrantFlag.Enter() ) + { + if( _anchorable.IsVisible ) + Visibility = Visibility.Visible; + else + Visibility = Visibility.Hidden; + } } + } + } - #endregion - } + + + + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorablePaneControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorablePaneControl.cs index 651a6592..3c725619 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorablePaneControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorablePaneControl.cs @@ -24,6 +24,14 @@ namespace Xceed.Wpf.AvalonDock.Controls { public class LayoutAnchorablePaneControl : TabControl, ILayoutControl//, ILogicalChildrenContainer { + #region Members + + private LayoutAnchorablePane _model; + + #endregion + + #region Constructors + static LayoutAnchorablePaneControl() { FocusableProperty.OverrideMetadata( typeof( LayoutAnchorablePaneControl ), new FrameworkPropertyMetadata( false ) ); @@ -42,14 +50,9 @@ namespace Xceed.Wpf.AvalonDock.Controls this.LayoutUpdated += new EventHandler( OnLayoutUpdated ); } - void OnLayoutUpdated( object sender, EventArgs e ) - { - var modelWithAtcualSize = _model as ILayoutPositionableElementWithActualSize; - modelWithAtcualSize.ActualWidth = ActualWidth; - modelWithAtcualSize.ActualHeight = ActualHeight; - } + #endregion - LayoutAnchorablePane _model; + #region Properties public ILayoutElement Model { @@ -59,6 +62,10 @@ namespace Xceed.Wpf.AvalonDock.Controls } } + #endregion + + #region Overrides + protected override void OnGotKeyboardFocus( System.Windows.Input.KeyboardFocusChangedEventArgs e ) { if( ( _model != null ) && ( _model.SelectedContent != null ) ) @@ -89,5 +96,18 @@ namespace Xceed.Wpf.AvalonDock.Controls } } + + #endregion + + #region Private Methods + + private void OnLayoutUpdated( object sender, EventArgs e ) + { + var modelWithAtcualSize = _model as ILayoutPositionableElementWithActualSize; + modelWithAtcualSize.ActualWidth = ActualWidth; + modelWithAtcualSize.ActualHeight = ActualHeight; + } + + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorablePaneGroupControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorablePaneGroupControl.cs index 0b7769bc..99269059 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorablePaneGroupControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorablePaneGroupControl.cs @@ -14,54 +14,60 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Controls; using System.Windows; using Xceed.Wpf.AvalonDock.Layout; - namespace Xceed.Wpf.AvalonDock.Controls { - public class LayoutAnchorablePaneGroupControl : LayoutGridControl, ILayoutControl + public class LayoutAnchorablePaneGroupControl : LayoutGridControl, ILayoutControl + { + #region Members + + private LayoutAnchorablePaneGroup _model; + + #endregion + + #region Constructors + + internal LayoutAnchorablePaneGroupControl( LayoutAnchorablePaneGroup model ) + : base( model, model.Orientation ) { - internal LayoutAnchorablePaneGroupControl(LayoutAnchorablePaneGroup model) - : base(model, model.Orientation) - { - _model = model; - } + _model = model; + } + + #endregion - LayoutAnchorablePaneGroup _model; + #region Overrides - protected override void OnFixChildrenDockLengths() + protected override void OnFixChildrenDockLengths() + { + #region Setup DockWidth/Height for children + if( _model.Orientation == Orientation.Horizontal ) + { + for( int i = 0; i < _model.Children.Count; i++ ) { - #region Setup DockWidth/Height for children - if (_model.Orientation == Orientation.Horizontal) - { - for (int i = 0; i < _model.Children.Count; i++) - { - var childModel = _model.Children[i] as ILayoutPositionableElement; - if (!childModel.DockWidth.IsStar) - { - childModel.DockWidth = new GridLength(1.0, GridUnitType.Star); - } - } - } - else - { - for (int i = 0; i < _model.Children.Count; i++) - { - var childModel = _model.Children[i] as ILayoutPositionableElement; - if (!childModel.DockHeight.IsStar) - { - childModel.DockHeight = new GridLength(1.0, GridUnitType.Star); - } - } - } - #endregion + var childModel = _model.Children[ i ] as ILayoutPositionableElement; + if( !childModel.DockWidth.IsStar ) + { + childModel.DockWidth = new GridLength( 1.0, GridUnitType.Star ); + } } - + } + else + { + for( int i = 0; i < _model.Children.Count; i++ ) + { + var childModel = _model.Children[ i ] as ILayoutPositionableElement; + if( !childModel.DockHeight.IsStar ) + { + childModel.DockHeight = new GridLength( 1.0, GridUnitType.Star ); + } + } + } + #endregion } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableTabItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableTabItem.cs index f376bd89..743e0265 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableTabItem.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableTabItem.cs @@ -14,17 +14,11 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows; -using System.Collections.ObjectModel; using System.Windows.Controls; using System.Windows.Input; using Xceed.Wpf.AvalonDock.Layout; -using System.Reflection; -using System.Diagnostics; namespace Xceed.Wpf.AvalonDock.Controls { @@ -38,6 +32,8 @@ namespace Xceed.Wpf.AvalonDock.Controls #endregion + #region Constructors + static LayoutAnchorableTabItem() { DefaultStyleKeyProperty.OverrideMetadata( typeof( LayoutAnchorableTabItem ), new FrameworkPropertyMetadata( typeof( LayoutAnchorableTabItem ) ) ); @@ -47,17 +43,17 @@ namespace Xceed.Wpf.AvalonDock.Controls { } + #endregion + #region Properties #region Model /// /// Model Dependency Property /// - public static readonly DependencyProperty ModelProperty = - DependencyProperty.Register( "Model", typeof( LayoutContent ), typeof( LayoutAnchorableTabItem ), - new FrameworkPropertyMetadata( (LayoutContent)null, - new PropertyChangedCallback( OnModelChanged ) ) ); + public static readonly DependencyProperty ModelProperty = DependencyProperty.Register( "Model", typeof( LayoutContent ), typeof( LayoutAnchorableTabItem ), + new FrameworkPropertyMetadata( ( LayoutContent )null, new PropertyChangedCallback( OnModelChanged ) ) ); /// /// Gets or sets the Model property. This dependency property @@ -67,7 +63,7 @@ namespace Xceed.Wpf.AvalonDock.Controls { get { - return (LayoutContent)GetValue( ModelProperty ); + return ( LayoutContent )GetValue( ModelProperty ); } set { @@ -80,7 +76,7 @@ namespace Xceed.Wpf.AvalonDock.Controls /// private static void OnModelChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) { - ( (LayoutAnchorableTabItem)d ).OnModelChanged( e ); + ( ( LayoutAnchorableTabItem )d ).OnModelChanged( e ); } /// @@ -102,12 +98,10 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// LayoutItem Read-Only Dependency Property /// - private static readonly DependencyPropertyKey LayoutItemPropertyKey - = DependencyProperty.RegisterReadOnly( "LayoutItem", typeof( LayoutItem ), typeof( LayoutAnchorableTabItem ), - new FrameworkPropertyMetadata( (LayoutItem)null ) ); + private static readonly DependencyPropertyKey LayoutItemPropertyKey = DependencyProperty.RegisterReadOnly( "LayoutItem", typeof( LayoutItem ), typeof( LayoutAnchorableTabItem ), + new FrameworkPropertyMetadata( ( LayoutItem )null ) ); - public static readonly DependencyProperty LayoutItemProperty - = LayoutItemPropertyKey.DependencyProperty; + public static readonly DependencyProperty LayoutItemProperty = LayoutItemPropertyKey.DependencyProperty; /// /// Gets the LayoutItem property. This dependency property @@ -117,7 +111,7 @@ namespace Xceed.Wpf.AvalonDock.Controls { get { - return (LayoutItem)GetValue( LayoutItemProperty ); + return ( LayoutItem )GetValue( LayoutItemProperty ); } } @@ -133,6 +127,9 @@ namespace Xceed.Wpf.AvalonDock.Controls #endregion + #endregion + + #region Overrides protected override void OnMouseLeftButtonDown( System.Windows.Input.MouseButtonEventArgs e ) { base.OnMouseLeftButtonDown( e ); @@ -184,17 +181,16 @@ namespace Xceed.Wpf.AvalonDock.Controls { base.OnMouseEnter( e ); - if( _draggingItem != null && - _draggingItem != this && + if( _draggingItem != this && e.LeftButton == MouseButtonState.Pressed ) { var model = Model; var container = model.Parent as ILayoutContainer; var containerPane = model.Parent as ILayoutPane; - if( ( containerPane is LayoutAnchorablePane ) && !( (LayoutAnchorablePane)containerPane ).CanRepositionItems ) + if( ( containerPane is LayoutAnchorablePane ) && !( ( LayoutAnchorablePane )containerPane ).CanRepositionItems ) return; - if( ( containerPane.Parent != null ) && ( containerPane.Parent is LayoutAnchorablePaneGroup ) && !( (LayoutAnchorablePaneGroup)containerPane.Parent ).CanRepositionItems ) + if( ( containerPane.Parent != null ) && ( containerPane.Parent is LayoutAnchorablePaneGroup ) && !( ( LayoutAnchorablePaneGroup )containerPane.Parent ).CanRepositionItems ) return; var childrenList = container.Children.ToList(); @@ -208,6 +204,10 @@ namespace Xceed.Wpf.AvalonDock.Controls } + #endregion + + #region Internal Methods + internal static bool IsDraggingItem() { return _draggingItem != null; @@ -221,10 +221,11 @@ namespace Xceed.Wpf.AvalonDock.Controls { _draggingItem = null; } - internal static void CancelMouseLeave() { _cancelMouseLeave = true; } - } + + #endregion +} } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAutoHideWindowControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAutoHideWindowControl.cs index f2216a90..7d97aafe 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAutoHideWindowControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAutoHideWindowControl.cs @@ -29,6 +29,28 @@ namespace Xceed.Wpf.AvalonDock.Controls { public class LayoutAutoHideWindowControl : HwndHost, ILayoutControl { + #region Members + + internal LayoutAnchorableControl _internalHost = null; + + private LayoutAnchorControl _anchor; + private LayoutAnchorable _model; + private HwndSource _internalHwndSource = null; + private IntPtr parentWindowHandle; + private bool _internalHost_ContentRendered = false; + private ContentPresenter _internalHostPresenter = new ContentPresenter(); + private Grid _internalGrid = null; + private AnchorSide _side; + private LayoutGridResizerControl _resizer = null; + private DockingManager _manager; + private Border _resizerGhost = null; + private Window _resizerWindowHost = null; + private Vector _initialStartPoint; + + #endregion + + #region Constructors + static LayoutAutoHideWindowControl() { DefaultStyleKeyProperty.OverrideMetadata( typeof( LayoutAutoHideWindowControl ), new FrameworkPropertyMetadata( typeof( LayoutAutoHideWindowControl ) ) ); @@ -41,41 +63,63 @@ namespace Xceed.Wpf.AvalonDock.Controls { } - internal void Show( LayoutAnchorControl anchor ) - { - if( _model != null ) - throw new InvalidOperationException(); + #endregion - _anchor = anchor; - _model = anchor.Model as LayoutAnchorable; - _side = ( anchor.Model.Parent.Parent as LayoutAnchorSide ).Side; - _manager = _model.Root.Manager; - CreateInternalGrid(); + #region Properties - _model.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler( _model_PropertyChanged ); + #region AnchorableStyle - Visibility = System.Windows.Visibility.Visible; - InvalidateMeasure(); - UpdateWindowPos(); - } + /// + /// AnchorableStyle Dependency Property + /// + public static readonly DependencyProperty AnchorableStyleProperty = DependencyProperty.Register( "AnchorableStyle", typeof( Style ), typeof( LayoutAutoHideWindowControl ), + new FrameworkPropertyMetadata( ( Style )null ) ); - internal void Hide() + /// + /// Gets or sets the AnchorableStyle property. This dependency property + /// indicates the style to apply to the LayoutAnchorableControl hosted in this auto hide window. + /// + public Style AnchorableStyle { - if( _model == null ) - return; + get + { + return ( Style )GetValue( AnchorableStyleProperty ); + } + set + { + SetValue( AnchorableStyleProperty, value ); + } + } - _model.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler( _model_PropertyChanged ); + #endregion - RemoveInternalGrid(); - _anchor = null; - _model = null; - _manager = null; - Visibility = System.Windows.Visibility.Hidden; + #region Background + + /// + /// Background Dependency Property + /// + public static readonly DependencyProperty BackgroundProperty = DependencyProperty.Register( "Background", typeof( Brush ), typeof( LayoutAutoHideWindowControl ), + new FrameworkPropertyMetadata( ( Brush )null ) ); + + /// + /// Gets or sets the Background property. This dependency property + /// indicates background of the autohide childwindow. + /// + public Brush Background + { + get + { + return ( Brush )GetValue( BackgroundProperty ); + } + set + { + SetValue( BackgroundProperty, value ); + } } - LayoutAnchorControl _anchor; + #endregion - LayoutAnchorable _model; + #region Model public ILayoutElement Model { @@ -85,8 +129,22 @@ namespace Xceed.Wpf.AvalonDock.Controls } } - HwndSource _internalHwndSource = null; - IntPtr parentWindowHandle; + #endregion + + #region Resizer + + internal bool IsResizing + { + get; + private set; + } + + #endregion + + #endregion + + #region Overrides + protected override System.Runtime.InteropServices.HandleRef BuildWindowCore( System.Runtime.InteropServices.HandleRef hwndParent ) { parentWindowHandle = hwndParent.Handle; @@ -106,14 +164,6 @@ namespace Xceed.Wpf.AvalonDock.Controls return new HandleRef( this, _internalHwndSource.Handle ); } - private bool _internalHost_ContentRendered = false; - - void _internalHwndSource_ContentRendered( object sender, EventArgs e ) - { - _internalHost_ContentRendered = true; - } - - protected override IntPtr WndProc( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled ) { if( msg == Win32Helper.WM_WINDOWPOSCHANGING ) @@ -137,18 +187,117 @@ namespace Xceed.Wpf.AvalonDock.Controls public override void OnApplyTemplate() { base.OnApplyTemplate(); + } + protected override bool HasFocusWithinCore() + { + return false; + } + protected override System.Collections.IEnumerator LogicalChildren + { + get + { + if( _internalHostPresenter == null ) + return new UIElement[] { }.GetEnumerator(); + return new UIElement[] { _internalHostPresenter }.GetEnumerator(); + } } - ContentPresenter _internalHostPresenter = new ContentPresenter(); - Grid _internalGrid = null; - internal LayoutAnchorableControl _internalHost = null; - AnchorSide _side; - LayoutGridResizerControl _resizer = null; - DockingManager _manager; + protected override Size MeasureOverride( Size constraint ) + { + if( _internalHostPresenter == null ) + return base.MeasureOverride( constraint ); + + _internalHostPresenter.Measure( constraint ); + //return base.MeasureOverride(constraint); + return _internalHostPresenter.DesiredSize; + } - void _model_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e ) + protected override Size ArrangeOverride( Size finalSize ) + { + if( _internalHostPresenter == null ) + return base.ArrangeOverride( finalSize ); + + _internalHostPresenter.Arrange( new Rect( finalSize ) ); + return base.ArrangeOverride( finalSize );// new Size(_internalHostPresenter.ActualWidth, _internalHostPresenter.ActualHeight); + } + + #endregion + + #region Internal Methods + + internal void Show( LayoutAnchorControl anchor ) + { + if( _model != null ) + throw new InvalidOperationException(); + + _anchor = anchor; + _model = anchor.Model as LayoutAnchorable; + _side = ( anchor.Model.Parent.Parent as LayoutAnchorSide ).Side; + _manager = _model.Root.Manager; + CreateInternalGrid(); + + _model.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler( _model_PropertyChanged ); + + Visibility = System.Windows.Visibility.Visible; + InvalidateMeasure(); + UpdateWindowPos(); + } + + internal void Hide() + { + if( _model == null ) + return; + + _model.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler( _model_PropertyChanged ); + + RemoveInternalGrid(); + _anchor = null; + _model = null; + _manager = null; + Visibility = System.Windows.Visibility.Hidden; + } + + internal bool IsWin32MouseOver + { + get + { + var ptMouse = new Win32Helper.Win32Point(); + if( !Win32Helper.GetCursorPos( ref ptMouse ) ) + return false; + + Point location = this.PointToScreenDPI( new Point() ); + + Rect rectWindow = this.GetScreenArea(); + if( rectWindow.Contains( new Point( ptMouse.X, ptMouse.Y ) ) ) + return true; + + var manager = Model.Root.Manager; + var anchor = manager.FindVisualChildren().Where( c => c.Model == Model ).FirstOrDefault(); + + if( anchor == null ) + return false; + + location = anchor.PointToScreenDPI( new Point() ); + + if( anchor.IsMouseOver ) + return true; + + return false; + } + } + + #endregion + + #region Private Methods + + private void _internalHwndSource_ContentRendered( object sender, EventArgs e ) + { + _internalHost_ContentRendered = true; + } + + private void _model_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e ) { if( e.PropertyName == "IsAutoHidden" ) { @@ -159,7 +308,7 @@ namespace Xceed.Wpf.AvalonDock.Controls } } - void CreateInternalGrid() + private void CreateInternalGrid() { _internalGrid = new Grid() { FlowDirection = System.Windows.FlowDirection.LeftToRight }; _internalGrid.SetBinding( Grid.BackgroundProperty, new Binding( "Background" ) { Source = this } ); @@ -248,7 +397,7 @@ namespace Xceed.Wpf.AvalonDock.Controls _internalHostPresenter.Content = _internalGrid; } - void RemoveInternalGrid() + private void RemoveInternalGrid() { _resizer.DragStarted -= new System.Windows.Controls.Primitives.DragStartedEventHandler( OnResizerDragStarted ); _resizer.DragDelta -= new System.Windows.Controls.Primitives.DragDeltaEventHandler( OnResizerDragDelta ); @@ -257,19 +406,7 @@ namespace Xceed.Wpf.AvalonDock.Controls _internalHostPresenter.Content = null; } - - protected override bool HasFocusWithinCore() - { - return false; - } - - #region Resizer - - Border _resizerGhost = null; - Window _resizerWindowHost = null; - Vector _initialStartPoint; - - void ShowResizerOverlayWindow( LayoutGridResizerControl splitter ) + private void ShowResizerOverlayWindow( LayoutGridResizerControl splitter ) { _resizerGhost = new Border() { @@ -346,7 +483,7 @@ namespace Xceed.Wpf.AvalonDock.Controls _resizerWindowHost.Show(); } - void HideResizerOverlayWindow() + private void HideResizerOverlayWindow() { if( _resizerWindowHost != null ) { @@ -355,13 +492,7 @@ namespace Xceed.Wpf.AvalonDock.Controls } } - internal bool IsResizing - { - get; - private set; - } - - void OnResizerDragCompleted( object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e ) + private void OnResizerDragCompleted( object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e ) { LayoutGridResizerControl splitter = sender as LayoutGridResizerControl; var rootVisual = this.FindVisualTreeRoot() as Visual; @@ -419,7 +550,7 @@ namespace Xceed.Wpf.AvalonDock.Controls InvalidateMeasure(); } - void OnResizerDragDelta( object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e ) + private void OnResizerDragDelta( object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e ) { LayoutGridResizerControl splitter = sender as LayoutGridResizerControl; var rootVisual = this.FindVisualTreeRoot() as Visual; @@ -440,126 +571,13 @@ namespace Xceed.Wpf.AvalonDock.Controls } } - void OnResizerDragStarted( object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e ) + private void OnResizerDragStarted( object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e ) { var resizer = sender as LayoutGridResizerControl; ShowResizerOverlayWindow( resizer ); IsResizing = true; } - #endregion - - protected override System.Collections.IEnumerator LogicalChildren - { - get - { - if( _internalHostPresenter == null ) - return new UIElement[] { }.GetEnumerator(); - return new UIElement[] { _internalHostPresenter }.GetEnumerator(); - } - } - - protected override Size MeasureOverride( Size constraint ) - { - if( _internalHostPresenter == null ) - return base.MeasureOverride( constraint ); - - _internalHostPresenter.Measure( constraint ); - //return base.MeasureOverride(constraint); - return _internalHostPresenter.DesiredSize; - } - - protected override Size ArrangeOverride( Size finalSize ) - { - if( _internalHostPresenter == null ) - return base.ArrangeOverride( finalSize ); - - _internalHostPresenter.Arrange( new Rect( finalSize ) ); - return base.ArrangeOverride( finalSize );// new Size(_internalHostPresenter.ActualWidth, _internalHostPresenter.ActualHeight); - } - - #region Background - - /// - /// Background Dependency Property - /// - public static readonly DependencyProperty BackgroundProperty = - DependencyProperty.Register( "Background", typeof( Brush ), typeof( LayoutAutoHideWindowControl ), - new FrameworkPropertyMetadata( ( Brush )null ) ); - - /// - /// Gets or sets the Background property. This dependency property - /// indicates background of the autohide childwindow. - /// - public Brush Background - { - get - { - return ( Brush )GetValue( BackgroundProperty ); - } - set - { - SetValue( BackgroundProperty, value ); - } - } - - #endregion - - internal bool IsWin32MouseOver - { - get - { - var ptMouse = new Win32Helper.Win32Point(); - if( !Win32Helper.GetCursorPos( ref ptMouse ) ) - return false; - - Point location = this.PointToScreenDPI( new Point() ); - - Rect rectWindow = this.GetScreenArea(); - if( rectWindow.Contains( new Point( ptMouse.X, ptMouse.Y ) ) ) - return true; - - var manager = Model.Root.Manager; - var anchor = manager.FindVisualChildren().Where( c => c.Model == Model ).FirstOrDefault(); - - if( anchor == null ) - return false; - - location = anchor.PointToScreenDPI( new Point() ); - - if( anchor.IsMouseOver ) - return true; - - return false; - } - } - - #region AnchorableStyle - - /// - /// AnchorableStyle Dependency Property - /// - public static readonly DependencyProperty AnchorableStyleProperty = - DependencyProperty.Register( "AnchorableStyle", typeof( Style ), typeof( LayoutAutoHideWindowControl ), - new FrameworkPropertyMetadata( ( Style )null ) ); - - /// - /// Gets or sets the AnchorableStyle property. This dependency property - /// indicates the style to apply to the LayoutAnchorableControl hosted in this auto hide window. - /// - public Style AnchorableStyle - { - get - { - return ( Style )GetValue( AnchorableStyleProperty ); - } - set - { - SetValue( AnchorableStyleProperty, value ); - } - } #endregion - - } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentControl.cs index 3baf8548..b2e4a37f 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentControl.cs @@ -24,21 +24,25 @@ namespace Xceed.Wpf.AvalonDock.Controls { public class LayoutDocumentControl : Control { + #region Constructors + static LayoutDocumentControl() { DefaultStyleKeyProperty.OverrideMetadata( typeof( LayoutDocumentControl ), new FrameworkPropertyMetadata( typeof( LayoutDocumentControl ) ) ); FocusableProperty.OverrideMetadata( typeof( LayoutDocumentControl ), new FrameworkPropertyMetadata( true ) ); } + #endregion + + #region Properties + #region Model /// /// Model Dependency Property /// - public static readonly DependencyProperty ModelProperty = DependencyProperty.Register( "Model", - typeof( LayoutContent ), - typeof( LayoutDocumentControl ), - new FrameworkPropertyMetadata( null, OnModelChanged ) ); + public static readonly DependencyProperty ModelProperty = DependencyProperty.Register( "Model", typeof( LayoutContent ), typeof( LayoutDocumentControl ), + new FrameworkPropertyMetadata( null, OnModelChanged ) ); /// /// Gets or sets the Model property. This dependency property @@ -110,11 +114,8 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// LayoutItem Read-Only Dependency Property /// - private static readonly DependencyPropertyKey LayoutItemPropertyKey = DependencyProperty.RegisterReadOnly( "LayoutItem", - typeof( LayoutItem ), - typeof( LayoutDocumentControl ), - new FrameworkPropertyMetadata( - ( LayoutItem )null ) ); + private static readonly DependencyPropertyKey LayoutItemPropertyKey = DependencyProperty.RegisterReadOnly( "LayoutItem", typeof( LayoutItem ), typeof( LayoutDocumentControl ), + new FrameworkPropertyMetadata(( LayoutItem )null ) ); public static readonly DependencyProperty LayoutItemProperty = LayoutItemPropertyKey.DependencyProperty; @@ -142,6 +143,10 @@ namespace Xceed.Wpf.AvalonDock.Controls #endregion + #endregion + + #region Overrides + protected override void OnPreviewGotKeyboardFocus( KeyboardFocusChangedEventArgs e ) { this.SetIsActive(); @@ -161,6 +166,10 @@ namespace Xceed.Wpf.AvalonDock.Controls } + #endregion + + #region Private Methods + private void SetIsActive() { if( this.Model != null ) @@ -168,5 +177,7 @@ namespace Xceed.Wpf.AvalonDock.Controls this.Model.IsActive = true; } } + + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs index 6d582e0d..77a2f258 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs @@ -15,20 +15,23 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Data; using Xceed.Wpf.AvalonDock.Layout; using System.Windows; using System.Windows.Controls.Primitives; -using System.Windows.Media; using Microsoft.Windows.Shell; namespace Xceed.Wpf.AvalonDock.Controls { public class LayoutDocumentFloatingWindowControl : LayoutFloatingWindowControl { + #region Members + + private LayoutDocumentFloatingWindow _model; + + #endregion + + #region Constructors + static LayoutDocumentFloatingWindowControl() { DefaultStyleKeyProperty.OverrideMetadata( typeof( LayoutDocumentFloatingWindowControl ), new FrameworkPropertyMetadata( typeof( LayoutDocumentFloatingWindowControl ) ) ); @@ -41,22 +44,27 @@ namespace Xceed.Wpf.AvalonDock.Controls UpdateThemeResources(); } + #endregion - LayoutDocumentFloatingWindow _model; + #region Properties - public override ILayoutElement Model + public LayoutItem RootDocumentLayoutItem { get { - return _model; + return _model.Root.Manager.GetLayoutItemFromModel( _model.RootDocument ); } } - public LayoutItem RootDocumentLayoutItem + #endregion + + #region Overrides + + public override ILayoutElement Model { get { - return _model.Root.Manager.GetLayoutItemFromModel( _model.RootDocument ); + return _model; } } @@ -78,14 +86,6 @@ namespace Xceed.Wpf.AvalonDock.Controls } } - void _model_RootDocumentChanged( object sender, EventArgs e ) - { - if( _model.RootDocument == null ) - { - InternalClose(); - } - } - protected override IntPtr FilterMessage( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled ) { switch( msg ) @@ -114,22 +114,6 @@ namespace Xceed.Wpf.AvalonDock.Controls return base.FilterMessage( hwnd, msg, wParam, lParam, ref handled ); } - bool OpenContextMenu() - { - var ctxMenu = _model.Root.Manager.DocumentContextMenu; - if( ctxMenu != null && RootDocumentLayoutItem != null ) - { - ctxMenu.PlacementTarget = null; - ctxMenu.Placement = PlacementMode.MousePoint; - ctxMenu.DataContext = RootDocumentLayoutItem; - ctxMenu.IsOpen = true; - return true; - } - - return false; - } - - protected override void OnClosed( EventArgs e ) { var root = Model.Root; @@ -146,5 +130,33 @@ namespace Xceed.Wpf.AvalonDock.Controls _model.RootDocumentChanged -= new EventHandler( _model_RootDocumentChanged ); } + #endregion + + #region Private Methods + + private void _model_RootDocumentChanged( object sender, EventArgs e ) + { + if( _model.RootDocument == null ) + { + InternalClose(); + } + } + + private bool OpenContextMenu() + { + var ctxMenu = _model.Root.Manager.DocumentContextMenu; + if( ctxMenu != null && RootDocumentLayoutItem != null ) + { + ctxMenu.PlacementTarget = null; + ctxMenu.Placement = PlacementMode.MousePoint; + ctxMenu.DataContext = RootDocumentLayoutItem; + ctxMenu.IsOpen = true; + return true; + } + + return false; + } + + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentItem.cs index bc3cbf50..7bcbba96 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentItem.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentItem.cs @@ -14,80 +14,130 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using Xceed.Wpf.AvalonDock.Layout; using System.Windows; +using Xceed.Wpf.AvalonDock.Commands; +using System.Windows.Input; +using System.Windows.Data; namespace Xceed.Wpf.AvalonDock.Controls { - public class LayoutDocumentItem : LayoutItem + public class LayoutDocumentItem : LayoutItem + { + #region Members + + private LayoutDocument _document; + + #endregion + + #region Constructors + + internal LayoutDocumentItem() { - LayoutDocument _document; - internal LayoutDocumentItem() - { + } - } + #endregion - internal override void Attach(LayoutContent model) - { - _document = model as LayoutDocument; - base.Attach(model); - } + #region Properties - protected override void Close() - { - if( (_document.Root != null) && (_document.Root.Manager != null) ) - { - var dockingManager = _document.Root.Manager; - dockingManager._ExecuteCloseCommand( _document ); - } - } + #region Description - #region Description - - /// - /// Description Dependency Property - /// - public static readonly DependencyProperty DescriptionProperty = - DependencyProperty.Register("Description", typeof(string), typeof(LayoutDocumentItem), - new FrameworkPropertyMetadata((string)null, - new PropertyChangedCallback(OnDescriptionChanged))); - - /// - /// Gets or sets the Description property. This dependency property - /// indicates the description to display for the document item. - /// - public string Description - { - get { return (string)GetValue(DescriptionProperty); } - set { SetValue(DescriptionProperty, value); } - } + /// + /// Description Dependency Property + /// + public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register( "Description", typeof( string ), typeof( LayoutDocumentItem ), + new FrameworkPropertyMetadata( ( string )null, new PropertyChangedCallback( OnDescriptionChanged ) ) ); - /// - /// Handles changes to the Description property. - /// - private static void OnDescriptionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((LayoutDocumentItem)d).OnDescriptionChanged(e); - } + /// + /// Gets or sets the Description property. This dependency property + /// indicates the description to display for the document item. + /// + public string Description + { + get + { + return ( string )GetValue( DescriptionProperty ); + } + set + { + SetValue( DescriptionProperty, value ); + } + } - /// - /// Provides derived classes an opportunity to handle changes to the Description property. - /// - protected virtual void OnDescriptionChanged(DependencyPropertyChangedEventArgs e) - { - _document.Description = (string)e.NewValue; - } + /// + /// Handles changes to the Description property. + /// + private static void OnDescriptionChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( LayoutDocumentItem )d ).OnDescriptionChanged( e ); + } - #endregion + /// + /// Provides derived classes an opportunity to handle changes to the Description property. + /// + protected virtual void OnDescriptionChanged( DependencyPropertyChangedEventArgs e ) + { + _document.Description = ( string )e.NewValue; + } + + #endregion - internal override void Detach() + #endregion + + #region Overrides + + protected override void Close() + { + if( ( _document.Root != null ) && ( _document.Root.Manager != null ) ) + { + var dockingManager = _document.Root.Manager; + dockingManager._ExecuteCloseCommand( _document ); + } + } + + protected override void OnVisibilityChanged() + { + if( (_document != null) && (_document.Root != null) ) + { + _document.IsVisible = ( this.Visibility == Visibility.Visible ); + + if( _document.Parent is LayoutDocumentPane ) { - _document = null; - base.Detach(); + ( ( LayoutDocumentPane )_document.Parent ).ComputeVisibility(); } + } + + base.OnVisibilityChanged(); + } + + + + + + + + internal override void Attach( LayoutContent model ) + { + _document = model as LayoutDocument; + base.Attach( model ); + } + + internal override void Detach() + { + _document = null; + base.Detach(); } + + #endregion + + #region Private Methods + + + + + + + +#endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs index d7371e3c..74827cbc 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs @@ -25,12 +25,20 @@ namespace Xceed.Wpf.AvalonDock.Controls { public class LayoutDocumentPaneControl : TabControl, ILayoutControl//, ILogicalChildrenContainer { + #region Members + + private List _logicalChildren = new List(); + private LayoutDocumentPane _model; + + #endregion + + #region Constructors + static LayoutDocumentPaneControl() { FocusableProperty.OverrideMetadata( typeof( LayoutDocumentPaneControl ), new FrameworkPropertyMetadata( false ) ); } - internal LayoutDocumentPaneControl( LayoutDocumentPane model ) { if( model == null ) @@ -43,22 +51,21 @@ namespace Xceed.Wpf.AvalonDock.Controls this.LayoutUpdated += new EventHandler( OnLayoutUpdated ); } - void OnLayoutUpdated( object sender, EventArgs e ) - { - var modelWithAtcualSize = _model as ILayoutPositionableElementWithActualSize; - modelWithAtcualSize.ActualWidth = ActualWidth; - modelWithAtcualSize.ActualHeight = ActualHeight; - } + #endregion - protected override void OnSelectionChanged( SelectionChangedEventArgs e ) - { - base.OnSelectionChanged( e ); + #region Properties - if( _model.SelectedContent != null ) - _model.SelectedContent.IsActive = true; + public ILayoutElement Model + { + get + { + return _model; + } } - List _logicalChildren = new List(); + #endregion + + #region Overrides protected override System.Collections.IEnumerator LogicalChildren { @@ -68,14 +75,12 @@ namespace Xceed.Wpf.AvalonDock.Controls } } - LayoutDocumentPane _model; - - public ILayoutElement Model + protected override void OnSelectionChanged( SelectionChangedEventArgs e ) { - get - { - return _model; - } + base.OnSelectionChanged( e ); + + if( _model.SelectedContent != null ) + _model.SelectedContent.IsActive = true; } protected override void OnMouseLeftButtonDown( System.Windows.Input.MouseButtonEventArgs e ) @@ -95,5 +100,18 @@ namespace Xceed.Wpf.AvalonDock.Controls } + + #endregion + + #region Private Methods + + private void OnLayoutUpdated( object sender, EventArgs e ) + { + var modelWithAtcualSize = _model as ILayoutPositionableElementWithActualSize; + modelWithAtcualSize.ActualWidth = ActualWidth; + modelWithAtcualSize.ActualHeight = ActualHeight; + } + + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneGroupControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneGroupControl.cs index e9b368f5..17d577fb 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneGroupControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneGroupControl.cs @@ -14,53 +14,60 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Controls; using System.Windows; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Controls { - public class LayoutDocumentPaneGroupControl : LayoutGridControl, ILayoutControl + public class LayoutDocumentPaneGroupControl : LayoutGridControl, ILayoutControl + { + #region Members + + private LayoutDocumentPaneGroup _model; + + #endregion + + #region Constructors + + internal LayoutDocumentPaneGroupControl( LayoutDocumentPaneGroup model ) + : base( model, model.Orientation ) { - internal LayoutDocumentPaneGroupControl(LayoutDocumentPaneGroup model) - :base(model, model.Orientation) - { - _model = model; - } + _model = model; + } - LayoutDocumentPaneGroup _model; + #endregion - protected override void OnFixChildrenDockLengths() + #region Overrides + + protected override void OnFixChildrenDockLengths() + { + #region Setup DockWidth/Height for children + if( _model.Orientation == Orientation.Horizontal ) + { + for( int i = 0; i < _model.Children.Count; i++ ) { - #region Setup DockWidth/Height for children - if (_model.Orientation == Orientation.Horizontal) - { - for (int i = 0; i < _model.Children.Count; i++) - { - var childModel = _model.Children[i] as ILayoutPositionableElement; - if (!childModel.DockWidth.IsStar) - { - childModel.DockWidth = new GridLength(1.0, GridUnitType.Star); - } - } - } - else - { - for (int i = 0; i < _model.Children.Count; i++) - { - var childModel = _model.Children[i] as ILayoutPositionableElement; - if (!childModel.DockHeight.IsStar) - { - childModel.DockHeight = new GridLength(1.0, GridUnitType.Star); - } - } - } - #endregion + var childModel = _model.Children[ i ] as ILayoutPositionableElement; + if( !childModel.DockWidth.IsStar ) + { + childModel.DockWidth = new GridLength( 1.0, GridUnitType.Star ); + } } - + } + else + { + for( int i = 0; i < _model.Children.Count; i++ ) + { + var childModel = _model.Children[ i ] as ILayoutPositionableElement; + if( !childModel.DockHeight.IsStar ) + { + childModel.DockHeight = new GridLength( 1.0, GridUnitType.Star ); + } + } + } + #endregion } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentTabItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentTabItem.cs index 6c2406a7..951d2c1e 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentTabItem.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentTabItem.cs @@ -17,218 +17,249 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using Xceed.Wpf.AvalonDock.Layout; -using System.Diagnostics; -using System.Windows.Media; namespace Xceed.Wpf.AvalonDock.Controls { - public class LayoutDocumentTabItem : Control + public class LayoutDocumentTabItem : Control + { + #region Members + + private List _otherTabsScreenArea = null; + private List _otherTabs = null; + private Rect _parentDocumentTabPanelScreenArea; + private DocumentPaneTabPanel _parentDocumentTabPanel; + private bool _isMouseDown = false; + private Point _mouseDownPoint; + + #endregion + + #region Contructors + + static LayoutDocumentTabItem() { - static LayoutDocumentTabItem() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(LayoutDocumentTabItem), new FrameworkPropertyMetadata(typeof(LayoutDocumentTabItem))); - } + DefaultStyleKeyProperty.OverrideMetadata( typeof( LayoutDocumentTabItem ), new FrameworkPropertyMetadata( typeof( LayoutDocumentTabItem ) ) ); + } - public LayoutDocumentTabItem() - { - } + public LayoutDocumentTabItem() + { + } - #region Model - - /// - /// Model Dependency Property - /// - public static readonly DependencyProperty ModelProperty = - DependencyProperty.Register("Model", typeof(LayoutContent), typeof(LayoutDocumentTabItem), - new FrameworkPropertyMetadata((LayoutContent)null, - new PropertyChangedCallback(OnModelChanged))); - - /// - /// Gets or sets the Model property. This dependency property - /// indicates the layout content model attached to the tab item. - /// - public LayoutContent Model - { - get { return (LayoutContent)GetValue(ModelProperty); } - set { SetValue(ModelProperty, value); } - } + #endregion - /// - /// Handles changes to the Model property. - /// - private static void OnModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((LayoutDocumentTabItem)d).OnModelChanged(e); - } + #region Properties + #region Model - /// - /// Provides derived classes an opportunity to handle changes to the Model property. - /// - protected virtual void OnModelChanged(DependencyPropertyChangedEventArgs e) - { - if (Model != null) - SetLayoutItem(Model.Root.Manager.GetLayoutItemFromModel(Model)); - else - SetLayoutItem(null); - //UpdateLogicalParent(); - } + /// + /// Model Dependency Property + /// + public static readonly DependencyProperty ModelProperty = DependencyProperty.Register( "Model", typeof( LayoutContent ), typeof( LayoutDocumentTabItem ), + new FrameworkPropertyMetadata( ( LayoutContent )null, new PropertyChangedCallback( OnModelChanged ) ) ); - #endregion + /// + /// Gets or sets the Model property. This dependency property + /// indicates the layout content model attached to the tab item. + /// + public LayoutContent Model + { + get + { + return ( LayoutContent )GetValue( ModelProperty ); + } + set + { + SetValue( ModelProperty, value ); + } + } - #region LayoutItem + /// + /// Handles changes to the Model property. + /// + private static void OnModelChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( LayoutDocumentTabItem )d ).OnModelChanged( e ); + } - /// - /// LayoutItem Read-Only Dependency Property - /// - private static readonly DependencyPropertyKey LayoutItemPropertyKey - = DependencyProperty.RegisterReadOnly("LayoutItem", typeof(LayoutItem), typeof(LayoutDocumentTabItem), - new FrameworkPropertyMetadata((LayoutItem)null)); - public static readonly DependencyProperty LayoutItemProperty - = LayoutItemPropertyKey.DependencyProperty; + /// + /// Provides derived classes an opportunity to handle changes to the Model property. + /// + protected virtual void OnModelChanged( DependencyPropertyChangedEventArgs e ) + { + if( Model != null ) + SetLayoutItem( Model.Root.Manager.GetLayoutItemFromModel( Model ) ); + else + SetLayoutItem( null ); + //UpdateLogicalParent(); + } - /// - /// Gets the LayoutItem property. This dependency property - /// indicates the LayoutItem attached to this tag item. - /// - public LayoutItem LayoutItem - { - get { return (LayoutItem)GetValue(LayoutItemProperty); } - } + #endregion - /// - /// Provides a secure method for setting the LayoutItem property. - /// This dependency property indicates the LayoutItem attached to this tag item. - /// - /// The new value for the property. - protected void SetLayoutItem(LayoutItem value) - { - SetValue(LayoutItemPropertyKey, value); - } + #region LayoutItem - #endregion + /// + /// LayoutItem Read-Only Dependency Property + /// + private static readonly DependencyPropertyKey LayoutItemPropertyKey = DependencyProperty.RegisterReadOnly( "LayoutItem", typeof( LayoutItem ), typeof( LayoutDocumentTabItem ), + new FrameworkPropertyMetadata( ( LayoutItem )null ) ); - List _otherTabsScreenArea = null; - List _otherTabs = null; - Rect _parentDocumentTabPanelScreenArea; - DocumentPaneTabPanel _parentDocumentTabPanel; - bool _isMouseDown = false; - Point _mouseDownPoint; + public static readonly DependencyProperty LayoutItemProperty = LayoutItemPropertyKey.DependencyProperty; - void UpdateDragDetails() - { - _parentDocumentTabPanel = this.FindLogicalAncestor(); - _parentDocumentTabPanelScreenArea = _parentDocumentTabPanel.GetScreenArea(); - _otherTabs = _parentDocumentTabPanel.Children.Cast().Where(ch => - ch.Visibility != System.Windows.Visibility.Collapsed).ToList(); - Rect currentTabScreenArea = this.FindLogicalAncestor().GetScreenArea(); - _otherTabsScreenArea = _otherTabs.Select(ti => - { - var screenArea = ti.GetScreenArea(); - return new Rect(screenArea.Left, screenArea.Top, currentTabScreenArea.Width, screenArea.Height); - }).ToList(); - } + /// + /// Gets the LayoutItem property. This dependency property + /// indicates the LayoutItem attached to this tag item. + /// + public LayoutItem LayoutItem + { + get + { + return ( LayoutItem )GetValue( LayoutItemProperty ); + } + } - protected override void OnMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e) - { - base.OnMouseLeftButtonDown(e); + /// + /// Provides a secure method for setting the LayoutItem property. + /// This dependency property indicates the LayoutItem attached to this tag item. + /// + /// The new value for the property. + protected void SetLayoutItem( LayoutItem value ) + { + SetValue( LayoutItemPropertyKey, value ); + } - Model.IsActive = true; + #endregion - if (e.ClickCount == 1) - { - _mouseDownPoint = e.GetPosition(this); - _isMouseDown = true; - } - } + #endregion - protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e) - { - base.OnMouseMove(e); - - if (_isMouseDown) - { - Point ptMouseMove = e.GetPosition(this); - - if (Math.Abs(ptMouseMove.X - _mouseDownPoint.X) > SystemParameters.MinimumHorizontalDragDistance || - Math.Abs(ptMouseMove.Y - _mouseDownPoint.Y) > SystemParameters.MinimumVerticalDragDistance) - { - UpdateDragDetails(); - CaptureMouse(); - _isMouseDown = false; - } - } - - if (IsMouseCaptured) - { - var mousePosInScreenCoord = this.PointToScreenDPI(e.GetPosition(this)); - if (!_parentDocumentTabPanelScreenArea.Contains(mousePosInScreenCoord)) - { - ReleaseMouseCapture(); - var manager = Model.Root.Manager; - manager.StartDraggingFloatingWindowForContent(Model); - } - else - { - int indexOfTabItemWithMouseOver = _otherTabsScreenArea.FindIndex(r => r.Contains(mousePosInScreenCoord)); - if (indexOfTabItemWithMouseOver >= 0) - { - var targetModel = _otherTabs[indexOfTabItemWithMouseOver].Content as LayoutContent; - var container = Model.Parent as ILayoutContainer; - var containerPane = Model.Parent as ILayoutPane; - - if( (containerPane is LayoutDocumentPane) && !((LayoutDocumentPane)containerPane).CanRepositionItems ) - return; - if( (containerPane.Parent != null) && (containerPane.Parent is LayoutDocumentPaneGroup) && !((LayoutDocumentPaneGroup)containerPane.Parent).CanRepositionItems ) - return; - - var childrenList = container.Children.ToList(); - containerPane.MoveChild( childrenList.IndexOf( Model ), childrenList.IndexOf( targetModel ) ); - Model.IsActive = true; - _parentDocumentTabPanel.UpdateLayout(); - UpdateDragDetails(); - } - } - } + #region Overrides - } + protected override void OnMouseLeftButtonDown( System.Windows.Input.MouseButtonEventArgs e ) + { + base.OnMouseLeftButtonDown( e ); - protected override void OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e) - { - if (IsMouseCaptured) - ReleaseMouseCapture(); - _isMouseDown = false; + Model.IsActive = true; - base.OnMouseLeftButtonUp(e); - } + if( e.ClickCount == 1 ) + { + _mouseDownPoint = e.GetPosition( this ); + _isMouseDown = true; + } + } + + protected override void OnMouseMove( System.Windows.Input.MouseEventArgs e ) + { + base.OnMouseMove( e ); + + if( _isMouseDown ) + { + Point ptMouseMove = e.GetPosition( this ); - protected override void OnMouseLeave(System.Windows.Input.MouseEventArgs e) + if( Math.Abs( ptMouseMove.X - _mouseDownPoint.X ) > SystemParameters.MinimumHorizontalDragDistance || + Math.Abs( ptMouseMove.Y - _mouseDownPoint.Y ) > SystemParameters.MinimumVerticalDragDistance ) { - base.OnMouseLeave(e); - _isMouseDown = false; + this.UpdateDragDetails(); + this.CaptureMouse(); + _isMouseDown = false; } + } - protected override void OnMouseEnter(MouseEventArgs e) + if( this.IsMouseCaptured ) + { + var mousePosInScreenCoord = this.PointToScreenDPI( e.GetPosition( this ) ); + if( !_parentDocumentTabPanelScreenArea.Contains( mousePosInScreenCoord ) ) { - base.OnMouseEnter(e); - _isMouseDown = false; + this.StartDraggingFloatingWindowForContent(); } - - protected override void OnMouseDown(MouseButtonEventArgs e) + else { - if (e.ChangedButton == MouseButton.Middle) - { - if (LayoutItem.CloseCommand.CanExecute(null)) - LayoutItem.CloseCommand.Execute(null); - } - - base.OnMouseDown(e); + int indexOfTabItemWithMouseOver = _otherTabsScreenArea.FindIndex( r => r.Contains( mousePosInScreenCoord ) ); + if( indexOfTabItemWithMouseOver >= 0 ) + { + var targetModel = _otherTabs[ indexOfTabItemWithMouseOver ].Content as LayoutContent; + var container = this.Model.Parent as ILayoutContainer; + var containerPane = this.Model.Parent as ILayoutPane; + + if( ( containerPane is LayoutDocumentPane ) && !( ( LayoutDocumentPane )containerPane ).CanRepositionItems ) + return; + if( ( containerPane.Parent != null ) && ( containerPane.Parent is LayoutDocumentPaneGroup ) && !( ( LayoutDocumentPaneGroup )containerPane.Parent ).CanRepositionItems ) + return; + + var childrenList = container.Children.ToList(); + containerPane.MoveChild( childrenList.IndexOf( Model ), childrenList.IndexOf( targetModel ) ); + this.Model.IsActive = true; + _parentDocumentTabPanel.UpdateLayout(); + this.UpdateDragDetails(); + } } + } + } + + protected override void OnMouseLeftButtonUp( System.Windows.Input.MouseButtonEventArgs e ) + { + if( IsMouseCaptured ) + ReleaseMouseCapture(); + _isMouseDown = false; + + base.OnMouseLeftButtonUp( e ); + } + + protected override void OnMouseLeave( System.Windows.Input.MouseEventArgs e ) + { + base.OnMouseLeave( e ); + _isMouseDown = false; } + + protected override void OnMouseEnter( MouseEventArgs e ) + { + base.OnMouseEnter( e ); + _isMouseDown = false; + } + + protected override void OnMouseDown( MouseButtonEventArgs e ) + { + if( e.ChangedButton == MouseButton.Middle ) + { + if( LayoutItem.CloseCommand.CanExecute( null ) ) + LayoutItem.CloseCommand.Execute( null ); + } + + base.OnMouseDown( e ); + } + + #endregion + + #region Private Methods + + private void UpdateDragDetails() + { + _parentDocumentTabPanel = this.FindLogicalAncestor(); + _parentDocumentTabPanelScreenArea = _parentDocumentTabPanel.GetScreenArea(); + _otherTabs = _parentDocumentTabPanel.Children.Cast().Where( ch => + ch.Visibility != System.Windows.Visibility.Collapsed ).ToList(); + Rect currentTabScreenArea = this.FindLogicalAncestor().GetScreenArea(); + _otherTabsScreenArea = _otherTabs.Select( ti => + { + var screenArea = ti.GetScreenArea(); + return new Rect( screenArea.Left, screenArea.Top, currentTabScreenArea.Width, screenArea.Height ); + } ).ToList(); + } + + private void StartDraggingFloatingWindowForContent() + { + this.ReleaseMouseCapture(); + + if( this.Model is LayoutAnchorable ) + { + ( ( LayoutAnchorable )this.Model ).ResetCanCloseInternal(); + } + var manager = this.Model.Root.Manager; + manager.StartDraggingFloatingWindowForContent( this.Model ); + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutFloatingWindowControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutFloatingWindowControl.cs index f8231f19..4a8b6a3d 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutFloatingWindowControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutFloatingWindowControl.cs @@ -31,8 +31,20 @@ namespace Xceed.Wpf.AvalonDock.Controls { public abstract class LayoutFloatingWindowControl : Window, ILayoutControl { + #region Members + private ResourceDictionary currentThemeResourceDictionary; // = null private bool _isInternalChange; //false + private ILayoutElement _model; + private bool _attachDrag = false; + private HwndSource _hwndSrc; + private HwndSourceHook _hwndSrcHook; + private DragService _dragService = null; + private bool _internalCloseFlag = false; + + #endregion + + #region Constructors static LayoutFloatingWindowControl() { @@ -41,165 +53,159 @@ namespace Xceed.Wpf.AvalonDock.Controls ShowInTaskbarProperty.OverrideMetadata( typeof( LayoutFloatingWindowControl ), new FrameworkPropertyMetadata( false ) ); } - static object CoerceContentValue( DependencyObject sender, object content ) + protected LayoutFloatingWindowControl( ILayoutElement model ) { - return new FloatingWindowContentHost( sender as LayoutFloatingWindowControl ) { Content = content as UIElement }; + this.Loaded += new RoutedEventHandler( OnLoaded ); + this.Unloaded += new RoutedEventHandler( OnUnloaded ); + _model = model; } - protected internal class FloatingWindowContentHost : HwndHost - { - LayoutFloatingWindowControl _owner; - public FloatingWindowContentHost( LayoutFloatingWindowControl owner ) - { - _owner = owner; - var manager = _owner.Model.Root.Manager; - } + #endregion + #region Properties - HwndSource _wpfContentHost = null; - Border _rootPresenter = null; - DockingManager _manager = null; + #region Model - protected override System.Runtime.InteropServices.HandleRef BuildWindowCore( System.Runtime.InteropServices.HandleRef hwndParent ) - { - _wpfContentHost = new HwndSource( new HwndSourceParameters() - { - ParentWindow = hwndParent.Handle, - WindowStyle = Win32Helper.WS_CHILD | Win32Helper.WS_VISIBLE | Win32Helper.WS_CLIPSIBLINGS | Win32Helper.WS_CLIPCHILDREN, - Width = 1, - Height = 1 - } ); - - _rootPresenter = new Border() { Child = new AdornerDecorator() { Child = Content }, Focusable = true }; - _rootPresenter.SetBinding( Border.BackgroundProperty, new Binding( "Background" ) { Source = _owner } ); - _wpfContentHost.RootVisual = _rootPresenter; - _wpfContentHost.SizeToContent = SizeToContent.Manual; - _manager = _owner.Model.Root.Manager; - _manager.InternalAddLogicalChild( _rootPresenter ); + public abstract ILayoutElement Model + { + get; + } - return new HandleRef( this, _wpfContentHost.Handle ); - } + #endregion + #region IsDragging - protected override void DestroyWindowCore( HandleRef hwnd ) - { - _manager.InternalRemoveLogicalChild( _rootPresenter ); - if( _wpfContentHost != null ) - { - _wpfContentHost.Dispose(); - _wpfContentHost = null; - } - } + /// + /// IsDragging Read-Only Dependency Property + /// + private static readonly DependencyPropertyKey IsDraggingPropertyKey = DependencyProperty.RegisterReadOnly( "IsDragging", typeof( bool ), typeof( LayoutFloatingWindowControl ), + new FrameworkPropertyMetadata( ( bool )false, new PropertyChangedCallback( OnIsDraggingChanged ) ) ); - public Visual RootVisual - { - get - { - return _rootPresenter; - } - } + public static readonly DependencyProperty IsDraggingProperty = IsDraggingPropertyKey.DependencyProperty; - protected override Size MeasureOverride( Size constraint ) + /// + /// Gets the IsDragging property. This dependency property + /// indicates that this floating window is being dragged. + /// + public bool IsDragging + { + get { - if( Content == null ) - return base.MeasureOverride( constraint ); - - Content.Measure( constraint ); - return Content.DesiredSize; + return ( bool )GetValue( IsDraggingProperty ); } + } - #region Content + /// + /// Provides a secure method for setting the IsDragging property. + /// This dependency property indicates that this floating window is being dragged. + /// + /// The new value for the property. + protected void SetIsDragging( bool value ) + { + SetValue( IsDraggingPropertyKey, value ); + } - /// - /// Content Dependency Property - /// - public static readonly DependencyProperty ContentProperty = - DependencyProperty.Register( "Content", typeof( UIElement ), typeof( FloatingWindowContentHost ), - new FrameworkPropertyMetadata( ( UIElement )null, - new PropertyChangedCallback( OnContentChanged ) ) ); + /// + /// Handles changes to the IsDragging property. + /// + private static void OnIsDraggingChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( LayoutFloatingWindowControl )d ).OnIsDraggingChanged( e ); + } - /// - /// Gets or sets the Content property. This dependency property - /// indicates .... - /// - public UIElement Content + /// + /// Provides derived classes an opportunity to handle changes to the IsDragging property. + /// + protected virtual void OnIsDraggingChanged( DependencyPropertyChangedEventArgs e ) + { + if( ( bool )e.NewValue ) { - get - { - return ( UIElement )GetValue( ContentProperty ); - } - set - { - SetValue( ContentProperty, value ); - } + CaptureMouse(); } - - /// - /// Handles changes to the Content property. - /// - private static void OnContentChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + else { - ( ( FloatingWindowContentHost )d ).OnContentChanged( e ); + ReleaseMouseCapture(); } + } - /// - /// Provides derived classes an opportunity to handle changes to the Content property. - /// - protected virtual void OnContentChanged( DependencyPropertyChangedEventArgs e ) + #endregion + + #region CloseInitiatedByUser + + protected bool CloseInitiatedByUser + { + get { - if( _rootPresenter != null ) - _rootPresenter.Child = Content; + return !_internalCloseFlag; } - - #endregion } - ILayoutElement _model; + #endregion - protected LayoutFloatingWindowControl( ILayoutElement model ) + #region KeepContentVisibleOnClose + + internal bool KeepContentVisibleOnClose { - this.Loaded += new RoutedEventHandler( OnLoaded ); - this.Unloaded += new RoutedEventHandler( OnUnloaded ); - _model = model; + get; + set; } - internal virtual void UpdateThemeResources( Theme oldTheme = null ) + #endregion + + #region IsMaximized + + /// + /// IsMaximized Dependency Property + /// + public static readonly DependencyProperty IsMaximizedProperty = DependencyProperty.Register( "IsMaximized", typeof( bool ), typeof( LayoutFloatingWindowControl ), + new FrameworkPropertyMetadata( ( bool )false ) ); + + /// + /// Gets/sets the IsMaximized property. This dependency property + /// indicates if the window is maximized. + /// + public bool IsMaximized { - if( oldTheme != null ) + get { - if( oldTheme is DictionaryTheme ) - { - if( currentThemeResourceDictionary != null ) - { - Resources.MergedDictionaries.Remove( currentThemeResourceDictionary ); - currentThemeResourceDictionary = null; - } - } - else - { - var resourceDictionaryToRemove = - Resources.MergedDictionaries.FirstOrDefault( r => r.Source == oldTheme.GetResourceUri() ); - if( resourceDictionaryToRemove != null ) - Resources.MergedDictionaries.Remove( - resourceDictionaryToRemove ); - } + return ( bool )GetValue( IsMaximizedProperty ); + } + private set + { + SetValue( IsMaximizedProperty, value ); + UpdatePositionAndSizeOfPanes(); } + } - var manager = _model.Root.Manager; - if( manager.Theme != null ) + /// + /// Provides a secure method for setting the IsMaximized property. + /// This dependency property indicates if the window is maximized. + /// + /// The new value for the property. + + protected override void OnStateChanged( EventArgs e ) + { + if( !_isInternalChange ) { - if( manager.Theme is DictionaryTheme ) + if( WindowState == WindowState.Maximized ) { - currentThemeResourceDictionary = ( ( DictionaryTheme )manager.Theme ).ThemeResourceDictionary; - Resources.MergedDictionaries.Add( currentThemeResourceDictionary ); + UpdateMaximizedState( true ); } else { - Resources.MergedDictionaries.Add( new ResourceDictionary() { Source = manager.Theme.GetResourceUri() } ); + WindowState = IsMaximized ? WindowState.Maximized : WindowState.Normal; } } + + base.OnStateChanged( e ); } + #endregion + + #endregion + + #region Overrides + protected override void OnClosed( EventArgs e ) { if( Content != null ) @@ -218,72 +224,6 @@ namespace Xceed.Wpf.AvalonDock.Controls base.OnClosed( e ); } - bool _attachDrag = false; - internal void AttachDrag( bool onActivated = true ) - { - if( onActivated ) - { - _attachDrag = true; - this.Activated += new EventHandler( OnActivated ); - } - else - { - IntPtr windowHandle = new WindowInteropHelper( this ).Handle; - IntPtr lParam = new IntPtr( ( ( int )Left & ( int )0xFFFF ) | ( ( ( int )Top ) << 16 ) ); - Win32Helper.SendMessage( windowHandle, Win32Helper.WM_NCLBUTTONDOWN, new IntPtr( Win32Helper.HT_CAPTION ), lParam ); - } - } - - HwndSource _hwndSrc; - HwndSourceHook _hwndSrcHook; - - void OnLoaded( object sender, RoutedEventArgs e ) - { - this.Loaded -= new RoutedEventHandler( OnLoaded ); - - this.SetParentToMainWindowOf( Model.Root.Manager ); - - _hwndSrc = HwndSource.FromDependencyObject( this ) as HwndSource; - _hwndSrcHook = new HwndSourceHook( FilterMessage ); - _hwndSrc.AddHook( _hwndSrcHook ); - - // Restore maximize state - var maximized = Model.Descendents().OfType().Any( l => l.IsMaximized ); - UpdateMaximizedState( maximized ); - } - - void OnUnloaded( object sender, RoutedEventArgs e ) - { - this.Unloaded -= new RoutedEventHandler( OnUnloaded ); - - if( _hwndSrc != null ) - { - _hwndSrc.RemoveHook( _hwndSrcHook ); - InternalClose(); - } - } - - void OnActivated( object sender, EventArgs e ) - { - this.Activated -= new EventHandler( OnActivated ); - - if( _attachDrag && Mouse.LeftButton == MouseButtonState.Pressed ) - { - IntPtr windowHandle = new WindowInteropHelper( this ).Handle; - var mousePosition = this.PointToScreenDPI( Mouse.GetPosition( this ) ); - var clientArea = Win32Helper.GetClientRect( windowHandle ); - var windowArea = Win32Helper.GetWindowRect( windowHandle ); - - Left = mousePosition.X - windowArea.Width / 2.0; - Top = mousePosition.Y - ( windowArea.Height - clientArea.Height ) / 2.0; - _attachDrag = false; - - IntPtr lParam = new IntPtr( ( ( int )mousePosition.X & ( int )0xFFFF ) | ( ( ( int )mousePosition.Y ) << 16 ) ); - Win32Helper.SendMessage( windowHandle, Win32Helper.WM_NCLBUTTONDOWN, new IntPtr( Win32Helper.HT_CAPTION ), lParam ); - } - } - - protected override void OnInitialized( EventArgs e ) { CommandBindings.Add( new CommandBinding( Microsoft.Windows.Shell.SystemCommands.CloseWindowCommand, @@ -299,105 +239,63 @@ namespace Xceed.Wpf.AvalonDock.Controls } - public abstract ILayoutElement Model - { - get; - } - - - #region IsDragging - - /// - /// IsDragging Read-Only Dependency Property - /// - private static readonly DependencyPropertyKey IsDraggingPropertyKey - = DependencyProperty.RegisterReadOnly( "IsDragging", typeof( bool ), typeof( LayoutFloatingWindowControl ), - new FrameworkPropertyMetadata( ( bool )false, - new PropertyChangedCallback( OnIsDraggingChanged ) ) ); - - public static readonly DependencyProperty IsDraggingProperty - = IsDraggingPropertyKey.DependencyProperty; - - /// - /// Gets the IsDragging property. This dependency property - /// indicates that this floating window is being dragged. - /// - public bool IsDragging - { - get - { - return ( bool )GetValue( IsDraggingProperty ); - } - } - - /// - /// Provides a secure method for setting the IsDragging property. - /// This dependency property indicates that this floating window is being dragged. - /// - /// The new value for the property. - protected void SetIsDragging( bool value ) - { - SetValue( IsDraggingPropertyKey, value ); - } + #endregion - /// - /// Handles changes to the IsDragging property. - /// - private static void OnIsDraggingChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) - { - ( ( LayoutFloatingWindowControl )d ).OnIsDraggingChanged( e ); - } + #region Internal Methods - /// - /// Provides derived classes an opportunity to handle changes to the IsDragging property. - /// - protected virtual void OnIsDraggingChanged( DependencyPropertyChangedEventArgs e ) + internal virtual void UpdateThemeResources( Theme oldTheme = null ) { - if( ( bool )e.NewValue ) + if( oldTheme != null ) { - CaptureMouse(); + if( oldTheme is DictionaryTheme ) + { + if( currentThemeResourceDictionary != null ) + { + Resources.MergedDictionaries.Remove( currentThemeResourceDictionary ); + currentThemeResourceDictionary = null; + } + } + else + { + var resourceDictionaryToRemove = + Resources.MergedDictionaries.FirstOrDefault( r => r.Source == oldTheme.GetResourceUri() ); + if( resourceDictionaryToRemove != null ) + Resources.MergedDictionaries.Remove( + resourceDictionaryToRemove ); + } } - else + + var manager = _model.Root.Manager; + if( manager.Theme != null ) { - ReleaseMouseCapture(); + if( manager.Theme is DictionaryTheme ) + { + currentThemeResourceDictionary = ( ( DictionaryTheme )manager.Theme ).ThemeResourceDictionary; + Resources.MergedDictionaries.Add( currentThemeResourceDictionary ); + } + else + { + Resources.MergedDictionaries.Add( new ResourceDictionary() { Source = manager.Theme.GetResourceUri() } ); + } } } - #endregion - - DragService _dragService = null; - - void UpdatePositionAndSizeOfPanes() + internal void AttachDrag( bool onActivated = true ) { - foreach( var posElement in Model.Descendents().OfType() ) + if( onActivated ) { - posElement.FloatingLeft = Left; - posElement.FloatingTop = Top; - posElement.FloatingWidth = Width; - posElement.FloatingHeight = Height; + _attachDrag = true; + this.Activated += new EventHandler( OnActivated ); } - } - - void UpdateMaximizedState( bool isMaximized ) - { - foreach( var posElement in Model.Descendents().OfType() ) + else { - posElement.IsMaximized = isMaximized; + IntPtr windowHandle = new WindowInteropHelper( this ).Handle; + IntPtr lParam = new IntPtr( ( ( int )Left & ( int )0xFFFF ) | ( ( ( int )Top ) << 16 ) ); + Win32Helper.SendMessage( windowHandle, Win32Helper.WM_NCLBUTTONDOWN, new IntPtr( Win32Helper.HT_CAPTION ), lParam ); } - IsMaximized = isMaximized; - _isInternalChange = true; - WindowState = isMaximized ? WindowState.Maximized : WindowState.Normal; - _isInternalChange = false; } - - protected virtual IntPtr FilterMessage( - IntPtr hwnd, - int msg, - IntPtr wParam, - IntPtr lParam, - ref bool handled - ) + protected virtual IntPtr FilterMessage( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled ) { handled = false; @@ -460,6 +358,90 @@ namespace Xceed.Wpf.AvalonDock.Controls return IntPtr.Zero; } + internal void InternalClose() + { + _internalCloseFlag = true; + Close(); + } + + #endregion + + #region Private Methods + + private static object CoerceContentValue( DependencyObject sender, object content ) + { + return new FloatingWindowContentHost( sender as LayoutFloatingWindowControl ) { Content = content as UIElement }; + } + + private void OnLoaded( object sender, RoutedEventArgs e ) + { + this.Loaded -= new RoutedEventHandler( OnLoaded ); + + this.SetParentToMainWindowOf( Model.Root.Manager ); + + _hwndSrc = HwndSource.FromDependencyObject( this ) as HwndSource; + _hwndSrcHook = new HwndSourceHook( FilterMessage ); + _hwndSrc.AddHook( _hwndSrcHook ); + + // Restore maximize state + var maximized = Model.Descendents().OfType().Any( l => l.IsMaximized ); + UpdateMaximizedState( maximized ); + } + + private void OnUnloaded( object sender, RoutedEventArgs e ) + { + this.Unloaded -= new RoutedEventHandler( OnUnloaded ); + + if( _hwndSrc != null ) + { + _hwndSrc.RemoveHook( _hwndSrcHook ); + InternalClose(); + } + } + + private void OnActivated( object sender, EventArgs e ) + { + this.Activated -= new EventHandler( OnActivated ); + + if( _attachDrag && Mouse.LeftButton == MouseButtonState.Pressed ) + { + IntPtr windowHandle = new WindowInteropHelper( this ).Handle; + var mousePosition = this.PointToScreenDPI( Mouse.GetPosition( this ) ); + var clientArea = Win32Helper.GetClientRect( windowHandle ); + var windowArea = Win32Helper.GetWindowRect( windowHandle ); + + Left = mousePosition.X - windowArea.Width / 2.0; + Top = mousePosition.Y - ( windowArea.Height - clientArea.Height ) / 2.0; + _attachDrag = false; + + IntPtr lParam = new IntPtr( ( ( int )mousePosition.X & ( int )0xFFFF ) | ( ( ( int )mousePosition.Y ) << 16 ) ); + Win32Helper.SendMessage( windowHandle, Win32Helper.WM_NCLBUTTONDOWN, new IntPtr( Win32Helper.HT_CAPTION ), lParam ); + } + } + + private void UpdatePositionAndSizeOfPanes() + { + foreach( var posElement in Model.Descendents().OfType() ) + { + posElement.FloatingLeft = Left; + posElement.FloatingTop = Top; + posElement.FloatingWidth = Width; + posElement.FloatingHeight = Height; + } + } + + private void UpdateMaximizedState( bool isMaximized ) + { + foreach( var posElement in Model.Descendents().OfType() ) + { + posElement.IsMaximized = isMaximized; + } + IsMaximized = isMaximized; + _isInternalChange = true; + WindowState = isMaximized ? WindowState.Maximized : WindowState.Normal; + _isInternalChange = false; + } + private void UpdateDragPosition() { if( _dragService == null ) @@ -472,76 +454,132 @@ namespace Xceed.Wpf.AvalonDock.Controls _dragService.UpdateMouseLocation( mousePosition ); } - bool _internalCloseFlag = false; + #endregion + + #region Internal Classes - internal void InternalClose() + protected internal class FloatingWindowContentHost : HwndHost { - _internalCloseFlag = true; - Close(); - } + #region Members + private LayoutFloatingWindowControl _owner; + private HwndSource _wpfContentHost = null; + private Border _rootPresenter = null; + private DockingManager _manager = null; - protected bool CloseInitiatedByUser - { - get + #endregion + + #region Constructors + + public FloatingWindowContentHost( LayoutFloatingWindowControl owner ) { - return !_internalCloseFlag; + _owner = owner; + var manager = _owner.Model.Root.Manager; } - } - internal bool KeepContentVisibleOnClose - { - get; - set; - } + #endregion - #region IsMaximized + #region Properties - /// - /// IsMaximized Dependency Property - /// - public static readonly DependencyProperty IsMaximizedProperty - = DependencyProperty.Register( "IsMaximized", typeof( bool ), typeof( LayoutFloatingWindowControl ), - new FrameworkPropertyMetadata( ( bool )false ) ); + #region RootVisual - /// - /// Gets/sets the IsMaximized property. This dependency property - /// indicates if the window is maximized. - /// - public bool IsMaximized - { - get + public Visual RootVisual { - return ( bool )GetValue( IsMaximizedProperty ); + get + { + return _rootPresenter; + } } - private set + + #endregion + + #region Content + + /// + /// Content Dependency Property + /// + public static readonly DependencyProperty ContentProperty = DependencyProperty.Register( "Content", typeof( UIElement ), typeof( FloatingWindowContentHost ), + new FrameworkPropertyMetadata( ( UIElement )null, new PropertyChangedCallback( OnContentChanged ) ) ); + + /// + /// Gets or sets the Content property. This dependency property + /// indicates .... + /// + public UIElement Content { - SetValue( IsMaximizedProperty, value ); - UpdatePositionAndSizeOfPanes(); + get + { + return ( UIElement )GetValue( ContentProperty ); + } + set + { + SetValue( ContentProperty, value ); + } } - } - /// - /// Provides a secure method for setting the IsMaximized property. - /// This dependency property indicates if the window is maximized. - /// - /// The new value for the property. + /// + /// Handles changes to the Content property. + /// + private static void OnContentChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( FloatingWindowContentHost )d ).OnContentChanged( e ); + } - protected override void OnStateChanged( EventArgs e ) - { - if( !_isInternalChange ) + /// + /// Provides derived classes an opportunity to handle changes to the Content property. + /// + protected virtual void OnContentChanged( DependencyPropertyChangedEventArgs e ) { - if( WindowState == WindowState.Maximized ) + if( _rootPresenter != null ) + _rootPresenter.Child = Content; + } + + #endregion + + #endregion + + #region Overrides + + protected override System.Runtime.InteropServices.HandleRef BuildWindowCore( System.Runtime.InteropServices.HandleRef hwndParent ) + { + _wpfContentHost = new HwndSource( new HwndSourceParameters() { - UpdateMaximizedState( true ); - } - else + ParentWindow = hwndParent.Handle, + WindowStyle = Win32Helper.WS_CHILD | Win32Helper.WS_VISIBLE | Win32Helper.WS_CLIPSIBLINGS | Win32Helper.WS_CLIPCHILDREN, + Width = 1, + Height = 1 + } ); + + _rootPresenter = new Border() { Child = new AdornerDecorator() { Child = Content }, Focusable = true }; + _rootPresenter.SetBinding( Border.BackgroundProperty, new Binding( "Background" ) { Source = _owner } ); + _wpfContentHost.RootVisual = _rootPresenter; + _wpfContentHost.SizeToContent = SizeToContent.Manual; + _manager = _owner.Model.Root.Manager; + _manager.InternalAddLogicalChild( _rootPresenter ); + + return new HandleRef( this, _wpfContentHost.Handle ); + } + + protected override void DestroyWindowCore( HandleRef hwnd ) + { + _manager.InternalRemoveLogicalChild( _rootPresenter ); + if( _wpfContentHost != null ) { - WindowState = IsMaximized ? WindowState.Maximized : WindowState.Normal; + _wpfContentHost.Dispose(); + _wpfContentHost = null; } } - base.OnStateChanged( e ); + protected override Size MeasureOverride( Size constraint ) + { + if( Content == null ) + return base.MeasureOverride( constraint ); + + Content.Measure( constraint ); + return Content.DesiredSize; + } + + #endregion } #endregion diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs index de21dc28..0f8960d6 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs @@ -15,370 +15,397 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows.Controls; using System.Windows; using System.Windows.Input; using System.Windows.Media; using Xceed.Wpf.AvalonDock.Layout; -using System.Diagnostics; using System.Windows.Threading; namespace Xceed.Wpf.AvalonDock.Controls { - public abstract class LayoutGridControl : Grid, ILayoutControl where T : class, ILayoutPanelElement + public abstract class LayoutGridControl : Grid, ILayoutControl where T : class, ILayoutPanelElement + { + #region Members + + private LayoutPositionableGroup _model; + private Orientation _orientation; + private bool _initialized; + private ChildrenTreeChange? _asyncRefreshCalled; + private ReentrantFlag _fixingChildrenDockLengths = new ReentrantFlag(); + private Border _resizerGhost = null; + private Window _resizerWindowHost = null; + private Vector _initialStartPoint; + + #endregion + + #region Constructors + + static LayoutGridControl() { - static LayoutGridControl() - { - } + } - internal LayoutGridControl(LayoutPositionableGroup model, Orientation orientation) - { - if (model == null) - throw new ArgumentNullException("model"); + internal LayoutGridControl( LayoutPositionableGroup model, Orientation orientation ) + { + if( model == null ) + throw new ArgumentNullException( "model" ); - _model = model; - _orientation = orientation; + _model = model; + _orientation = orientation; - FlowDirection = System.Windows.FlowDirection.LeftToRight; - } + FlowDirection = System.Windows.FlowDirection.LeftToRight; + } - LayoutPositionableGroup _model; - public ILayoutElement Model - { - get { return _model; } - } + #endregion - Orientation _orientation; + #region Properties - public Orientation Orientation - { - get { return (_model as ILayoutOrientableGroup).Orientation; } - } + public ILayoutElement Model + { + get + { + return _model; + } + } - bool _initialized; - ChildrenTreeChange? _asyncRefreshCalled; + public Orientation Orientation + { + get + { + return ( _model as ILayoutOrientableGroup ).Orientation; + } + } - bool AsyncRefreshCalled - { - get { return _asyncRefreshCalled != null; } - } + private bool AsyncRefreshCalled + { + get + { + return _asyncRefreshCalled != null; + } + } - protected override void OnInitialized(EventArgs e) - { - base.OnInitialized(e); - - _model.ChildrenTreeChanged += (s, args) => - { - if (_asyncRefreshCalled.HasValue && - _asyncRefreshCalled.Value == args.Change) - return; - _asyncRefreshCalled = args.Change; - Dispatcher.BeginInvoke(new Action(() => - { - _asyncRefreshCalled = null; - UpdateChildren(); - }), DispatcherPriority.Normal, null); - }; - - this.LayoutUpdated += new EventHandler(OnLayoutUpdated); - } + #endregion - void OnLayoutUpdated(object sender, EventArgs e) - { - var modelWithAtcualSize = _model as ILayoutPositionableElementWithActualSize; - modelWithAtcualSize.ActualWidth = ActualWidth; - modelWithAtcualSize.ActualHeight = ActualHeight; + #region Overrides - if (!_initialized) - { - _initialized = true; - UpdateChildren(); - } - } + protected override void OnInitialized( EventArgs e ) + { + base.OnInitialized( e ); + + _model.ChildrenTreeChanged += ( s, args ) => + { + if( _asyncRefreshCalled.HasValue && + _asyncRefreshCalled.Value == args.Change ) + return; + _asyncRefreshCalled = args.Change; + Dispatcher.BeginInvoke( new Action( () => + { + _asyncRefreshCalled = null; + UpdateChildren(); + } ), DispatcherPriority.Normal, null ); + }; + + this.LayoutUpdated += new EventHandler( OnLayoutUpdated ); + } - void UpdateChildren() - { - var alreadyContainedChildren = Children.OfType().ToArray(); + #endregion - DetachOldSplitters(); - DetachPropertChangeHandler(); + #region Internal Methods - Children.Clear(); - ColumnDefinitions.Clear(); - RowDefinitions.Clear(); + protected void FixChildrenDockLengths() + { + using( _fixingChildrenDockLengths.Enter() ) + OnFixChildrenDockLengths(); + } - if (_model == null || - _model.Root == null) - return; + protected abstract void OnFixChildrenDockLengths(); - var manager = _model.Root.Manager; - if (manager == null) - return; + #endregion + #region Private Methods - foreach (ILayoutElement child in _model.Children) - { - var foundContainedChild = alreadyContainedChildren.FirstOrDefault(chVM => chVM.Model == child); - if (foundContainedChild != null) - Children.Add(foundContainedChild as UIElement); - else - Children.Add(manager.CreateUIElementForModel(child)); - } + private void OnLayoutUpdated( object sender, EventArgs e ) + { + var modelWithAtcualSize = _model as ILayoutPositionableElementWithActualSize; + modelWithAtcualSize.ActualWidth = ActualWidth; + modelWithAtcualSize.ActualHeight = ActualHeight; - CreateSplitters(); + if( !_initialized ) + { + _initialized = true; + UpdateChildren(); + } + } - UpdateRowColDefinitions(); + private void UpdateChildren() + { + var alreadyContainedChildren = Children.OfType().ToArray(); - AttachNewSplitters(); - AttachPropertyChangeHandler(); - } + DetachOldSplitters(); + DetachPropertChangeHandler(); - private void AttachPropertyChangeHandler() - { - foreach (var child in InternalChildren.OfType()) - { - child.Model.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(this.OnChildModelPropertyChanged); - } - } + Children.Clear(); + ColumnDefinitions.Clear(); + RowDefinitions.Clear(); - private void DetachPropertChangeHandler() - { - foreach (var child in InternalChildren.OfType()) - { - child.Model.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(this.OnChildModelPropertyChanged); - } - } + if( _model == null || + _model.Root == null ) + return; - void OnChildModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) - { - if (AsyncRefreshCalled) - return; + var manager = _model.Root.Manager; + if( manager == null ) + return; - if (_fixingChildrenDockLengths.CanEnter && e.PropertyName == "DockWidth" && Orientation == System.Windows.Controls.Orientation.Horizontal) - { - if (ColumnDefinitions.Count == InternalChildren.Count) - { - var changedElement = sender as ILayoutPositionableElement; - var childFromModel = InternalChildren.OfType().First(ch => ch.Model == changedElement) as UIElement; - int indexOfChild = InternalChildren.IndexOf(childFromModel); - ColumnDefinitions[indexOfChild].Width = changedElement.DockWidth; - } - } - else if (_fixingChildrenDockLengths.CanEnter && e.PropertyName == "DockHeight" && Orientation == System.Windows.Controls.Orientation.Vertical) - { - if (RowDefinitions.Count == InternalChildren.Count) - { - var changedElement = sender as ILayoutPositionableElement; - var childFromModel = InternalChildren.OfType().First(ch => ch.Model == changedElement) as UIElement; - int indexOfChild = InternalChildren.IndexOf(childFromModel); - RowDefinitions[indexOfChild].Height = changedElement.DockHeight; - } - } - else if (e.PropertyName == "IsVisible") - { - UpdateRowColDefinitions(); - } - } + foreach( ILayoutElement child in _model.Children ) + { + var foundContainedChild = alreadyContainedChildren.FirstOrDefault( chVM => chVM.Model == child ); + if( foundContainedChild != null ) + Children.Add( foundContainedChild as UIElement ); + else + Children.Add( manager.CreateUIElementForModel( child ) ); + } - void UpdateRowColDefinitions() - { - var root = _model.Root; - if (root == null) - return; - var manager = root.Manager; - if (manager == null) - return; + CreateSplitters(); - FixChildrenDockLengths(); + UpdateRowColDefinitions(); - //Debug.Assert(InternalChildren.Count == _model.ChildrenCount + (_model.ChildrenCount - 1)); + AttachNewSplitters(); + AttachPropertyChangeHandler(); + } - #region Setup GridRows/Cols - RowDefinitions.Clear(); - ColumnDefinitions.Clear(); - if (Orientation == Orientation.Horizontal) - { - int iColumn = 0; - int iChild = 0; - for (int iChildModel = 0; iChildModel < _model.Children.Count; iChildModel++, iColumn++, iChild++) - { - var childModel = _model.Children[iChildModel] as ILayoutPositionableElement; - ColumnDefinitions.Add(new ColumnDefinition() - { - Width = childModel.IsVisible ? childModel.DockWidth : new GridLength(0.0, GridUnitType.Pixel), - MinWidth = childModel.IsVisible ? childModel.DockMinWidth : 0.0 - }); - Grid.SetColumn(InternalChildren[iChild], iColumn); - - //append column for splitter - if (iChild < InternalChildren.Count - 1) - { - iChild++; - iColumn++; - - bool nextChildModelVisibleExist = false; - for (int i = iChildModel + 1; i < _model.Children.Count; i++) - { - var nextChildModel = _model.Children[i] as ILayoutPositionableElement; - if (nextChildModel.IsVisible) - { - nextChildModelVisibleExist = true; - break; - } - } - - ColumnDefinitions.Add(new ColumnDefinition() - { - Width = childModel.IsVisible && nextChildModelVisibleExist ? new GridLength(manager.GridSplitterWidth) : new GridLength(0.0, GridUnitType.Pixel) - }); - Grid.SetColumn(InternalChildren[iChild], iColumn); - } - } - } - else //if (_model.Orientation == Orientation.Vertical) - { - int iRow = 0; - int iChild = 0; - for (int iChildModel = 0; iChildModel < _model.Children.Count; iChildModel++, iRow++, iChild++) - { - var childModel = _model.Children[iChildModel] as ILayoutPositionableElement; - RowDefinitions.Add(new RowDefinition() - { - Height = childModel.IsVisible ? childModel.DockHeight : new GridLength(0.0, GridUnitType.Pixel), - MinHeight = childModel.IsVisible ? childModel.DockMinHeight : 0.0 - }); - Grid.SetRow(InternalChildren[iChild], iRow); - - //if (RowDefinitions.Last().Height.Value == 0.0) - // System.Diagnostics.Debugger.Break(); - - //append row for splitter (if necessary) - if (iChild < InternalChildren.Count - 1) - { - iChild++; - iRow++; - - bool nextChildModelVisibleExist = false; - for (int i = iChildModel + 1; i < _model.Children.Count; i++) - { - var nextChildModel = _model.Children[i] as ILayoutPositionableElement; - if (nextChildModel.IsVisible) - { - nextChildModelVisibleExist = true; - break; - } - } - - RowDefinitions.Add(new RowDefinition() - { - Height = childModel.IsVisible && nextChildModelVisibleExist ? new GridLength(manager.GridSplitterHeight) : new GridLength(0.0, GridUnitType.Pixel) - }); - //if (RowDefinitions.Last().Height.Value == 0.0) - // System.Diagnostics.Debugger.Break(); - Grid.SetRow(InternalChildren[iChild], iRow); - } - } - } + private void AttachPropertyChangeHandler() + { + foreach( var child in InternalChildren.OfType() ) + { + child.Model.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler( this.OnChildModelPropertyChanged ); + } + } - #endregion - } + private void DetachPropertChangeHandler() + { + foreach( var child in InternalChildren.OfType() ) + { + child.Model.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler( this.OnChildModelPropertyChanged ); + } + } + + private void OnChildModelPropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e ) + { + if( AsyncRefreshCalled ) + return; - ReentrantFlag _fixingChildrenDockLengths = new ReentrantFlag(); - protected void FixChildrenDockLengths() + if( _fixingChildrenDockLengths.CanEnter && e.PropertyName == "DockWidth" && Orientation == System.Windows.Controls.Orientation.Horizontal ) + { + if( ColumnDefinitions.Count == InternalChildren.Count ) + { + var changedElement = sender as ILayoutPositionableElement; + var childFromModel = InternalChildren.OfType().First( ch => ch.Model == changedElement ) as UIElement; + int indexOfChild = InternalChildren.IndexOf( childFromModel ); + ColumnDefinitions[ indexOfChild ].Width = changedElement.DockWidth; + } + } + else if( _fixingChildrenDockLengths.CanEnter && e.PropertyName == "DockHeight" && Orientation == System.Windows.Controls.Orientation.Vertical ) + { + if( RowDefinitions.Count == InternalChildren.Count ) { - using (_fixingChildrenDockLengths.Enter()) - OnFixChildrenDockLengths(); + var changedElement = sender as ILayoutPositionableElement; + var childFromModel = InternalChildren.OfType().First( ch => ch.Model == changedElement ) as UIElement; + int indexOfChild = InternalChildren.IndexOf( childFromModel ); + RowDefinitions[ indexOfChild ].Height = changedElement.DockHeight; } + } + else if( e.PropertyName == "IsVisible" ) + { + UpdateRowColDefinitions(); + } + } - protected abstract void OnFixChildrenDockLengths(); + private void UpdateRowColDefinitions() + { + var root = _model.Root; + if( root == null ) + return; + var manager = root.Manager; + if( manager == null ) + return; + + FixChildrenDockLengths(); - #region Splitters + //Debug.Assert(InternalChildren.Count == _model.ChildrenCount + (_model.ChildrenCount - 1)); - void CreateSplitters() + #region Setup GridRows/Cols + RowDefinitions.Clear(); + ColumnDefinitions.Clear(); + if( Orientation == Orientation.Horizontal ) + { + int iColumn = 0; + int iChild = 0; + for( int iChildModel = 0; iChildModel < _model.Children.Count; iChildModel++, iColumn++, iChild++ ) { - for (int iChild = 1; iChild < Children.Count; iChild++) + var childModel = _model.Children[ iChildModel ] as ILayoutPositionableElement; + ColumnDefinitions.Add( new ColumnDefinition() + { + Width = childModel.IsVisible ? childModel.DockWidth : new GridLength( 0.0, GridUnitType.Pixel ), + MinWidth = childModel.IsVisible ? childModel.DockMinWidth : 0.0 + } ); + Grid.SetColumn( InternalChildren[ iChild ], iColumn ); + + //append column for splitter + if( iChild < InternalChildren.Count - 1 ) + { + iChild++; + iColumn++; + + bool nextChildModelVisibleExist = false; + for( int i = iChildModel + 1; i < _model.Children.Count; i++ ) { - var splitter = new LayoutGridResizerControl(); - splitter.Cursor = this.Orientation == Orientation.Horizontal ? Cursors.SizeWE : Cursors.SizeNS; - Children.Insert(iChild, splitter); - iChild++; + var nextChildModel = _model.Children[ i ] as ILayoutPositionableElement; + if( nextChildModel.IsVisible ) + { + nextChildModelVisibleExist = true; + break; + } } - } - void DetachOldSplitters() - { - foreach (var splitter in Children.OfType()) + ColumnDefinitions.Add( new ColumnDefinition() { - splitter.DragStarted -= new System.Windows.Controls.Primitives.DragStartedEventHandler(OnSplitterDragStarted); - splitter.DragDelta -= new System.Windows.Controls.Primitives.DragDeltaEventHandler(OnSplitterDragDelta); - splitter.DragCompleted -= new System.Windows.Controls.Primitives.DragCompletedEventHandler(OnSplitterDragCompleted); - } + Width = childModel.IsVisible && nextChildModelVisibleExist ? new GridLength( manager.GridSplitterWidth ) : new GridLength( 0.0, GridUnitType.Pixel ) + } ); + Grid.SetColumn( InternalChildren[ iChild ], iColumn ); + } } - - void AttachNewSplitters() + } + else //if (_model.Orientation == Orientation.Vertical) + { + int iRow = 0; + int iChild = 0; + for( int iChildModel = 0; iChildModel < _model.Children.Count; iChildModel++, iRow++, iChild++ ) { - foreach (var splitter in Children.OfType()) + var childModel = _model.Children[ iChildModel ] as ILayoutPositionableElement; + RowDefinitions.Add( new RowDefinition() + { + Height = childModel.IsVisible ? childModel.DockHeight : new GridLength( 0.0, GridUnitType.Pixel ), + MinHeight = childModel.IsVisible ? childModel.DockMinHeight : 0.0 + } ); + Grid.SetRow( InternalChildren[ iChild ], iRow ); + + //if (RowDefinitions.Last().Height.Value == 0.0) + // System.Diagnostics.Debugger.Break(); + + //append row for splitter (if necessary) + if( iChild < InternalChildren.Count - 1 ) + { + iChild++; + iRow++; + + bool nextChildModelVisibleExist = false; + for( int i = iChildModel + 1; i < _model.Children.Count; i++ ) { - splitter.DragStarted += new System.Windows.Controls.Primitives.DragStartedEventHandler(OnSplitterDragStarted); - splitter.DragDelta += new System.Windows.Controls.Primitives.DragDeltaEventHandler(OnSplitterDragDelta); - splitter.DragCompleted += new System.Windows.Controls.Primitives.DragCompletedEventHandler(OnSplitterDragCompleted); + var nextChildModel = _model.Children[ i ] as ILayoutPositionableElement; + if( nextChildModel.IsVisible ) + { + nextChildModelVisibleExist = true; + break; + } } - } - void OnSplitterDragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e) - { - var resizer = sender as LayoutGridResizerControl; - ShowResizerOverlayWindow(resizer); + RowDefinitions.Add( new RowDefinition() + { + Height = childModel.IsVisible && nextChildModelVisibleExist ? new GridLength( manager.GridSplitterHeight ) : new GridLength( 0.0, GridUnitType.Pixel ) + } ); + //if (RowDefinitions.Last().Height.Value == 0.0) + // System.Diagnostics.Debugger.Break(); + Grid.SetRow( InternalChildren[ iChild ], iRow ); + } } + } - void OnSplitterDragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e) - { - LayoutGridResizerControl splitter = sender as LayoutGridResizerControl; - var rootVisual = this.FindVisualTreeRoot() as Visual; + #endregion + } - var trToWnd = TransformToAncestor(rootVisual); - Vector transformedDelta = trToWnd.Transform(new Point(e.HorizontalChange, e.VerticalChange)) - - trToWnd.Transform(new Point()); + private void CreateSplitters() + { + for( int iChild = 1; iChild < Children.Count; iChild++ ) + { + var splitter = new LayoutGridResizerControl(); + splitter.Cursor = this.Orientation == Orientation.Horizontal ? Cursors.SizeWE : Cursors.SizeNS; + Children.Insert( iChild, splitter ); + iChild++; + } + } - if (Orientation == System.Windows.Controls.Orientation.Horizontal) - { - Canvas.SetLeft(_resizerGhost, MathHelper.MinMax(_initialStartPoint.X + transformedDelta.X, 0.0, _resizerWindowHost.Width - _resizerGhost.Width)); - } - else - { - Canvas.SetTop(_resizerGhost, MathHelper.MinMax(_initialStartPoint.Y + transformedDelta.Y, 0.0, _resizerWindowHost.Height - _resizerGhost.Height)); - } - } + private void DetachOldSplitters() + { + foreach( var splitter in Children.OfType() ) + { + splitter.DragStarted -= new System.Windows.Controls.Primitives.DragStartedEventHandler( OnSplitterDragStarted ); + splitter.DragDelta -= new System.Windows.Controls.Primitives.DragDeltaEventHandler( OnSplitterDragDelta ); + splitter.DragCompleted -= new System.Windows.Controls.Primitives.DragCompletedEventHandler( OnSplitterDragCompleted ); + } + } - void OnSplitterDragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e) - { - LayoutGridResizerControl splitter = sender as LayoutGridResizerControl; - var rootVisual = this.FindVisualTreeRoot() as Visual; + private void AttachNewSplitters() + { + foreach( var splitter in Children.OfType() ) + { + splitter.DragStarted += new System.Windows.Controls.Primitives.DragStartedEventHandler( OnSplitterDragStarted ); + splitter.DragDelta += new System.Windows.Controls.Primitives.DragDeltaEventHandler( OnSplitterDragDelta ); + splitter.DragCompleted += new System.Windows.Controls.Primitives.DragCompletedEventHandler( OnSplitterDragCompleted ); + } + } + + private void OnSplitterDragStarted( object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e ) + { + var resizer = sender as LayoutGridResizerControl; + ShowResizerOverlayWindow( resizer ); + } + + private void OnSplitterDragDelta( object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e ) + { + LayoutGridResizerControl splitter = sender as LayoutGridResizerControl; + var rootVisual = this.FindVisualTreeRoot() as Visual; + + var trToWnd = TransformToAncestor( rootVisual ); + Vector transformedDelta = trToWnd.Transform( new Point( e.HorizontalChange, e.VerticalChange ) ) - + trToWnd.Transform( new Point() ); + + if( Orientation == System.Windows.Controls.Orientation.Horizontal ) + { + Canvas.SetLeft( _resizerGhost, MathHelper.MinMax( _initialStartPoint.X + transformedDelta.X, 0.0, _resizerWindowHost.Width - _resizerGhost.Width ) ); + } + else + { + Canvas.SetTop( _resizerGhost, MathHelper.MinMax( _initialStartPoint.Y + transformedDelta.Y, 0.0, _resizerWindowHost.Height - _resizerGhost.Height ) ); + } + } + + private void OnSplitterDragCompleted( object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e ) + { + LayoutGridResizerControl splitter = sender as LayoutGridResizerControl; + var rootVisual = this.FindVisualTreeRoot() as Visual; - var trToWnd = TransformToAncestor(rootVisual); - Vector transformedDelta = trToWnd.Transform(new Point(e.HorizontalChange, e.VerticalChange)) - - trToWnd.Transform(new Point()); + var trToWnd = TransformToAncestor( rootVisual ); + Vector transformedDelta = trToWnd.Transform( new Point( e.HorizontalChange, e.VerticalChange ) ) - + trToWnd.Transform( new Point() ); - double delta; - if (Orientation == System.Windows.Controls.Orientation.Horizontal) - delta = Canvas.GetLeft(_resizerGhost) - _initialStartPoint.X; - else - delta = Canvas.GetTop(_resizerGhost) - _initialStartPoint.Y; + double delta; + if( Orientation == System.Windows.Controls.Orientation.Horizontal ) + delta = Canvas.GetLeft( _resizerGhost ) - _initialStartPoint.X; + else + delta = Canvas.GetTop( _resizerGhost ) - _initialStartPoint.Y; - int indexOfResizer = InternalChildren.IndexOf(splitter); + int indexOfResizer = InternalChildren.IndexOf( splitter ); - var prevChild = InternalChildren[indexOfResizer - 1] as FrameworkElement; - var nextChild = GetNextVisibleChild(indexOfResizer); + var prevChild = InternalChildren[ indexOfResizer - 1 ] as FrameworkElement; + var nextChild = GetNextVisibleChild( indexOfResizer ); - var prevChildActualSize = prevChild.TransformActualSizeToAncestor(); - var nextChildActualSize = nextChild.TransformActualSizeToAncestor(); + var prevChildActualSize = prevChild.TransformActualSizeToAncestor(); + var nextChildActualSize = nextChild.TransformActualSizeToAncestor(); - var prevChildModel = (ILayoutPositionableElement)(prevChild as ILayoutControl).Model; - var nextChildModel = (ILayoutPositionableElement)(nextChild as ILayoutControl).Model; + var prevChildModel = ( ILayoutPositionableElement )( prevChild as ILayoutControl ).Model; + var nextChildModel = ( ILayoutPositionableElement )( nextChild as ILayoutControl ).Model; if( Orientation == System.Windows.Controls.Orientation.Horizontal ) { @@ -425,136 +452,128 @@ namespace Xceed.Wpf.AvalonDock.Controls } } - HideResizerOverlayWindow(); - } + HideResizerOverlayWindow(); + } - Border _resizerGhost = null; - Window _resizerWindowHost = null; - Vector _initialStartPoint; + private FrameworkElement GetNextVisibleChild( int index ) + { + for( int i = index + 1; i < InternalChildren.Count; i++ ) + { + if( InternalChildren[ i ] is LayoutGridResizerControl ) + continue; - FrameworkElement GetNextVisibleChild(int index) + if( Orientation == System.Windows.Controls.Orientation.Horizontal ) { - for (int i = index + 1; i < InternalChildren.Count; i++) - { - if (InternalChildren[i] is LayoutGridResizerControl) - continue; - - if (Orientation == System.Windows.Controls.Orientation.Horizontal) - { - if (ColumnDefinitions[i].Width.IsStar || ColumnDefinitions[i].Width.Value > 0) - return InternalChildren[i] as FrameworkElement; - } - else - { - if (RowDefinitions[i].Height.IsStar || RowDefinitions[i].Height.Value > 0) - return InternalChildren[i] as FrameworkElement; - } - } - - return null; + if( ColumnDefinitions[ i ].Width.IsStar || ColumnDefinitions[ i ].Width.Value > 0 ) + return InternalChildren[ i ] as FrameworkElement; } - - void ShowResizerOverlayWindow(LayoutGridResizerControl splitter) + else { - _resizerGhost = new Border() - { - Background = splitter.BackgroundWhileDragging, - Opacity = splitter.OpacityWhileDragging - }; - - int indexOfResizer = InternalChildren.IndexOf(splitter); - - var prevChild = InternalChildren[indexOfResizer - 1] as FrameworkElement; - var nextChild = GetNextVisibleChild(indexOfResizer); - - var prevChildActualSize = prevChild.TransformActualSizeToAncestor(); - var nextChildActualSize = nextChild.TransformActualSizeToAncestor(); + if( RowDefinitions[ i ].Height.IsStar || RowDefinitions[ i ].Height.Value > 0 ) + return InternalChildren[ i ] as FrameworkElement; + } + } - var prevChildModel = (ILayoutPositionableElement)(prevChild as ILayoutControl).Model; - var nextChildModel = (ILayoutPositionableElement)(nextChild as ILayoutControl).Model; + return null; + } - Point ptTopLeftScreen = prevChild.PointToScreenDPIWithoutFlowDirection(new Point()); + private void ShowResizerOverlayWindow( LayoutGridResizerControl splitter ) + { + _resizerGhost = new Border() + { + Background = splitter.BackgroundWhileDragging, + Opacity = splitter.OpacityWhileDragging + }; - Size actualSize; + int indexOfResizer = InternalChildren.IndexOf( splitter ); - if (Orientation == System.Windows.Controls.Orientation.Horizontal) - { - actualSize = new Size( - prevChildActualSize.Width - prevChildModel.DockMinWidth + splitter.ActualWidth + nextChildActualSize.Width - nextChildModel.DockMinWidth, - nextChildActualSize.Height); + var prevChild = InternalChildren[ indexOfResizer - 1 ] as FrameworkElement; + var nextChild = GetNextVisibleChild( indexOfResizer ); - _resizerGhost.Width = splitter.ActualWidth; - _resizerGhost.Height = actualSize.Height; - ptTopLeftScreen.Offset(prevChildModel.DockMinWidth, 0.0); - } - else - { - actualSize = new Size( - prevChildActualSize.Width, - prevChildActualSize.Height - prevChildModel.DockMinHeight + splitter.ActualHeight + nextChildActualSize.Height - nextChildModel.DockMinHeight); + var prevChildActualSize = prevChild.TransformActualSizeToAncestor(); + var nextChildActualSize = nextChild.TransformActualSizeToAncestor(); - _resizerGhost.Height = splitter.ActualHeight; - _resizerGhost.Width = actualSize.Width; + var prevChildModel = ( ILayoutPositionableElement )( prevChild as ILayoutControl ).Model; + var nextChildModel = ( ILayoutPositionableElement )( nextChild as ILayoutControl ).Model; - ptTopLeftScreen.Offset(0.0, prevChildModel.DockMinHeight); - } + Point ptTopLeftScreen = prevChild.PointToScreenDPIWithoutFlowDirection( new Point() ); - _initialStartPoint = splitter.PointToScreenDPIWithoutFlowDirection(new Point()) - ptTopLeftScreen; + Size actualSize; - if (Orientation == System.Windows.Controls.Orientation.Horizontal) - { - Canvas.SetLeft(_resizerGhost, _initialStartPoint.X); - } - else - { - Canvas.SetTop(_resizerGhost, _initialStartPoint.Y); - } + if( Orientation == System.Windows.Controls.Orientation.Horizontal ) + { + actualSize = new Size( + prevChildActualSize.Width - prevChildModel.DockMinWidth + splitter.ActualWidth + nextChildActualSize.Width - nextChildModel.DockMinWidth, + nextChildActualSize.Height ); - Canvas panelHostResizer = new Canvas() - { - HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch, - VerticalAlignment = System.Windows.VerticalAlignment.Stretch - }; + _resizerGhost.Width = splitter.ActualWidth; + _resizerGhost.Height = actualSize.Height; + ptTopLeftScreen.Offset( prevChildModel.DockMinWidth, 0.0 ); + } + else + { + actualSize = new Size( + prevChildActualSize.Width, + prevChildActualSize.Height - prevChildModel.DockMinHeight + splitter.ActualHeight + nextChildActualSize.Height - nextChildModel.DockMinHeight ); - panelHostResizer.Children.Add(_resizerGhost); + _resizerGhost.Height = splitter.ActualHeight; + _resizerGhost.Width = actualSize.Width; + ptTopLeftScreen.Offset( 0.0, prevChildModel.DockMinHeight ); + } - _resizerWindowHost = new Window() - { - SizeToContent = System.Windows.SizeToContent.Manual, - ResizeMode = ResizeMode.NoResize, - WindowStyle = System.Windows.WindowStyle.None, - ShowInTaskbar = false, - AllowsTransparency = true, - Background = null, - Width = actualSize.Width, - Height = actualSize.Height, - Left = ptTopLeftScreen.X, - Top = ptTopLeftScreen.Y, - ShowActivated = false, - //Owner = Window.GetWindow(this), - Content = panelHostResizer - }; - _resizerWindowHost.Loaded += (s, e) => - { - _resizerWindowHost.SetParentToMainWindowOf(this); - }; - _resizerWindowHost.Show(); - } + _initialStartPoint = splitter.PointToScreenDPIWithoutFlowDirection( new Point() ) - ptTopLeftScreen; - void HideResizerOverlayWindow() - { - if (_resizerWindowHost != null) - { - _resizerWindowHost.Close(); - _resizerWindowHost = null; - } - } + if( Orientation == System.Windows.Controls.Orientation.Horizontal ) + { + Canvas.SetLeft( _resizerGhost, _initialStartPoint.X ); + } + else + { + Canvas.SetTop( _resizerGhost, _initialStartPoint.Y ); + } - #endregion + Canvas panelHostResizer = new Canvas() + { + HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch, + VerticalAlignment = System.Windows.VerticalAlignment.Stretch + }; + panelHostResizer.Children.Add( _resizerGhost ); + _resizerWindowHost = new Window() + { + SizeToContent = System.Windows.SizeToContent.Manual, + ResizeMode = ResizeMode.NoResize, + WindowStyle = System.Windows.WindowStyle.None, + ShowInTaskbar = false, + AllowsTransparency = true, + Background = null, + Width = actualSize.Width, + Height = actualSize.Height, + Left = ptTopLeftScreen.X, + Top = ptTopLeftScreen.Y, + ShowActivated = false, + //Owner = Window.GetWindow(this), + Content = panelHostResizer + }; + _resizerWindowHost.Loaded += ( s, e ) => + { + _resizerWindowHost.SetParentToMainWindowOf( this ); + }; + _resizerWindowHost.Show(); + } + private void HideResizerOverlayWindow() + { + if( _resizerWindowHost != null ) + { + _resizerWindowHost.Close(); + _resizerWindowHost = null; + } } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutGridResizerControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutGridResizerControl.cs index 709f6c47..6347f96b 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutGridResizerControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutGridResizerControl.cs @@ -14,70 +14,83 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Controls.Primitives; using System.Windows; using System.Windows.Media; namespace Xceed.Wpf.AvalonDock.Controls { - public class LayoutGridResizerControl : Thumb + public class LayoutGridResizerControl : Thumb + { + #region Constructors + + static LayoutGridResizerControl() + { + //This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class. + //This style is defined in themes\generic.xaml + DefaultStyleKeyProperty.OverrideMetadata( typeof( LayoutGridResizerControl ), new FrameworkPropertyMetadata( typeof( LayoutGridResizerControl ) ) ); + HorizontalAlignmentProperty.OverrideMetadata( typeof( LayoutGridResizerControl ), new FrameworkPropertyMetadata( HorizontalAlignment.Stretch, FrameworkPropertyMetadataOptions.AffectsParentMeasure ) ); + VerticalAlignmentProperty.OverrideMetadata( typeof( LayoutGridResizerControl ), new FrameworkPropertyMetadata( VerticalAlignment.Stretch, FrameworkPropertyMetadataOptions.AffectsParentMeasure ) ); + BackgroundProperty.OverrideMetadata( typeof( LayoutGridResizerControl ), new FrameworkPropertyMetadata( Brushes.Transparent ) ); + IsHitTestVisibleProperty.OverrideMetadata( typeof( LayoutGridResizerControl ), new FrameworkPropertyMetadata( true, null ) ); + } + + #endregion + + #region Properties + + #region BackgroundWhileDragging + + /// + /// BackgroundWhileDragging Dependency Property + /// + public static readonly DependencyProperty BackgroundWhileDraggingProperty = DependencyProperty.Register( "BackgroundWhileDragging", typeof( Brush ), typeof( LayoutGridResizerControl ), + new FrameworkPropertyMetadata( ( Brush )Brushes.Black ) ); + + /// + /// Gets or sets the BackgroundWhileDragging property. This dependency property + /// indicates .... + /// + public Brush BackgroundWhileDragging { - static LayoutGridResizerControl() - { - //This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class. - //This style is defined in themes\generic.xaml - DefaultStyleKeyProperty.OverrideMetadata(typeof(LayoutGridResizerControl), new FrameworkPropertyMetadata(typeof(LayoutGridResizerControl))); - HorizontalAlignmentProperty.OverrideMetadata(typeof(LayoutGridResizerControl), new FrameworkPropertyMetadata(HorizontalAlignment.Stretch, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); - VerticalAlignmentProperty.OverrideMetadata(typeof(LayoutGridResizerControl), new FrameworkPropertyMetadata(VerticalAlignment.Stretch, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); - BackgroundProperty.OverrideMetadata(typeof(LayoutGridResizerControl), new FrameworkPropertyMetadata(Brushes.Transparent)); - IsHitTestVisibleProperty.OverrideMetadata(typeof(LayoutGridResizerControl), new FrameworkPropertyMetadata(true, null)); - } - - - #region BackgroundWhileDragging - - /// - /// BackgroundWhileDragging Dependency Property - /// - public static readonly DependencyProperty BackgroundWhileDraggingProperty = - DependencyProperty.Register("BackgroundWhileDragging", typeof(Brush), typeof(LayoutGridResizerControl), - new FrameworkPropertyMetadata((Brush)Brushes.Black)); - - /// - /// Gets or sets the BackgroundWhileDragging property. This dependency property - /// indicates .... - /// - public Brush BackgroundWhileDragging - { - get { return (Brush)GetValue(BackgroundWhileDraggingProperty); } - set { SetValue(BackgroundWhileDraggingProperty, value); } - } - - #endregion - - #region OpacityWhileDragging - - /// - /// OpacityWhileDragging Dependency Property - /// - public static readonly DependencyProperty OpacityWhileDraggingProperty = - DependencyProperty.Register("OpacityWhileDragging", typeof(double), typeof(LayoutGridResizerControl), - new FrameworkPropertyMetadata((double)0.5)); - - /// - /// Gets or sets the OpacityWhileDragging property. This dependency property - /// indicates .... - /// - public double OpacityWhileDragging - { - get { return (double)GetValue(OpacityWhileDraggingProperty); } - set { SetValue(OpacityWhileDraggingProperty, value); } - } - - #endregion + get + { + return ( Brush )GetValue( BackgroundWhileDraggingProperty ); + } + set + { + SetValue( BackgroundWhileDraggingProperty, value ); + } } + + #endregion + + #region OpacityWhileDragging + + /// + /// OpacityWhileDragging Dependency Property + /// + public static readonly DependencyProperty OpacityWhileDraggingProperty = DependencyProperty.Register( "OpacityWhileDragging", typeof( double ), typeof( LayoutGridResizerControl ), + new FrameworkPropertyMetadata( ( double )0.5 ) ); + + /// + /// Gets or sets the OpacityWhileDragging property. This dependency property + /// indicates .... + /// + public double OpacityWhileDragging + { + get + { + return ( double )GetValue( OpacityWhileDraggingProperty ); + } + set + { + SetValue( OpacityWhileDraggingProperty, value ); + } + } + + #endregion + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutItem.cs index a57f9c13..8f61c4a9 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutItem.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutItem.cs @@ -15,14 +15,11 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows; using Xceed.Wpf.AvalonDock.Layout; using System.Windows.Input; using Xceed.Wpf.AvalonDock.Commands; -using System.ComponentModel; using System.Windows.Data; using System.Windows.Media; using System.Windows.Controls; @@ -31,6 +28,26 @@ namespace Xceed.Wpf.AvalonDock.Controls { public abstract class LayoutItem : FrameworkElement { + #region Members + + private ICommand _defaultCloseCommand; + private ICommand _defaultFloatCommand; + private ICommand _defaultDockAsDocumentCommand; + private ICommand _defaultCloseAllButThisCommand; + private ICommand _defaultCloseAllCommand; + private ICommand _defaultActivateCommand; + private ICommand _defaultNewVerticalTabGroupCommand; + private ICommand _defaultNewHorizontalTabGroupCommand; + private ICommand _defaultMoveToNextTabGroupCommand; + private ICommand _defaultMoveToPreviousTabGroupCommand; + private ContentPresenter _view = null; + private ReentrantFlag _isSelectedReentrantFlag = new ReentrantFlag(); + private ReentrantFlag _isActiveReentrantFlag = new ReentrantFlag(); + + #endregion + + #region Constructors + static LayoutItem() { ToolTipProperty.OverrideMetadata( typeof( LayoutItem ), new FrameworkPropertyMetadata( null, ( s, e ) => OnToolTipChanged( s, e ) ) ); @@ -40,55 +57,13 @@ namespace Xceed.Wpf.AvalonDock.Controls internal LayoutItem() { - } - internal virtual void Attach( LayoutContent model ) - { - LayoutElement = model; - Model = model.Content; - - InitDefaultCommands(); - - LayoutElement.IsSelectedChanged += new EventHandler( LayoutElement_IsSelectedChanged ); - LayoutElement.IsActiveChanged += new EventHandler( LayoutElement_IsActiveChanged ); - - DataContext = this; - } + #endregion + #region Properties - - void LayoutElement_IsActiveChanged( object sender, EventArgs e ) - { - if( _isActiveReentrantFlag.CanEnter ) - { - using( _isActiveReentrantFlag.Enter() ) - { - var bnd = BindingOperations.GetBinding( this, IsActiveProperty ); - IsActive = LayoutElement.IsActive; - var bnd2 = BindingOperations.GetBinding( this, IsActiveProperty ); - } - } - } - - void LayoutElement_IsSelectedChanged( object sender, EventArgs e ) - { - if( _isSelectedReentrantFlag.CanEnter ) - { - using( _isSelectedReentrantFlag.Enter() ) - { - IsSelected = LayoutElement.IsSelected; - } - } - } - - internal virtual void Detach() - { - LayoutElement.IsSelectedChanged -= new EventHandler( LayoutElement_IsSelectedChanged ); - LayoutElement.IsActiveChanged -= new EventHandler( LayoutElement_IsActiveChanged ); - LayoutElement = null; - Model = null; - } + #region LayoutElement public LayoutContent LayoutElement { @@ -96,106 +71,20 @@ namespace Xceed.Wpf.AvalonDock.Controls private set; } + #endregion + + #region Model + public object Model { get; private set; } - ICommand _defaultCloseCommand; - ICommand _defaultFloatCommand; - ICommand _defaultDockAsDocumentCommand; - ICommand _defaultCloseAllButThisCommand; - ICommand _defaultCloseAllCommand; - ICommand _defaultActivateCommand; - ICommand _defaultNewVerticalTabGroupCommand; - ICommand _defaultNewHorizontalTabGroupCommand; - ICommand _defaultMoveToNextTabGroupCommand; - ICommand _defaultMoveToPreviousTabGroupCommand; - - protected virtual void InitDefaultCommands() - { - _defaultCloseCommand = new RelayCommand( ( p ) => ExecuteCloseCommand( p ), ( p ) => CanExecuteCloseCommand( p ) ); - _defaultFloatCommand = new RelayCommand( ( p ) => ExecuteFloatCommand( p ), ( p ) => CanExecuteFloatCommand( p ) ); - _defaultDockAsDocumentCommand = new RelayCommand( ( p ) => ExecuteDockAsDocumentCommand( p ), ( p ) => CanExecuteDockAsDocumentCommand( p ) ); - _defaultCloseAllButThisCommand = new RelayCommand( ( p ) => ExecuteCloseAllButThisCommand( p ), ( p ) => CanExecuteCloseAllButThisCommand( p ) ); - _defaultCloseAllCommand = new RelayCommand( ( p ) => ExecuteCloseAllCommand( p ), ( p ) => CanExecuteCloseAllCommand( p ) ); - _defaultActivateCommand = new RelayCommand( ( p ) => ExecuteActivateCommand( p ), ( p ) => CanExecuteActivateCommand( p ) ); - _defaultNewVerticalTabGroupCommand = new RelayCommand( ( p ) => ExecuteNewVerticalTabGroupCommand( p ), ( p ) => CanExecuteNewVerticalTabGroupCommand( p ) ); - _defaultNewHorizontalTabGroupCommand = new RelayCommand( ( p ) => ExecuteNewHorizontalTabGroupCommand( p ), ( p ) => CanExecuteNewHorizontalTabGroupCommand( p ) ); - _defaultMoveToNextTabGroupCommand = new RelayCommand( ( p ) => ExecuteMoveToNextTabGroupCommand( p ), ( p ) => CanExecuteMoveToNextTabGroupCommand( p ) ); - _defaultMoveToPreviousTabGroupCommand = new RelayCommand( ( p ) => ExecuteMoveToPreviousTabGroupCommand( p ), ( p ) => CanExecuteMoveToPreviousTabGroupCommand( p ) ); - } - - protected virtual void ClearDefaultBindings() - { - if( CloseCommand == _defaultCloseCommand ) - BindingOperations.ClearBinding( this, CloseCommandProperty ); - if( FloatCommand == _defaultFloatCommand ) - BindingOperations.ClearBinding( this, FloatCommandProperty ); - if( DockAsDocumentCommand == _defaultDockAsDocumentCommand ) - BindingOperations.ClearBinding( this, DockAsDocumentCommandProperty ); - if( CloseAllButThisCommand == _defaultCloseAllButThisCommand ) - BindingOperations.ClearBinding( this, CloseAllButThisCommandProperty ); - if( CloseAllCommand == _defaultCloseAllCommand ) - BindingOperations.ClearBinding( this, CloseAllCommandProperty ); - if( ActivateCommand == _defaultActivateCommand ) - BindingOperations.ClearBinding( this, ActivateCommandProperty ); - if( NewVerticalTabGroupCommand == _defaultNewVerticalTabGroupCommand ) - BindingOperations.ClearBinding( this, NewVerticalTabGroupCommandProperty ); - if( NewHorizontalTabGroupCommand == _defaultNewHorizontalTabGroupCommand ) - BindingOperations.ClearBinding( this, NewHorizontalTabGroupCommandProperty ); - if( MoveToNextTabGroupCommand == _defaultMoveToNextTabGroupCommand ) - BindingOperations.ClearBinding( this, MoveToNextTabGroupCommandProperty ); - if( MoveToPreviousTabGroupCommand == _defaultMoveToPreviousTabGroupCommand ) - BindingOperations.ClearBinding( this, MoveToPreviousTabGroupCommandProperty ); - } - - protected virtual void SetDefaultBindings() - { - if( CloseCommand == null ) - CloseCommand = _defaultCloseCommand; - if( FloatCommand == null ) - FloatCommand = _defaultFloatCommand; - if( DockAsDocumentCommand == null ) - DockAsDocumentCommand = _defaultDockAsDocumentCommand; - if( CloseAllButThisCommand == null ) - CloseAllButThisCommand = _defaultCloseAllButThisCommand; - if( CloseAllCommand == null ) - CloseAllCommand = _defaultCloseAllCommand; - if( ActivateCommand == null ) - ActivateCommand = _defaultActivateCommand; - if( NewVerticalTabGroupCommand == null ) - NewVerticalTabGroupCommand = _defaultNewVerticalTabGroupCommand; - if( NewHorizontalTabGroupCommand == null ) - NewHorizontalTabGroupCommand = _defaultNewHorizontalTabGroupCommand; - if( MoveToNextTabGroupCommand == null ) - MoveToNextTabGroupCommand = _defaultMoveToNextTabGroupCommand; - if( MoveToPreviousTabGroupCommand == null ) - MoveToPreviousTabGroupCommand = _defaultMoveToPreviousTabGroupCommand; - - - IsSelected = LayoutElement.IsSelected; - IsActive = LayoutElement.IsActive; - CanClose = LayoutElement.CanClose; - } - - internal void _ClearDefaultBindings() - { - ClearDefaultBindings(); - } - - internal void _SetDefaultBindings() - { - SetDefaultBindings(); - } + #endregion - internal bool IsViewExists() - { - return ( _view != null ); - } + #region View - ContentPresenter _view = null; public ContentPresenter View { get @@ -220,16 +109,15 @@ namespace Xceed.Wpf.AvalonDock.Controls } } + #endregion #region Title /// /// Title Dependency Property /// - public static readonly DependencyProperty TitleProperty = - DependencyProperty.Register( "Title", typeof( string ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( ( string )null, - new PropertyChangedCallback( OnTitleChanged ) ) ); + public static readonly DependencyProperty TitleProperty = DependencyProperty.Register( "Title", typeof( string ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( ( string )null, new PropertyChangedCallback( OnTitleChanged ) ) ); /// /// Gets or sets the Title property. This dependency property @@ -266,28 +154,13 @@ namespace Xceed.Wpf.AvalonDock.Controls #endregion - #region ToolTip - private static void OnToolTipChanged( DependencyObject s, DependencyPropertyChangedEventArgs e ) - { - ( ( LayoutItem )s ).OnToolTipChanged(); - } - - private void OnToolTipChanged() - { - if( LayoutElement != null ) - LayoutElement.ToolTip = ToolTip; - } - #endregion - #region IconSource /// /// IconSource Dependency Property /// - public static readonly DependencyProperty IconSourceProperty = - DependencyProperty.Register( "IconSource", typeof( ImageSource ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( ( ImageSource )null, - new PropertyChangedCallback( OnIconSourceChanged ) ) ); + public static readonly DependencyProperty IconSourceProperty = DependencyProperty.Register( "IconSource", typeof( ImageSource ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( ( ImageSource )null, new PropertyChangedCallback( OnIconSourceChanged ) ) ); /// /// Gets or sets the IconSource property. This dependency property @@ -324,31 +197,13 @@ namespace Xceed.Wpf.AvalonDock.Controls #endregion - #region Visibility - - private static void OnVisibilityChanged( DependencyObject s, DependencyPropertyChangedEventArgs e ) - { - ( ( LayoutItem )s ).OnVisibilityChanged(); - } - - protected virtual void OnVisibilityChanged() - { - if( LayoutElement != null && - Visibility == System.Windows.Visibility.Collapsed ) - LayoutElement.Close(); - } - - #endregion - #region ContentId /// /// ContentId Dependency Property /// - public static readonly DependencyProperty ContentIdProperty = - DependencyProperty.Register( "ContentId", typeof( string ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( ( string )null, - new PropertyChangedCallback( OnContentIdChanged ) ) ); + public static readonly DependencyProperty ContentIdProperty = DependencyProperty.Register( "ContentId", typeof( string ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( ( string )null, new PropertyChangedCallback( OnContentIdChanged ) ) ); /// /// Gets or sets the ContentId property. This dependency property @@ -387,15 +242,11 @@ namespace Xceed.Wpf.AvalonDock.Controls #region IsSelected - ReentrantFlag _isSelectedReentrantFlag = new ReentrantFlag(); - /// /// IsSelected Dependency Property /// - public static readonly DependencyProperty IsSelectedProperty = - DependencyProperty.Register( "IsSelected", typeof( bool ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( ( bool )false, - new PropertyChangedCallback( OnIsSelectedChanged ) ) ); + public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register( "IsSelected", typeof( bool ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( ( bool )false, new PropertyChangedCallback( OnIsSelectedChanged ) ) ); /// /// Gets or sets the IsSelected property. This dependency property @@ -438,17 +289,13 @@ namespace Xceed.Wpf.AvalonDock.Controls #endregion - #region IsActive - - ReentrantFlag _isActiveReentrantFlag = new ReentrantFlag(); + #region IsActive /// /// IsActive Dependency Property /// - public static readonly DependencyProperty IsActiveProperty = - DependencyProperty.Register( "IsActive", typeof( bool ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( ( bool )false, - new PropertyChangedCallback( OnIsActiveChanged ) ) ); + public static readonly DependencyProperty IsActiveProperty = DependencyProperty.Register( "IsActive", typeof( bool ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( ( bool )false, new PropertyChangedCallback( OnIsActiveChanged ) ) ); /// /// Gets or sets the IsActive property. This dependency property @@ -496,10 +343,8 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// CanClose Dependency Property /// - public static readonly DependencyProperty CanCloseProperty = - DependencyProperty.Register( "CanClose", typeof( bool ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( ( bool )true, - new PropertyChangedCallback( OnCanCloseChanged ) ) ); + public static readonly DependencyProperty CanCloseProperty = DependencyProperty.Register( "CanClose", typeof( bool ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( ( bool )true, new PropertyChangedCallback( OnCanCloseChanged ) ) ); /// /// Gets or sets the CanClose property. This dependency property @@ -541,10 +386,8 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// CanFloat Dependency Property /// - public static readonly DependencyProperty CanFloatProperty = - DependencyProperty.Register( "CanFloat", typeof( bool ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( ( bool )true, - new PropertyChangedCallback( OnCanFloatChanged ) ) ); + public static readonly DependencyProperty CanFloatProperty = DependencyProperty.Register( "CanFloat", typeof( bool ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( ( bool )true, new PropertyChangedCallback( OnCanFloatChanged ) ) ); /// /// Gets or sets the CanFloat property. This dependency property @@ -586,11 +429,8 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// CloseCommand Dependency Property /// - public static readonly DependencyProperty CloseCommandProperty = - DependencyProperty.Register( "CloseCommand", typeof( ICommand ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( null, - new PropertyChangedCallback( OnCloseCommandChanged ), - new CoerceValueCallback( CoerceCloseCommandValue ) ) ); + public static readonly DependencyProperty CloseCommandProperty = DependencyProperty.Register( "CloseCommand", typeof( ICommand ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( null, new PropertyChangedCallback( OnCloseCommandChanged ), new CoerceValueCallback( CoerceCloseCommandValue ) ) ); /// /// Gets or sets the CloseCommand property. This dependency property @@ -650,11 +490,8 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// FloatCommand Dependency Property /// - public static readonly DependencyProperty FloatCommandProperty = - DependencyProperty.Register( "FloatCommand", typeof( ICommand ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( null, - new PropertyChangedCallback( OnFloatCommandChanged ), - new CoerceValueCallback( CoerceFloatCommandValue ) ) ); + public static readonly DependencyProperty FloatCommandProperty = DependencyProperty.Register( "FloatCommand", typeof( ICommand ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( null, new PropertyChangedCallback( OnFloatCommandChanged ), new CoerceValueCallback( CoerceFloatCommandValue ) ) ); /// /// Gets or sets the FloatCommand property. This dependency property @@ -713,16 +550,20 @@ namespace Xceed.Wpf.AvalonDock.Controls #endregion + + + + + + + #region DockAsDocumentCommand /// /// DockAsDocumentCommand Dependency Property /// - public static readonly DependencyProperty DockAsDocumentCommandProperty = - DependencyProperty.Register( "DockAsDocumentCommand", typeof( ICommand ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( null, - new PropertyChangedCallback( OnDockAsDocumentCommandChanged ), - new CoerceValueCallback( CoerceDockAsDocumentCommandValue ) ) ); + public static readonly DependencyProperty DockAsDocumentCommandProperty = DependencyProperty.Register( "DockAsDocumentCommand", typeof( ICommand ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( null, new PropertyChangedCallback( OnDockAsDocumentCommandChanged ), new CoerceValueCallback( CoerceDockAsDocumentCommandValue ) ) ); /// /// Gets or sets the DockAsDocumentCommand property. This dependency property @@ -781,11 +622,8 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// CloseAllButThisCommand Dependency Property /// - public static readonly DependencyProperty CloseAllButThisCommandProperty = - DependencyProperty.Register( "CloseAllButThisCommand", typeof( ICommand ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( null, - new PropertyChangedCallback( OnCloseAllButThisCommandChanged ), - new CoerceValueCallback( CoerceCloseAllButThisCommandValue ) ) ); + public static readonly DependencyProperty CloseAllButThisCommandProperty = DependencyProperty.Register( "CloseAllButThisCommand", typeof( ICommand ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( null, new PropertyChangedCallback( OnCloseAllButThisCommandChanged ), new CoerceValueCallback( CoerceCloseAllButThisCommandValue ) ) ); /// /// Gets or sets the CloseAllButThisCommand property. This dependency property @@ -850,11 +688,8 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// CloseAllCommand Dependency Property /// - public static readonly DependencyProperty CloseAllCommandProperty = - DependencyProperty.Register( "CloseAllCommand", typeof( ICommand ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( null, - new PropertyChangedCallback( OnCloseAllCommandChanged ), - new CoerceValueCallback( CoerceCloseAllCommandValue ) ) ); + public static readonly DependencyProperty CloseAllCommandProperty = DependencyProperty.Register( "CloseAllCommand", typeof( ICommand ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( null, new PropertyChangedCallback( OnCloseAllCommandChanged ), new CoerceValueCallback( CoerceCloseAllCommandValue ) ) ); /// /// Gets or sets the CloseAllCommand property. This dependency property @@ -919,11 +754,8 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// ActivateCommand Dependency Property /// - public static readonly DependencyProperty ActivateCommandProperty = - DependencyProperty.Register( "ActivateCommand", typeof( ICommand ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( null, - new PropertyChangedCallback( OnActivateCommandChanged ), - new CoerceValueCallback( CoerceActivateCommandValue ) ) ); + public static readonly DependencyProperty ActivateCommandProperty = DependencyProperty.Register( "ActivateCommand", typeof( ICommand ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( null, new PropertyChangedCallback( OnActivateCommandChanged ), new CoerceValueCallback( CoerceActivateCommandValue ) ) ); /// /// Gets or sets the ActivateCommand property. This dependency property @@ -981,10 +813,8 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// NewVerticalTabGroupCommand Dependency Property /// - public static readonly DependencyProperty NewVerticalTabGroupCommandProperty = - DependencyProperty.Register( "NewVerticalTabGroupCommand", typeof( ICommand ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( ( ICommand )null, - new PropertyChangedCallback( OnNewVerticalTabGroupCommandChanged ) ) ); + public static readonly DependencyProperty NewVerticalTabGroupCommandProperty = DependencyProperty.Register( "NewVerticalTabGroupCommand", typeof( ICommand ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( ( ICommand )null, new PropertyChangedCallback( OnNewVerticalTabGroupCommandChanged ) ) ); /// /// Gets or sets the NewVerticalTabGroupCommand property. This dependency property @@ -1057,10 +887,8 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// NewHorizontalTabGroupCommand Dependency Property /// - public static readonly DependencyProperty NewHorizontalTabGroupCommandProperty = - DependencyProperty.Register( "NewHorizontalTabGroupCommand", typeof( ICommand ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( ( ICommand )null, - new PropertyChangedCallback( OnNewHorizontalTabGroupCommandChanged ) ) ); + public static readonly DependencyProperty NewHorizontalTabGroupCommandProperty = DependencyProperty.Register( "NewHorizontalTabGroupCommand", typeof( ICommand ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( ( ICommand )null, new PropertyChangedCallback( OnNewHorizontalTabGroupCommandChanged ) ) ); /// /// Gets or sets the NewHorizontalTabGroupCommand property. This dependency property @@ -1134,10 +962,8 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// MoveToNextTabGroupCommand Dependency Property /// - public static readonly DependencyProperty MoveToNextTabGroupCommandProperty = - DependencyProperty.Register( "MoveToNextTabGroupCommand", typeof( ICommand ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( ( ICommand )null, - new PropertyChangedCallback( OnMoveToNextTabGroupCommandChanged ) ) ); + public static readonly DependencyProperty MoveToNextTabGroupCommandProperty = DependencyProperty.Register( "MoveToNextTabGroupCommand", typeof( ICommand ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( ( ICommand )null, new PropertyChangedCallback( OnMoveToNextTabGroupCommandChanged ) ) ); /// /// Gets or sets the MoveToNextTabGroupCommand property. This dependency property @@ -1203,10 +1029,8 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// MoveToPreviousTabGroupCommand Dependency Property /// - public static readonly DependencyProperty MoveToPreviousTabGroupCommandProperty = - DependencyProperty.Register( "MoveToPreviousTabGroupCommand", typeof( ICommand ), typeof( LayoutItem ), - new FrameworkPropertyMetadata( ( ICommand )null, - new PropertyChangedCallback( OnMoveToPreviousTabGroupCommandChanged ) ) ); + public static readonly DependencyProperty MoveToPreviousTabGroupCommandProperty = DependencyProperty.Register( "MoveToPreviousTabGroupCommand", typeof( ICommand ), typeof( LayoutItem ), + new FrameworkPropertyMetadata( ( ICommand )null, new PropertyChangedCallback( OnMoveToPreviousTabGroupCommandChanged ) ) ); /// /// Gets or sets the MoveToPreviousTabGroupCommand property. This dependency property @@ -1265,7 +1089,164 @@ namespace Xceed.Wpf.AvalonDock.Controls } #endregion + #endregion + #region Internal Methods + protected virtual void InitDefaultCommands() + { + _defaultCloseCommand = new RelayCommand( ( p ) => ExecuteCloseCommand( p ), ( p ) => CanExecuteCloseCommand( p ) ); + _defaultFloatCommand = new RelayCommand( ( p ) => ExecuteFloatCommand( p ), ( p ) => CanExecuteFloatCommand( p ) ); + _defaultDockAsDocumentCommand = new RelayCommand( ( p ) => ExecuteDockAsDocumentCommand( p ), ( p ) => CanExecuteDockAsDocumentCommand( p ) ); + _defaultCloseAllButThisCommand = new RelayCommand( ( p ) => ExecuteCloseAllButThisCommand( p ), ( p ) => CanExecuteCloseAllButThisCommand( p ) ); + _defaultCloseAllCommand = new RelayCommand( ( p ) => ExecuteCloseAllCommand( p ), ( p ) => CanExecuteCloseAllCommand( p ) ); + _defaultActivateCommand = new RelayCommand( ( p ) => ExecuteActivateCommand( p ), ( p ) => CanExecuteActivateCommand( p ) ); + _defaultNewVerticalTabGroupCommand = new RelayCommand( ( p ) => ExecuteNewVerticalTabGroupCommand( p ), ( p ) => CanExecuteNewVerticalTabGroupCommand( p ) ); + _defaultNewHorizontalTabGroupCommand = new RelayCommand( ( p ) => ExecuteNewHorizontalTabGroupCommand( p ), ( p ) => CanExecuteNewHorizontalTabGroupCommand( p ) ); + _defaultMoveToNextTabGroupCommand = new RelayCommand( ( p ) => ExecuteMoveToNextTabGroupCommand( p ), ( p ) => CanExecuteMoveToNextTabGroupCommand( p ) ); + _defaultMoveToPreviousTabGroupCommand = new RelayCommand( ( p ) => ExecuteMoveToPreviousTabGroupCommand( p ), ( p ) => CanExecuteMoveToPreviousTabGroupCommand( p ) ); + } + + protected virtual void ClearDefaultBindings() + { + if( CloseCommand == _defaultCloseCommand ) + BindingOperations.ClearBinding( this, CloseCommandProperty ); + if( FloatCommand == _defaultFloatCommand ) + BindingOperations.ClearBinding( this, FloatCommandProperty ); + if( DockAsDocumentCommand == _defaultDockAsDocumentCommand ) + BindingOperations.ClearBinding( this, DockAsDocumentCommandProperty ); + if( CloseAllButThisCommand == _defaultCloseAllButThisCommand ) + BindingOperations.ClearBinding( this, CloseAllButThisCommandProperty ); + if( CloseAllCommand == _defaultCloseAllCommand ) + BindingOperations.ClearBinding( this, CloseAllCommandProperty ); + if( ActivateCommand == _defaultActivateCommand ) + BindingOperations.ClearBinding( this, ActivateCommandProperty ); + if( NewVerticalTabGroupCommand == _defaultNewVerticalTabGroupCommand ) + BindingOperations.ClearBinding( this, NewVerticalTabGroupCommandProperty ); + if( NewHorizontalTabGroupCommand == _defaultNewHorizontalTabGroupCommand ) + BindingOperations.ClearBinding( this, NewHorizontalTabGroupCommandProperty ); + if( MoveToNextTabGroupCommand == _defaultMoveToNextTabGroupCommand ) + BindingOperations.ClearBinding( this, MoveToNextTabGroupCommandProperty ); + if( MoveToPreviousTabGroupCommand == _defaultMoveToPreviousTabGroupCommand ) + BindingOperations.ClearBinding( this, MoveToPreviousTabGroupCommandProperty ); + } + + protected virtual void SetDefaultBindings() + { + if( CloseCommand == null ) + CloseCommand = _defaultCloseCommand; + if( FloatCommand == null ) + FloatCommand = _defaultFloatCommand; + if( DockAsDocumentCommand == null ) + DockAsDocumentCommand = _defaultDockAsDocumentCommand; + if( CloseAllButThisCommand == null ) + CloseAllButThisCommand = _defaultCloseAllButThisCommand; + if( CloseAllCommand == null ) + CloseAllCommand = _defaultCloseAllCommand; + if( ActivateCommand == null ) + ActivateCommand = _defaultActivateCommand; + if( NewVerticalTabGroupCommand == null ) + NewVerticalTabGroupCommand = _defaultNewVerticalTabGroupCommand; + if( NewHorizontalTabGroupCommand == null ) + NewHorizontalTabGroupCommand = _defaultNewHorizontalTabGroupCommand; + if( MoveToNextTabGroupCommand == null ) + MoveToNextTabGroupCommand = _defaultMoveToNextTabGroupCommand; + if( MoveToPreviousTabGroupCommand == null ) + MoveToPreviousTabGroupCommand = _defaultMoveToPreviousTabGroupCommand; + + + IsSelected = LayoutElement.IsSelected; + IsActive = LayoutElement.IsActive; + CanClose = LayoutElement.CanClose; + } + + protected virtual void OnVisibilityChanged() + { + if( LayoutElement != null && + Visibility == System.Windows.Visibility.Collapsed ) + LayoutElement.Close(); + } + + internal virtual void Attach( LayoutContent model ) + { + LayoutElement = model; + Model = model.Content; + + InitDefaultCommands(); + + LayoutElement.IsSelectedChanged += new EventHandler( LayoutElement_IsSelectedChanged ); + LayoutElement.IsActiveChanged += new EventHandler( LayoutElement_IsActiveChanged ); + + DataContext = this; + } + + internal virtual void Detach() + { + LayoutElement.IsSelectedChanged -= new EventHandler( LayoutElement_IsSelectedChanged ); + LayoutElement.IsActiveChanged -= new EventHandler( LayoutElement_IsActiveChanged ); + LayoutElement = null; + Model = null; + } + + internal void _ClearDefaultBindings() + { + ClearDefaultBindings(); + } + + internal void _SetDefaultBindings() + { + SetDefaultBindings(); + } + + internal bool IsViewExists() + { + return ( _view != null ); + } + + #endregion + + #region Private Methods + + private void LayoutElement_IsActiveChanged( object sender, EventArgs e ) + { + if( _isActiveReentrantFlag.CanEnter ) + { + using( _isActiveReentrantFlag.Enter() ) + { + var bnd = BindingOperations.GetBinding( this, IsActiveProperty ); + IsActive = LayoutElement.IsActive; + var bnd2 = BindingOperations.GetBinding( this, IsActiveProperty ); + } + } + } + + private void LayoutElement_IsSelectedChanged( object sender, EventArgs e ) + { + if( _isSelectedReentrantFlag.CanEnter ) + { + using( _isSelectedReentrantFlag.Enter() ) + { + IsSelected = LayoutElement.IsSelected; + } + } + } + + private static void OnToolTipChanged( DependencyObject s, DependencyPropertyChangedEventArgs e ) + { + ( ( LayoutItem )s ).OnToolTipChanged(); + } + + private void OnToolTipChanged() + { + if( LayoutElement != null ) + LayoutElement.ToolTip = ToolTip; + } + + private static void OnVisibilityChanged( DependencyObject s, DependencyPropertyChangedEventArgs e ) + { + ( ( LayoutItem )s ).OnVisibilityChanged(); + } + + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutPanelControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutPanelControl.cs index d71bc3ee..3fe90c42 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutPanelControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutPanelControl.cs @@ -15,117 +15,125 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Controls; using System.Windows; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Controls { - public class LayoutPanelControl : LayoutGridControl, ILayoutControl + public class LayoutPanelControl : LayoutGridControl, ILayoutControl + { + #region Members + + private LayoutPanel _model; + + #endregion + + #region Constructors + + internal LayoutPanelControl( LayoutPanel model ) + : base( model, model.Orientation ) { - internal LayoutPanelControl(LayoutPanel model) - :base(model, model.Orientation) - { - _model = model; + _model = model; - } + } - LayoutPanel _model; + #endregion - protected override void OnFixChildrenDockLengths() - { - if (ActualWidth == 0.0 || - ActualHeight == 0.0) - return; + #region Overrides - var modelAsPositionableElement = _model as ILayoutPositionableElementWithActualSize; - #region Setup DockWidth/Height for children - if (_model.Orientation == Orientation.Horizontal) + protected override void OnFixChildrenDockLengths() + { + if( ActualWidth == 0.0 || + ActualHeight == 0.0 ) + return; + + var modelAsPositionableElement = _model as ILayoutPositionableElementWithActualSize; + #region Setup DockWidth/Height for children + if( _model.Orientation == Orientation.Horizontal ) + { + if( _model.ContainsChildOfType() ) + { + for( int i = 0; i < _model.Children.Count; i++ ) + { + var childContainerModel = _model.Children[ i ] as ILayoutContainer; + var childPositionableModel = _model.Children[ i ] as ILayoutPositionableElement; + + if( childContainerModel != null && + ( childContainerModel.IsOfType() || + childContainerModel.ContainsChildOfType() ) ) { - if (_model.ContainsChildOfType()) - { - for (int i = 0; i < _model.Children.Count; i++) - { - var childContainerModel = _model.Children[i] as ILayoutContainer; - var childPositionableModel = _model.Children[i] as ILayoutPositionableElement; - - if (childContainerModel != null && - (childContainerModel.IsOfType() || - childContainerModel.ContainsChildOfType())) - { - childPositionableModel.DockWidth = new GridLength(1.0, GridUnitType.Star); - } - else if (childPositionableModel != null && childPositionableModel.DockWidth.IsStar) - { - var childPositionableModelWidthActualSize = childPositionableModel as ILayoutPositionableElementWithActualSize; - - var widthToSet = Math.Max(childPositionableModelWidthActualSize.ActualWidth, childPositionableModel.DockMinWidth); - - widthToSet = Math.Min(widthToSet, ActualWidth / 2.0); - widthToSet = Math.Max(widthToSet, childPositionableModel.DockMinWidth); - - childPositionableModel.DockWidth = new GridLength( - widthToSet, - GridUnitType.Pixel); - } - } - } - else - { - for (int i = 0; i < _model.Children.Count; i++) - { - var childPositionableModel = _model.Children[i] as ILayoutPositionableElement; - if (!childPositionableModel.DockWidth.IsStar) - { - childPositionableModel.DockWidth = new GridLength(1.0, GridUnitType.Star); - } - } - } + childPositionableModel.DockWidth = new GridLength( 1.0, GridUnitType.Star ); } - else + else if( childPositionableModel != null && childPositionableModel.DockWidth.IsStar ) { - if (_model.ContainsChildOfType()) - { - for (int i = 0; i < _model.Children.Count; i++) - { - var childContainerModel = _model.Children[i] as ILayoutContainer; - var childPositionableModel = _model.Children[i] as ILayoutPositionableElement; - - if (childContainerModel != null && - (childContainerModel.IsOfType() || - childContainerModel.ContainsChildOfType())) - { - childPositionableModel.DockHeight = new GridLength(1.0, GridUnitType.Star); - } - else if (childPositionableModel != null && childPositionableModel.DockHeight.IsStar) - { - var childPositionableModelWidthActualSize = childPositionableModel as ILayoutPositionableElementWithActualSize; - - var heightToSet = Math.Max(childPositionableModelWidthActualSize.ActualHeight, childPositionableModel.DockMinHeight); - heightToSet = Math.Min(heightToSet, ActualHeight / 2.0); - heightToSet = Math.Max(heightToSet, childPositionableModel.DockMinHeight); - - childPositionableModel.DockHeight = new GridLength(heightToSet, GridUnitType.Pixel); - } - } - } - else - { - for (int i = 0; i < _model.Children.Count; i++) - { - var childPositionableModel = _model.Children[i] as ILayoutPositionableElement; - if (!childPositionableModel.DockHeight.IsStar) - { - childPositionableModel.DockHeight = new GridLength(1.0, GridUnitType.Star); - } - } - } + var childPositionableModelWidthActualSize = childPositionableModel as ILayoutPositionableElementWithActualSize; + + var widthToSet = Math.Max( childPositionableModelWidthActualSize.ActualWidth, childPositionableModel.DockMinWidth ); + + widthToSet = Math.Min( widthToSet, ActualWidth / 2.0 ); + widthToSet = Math.Max( widthToSet, childPositionableModel.DockMinWidth ); + + childPositionableModel.DockWidth = new GridLength( + widthToSet, + GridUnitType.Pixel ); } - #endregion + } } + else + { + for( int i = 0; i < _model.Children.Count; i++ ) + { + var childPositionableModel = _model.Children[ i ] as ILayoutPositionableElement; + if( !childPositionableModel.DockWidth.IsStar ) + { + childPositionableModel.DockWidth = new GridLength( 1.0, GridUnitType.Star ); + } + } + } + } + else + { + if( _model.ContainsChildOfType() ) + { + for( int i = 0; i < _model.Children.Count; i++ ) + { + var childContainerModel = _model.Children[ i ] as ILayoutContainer; + var childPositionableModel = _model.Children[ i ] as ILayoutPositionableElement; + + if( childContainerModel != null && + ( childContainerModel.IsOfType() || + childContainerModel.ContainsChildOfType() ) ) + { + childPositionableModel.DockHeight = new GridLength( 1.0, GridUnitType.Star ); + } + else if( childPositionableModel != null && childPositionableModel.DockHeight.IsStar ) + { + var childPositionableModelWidthActualSize = childPositionableModel as ILayoutPositionableElementWithActualSize; + + var heightToSet = Math.Max( childPositionableModelWidthActualSize.ActualHeight, childPositionableModel.DockMinHeight ); + heightToSet = Math.Min( heightToSet, ActualHeight / 2.0 ); + heightToSet = Math.Max( heightToSet, childPositionableModel.DockMinHeight ); + childPositionableModel.DockHeight = new GridLength( heightToSet, GridUnitType.Pixel ); + } + } + } + else + { + for( int i = 0; i < _model.Children.Count; i++ ) + { + var childPositionableModel = _model.Children[ i ] as ILayoutPositionableElement; + if( !childPositionableModel.DockHeight.IsStar ) + { + childPositionableModel.DockHeight = new GridLength( 1.0, GridUnitType.Star ); + } + } + } + } + #endregion } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/MenuItemEx.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/MenuItemEx.cs index 811efb11..55803e0b 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/MenuItemEx.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/MenuItemEx.cs @@ -14,126 +14,146 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Controls; using System.Windows; namespace Xceed.Wpf.AvalonDock.Controls { - public class MenuItemEx : MenuItem + public class MenuItemEx : MenuItem + { + #region Members + + private bool _reentrantFlag = false; + + #endregion + + #region Constructors + + static MenuItemEx() + { + IconProperty.OverrideMetadata( typeof( MenuItemEx ), new FrameworkPropertyMetadata( new PropertyChangedCallback( OnIconPropertyChanged ) ) ); + } + + public MenuItemEx() + { + } + + #endregion + + #region Properties + + #region IconTemplate + + /// + /// IconTemplate Dependency Property + /// + public static readonly DependencyProperty IconTemplateProperty = DependencyProperty.Register( "IconTemplate", typeof( DataTemplate ), typeof( MenuItemEx ), + new FrameworkPropertyMetadata( ( DataTemplate )null, new PropertyChangedCallback( OnIconTemplateChanged ) ) ); + + /// + /// Gets or sets the IconTemplate property. This dependency property + /// indicates the data template for the icon. + /// + public DataTemplate IconTemplate + { + get + { + return ( DataTemplate )GetValue( IconTemplateProperty ); + } + set + { + SetValue( IconTemplateProperty, value ); + } + } + + /// + /// Handles changes to the IconTemplate property. + /// + private static void OnIconTemplateChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( MenuItemEx )d ).OnIconTemplateChanged( e ); + } + + /// + /// Provides derived classes an opportunity to handle changes to the IconTemplate property. + /// + protected virtual void OnIconTemplateChanged( DependencyPropertyChangedEventArgs e ) + { + UpdateIcon(); + } + + #endregion + + #region IconTemplateSelector + + /// + /// IconTemplateSelector Dependency Property + /// + public static readonly DependencyProperty IconTemplateSelectorProperty = DependencyProperty.Register( "IconTemplateSelector", typeof( DataTemplateSelector ), typeof( MenuItemEx ), + new FrameworkPropertyMetadata( ( DataTemplateSelector )null, new PropertyChangedCallback( OnIconTemplateSelectorChanged ) ) ); + + /// + /// Gets or sets the IconTemplateSelector property. This dependency property + /// indicates the DataTemplateSelector for the Icon. + /// + public DataTemplateSelector IconTemplateSelector + { + get + { + return ( DataTemplateSelector )GetValue( IconTemplateSelectorProperty ); + } + set + { + SetValue( IconTemplateSelectorProperty, value ); + } + } + + /// + /// Handles changes to the IconTemplateSelector property. + /// + private static void OnIconTemplateSelectorChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( MenuItemEx )d ).OnIconTemplateSelectorChanged( e ); + } + + /// + /// Provides derived classes an opportunity to handle changes to the IconTemplateSelector property. + /// + protected virtual void OnIconTemplateSelectorChanged( DependencyPropertyChangedEventArgs e ) { - static MenuItemEx() - { - IconProperty.OverrideMetadata(typeof(MenuItemEx), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnIconPropertyChanged))); - } - - - public MenuItemEx() - { - } - - #region IconTemplate - - /// - /// IconTemplate Dependency Property - /// - public static readonly DependencyProperty IconTemplateProperty = - DependencyProperty.Register("IconTemplate", typeof(DataTemplate), typeof(MenuItemEx), - new FrameworkPropertyMetadata((DataTemplate)null, - new PropertyChangedCallback(OnIconTemplateChanged))); - - /// - /// Gets or sets the IconTemplate property. This dependency property - /// indicates the data template for the icon. - /// - public DataTemplate IconTemplate - { - get { return (DataTemplate)GetValue(IconTemplateProperty); } - set { SetValue(IconTemplateProperty, value); } - } - - /// - /// Handles changes to the IconTemplate property. - /// - private static void OnIconTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((MenuItemEx)d).OnIconTemplateChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the IconTemplate property. - /// - protected virtual void OnIconTemplateChanged(DependencyPropertyChangedEventArgs e) - { - UpdateIcon(); - } - - #endregion - - #region IconTemplateSelector - - /// - /// IconTemplateSelector Dependency Property - /// - public static readonly DependencyProperty IconTemplateSelectorProperty = - DependencyProperty.Register("IconTemplateSelector", typeof(DataTemplateSelector), typeof(MenuItemEx), - new FrameworkPropertyMetadata((DataTemplateSelector)null, - new PropertyChangedCallback(OnIconTemplateSelectorChanged))); - - /// - /// Gets or sets the IconTemplateSelector property. This dependency property - /// indicates the DataTemplateSelector for the Icon. - /// - public DataTemplateSelector IconTemplateSelector - { - get { return (DataTemplateSelector)GetValue(IconTemplateSelectorProperty); } - set { SetValue(IconTemplateSelectorProperty, value); } - } - - /// - /// Handles changes to the IconTemplateSelector property. - /// - private static void OnIconTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((MenuItemEx)d).OnIconTemplateSelectorChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the IconTemplateSelector property. - /// - protected virtual void OnIconTemplateSelectorChanged(DependencyPropertyChangedEventArgs e) - { - UpdateIcon(); - } - - #endregion - - static void OnIconPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) - { - if (e.NewValue != null) - { - ((MenuItemEx)sender).UpdateIcon(); - } - } - - bool _reentrantFlag = false; - void UpdateIcon() - { - if (_reentrantFlag) - return; - _reentrantFlag = true; - if (IconTemplateSelector != null) - { - var dataTemplateToUse = IconTemplateSelector.SelectTemplate(Icon, this); - if (dataTemplateToUse != null) - Icon = dataTemplateToUse.LoadContent(); - } - else if (IconTemplate != null) - Icon = IconTemplate.LoadContent(); - _reentrantFlag = false; - } + UpdateIcon(); } + + #endregion + + #endregion + + #region Private Mehods + + private static void OnIconPropertyChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) + { + if( e.NewValue != null ) + { + ( ( MenuItemEx )sender ).UpdateIcon(); + } + } + + private void UpdateIcon() + { + if( _reentrantFlag ) + return; + _reentrantFlag = true; + if( IconTemplateSelector != null ) + { + var dataTemplateToUse = IconTemplateSelector.SelectTemplate( Icon, this ); + if( dataTemplateToUse != null ) + Icon = dataTemplateToUse.LoadContent(); + } + else if( IconTemplate != null ) + Icon = IconTemplate.LoadContent(); + _reentrantFlag = false; + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/NavigatorWindow.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/NavigatorWindow.cs index daf27ceb..9c2ea878 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/NavigatorWindow.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/NavigatorWindow.cs @@ -19,12 +19,30 @@ using System.Linq; using System.Windows; using Xceed.Wpf.AvalonDock.Layout; using Xceed.Wpf.AvalonDock.Themes; +using System.Windows.Controls; namespace Xceed.Wpf.AvalonDock.Controls { + [TemplatePart( Name = PART_AnchorableListBox, Type = typeof( ListBox ) )] + [TemplatePart( Name = PART_DocumentListBox, Type = typeof( ListBox ) )] public class NavigatorWindow : Window { + #region Members + + private const string PART_AnchorableListBox = "PART_AnchorableListBox"; + private const string PART_DocumentListBox = "PART_DocumentListBox"; + private ResourceDictionary currentThemeResourceDictionary; // = null + private DockingManager _manager; + private bool _isSelectingDocument; + private ListBox _anchorableListBox; + private ListBox _documentListBox; + private bool _internalSetSelectedDocument = false; + private bool _internalSetSelectedAnchorable = false; + + #endregion + + #region Constructors static NavigatorWindow() { @@ -33,124 +51,47 @@ namespace Xceed.Wpf.AvalonDock.Controls ShowInTaskbarProperty.OverrideMetadata( typeof( NavigatorWindow ), new FrameworkPropertyMetadata( false ) ); } - DockingManager _manager; internal NavigatorWindow( DockingManager manager ) { _manager = manager; _internalSetSelectedDocument = true; - SetAnchorables( _manager.Layout.Descendents().OfType().Where( a => a.IsVisible ).Select( d => ( LayoutAnchorableItem )_manager.GetLayoutItemFromModel( d ) ).ToArray() ); - SetDocuments( _manager.Layout.Descendents().OfType().OrderByDescending( d => d.LastActivationTimeStamp.GetValueOrDefault() ).Select( d => ( LayoutDocumentItem )_manager.GetLayoutItemFromModel( d ) ).ToArray() ); + this.SetAnchorables( _manager.Layout.Descendents().OfType().Where( a => a.IsVisible ).Select( d => ( LayoutAnchorableItem )_manager.GetLayoutItemFromModel( d ) ).ToArray() ); + this.SetDocuments( _manager.Layout.Descendents().OfType().OrderByDescending( d => d.LastActivationTimeStamp.GetValueOrDefault() ).Select( d => ( LayoutDocumentItem )_manager.GetLayoutItemFromModel( d ) ).ToArray() ); _internalSetSelectedDocument = false; - if( Documents.Length > 1 ) - InternalSetSelectedDocument( Documents[ 1 ] ); - - this.DataContext = this; - - this.Loaded += new RoutedEventHandler( OnLoaded ); - this.Unloaded += new RoutedEventHandler( OnUnloaded ); - - UpdateThemeResources(); - } - - - internal void UpdateThemeResources( Theme oldTheme = null ) - { - if( oldTheme != null ) + if( this.Documents.Length > 1 ) { - if( oldTheme is DictionaryTheme ) - { - if( currentThemeResourceDictionary != null ) - { - Resources.MergedDictionaries.Remove( currentThemeResourceDictionary ); - currentThemeResourceDictionary = null; - } - } - else - { - var resourceDictionaryToRemove = - Resources.MergedDictionaries.FirstOrDefault( r => r.Source == oldTheme.GetResourceUri() ); - if( resourceDictionaryToRemove != null ) - Resources.MergedDictionaries.Remove( - resourceDictionaryToRemove ); - } + this.InternalSetSelectedDocument( this.Documents[ 1 ] ); + _isSelectingDocument = true; } - - if( _manager.Theme != null ) + else if( this.Anchorables.Count() > 1 ) { - if( _manager.Theme is DictionaryTheme ) - { - currentThemeResourceDictionary = ( ( DictionaryTheme )_manager.Theme ).ThemeResourceDictionary; - Resources.MergedDictionaries.Add( currentThemeResourceDictionary ); - } - else - { - Resources.MergedDictionaries.Add( new ResourceDictionary() { Source = _manager.Theme.GetResourceUri() } ); - } + this.InternalSetSelectedAnchorable( this.Anchorables.ToArray()[ 1 ] ); + _isSelectingDocument = false; } - } - - - void OnLoaded( object sender, RoutedEventArgs e ) - { - this.Loaded -= new RoutedEventHandler( OnLoaded ); - this.Focus(); - - //this.SetParentToMainWindowOf(_manager); - WindowStartupLocation = WindowStartupLocation.CenterOwner; - } + this.DataContext = this; - void OnUnloaded( object sender, RoutedEventArgs e ) - { - this.Unloaded -= new RoutedEventHandler( OnUnloaded ); + this.Loaded += new RoutedEventHandler( OnLoaded ); + this.Unloaded += new RoutedEventHandler( OnUnloaded ); - //_hwndSrc.RemoveHook(_hwndSrcHook); - //_hwndSrc.Dispose(); - //_hwndSrc = null; + this.UpdateThemeResources(); } - //protected virtual IntPtr FilterMessage( - // IntPtr hwnd, - // int msg, - // IntPtr wParam, - // IntPtr lParam, - // ref bool handled - // ) - //{ - // handled = false; - - // switch (msg) - // { - // case Win32Helper.WM_ACTIVATE: - // if (((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE) - // { - // if (lParam == new WindowInteropHelper(this.Owner).Handle) - // { - // Win32Helper.SetActiveWindow(_hwndSrc.Handle); - // handled = true; - // } - - // } - // break; - // } - - // return IntPtr.Zero; - //} + #endregion + #region Properties #region Documents /// /// Documents Read-Only Dependency Property /// - private static readonly DependencyPropertyKey DocumentsPropertyKey - = DependencyProperty.RegisterReadOnly( "Documents", typeof( IEnumerable ), typeof( NavigatorWindow ), + private static readonly DependencyPropertyKey DocumentsPropertyKey = DependencyProperty.RegisterReadOnly( "Documents", typeof( IEnumerable ), typeof( NavigatorWindow ), new FrameworkPropertyMetadata( null ) ); - public static readonly DependencyProperty DocumentsProperty - = DocumentsPropertyKey.DependencyProperty; + public static readonly DependencyProperty DocumentsProperty = DocumentsPropertyKey.DependencyProperty; /// /// Gets the Documents property. This dependency property @@ -164,16 +105,6 @@ namespace Xceed.Wpf.AvalonDock.Controls } } - /// - /// Provides a secure method for setting the Documents property. - /// This dependency property indicates the list of documents. - /// - /// The new value for the property. - protected void SetDocuments( LayoutDocumentItem[] value ) - { - SetValue( DocumentsPropertyKey, value ); - } - #endregion #region Anchorables @@ -181,12 +112,10 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// Anchorables Read-Only Dependency Property /// - private static readonly DependencyPropertyKey AnchorablesPropertyKey - = DependencyProperty.RegisterReadOnly( "Anchorables", typeof( IEnumerable ), typeof( NavigatorWindow ), + private static readonly DependencyPropertyKey AnchorablesPropertyKey = DependencyProperty.RegisterReadOnly( "Anchorables", typeof( IEnumerable ), typeof( NavigatorWindow ), new FrameworkPropertyMetadata( ( IEnumerable )null ) ); - public static readonly DependencyProperty AnchorablesProperty - = AnchorablesPropertyKey.DependencyProperty; + public static readonly DependencyProperty AnchorablesProperty = AnchorablesPropertyKey.DependencyProperty; /// /// Gets the Anchorables property. This dependency property @@ -200,16 +129,6 @@ namespace Xceed.Wpf.AvalonDock.Controls } } - /// - /// Provides a secure method for setting the Anchorables property. - /// This dependency property indicates the list of anchorables. - /// - /// The new value for the property. - protected void SetAnchorables( IEnumerable value ) - { - SetValue( AnchorablesPropertyKey, value ); - } - #endregion #region SelectedDocument @@ -217,10 +136,8 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// SelectedDocument Dependency Property /// - public static readonly DependencyProperty SelectedDocumentProperty = - DependencyProperty.Register( "SelectedDocument", typeof( LayoutDocumentItem ), typeof( NavigatorWindow ), - new FrameworkPropertyMetadata( ( LayoutDocumentItem )null, - new PropertyChangedCallback( OnSelectedDocumentChanged ) ) ); + public static readonly DependencyProperty SelectedDocumentProperty = DependencyProperty.Register( "SelectedDocument", typeof( LayoutDocumentItem ), typeof( NavigatorWindow ), + new FrameworkPropertyMetadata( ( LayoutDocumentItem )null, new PropertyChangedCallback( OnSelectedDocumentChanged ) ) ); /// /// Gets or sets the SelectedDocument property. This dependency property @@ -254,21 +171,12 @@ namespace Xceed.Wpf.AvalonDock.Controls if( _internalSetSelectedDocument ) return; - if( SelectedDocument != null && - SelectedDocument.ActivateCommand.CanExecute( null ) ) + if( this.SelectedDocument != null && + this.SelectedDocument.ActivateCommand.CanExecute( null ) ) { - SelectedDocument.ActivateCommand.Execute( null ); - Hide(); + this.Hide(); + this.SelectedDocument.ActivateCommand.Execute( null ); } - - } - - bool _internalSetSelectedDocument = false; - void InternalSetSelectedDocument( LayoutDocumentItem documentToSelect ) - { - _internalSetSelectedDocument = true; - SelectedDocument = documentToSelect; - _internalSetSelectedDocument = false; } #endregion @@ -278,10 +186,8 @@ namespace Xceed.Wpf.AvalonDock.Controls /// /// SelectedAnchorable Dependency Property /// - public static readonly DependencyProperty SelectedAnchorableProperty = - DependencyProperty.Register( "SelectedAnchorable", typeof( LayoutAnchorableItem ), typeof( NavigatorWindow ), - new FrameworkPropertyMetadata( ( LayoutAnchorableItem )null, - new PropertyChangedCallback( OnSelectedAnchorableChanged ) ) ); + public static readonly DependencyProperty SelectedAnchorableProperty = DependencyProperty.Register( "SelectedAnchorable", typeof( LayoutAnchorableItem ), typeof( NavigatorWindow ), + new FrameworkPropertyMetadata( ( LayoutAnchorableItem )null, new PropertyChangedCallback( OnSelectedAnchorableChanged ) ) ); /// /// Gets or sets the SelectedAnchorable property. This dependency property @@ -312,68 +218,274 @@ namespace Xceed.Wpf.AvalonDock.Controls /// protected virtual void OnSelectedAnchorableChanged( DependencyPropertyChangedEventArgs e ) { + if( _internalSetSelectedAnchorable ) + return; + var selectedAnchorable = e.NewValue as LayoutAnchorableItem; - if( SelectedAnchorable != null && - SelectedAnchorable.ActivateCommand.CanExecute( null ) ) + if( this.SelectedAnchorable != null && + this.SelectedAnchorable.ActivateCommand.CanExecute( null ) ) + { + this.Close(); + this.SelectedAnchorable.ActivateCommand.Execute( null ); + } + } + + #endregion + + #endregion + + #region Overrides + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + _anchorableListBox = this.GetTemplateChild( PART_AnchorableListBox ) as ListBox; + _documentListBox = this.GetTemplateChild( PART_DocumentListBox ) as ListBox; + } + + protected override void OnPreviewKeyDown( System.Windows.Input.KeyEventArgs e ) + { + bool shouldHandle = false; + + // Press Tab to switch Selected LayoutContent. + if( e.Key == System.Windows.Input.Key.Tab) + { + // Selecting LayoutDocuments + if( _isSelectingDocument ) + { + if( this.SelectedDocument != null ) + { + // Jump to next LayoutDocument + var docIndex = this.Documents.IndexOf( this.SelectedDocument ); + if( docIndex < (this.Documents.Length - 1) ) + { + this.SelectNextDocument(); + shouldHandle = true; + } + // Jump to first LayoutAnchorable + else if( this.Anchorables.Count() > 0 ) + { + _isSelectingDocument = false; + this.InternalSetSelectedDocument( null ); + this.InternalSetSelectedAnchorable( this.Anchorables.First() ); + shouldHandle = true; + } + } + // There is no SelectedDocument, select the first one. + else + { + if( this.Documents.Length > 0 ) + { + this.InternalSetSelectedDocument( this.Documents[ 0 ] ); + shouldHandle = true; + } + } + } + // Selecting LayoutAnchorables + else + { + if( this.SelectedAnchorable != null ) + { + // Jump to next LayoutAnchorable + var anchorableIndex = this.Anchorables.ToArray().IndexOf( this.SelectedAnchorable ); + if( anchorableIndex < (this.Anchorables.Count() - 1) ) + { + this.SelectNextAnchorable(); + shouldHandle = true; + } + // Jump to first LayoutDocument + else if( this.Documents.Length > 0 ) + { + _isSelectingDocument = true; + this.InternalSetSelectedAnchorable( null ); + this.InternalSetSelectedDocument( this.Documents[ 0 ] ); + shouldHandle = true; + } + } + // There is no SelectedAnchorable, select the first one. + else + { + if( this.Anchorables.Count() > 0 ) + { + this.InternalSetSelectedAnchorable( this.Anchorables.ToArray()[ 0 ] ); + shouldHandle = true; + } + } + } + } + + if( shouldHandle ) { - SelectedAnchorable.ActivateCommand.Execute( null ); - Close(); + e.Handled = true; } + base.OnPreviewKeyDown( e ); } + protected override void OnPreviewKeyUp( System.Windows.Input.KeyEventArgs e ) + { + if( e.Key != System.Windows.Input.Key.Tab ) + { + this.Close(); + + if( this.SelectedDocument != null && + this.SelectedDocument.ActivateCommand.CanExecute( null ) ) + { + this.SelectedDocument.ActivateCommand.Execute( null ); + } + + if( this.SelectedDocument == null && + this.SelectedAnchorable != null && + this.SelectedAnchorable.ActivateCommand.CanExecute( null ) ) + { + this.SelectedAnchorable.ActivateCommand.Execute( null ); + } + + e.Handled = true; + } + + base.OnPreviewKeyUp( e ); + } + + #endregion + #region Internal Methods + + /// + /// Provides a secure method for setting the Anchorables property. + /// This dependency property indicates the list of anchorables. + /// + /// The new value for the property. + protected void SetAnchorables( IEnumerable value ) + { + this.SetValue( AnchorablesPropertyKey, value ); + } + + /// + /// Provides a secure method for setting the Documents property. + /// This dependency property indicates the list of documents. + /// + /// The new value for the property. + protected void SetDocuments( LayoutDocumentItem[] value ) + { + this.SetValue( DocumentsPropertyKey, value ); + } + + internal void UpdateThemeResources( Theme oldTheme = null ) + { + if( oldTheme != null ) + { + if( oldTheme is DictionaryTheme ) + { + if( currentThemeResourceDictionary != null ) + { + this.Resources.MergedDictionaries.Remove( currentThemeResourceDictionary ); + currentThemeResourceDictionary = null; + } + } + else + { + var resourceDictionaryToRemove = this.Resources.MergedDictionaries.FirstOrDefault( r => r.Source == oldTheme.GetResourceUri() ); + if( resourceDictionaryToRemove != null ) + { + this.Resources.MergedDictionaries.Remove( resourceDictionaryToRemove ); + } + } + } + + if( _manager.Theme != null ) + { + if( _manager.Theme is DictionaryTheme ) + { + currentThemeResourceDictionary = ( ( DictionaryTheme )_manager.Theme ).ThemeResourceDictionary; + this.Resources.MergedDictionaries.Add( currentThemeResourceDictionary ); + } + else + { + this.Resources.MergedDictionaries.Add( new ResourceDictionary() { Source = _manager.Theme.GetResourceUri() } ); + } + } + } internal void SelectNextDocument() { - if( SelectedDocument != null ) + if( this.SelectedDocument != null ) { - int docIndex = Documents.IndexOf( SelectedDocument ); + int docIndex = this.Documents.IndexOf( this.SelectedDocument ); docIndex++; - if( docIndex == Documents.Length ) + if( docIndex == this.Documents.Length ) + { docIndex = 0; - InternalSetSelectedDocument( Documents[ docIndex ] ); + } + this.InternalSetSelectedDocument( this.Documents[ docIndex ] ); } - } - protected override void OnKeyDown( System.Windows.Input.KeyEventArgs e ) + internal void SelectNextAnchorable() { - base.OnKeyDown( e ); + if( this.SelectedAnchorable != null ) + { + var anchorablesArray = this.Anchorables.ToArray(); + int anchorableIndex = anchorablesArray.IndexOf( this.SelectedAnchorable ); + anchorableIndex++; + if( anchorableIndex == this.Anchorables.Count() ) + { + anchorableIndex = 0; + } + this.InternalSetSelectedAnchorable( anchorablesArray[ anchorableIndex ] ); + } } - protected override void OnPreviewKeyDown( System.Windows.Input.KeyEventArgs e ) + #endregion + + #region Private Methods + + private void InternalSetSelectedAnchorable( LayoutAnchorableItem anchorableToSelect ) { - if( e.Key == System.Windows.Input.Key.Tab ) + _internalSetSelectedAnchorable = true; + this.SelectedAnchorable = anchorableToSelect; + _internalSetSelectedAnchorable = false; + + if( _anchorableListBox != null ) { - SelectNextDocument(); - e.Handled = true; + _anchorableListBox.Focus(); } + } + private void InternalSetSelectedDocument( LayoutDocumentItem documentToSelect ) + { + _internalSetSelectedDocument = true; + this.SelectedDocument = documentToSelect; + _internalSetSelectedDocument = false; - base.OnPreviewKeyDown( e ); + if( ( _documentListBox != null ) && ( documentToSelect != null ) ) + { + _documentListBox.Focus(); + } } - protected override void OnPreviewKeyUp( System.Windows.Input.KeyEventArgs e ) + private void OnLoaded( object sender, RoutedEventArgs e ) { - if( e.Key != System.Windows.Input.Key.Tab ) + this.Loaded -= new RoutedEventHandler( OnLoaded ); + + if( ( _documentListBox != null ) && (this.SelectedDocument != null) ) { - if( SelectedAnchorable != null && - SelectedAnchorable.ActivateCommand.CanExecute( null ) ) - SelectedAnchorable.ActivateCommand.Execute( null ); - - if( SelectedAnchorable == null && - SelectedDocument != null && - SelectedDocument.ActivateCommand.CanExecute( null ) ) - SelectedDocument.ActivateCommand.Execute( null ); - Close(); - e.Handled = true; + _documentListBox.Focus(); + } + else if( ( _anchorableListBox != null ) && (this.SelectedAnchorable != null) ) + { + _anchorableListBox.Focus(); } - - base.OnPreviewKeyUp( e ); + WindowStartupLocation = WindowStartupLocation.CenterOwner; } + private void OnUnloaded( object sender, RoutedEventArgs e ) + { + this.Unloaded -= new RoutedEventHandler( OnUnloaded ); + } + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayArea.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayArea.cs index c402c97f..d6fa1f76 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayArea.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayArea.cs @@ -14,41 +14,47 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Controls; using System.Windows; -using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Controls { - public abstract class OverlayArea : IOverlayWindowArea - { - internal OverlayArea(IOverlayWindow overlayWindow) - { - _overlayWindow = overlayWindow; - } + public abstract class OverlayArea : IOverlayWindowArea + { + #region Members + + private IOverlayWindow _overlayWindow; + private Rect? _screenDetectionArea; + + #endregion - IOverlayWindow _overlayWindow; + #region Constructors + + internal OverlayArea( IOverlayWindow overlayWindow ) + { + _overlayWindow = overlayWindow; + } - Rect? _screenDetectionArea; - Rect IOverlayWindowArea.ScreenDetectionArea - { - get - { - return _screenDetectionArea.Value; - } - } + #endregion - protected void SetScreenDetectionArea(Rect rect) - { - _screenDetectionArea = rect; - } + #region Internal Methods + protected void SetScreenDetectionArea( Rect rect ) + { + _screenDetectionArea = rect; + } + #endregion + #region IOverlayWindowArea + Rect IOverlayWindowArea.ScreenDetectionArea + { + get + { + return _screenDetectionArea.Value; + } } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindow.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindow.cs index ee618808..e7a74d62 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindow.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindow.cs @@ -14,706 +14,716 @@ ***********************************************************************************/ -using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows; using System.Windows.Controls; -using System.Windows.Media; using System.Windows.Shapes; using Xceed.Wpf.AvalonDock.Layout; -using System.Diagnostics; using Xceed.Wpf.AvalonDock.Themes; namespace Xceed.Wpf.AvalonDock.Controls { - public class OverlayWindow : Window, IOverlayWindow + public class OverlayWindow : Window, IOverlayWindow + { + #region Members + + private ResourceDictionary currentThemeResourceDictionary; // = null + private Canvas _mainCanvasPanel; + private Grid _gridDockingManagerDropTargets; + private Grid _gridAnchorablePaneDropTargets; + private Grid _gridDocumentPaneDropTargets; + private Grid _gridDocumentPaneFullDropTargets; + + private FrameworkElement _dockingManagerDropTargetBottom; + private FrameworkElement _dockingManagerDropTargetTop; + private FrameworkElement _dockingManagerDropTargetLeft; + private FrameworkElement _dockingManagerDropTargetRight; + + private FrameworkElement _anchorablePaneDropTargetBottom; + private FrameworkElement _anchorablePaneDropTargetTop; + private FrameworkElement _anchorablePaneDropTargetLeft; + private FrameworkElement _anchorablePaneDropTargetRight; + private FrameworkElement _anchorablePaneDropTargetInto; + + private FrameworkElement _documentPaneDropTargetBottom; + private FrameworkElement _documentPaneDropTargetTop; + private FrameworkElement _documentPaneDropTargetLeft; + private FrameworkElement _documentPaneDropTargetRight; + private FrameworkElement _documentPaneDropTargetInto; + + private FrameworkElement _documentPaneDropTargetBottomAsAnchorablePane; + private FrameworkElement _documentPaneDropTargetTopAsAnchorablePane; + private FrameworkElement _documentPaneDropTargetLeftAsAnchorablePane; + private FrameworkElement _documentPaneDropTargetRightAsAnchorablePane; + + private FrameworkElement _documentPaneFullDropTargetBottom; + private FrameworkElement _documentPaneFullDropTargetTop; + private FrameworkElement _documentPaneFullDropTargetLeft; + private FrameworkElement _documentPaneFullDropTargetRight; + private FrameworkElement _documentPaneFullDropTargetInto; + + private Path _previewBox; + private IOverlayWindowHost _host; + private LayoutFloatingWindowControl _floatingWindow = null; + private List _visibleAreas = new List(); + + #endregion + + #region Constructors + + static OverlayWindow() { - private ResourceDictionary currentThemeResourceDictionary; // = null + DefaultStyleKeyProperty.OverrideMetadata( typeof( OverlayWindow ), new FrameworkPropertyMetadata( typeof( OverlayWindow ) ) ); - static OverlayWindow() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(typeof(OverlayWindow))); + OverlayWindow.AllowsTransparencyProperty.OverrideMetadata( typeof( OverlayWindow ), new FrameworkPropertyMetadata( true ) ); + OverlayWindow.WindowStyleProperty.OverrideMetadata( typeof( OverlayWindow ), new FrameworkPropertyMetadata( WindowStyle.None ) ); + OverlayWindow.ShowInTaskbarProperty.OverrideMetadata( typeof( OverlayWindow ), new FrameworkPropertyMetadata( false ) ); + OverlayWindow.ShowActivatedProperty.OverrideMetadata( typeof( OverlayWindow ), new FrameworkPropertyMetadata( false ) ); + OverlayWindow.VisibilityProperty.OverrideMetadata( typeof( OverlayWindow ), new FrameworkPropertyMetadata( Visibility.Hidden ) ); + } - OverlayWindow.AllowsTransparencyProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(true)); - OverlayWindow.WindowStyleProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(WindowStyle.None)); - OverlayWindow.ShowInTaskbarProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(false)); - OverlayWindow.ShowActivatedProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(false)); - OverlayWindow.VisibilityProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(Visibility.Hidden)); - } + internal OverlayWindow( IOverlayWindowHost host ) + { + _host = host; + UpdateThemeResources(); + } + #endregion - internal OverlayWindow(IOverlayWindowHost host) - { - _host = host; - UpdateThemeResources(); - } + #region Overrides + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + _mainCanvasPanel = GetTemplateChild( "PART_DropTargetsContainer" ) as Canvas; + _gridDockingManagerDropTargets = GetTemplateChild( "PART_DockingManagerDropTargets" ) as Grid; + _gridAnchorablePaneDropTargets = GetTemplateChild( "PART_AnchorablePaneDropTargets" ) as Grid; + _gridDocumentPaneDropTargets = GetTemplateChild( "PART_DocumentPaneDropTargets" ) as Grid; + _gridDocumentPaneFullDropTargets = GetTemplateChild( "PART_DocumentPaneFullDropTargets" ) as Grid; + + _gridDockingManagerDropTargets.Visibility = System.Windows.Visibility.Hidden; + _gridAnchorablePaneDropTargets.Visibility = System.Windows.Visibility.Hidden; + _gridDocumentPaneDropTargets.Visibility = System.Windows.Visibility.Hidden; + if( _gridDocumentPaneFullDropTargets != null ) + _gridDocumentPaneFullDropTargets.Visibility = System.Windows.Visibility.Hidden; + + _dockingManagerDropTargetBottom = GetTemplateChild( "PART_DockingManagerDropTargetBottom" ) as FrameworkElement; + _dockingManagerDropTargetTop = GetTemplateChild( "PART_DockingManagerDropTargetTop" ) as FrameworkElement; + _dockingManagerDropTargetLeft = GetTemplateChild( "PART_DockingManagerDropTargetLeft" ) as FrameworkElement; + _dockingManagerDropTargetRight = GetTemplateChild( "PART_DockingManagerDropTargetRight" ) as FrameworkElement; + + _anchorablePaneDropTargetBottom = GetTemplateChild( "PART_AnchorablePaneDropTargetBottom" ) as FrameworkElement; + _anchorablePaneDropTargetTop = GetTemplateChild( "PART_AnchorablePaneDropTargetTop" ) as FrameworkElement; + _anchorablePaneDropTargetLeft = GetTemplateChild( "PART_AnchorablePaneDropTargetLeft" ) as FrameworkElement; + _anchorablePaneDropTargetRight = GetTemplateChild( "PART_AnchorablePaneDropTargetRight" ) as FrameworkElement; + _anchorablePaneDropTargetInto = GetTemplateChild( "PART_AnchorablePaneDropTargetInto" ) as FrameworkElement; + + _documentPaneDropTargetBottom = GetTemplateChild( "PART_DocumentPaneDropTargetBottom" ) as FrameworkElement; + _documentPaneDropTargetTop = GetTemplateChild( "PART_DocumentPaneDropTargetTop" ) as FrameworkElement; + _documentPaneDropTargetLeft = GetTemplateChild( "PART_DocumentPaneDropTargetLeft" ) as FrameworkElement; + _documentPaneDropTargetRight = GetTemplateChild( "PART_DocumentPaneDropTargetRight" ) as FrameworkElement; + _documentPaneDropTargetInto = GetTemplateChild( "PART_DocumentPaneDropTargetInto" ) as FrameworkElement; + + _documentPaneDropTargetBottomAsAnchorablePane = GetTemplateChild( "PART_DocumentPaneDropTargetBottomAsAnchorablePane" ) as FrameworkElement; + _documentPaneDropTargetTopAsAnchorablePane = GetTemplateChild( "PART_DocumentPaneDropTargetTopAsAnchorablePane" ) as FrameworkElement; + _documentPaneDropTargetLeftAsAnchorablePane = GetTemplateChild( "PART_DocumentPaneDropTargetLeftAsAnchorablePane" ) as FrameworkElement; + _documentPaneDropTargetRightAsAnchorablePane = GetTemplateChild( "PART_DocumentPaneDropTargetRightAsAnchorablePane" ) as FrameworkElement; + + _documentPaneFullDropTargetBottom = GetTemplateChild( "PART_DocumentPaneFullDropTargetBottom" ) as FrameworkElement; + _documentPaneFullDropTargetTop = GetTemplateChild( "PART_DocumentPaneFullDropTargetTop" ) as FrameworkElement; + _documentPaneFullDropTargetLeft = GetTemplateChild( "PART_DocumentPaneFullDropTargetLeft" ) as FrameworkElement; + _documentPaneFullDropTargetRight = GetTemplateChild( "PART_DocumentPaneFullDropTargetRight" ) as FrameworkElement; + _documentPaneFullDropTargetInto = GetTemplateChild( "PART_DocumentPaneFullDropTargetInto" ) as FrameworkElement; + + _previewBox = GetTemplateChild( "PART_PreviewBox" ) as Path; + } - internal void UpdateThemeResources(Theme oldTheme = null) - { - if (oldTheme != null) - { - if( oldTheme is DictionaryTheme ) - { - if( currentThemeResourceDictionary != null ) - { - Resources.MergedDictionaries.Remove( currentThemeResourceDictionary ); - currentThemeResourceDictionary = null; - } - } - else - { - var resourceDictionaryToRemove = - Resources.MergedDictionaries.FirstOrDefault( r => r.Source == oldTheme.GetResourceUri() ); - if( resourceDictionaryToRemove != null ) - Resources.MergedDictionaries.Remove( - resourceDictionaryToRemove ); - } - } + protected override void OnClosing( System.ComponentModel.CancelEventArgs e ) + { + base.OnClosing( e ); + } - if (_host.Manager.Theme != null) - { - if( _host.Manager.Theme is DictionaryTheme ) - { - currentThemeResourceDictionary = ( ( DictionaryTheme )_host.Manager.Theme ).ThemeResourceDictionary; - Resources.MergedDictionaries.Add( currentThemeResourceDictionary ); - } - else - { - Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = _host.Manager.Theme.GetResourceUri() }); - } - } - } + #endregion + #region Internal Methods - Canvas _mainCanvasPanel; - Grid _gridDockingManagerDropTargets; - Grid _gridAnchorablePaneDropTargets; - Grid _gridDocumentPaneDropTargets; - Grid _gridDocumentPaneFullDropTargets; + internal void UpdateThemeResources( Theme oldTheme = null ) + { + if( oldTheme != null ) + { + if( oldTheme is DictionaryTheme ) + { + if( currentThemeResourceDictionary != null ) + { + Resources.MergedDictionaries.Remove( currentThemeResourceDictionary ); + currentThemeResourceDictionary = null; + } + } + else + { + var resourceDictionaryToRemove = + Resources.MergedDictionaries.FirstOrDefault( r => r.Source == oldTheme.GetResourceUri() ); + if( resourceDictionaryToRemove != null ) + Resources.MergedDictionaries.Remove( + resourceDictionaryToRemove ); + } + } - FrameworkElement _dockingManagerDropTargetBottom; - FrameworkElement _dockingManagerDropTargetTop; - FrameworkElement _dockingManagerDropTargetLeft; - FrameworkElement _dockingManagerDropTargetRight; + if( _host.Manager.Theme != null ) + { + if( _host.Manager.Theme is DictionaryTheme ) + { + currentThemeResourceDictionary = ( ( DictionaryTheme )_host.Manager.Theme ).ThemeResourceDictionary; + Resources.MergedDictionaries.Add( currentThemeResourceDictionary ); + } + else + { + Resources.MergedDictionaries.Add( new ResourceDictionary() { Source = _host.Manager.Theme.GetResourceUri() } ); + } + } + } - FrameworkElement _anchorablePaneDropTargetBottom; - FrameworkElement _anchorablePaneDropTargetTop; - FrameworkElement _anchorablePaneDropTargetLeft; - FrameworkElement _anchorablePaneDropTargetRight; - FrameworkElement _anchorablePaneDropTargetInto; + internal void EnableDropTargets() + { + if( _mainCanvasPanel != null ) + _mainCanvasPanel.Visibility = System.Windows.Visibility.Visible; + } - FrameworkElement _documentPaneDropTargetBottom; - FrameworkElement _documentPaneDropTargetTop; - FrameworkElement _documentPaneDropTargetLeft; - FrameworkElement _documentPaneDropTargetRight; - FrameworkElement _documentPaneDropTargetInto; + internal void HideDropTargets() + { + if( _mainCanvasPanel != null ) + _mainCanvasPanel.Visibility = System.Windows.Visibility.Hidden; - FrameworkElement _documentPaneDropTargetBottomAsAnchorablePane; - FrameworkElement _documentPaneDropTargetTopAsAnchorablePane; - FrameworkElement _documentPaneDropTargetLeftAsAnchorablePane; - FrameworkElement _documentPaneDropTargetRightAsAnchorablePane; + } - FrameworkElement _documentPaneFullDropTargetBottom; - FrameworkElement _documentPaneFullDropTargetTop; - FrameworkElement _documentPaneFullDropTargetLeft; - FrameworkElement _documentPaneFullDropTargetRight; - FrameworkElement _documentPaneFullDropTargetInto; + #endregion - Path _previewBox; + #region Private Methods - public override void OnApplyTemplate() + /// + /// This method controls the DropTargetInto button of the overlay window. + /// It checks that only 1 of the defined ContentLayouts can be present on the LayoutDocumentPane or LayoutAnchorablePane. + /// The combination between the ContentLayout Title and the ContentId is the search key, and has to be unique. + /// If a floating window is dropped on a LayoutDocumentPane or LayoutAnchorablePane, it checks if one of the containing LayoutContents + /// is already present on the LayoutDocumentPane or LayoutAnchorablePane. If so, then it will disable the DropTargetInto button. + /// + /// The given LayoutDocumentPane or LayoutAnchorablePane + private void SetDropTargetIntoVisibility( ILayoutPositionableElement positionableElement ) + { + if( positionableElement is LayoutAnchorablePane ) + { + _anchorablePaneDropTargetInto.Visibility = Visibility.Visible; + } + else if( positionableElement is LayoutDocumentPane ) + { + _documentPaneDropTargetInto.Visibility = Visibility.Visible; + } + + if( positionableElement == null || _floatingWindow.Model == null || positionableElement.AllowDuplicateContent ) + { + return; + } + + // Find all content layouts in the anchorable pane (object to drop on) + var contentLayoutsOnPositionableElementPane = GetAllLayoutContents( positionableElement ); + + // Find all content layouts in the floating window (object to drop) + var contentLayoutsOnFloatingWindow = GetAllLayoutContents( _floatingWindow.Model ); + + // If any of the content layouts is present in the drop area, then disable the DropTargetInto button. + foreach( var content in contentLayoutsOnFloatingWindow ) + { + if( !contentLayoutsOnPositionableElementPane.Any( item => + item.Title == content.Title && + item.ContentId == content.ContentId ) ) { - base.OnApplyTemplate(); - - _mainCanvasPanel = GetTemplateChild("PART_DropTargetsContainer") as Canvas; - _gridDockingManagerDropTargets = GetTemplateChild("PART_DockingManagerDropTargets") as Grid; - _gridAnchorablePaneDropTargets = GetTemplateChild("PART_AnchorablePaneDropTargets") as Grid; - _gridDocumentPaneDropTargets = GetTemplateChild("PART_DocumentPaneDropTargets") as Grid; - _gridDocumentPaneFullDropTargets = GetTemplateChild("PART_DocumentPaneFullDropTargets") as Grid; - - _gridDockingManagerDropTargets.Visibility = System.Windows.Visibility.Hidden; - _gridAnchorablePaneDropTargets.Visibility = System.Windows.Visibility.Hidden; - _gridDocumentPaneDropTargets.Visibility = System.Windows.Visibility.Hidden; - if (_gridDocumentPaneFullDropTargets != null) - _gridDocumentPaneFullDropTargets.Visibility = System.Windows.Visibility.Hidden; - - _dockingManagerDropTargetBottom = GetTemplateChild("PART_DockingManagerDropTargetBottom") as FrameworkElement; - _dockingManagerDropTargetTop = GetTemplateChild("PART_DockingManagerDropTargetTop") as FrameworkElement; - _dockingManagerDropTargetLeft = GetTemplateChild("PART_DockingManagerDropTargetLeft") as FrameworkElement; - _dockingManagerDropTargetRight = GetTemplateChild("PART_DockingManagerDropTargetRight") as FrameworkElement; - - _anchorablePaneDropTargetBottom = GetTemplateChild("PART_AnchorablePaneDropTargetBottom") as FrameworkElement; - _anchorablePaneDropTargetTop = GetTemplateChild("PART_AnchorablePaneDropTargetTop") as FrameworkElement; - _anchorablePaneDropTargetLeft = GetTemplateChild("PART_AnchorablePaneDropTargetLeft") as FrameworkElement; - _anchorablePaneDropTargetRight = GetTemplateChild("PART_AnchorablePaneDropTargetRight") as FrameworkElement; - _anchorablePaneDropTargetInto = GetTemplateChild("PART_AnchorablePaneDropTargetInto") as FrameworkElement; - - _documentPaneDropTargetBottom = GetTemplateChild("PART_DocumentPaneDropTargetBottom") as FrameworkElement; - _documentPaneDropTargetTop = GetTemplateChild("PART_DocumentPaneDropTargetTop") as FrameworkElement; - _documentPaneDropTargetLeft = GetTemplateChild("PART_DocumentPaneDropTargetLeft") as FrameworkElement; - _documentPaneDropTargetRight = GetTemplateChild("PART_DocumentPaneDropTargetRight") as FrameworkElement; - _documentPaneDropTargetInto = GetTemplateChild("PART_DocumentPaneDropTargetInto") as FrameworkElement; - - _documentPaneDropTargetBottomAsAnchorablePane = GetTemplateChild("PART_DocumentPaneDropTargetBottomAsAnchorablePane") as FrameworkElement; - _documentPaneDropTargetTopAsAnchorablePane = GetTemplateChild("PART_DocumentPaneDropTargetTopAsAnchorablePane") as FrameworkElement; - _documentPaneDropTargetLeftAsAnchorablePane = GetTemplateChild("PART_DocumentPaneDropTargetLeftAsAnchorablePane") as FrameworkElement; - _documentPaneDropTargetRightAsAnchorablePane = GetTemplateChild("PART_DocumentPaneDropTargetRightAsAnchorablePane") as FrameworkElement; - - _documentPaneFullDropTargetBottom = GetTemplateChild("PART_DocumentPaneFullDropTargetBottom") as FrameworkElement; - _documentPaneFullDropTargetTop = GetTemplateChild("PART_DocumentPaneFullDropTargetTop") as FrameworkElement; - _documentPaneFullDropTargetLeft = GetTemplateChild("PART_DocumentPaneFullDropTargetLeft") as FrameworkElement; - _documentPaneFullDropTargetRight = GetTemplateChild("PART_DocumentPaneFullDropTargetRight") as FrameworkElement; - _documentPaneFullDropTargetInto = GetTemplateChild("PART_DocumentPaneFullDropTargetInto") as FrameworkElement; - - _previewBox = GetTemplateChild("PART_PreviewBox") as Path; + continue; } - - internal void EnableDropTargets() + if( positionableElement is LayoutAnchorablePane ) { - if (_mainCanvasPanel != null) - _mainCanvasPanel.Visibility = System.Windows.Visibility.Visible; + _anchorablePaneDropTargetInto.Visibility = Visibility.Hidden; } - - internal void HideDropTargets() + else if( positionableElement is LayoutDocumentPane ) { - if (_mainCanvasPanel != null) - _mainCanvasPanel.Visibility = System.Windows.Visibility.Hidden; - + _documentPaneDropTargetInto.Visibility = Visibility.Hidden; } + break; + } + } - IOverlayWindowHost _host; + /// + /// Find any LayoutDocument or LayoutAnchorable from a given source (e.g. LayoutDocumentPane, LayoutAnchorableFloatingWindow, etc.) + /// + /// The given source to search in + /// A list of all LayoutContent's + private List GetAllLayoutContents( object source ) + { + var result = new List(); - IEnumerable IOverlayWindow.GetTargets() + var documentFloatingWindow = source as LayoutDocumentFloatingWindow; + if( documentFloatingWindow != null ) + { + foreach( var layoutElement in documentFloatingWindow.Children ) { - foreach (var visibleArea in _visibleAreas) - { - switch (visibleArea.Type) - { - case DropAreaType.DockingManager: - { - var dropAreaDockingManager = visibleArea as DropArea; - yield return new DockingManagerDropTarget(dropAreaDockingManager.AreaElement, _dockingManagerDropTargetLeft.GetScreenArea(), DropTargetType.DockingManagerDockLeft); - yield return new DockingManagerDropTarget(dropAreaDockingManager.AreaElement, _dockingManagerDropTargetTop.GetScreenArea(), DropTargetType.DockingManagerDockTop); - yield return new DockingManagerDropTarget(dropAreaDockingManager.AreaElement, _dockingManagerDropTargetBottom.GetScreenArea(), DropTargetType.DockingManagerDockBottom); - yield return new DockingManagerDropTarget(dropAreaDockingManager.AreaElement, _dockingManagerDropTargetRight.GetScreenArea(), DropTargetType.DockingManagerDockRight); - } - break; - case DropAreaType.AnchorablePane: - { - var dropAreaAnchorablePane = visibleArea as DropArea; - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetLeft.GetScreenArea(), DropTargetType.AnchorablePaneDockLeft); - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetTop.GetScreenArea(), DropTargetType.AnchorablePaneDockTop); - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetRight.GetScreenArea(), DropTargetType.AnchorablePaneDockRight); - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetBottom.GetScreenArea(), DropTargetType.AnchorablePaneDockBottom); - if( _anchorablePaneDropTargetInto.IsVisible ) - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetInto.GetScreenArea(), DropTargetType.AnchorablePaneDockInside); - - var parentPaneModel = dropAreaAnchorablePane.AreaElement.Model as LayoutAnchorablePane; - LayoutAnchorableTabItem lastAreaTabItem = null; - foreach (var dropAreaTabItem in dropAreaAnchorablePane.AreaElement.FindVisualChildren()) - { - var tabItemModel = dropAreaTabItem.Model as LayoutAnchorable; - lastAreaTabItem = lastAreaTabItem == null || lastAreaTabItem.GetScreenArea().Right < dropAreaTabItem.GetScreenArea().Right ? - dropAreaTabItem : lastAreaTabItem; - int tabIndex = parentPaneModel.Children.IndexOf(tabItemModel); - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, dropAreaTabItem.GetScreenArea(), DropTargetType.AnchorablePaneDockInside, tabIndex); - } - - if (lastAreaTabItem != null) - { - var lastAreaTabItemScreenArea = lastAreaTabItem.GetScreenArea(); - var newAreaTabItemScreenArea = new Rect(lastAreaTabItemScreenArea.TopRight, new Point(lastAreaTabItemScreenArea.Right + lastAreaTabItemScreenArea.Width, lastAreaTabItemScreenArea.Bottom)); - if (newAreaTabItemScreenArea.Right < dropAreaAnchorablePane.AreaElement.GetScreenArea().Right) - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, newAreaTabItemScreenArea, DropTargetType.AnchorablePaneDockInside, parentPaneModel.Children.Count); - } - - var dropAreaTitle = dropAreaAnchorablePane.AreaElement.FindVisualChildren().FirstOrDefault(); - if (dropAreaTitle != null) - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, dropAreaTitle.GetScreenArea(), DropTargetType.AnchorablePaneDockInside); - } - break; - case DropAreaType.DocumentPane: - { - bool isDraggingAnchorables = _floatingWindow.Model is LayoutAnchorableFloatingWindow; - if (isDraggingAnchorables && _gridDocumentPaneFullDropTargets != null) - { - var dropAreaDocumentPane = visibleArea as DropArea; - if (_documentPaneFullDropTargetLeft.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetLeft.GetScreenArea(), DropTargetType.DocumentPaneDockLeft); - if (_documentPaneFullDropTargetTop.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetTop.GetScreenArea(), DropTargetType.DocumentPaneDockTop); - if (_documentPaneFullDropTargetRight.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetRight.GetScreenArea(), DropTargetType.DocumentPaneDockRight); - if (_documentPaneFullDropTargetBottom.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetBottom.GetScreenArea(), DropTargetType.DocumentPaneDockBottom); - if (_documentPaneFullDropTargetInto.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetInto.GetScreenArea(), DropTargetType.DocumentPaneDockInside); - - var parentPaneModel = dropAreaDocumentPane.AreaElement.Model as LayoutDocumentPane; - LayoutDocumentTabItem lastAreaTabItem = null; - foreach (var dropAreaTabItem in dropAreaDocumentPane.AreaElement.FindVisualChildren()) - { - var tabItemModel = dropAreaTabItem.Model; - lastAreaTabItem = lastAreaTabItem == null || lastAreaTabItem.GetScreenArea().Right < dropAreaTabItem.GetScreenArea().Right ? - dropAreaTabItem : lastAreaTabItem; - int tabIndex = parentPaneModel.Children.IndexOf(tabItemModel); - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, dropAreaTabItem.GetScreenArea(), DropTargetType.DocumentPaneDockInside, tabIndex); - } - - if (lastAreaTabItem != null) - { - var lastAreaTabItemScreenArea = lastAreaTabItem.GetScreenArea(); - var newAreaTabItemScreenArea = new Rect(lastAreaTabItemScreenArea.TopRight, new Point(lastAreaTabItemScreenArea.Right + lastAreaTabItemScreenArea.Width, lastAreaTabItemScreenArea.Bottom)); - if (newAreaTabItemScreenArea.Right < dropAreaDocumentPane.AreaElement.GetScreenArea().Right) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, newAreaTabItemScreenArea, DropTargetType.DocumentPaneDockInside, parentPaneModel.Children.Count); - } - - if (_documentPaneDropTargetLeftAsAnchorablePane.IsVisible) - yield return new DocumentPaneDropAsAnchorableTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetLeftAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableLeft); - if (_documentPaneDropTargetTopAsAnchorablePane.IsVisible) - yield return new DocumentPaneDropAsAnchorableTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetTopAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableTop); - if (_documentPaneDropTargetRightAsAnchorablePane.IsVisible) - yield return new DocumentPaneDropAsAnchorableTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetRightAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableRight); - if (_documentPaneDropTargetBottomAsAnchorablePane.IsVisible) - yield return new DocumentPaneDropAsAnchorableTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetBottomAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableBottom); - } - else - { - - var dropAreaDocumentPane = visibleArea as DropArea; - if (_documentPaneDropTargetLeft.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetLeft.GetScreenArea(), DropTargetType.DocumentPaneDockLeft); - if (_documentPaneDropTargetTop.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetTop.GetScreenArea(), DropTargetType.DocumentPaneDockTop); - if (_documentPaneDropTargetRight.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetRight.GetScreenArea(), DropTargetType.DocumentPaneDockRight); - if (_documentPaneDropTargetBottom.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetBottom.GetScreenArea(), DropTargetType.DocumentPaneDockBottom); - if (_documentPaneDropTargetInto.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetInto.GetScreenArea(), DropTargetType.DocumentPaneDockInside); - - var parentPaneModel = dropAreaDocumentPane.AreaElement.Model as LayoutDocumentPane; - LayoutDocumentTabItem lastAreaTabItem = null; - foreach (var dropAreaTabItem in dropAreaDocumentPane.AreaElement.FindVisualChildren()) - { - var tabItemModel = dropAreaTabItem.Model; - lastAreaTabItem = lastAreaTabItem == null || lastAreaTabItem.GetScreenArea().Right < dropAreaTabItem.GetScreenArea().Right ? - dropAreaTabItem : lastAreaTabItem; - int tabIndex = parentPaneModel.Children.IndexOf(tabItemModel); - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, dropAreaTabItem.GetScreenArea(), DropTargetType.DocumentPaneDockInside, tabIndex); - } - - if (lastAreaTabItem != null) - { - var lastAreaTabItemScreenArea = lastAreaTabItem.GetScreenArea(); - var newAreaTabItemScreenArea = new Rect(lastAreaTabItemScreenArea.TopRight, new Point(lastAreaTabItemScreenArea.Right + lastAreaTabItemScreenArea.Width, lastAreaTabItemScreenArea.Bottom)); - if (newAreaTabItemScreenArea.Right < dropAreaDocumentPane.AreaElement.GetScreenArea().Right) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, newAreaTabItemScreenArea, DropTargetType.DocumentPaneDockInside, parentPaneModel.Children.Count); - } - } - } - break; - case DropAreaType.DocumentPaneGroup: - { - var dropAreaDocumentPane = visibleArea as DropArea; - if (_documentPaneDropTargetInto.IsVisible) - yield return new DocumentPaneGroupDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetInto.GetScreenArea(), DropTargetType.DocumentPaneGroupDockInside); - } - break; - } + result.AddRange( GetAllLayoutContents( layoutElement ) ); + } + } - } - yield break; + var anchorableFloatingWindow = source as LayoutAnchorableFloatingWindow; + if( anchorableFloatingWindow != null ) + { + foreach( var layoutElement in anchorableFloatingWindow.Children ) + { + result.AddRange( GetAllLayoutContents( layoutElement ) ); } + } - LayoutFloatingWindowControl _floatingWindow = null; - void IOverlayWindow.DragEnter(LayoutFloatingWindowControl floatingWindow) + var documentPaneGroup = source as LayoutDocumentPaneGroup; + if( documentPaneGroup != null ) + { + foreach( var layoutDocumentPane in documentPaneGroup.Children ) { - _floatingWindow = floatingWindow; - EnableDropTargets(); + result.AddRange( GetAllLayoutContents( layoutDocumentPane ) ); } + } - void IOverlayWindow.DragLeave(LayoutFloatingWindowControl floatingWindow) + var anchorablePaneGroup = source as LayoutAnchorablePaneGroup; + if( anchorablePaneGroup != null ) + { + foreach( var layoutDocumentPane in anchorablePaneGroup.Children ) { - Visibility = System.Windows.Visibility.Hidden; - _floatingWindow = null; + result.AddRange( GetAllLayoutContents( layoutDocumentPane ) ); } + } - /// - /// This method controls the DropTargetInto button of the overlay window. - /// It checks that only 1 of the defined ContentLayouts can be present on the LayoutDocumentPane or LayoutAnchorablePane. - /// The combination between the ContentLayout Title and the ContentId is the search key, and has to be unique. - /// If a floating window is dropped on a LayoutDocumentPane or LayoutAnchorablePane, it checks if one of the containing LayoutContents - /// is already present on the LayoutDocumentPane or LayoutAnchorablePane. If so, then it will disable the DropTargetInto button. - /// - /// The given LayoutDocumentPane or LayoutAnchorablePane - private void SetDropTargetIntoVisibility( ILayoutPositionableElement positionableElement ) + var documentPane = source as LayoutDocumentPane; + if( documentPane != null ) + { + foreach( var layoutContent in documentPane.Children ) { - if( positionableElement is LayoutAnchorablePane ) - { - _anchorablePaneDropTargetInto.Visibility = Visibility.Visible; - } - else if( positionableElement is LayoutDocumentPane ) - { - _documentPaneDropTargetInto.Visibility = Visibility.Visible; - } + result.Add( layoutContent ); + } + } - if( positionableElement == null || _floatingWindow.Model == null || positionableElement.AllowDuplicateContent ) - { - return; - } + var anchorablePane = source as LayoutAnchorablePane; + if( anchorablePane != null ) + { + foreach( var layoutContent in anchorablePane.Children ) + { + result.Add( layoutContent ); + } + } - // Find all content layouts in the anchorable pane (object to drop on) - var contentLayoutsOnPositionableElementPane = GetAllLayoutContents( positionableElement ); + var document = source as LayoutDocument; + if( document != null ) + { + result.Add( document ); + } - // Find all content layouts in the floating window (object to drop) - var contentLayoutsOnFloatingWindow = GetAllLayoutContents( _floatingWindow.Model ); + var anchorable = source as LayoutAnchorable; + if( anchorable != null ) + { + result.Add( anchorable ); + } - // If any of the content layouts is present in the drop area, then disable the DropTargetInto button. - foreach( var content in contentLayoutsOnFloatingWindow ) - { - if( !contentLayoutsOnPositionableElementPane.Any( item => - item.Title == content.Title && - item.ContentId == content.ContentId ) ) - { - continue; - } + return result; + } + + #endregion + + #region IOverlayWindow - if( positionableElement is LayoutAnchorablePane ) + IEnumerable IOverlayWindow.GetTargets() + { + foreach( var visibleArea in _visibleAreas ) + { + switch( visibleArea.Type ) + { + case DropAreaType.DockingManager: { - _anchorablePaneDropTargetInto.Visibility = Visibility.Hidden; + var dropAreaDockingManager = visibleArea as DropArea; + yield return new DockingManagerDropTarget( dropAreaDockingManager.AreaElement, _dockingManagerDropTargetLeft.GetScreenArea(), DropTargetType.DockingManagerDockLeft ); + yield return new DockingManagerDropTarget( dropAreaDockingManager.AreaElement, _dockingManagerDropTargetTop.GetScreenArea(), DropTargetType.DockingManagerDockTop ); + yield return new DockingManagerDropTarget( dropAreaDockingManager.AreaElement, _dockingManagerDropTargetBottom.GetScreenArea(), DropTargetType.DockingManagerDockBottom ); + yield return new DockingManagerDropTarget( dropAreaDockingManager.AreaElement, _dockingManagerDropTargetRight.GetScreenArea(), DropTargetType.DockingManagerDockRight ); } - else if( positionableElement is LayoutDocumentPane ) + break; + case DropAreaType.AnchorablePane: { - _documentPaneDropTargetInto.Visibility = Visibility.Hidden; + var dropAreaAnchorablePane = visibleArea as DropArea; + yield return new AnchorablePaneDropTarget( dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetLeft.GetScreenArea(), DropTargetType.AnchorablePaneDockLeft ); + yield return new AnchorablePaneDropTarget( dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetTop.GetScreenArea(), DropTargetType.AnchorablePaneDockTop ); + yield return new AnchorablePaneDropTarget( dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetRight.GetScreenArea(), DropTargetType.AnchorablePaneDockRight ); + yield return new AnchorablePaneDropTarget( dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetBottom.GetScreenArea(), DropTargetType.AnchorablePaneDockBottom ); + if( _anchorablePaneDropTargetInto.IsVisible ) + yield return new AnchorablePaneDropTarget( dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetInto.GetScreenArea(), DropTargetType.AnchorablePaneDockInside ); + + var parentPaneModel = dropAreaAnchorablePane.AreaElement.Model as LayoutAnchorablePane; + LayoutAnchorableTabItem lastAreaTabItem = null; + foreach( var dropAreaTabItem in dropAreaAnchorablePane.AreaElement.FindVisualChildren() ) + { + var tabItemModel = dropAreaTabItem.Model as LayoutAnchorable; + lastAreaTabItem = lastAreaTabItem == null || lastAreaTabItem.GetScreenArea().Right < dropAreaTabItem.GetScreenArea().Right ? + dropAreaTabItem : lastAreaTabItem; + int tabIndex = parentPaneModel.Children.IndexOf( tabItemModel ); + yield return new AnchorablePaneDropTarget( dropAreaAnchorablePane.AreaElement, dropAreaTabItem.GetScreenArea(), DropTargetType.AnchorablePaneDockInside, tabIndex ); + } + + if( lastAreaTabItem != null ) + { + var lastAreaTabItemScreenArea = lastAreaTabItem.GetScreenArea(); + var newAreaTabItemScreenArea = new Rect( lastAreaTabItemScreenArea.TopRight, new Point( lastAreaTabItemScreenArea.Right + lastAreaTabItemScreenArea.Width, lastAreaTabItemScreenArea.Bottom ) ); + if( newAreaTabItemScreenArea.Right < dropAreaAnchorablePane.AreaElement.GetScreenArea().Right ) + yield return new AnchorablePaneDropTarget( dropAreaAnchorablePane.AreaElement, newAreaTabItemScreenArea, DropTargetType.AnchorablePaneDockInside, parentPaneModel.Children.Count ); + } + + var dropAreaTitle = dropAreaAnchorablePane.AreaElement.FindVisualChildren().FirstOrDefault(); + if( dropAreaTitle != null ) + yield return new AnchorablePaneDropTarget( dropAreaAnchorablePane.AreaElement, dropAreaTitle.GetScreenArea(), DropTargetType.AnchorablePaneDockInside ); } break; - } - } + case DropAreaType.DocumentPane: + { + bool isDraggingAnchorables = _floatingWindow.Model is LayoutAnchorableFloatingWindow; + if( isDraggingAnchorables && _gridDocumentPaneFullDropTargets != null ) + { + var dropAreaDocumentPane = visibleArea as DropArea; + if( _documentPaneFullDropTargetLeft.IsVisible ) + yield return new DocumentPaneDropTarget( dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetLeft.GetScreenArea(), DropTargetType.DocumentPaneDockLeft ); + if( _documentPaneFullDropTargetTop.IsVisible ) + yield return new DocumentPaneDropTarget( dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetTop.GetScreenArea(), DropTargetType.DocumentPaneDockTop ); + if( _documentPaneFullDropTargetRight.IsVisible ) + yield return new DocumentPaneDropTarget( dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetRight.GetScreenArea(), DropTargetType.DocumentPaneDockRight ); + if( _documentPaneFullDropTargetBottom.IsVisible ) + yield return new DocumentPaneDropTarget( dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetBottom.GetScreenArea(), DropTargetType.DocumentPaneDockBottom ); + if( _documentPaneFullDropTargetInto.IsVisible ) + yield return new DocumentPaneDropTarget( dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetInto.GetScreenArea(), DropTargetType.DocumentPaneDockInside ); + + var parentPaneModel = dropAreaDocumentPane.AreaElement.Model as LayoutDocumentPane; + LayoutDocumentTabItem lastAreaTabItem = null; + foreach( var dropAreaTabItem in dropAreaDocumentPane.AreaElement.FindVisualChildren() ) + { + var tabItemModel = dropAreaTabItem.Model; + lastAreaTabItem = lastAreaTabItem == null || lastAreaTabItem.GetScreenArea().Right < dropAreaTabItem.GetScreenArea().Right ? + dropAreaTabItem : lastAreaTabItem; + int tabIndex = parentPaneModel.Children.IndexOf( tabItemModel ); + yield return new DocumentPaneDropTarget( dropAreaDocumentPane.AreaElement, dropAreaTabItem.GetScreenArea(), DropTargetType.DocumentPaneDockInside, tabIndex ); + } - /// - /// Find any LayoutDocument or LayoutAnchorable from a given source (e.g. LayoutDocumentPane, LayoutAnchorableFloatingWindow, etc.) - /// - /// The given source to search in - /// A list of all LayoutContent's - private List GetAllLayoutContents( object source ) - { - var result = new List(); + if( lastAreaTabItem != null ) + { + var lastAreaTabItemScreenArea = lastAreaTabItem.GetScreenArea(); + var newAreaTabItemScreenArea = new Rect( lastAreaTabItemScreenArea.TopRight, new Point( lastAreaTabItemScreenArea.Right + lastAreaTabItemScreenArea.Width, lastAreaTabItemScreenArea.Bottom ) ); + if( newAreaTabItemScreenArea.Right < dropAreaDocumentPane.AreaElement.GetScreenArea().Right ) + yield return new DocumentPaneDropTarget( dropAreaDocumentPane.AreaElement, newAreaTabItemScreenArea, DropTargetType.DocumentPaneDockInside, parentPaneModel.Children.Count ); + } - var documentFloatingWindow = source as LayoutDocumentFloatingWindow; - if( documentFloatingWindow != null ) - { - foreach( var layoutElement in documentFloatingWindow.Children ) - { - result.AddRange( GetAllLayoutContents( layoutElement ) ); - } - } + if( _documentPaneDropTargetLeftAsAnchorablePane.IsVisible ) + yield return new DocumentPaneDropAsAnchorableTarget( dropAreaDocumentPane.AreaElement, _documentPaneDropTargetLeftAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableLeft ); + if( _documentPaneDropTargetTopAsAnchorablePane.IsVisible ) + yield return new DocumentPaneDropAsAnchorableTarget( dropAreaDocumentPane.AreaElement, _documentPaneDropTargetTopAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableTop ); + if( _documentPaneDropTargetRightAsAnchorablePane.IsVisible ) + yield return new DocumentPaneDropAsAnchorableTarget( dropAreaDocumentPane.AreaElement, _documentPaneDropTargetRightAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableRight ); + if( _documentPaneDropTargetBottomAsAnchorablePane.IsVisible ) + yield return new DocumentPaneDropAsAnchorableTarget( dropAreaDocumentPane.AreaElement, _documentPaneDropTargetBottomAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableBottom ); + } + else + { - var anchorableFloatingWindow = source as LayoutAnchorableFloatingWindow; - if( anchorableFloatingWindow != null ) - { - foreach( var layoutElement in anchorableFloatingWindow.Children ) - { - result.AddRange( GetAllLayoutContents( layoutElement ) ); - } - } + var dropAreaDocumentPane = visibleArea as DropArea; + if( _documentPaneDropTargetLeft.IsVisible ) + yield return new DocumentPaneDropTarget( dropAreaDocumentPane.AreaElement, _documentPaneDropTargetLeft.GetScreenArea(), DropTargetType.DocumentPaneDockLeft ); + if( _documentPaneDropTargetTop.IsVisible ) + yield return new DocumentPaneDropTarget( dropAreaDocumentPane.AreaElement, _documentPaneDropTargetTop.GetScreenArea(), DropTargetType.DocumentPaneDockTop ); + if( _documentPaneDropTargetRight.IsVisible ) + yield return new DocumentPaneDropTarget( dropAreaDocumentPane.AreaElement, _documentPaneDropTargetRight.GetScreenArea(), DropTargetType.DocumentPaneDockRight ); + if( _documentPaneDropTargetBottom.IsVisible ) + yield return new DocumentPaneDropTarget( dropAreaDocumentPane.AreaElement, _documentPaneDropTargetBottom.GetScreenArea(), DropTargetType.DocumentPaneDockBottom ); + if( _documentPaneDropTargetInto.IsVisible ) + yield return new DocumentPaneDropTarget( dropAreaDocumentPane.AreaElement, _documentPaneDropTargetInto.GetScreenArea(), DropTargetType.DocumentPaneDockInside ); + + var parentPaneModel = dropAreaDocumentPane.AreaElement.Model as LayoutDocumentPane; + LayoutDocumentTabItem lastAreaTabItem = null; + foreach( var dropAreaTabItem in dropAreaDocumentPane.AreaElement.FindVisualChildren() ) + { + var tabItemModel = dropAreaTabItem.Model; + lastAreaTabItem = lastAreaTabItem == null || lastAreaTabItem.GetScreenArea().Right < dropAreaTabItem.GetScreenArea().Right ? + dropAreaTabItem : lastAreaTabItem; + int tabIndex = parentPaneModel.Children.IndexOf( tabItemModel ); + yield return new DocumentPaneDropTarget( dropAreaDocumentPane.AreaElement, dropAreaTabItem.GetScreenArea(), DropTargetType.DocumentPaneDockInside, tabIndex ); + } - var documentPaneGroup = source as LayoutDocumentPaneGroup; - if( documentPaneGroup != null ) - { - foreach( var layoutDocumentPane in documentPaneGroup.Children ) - { - result.AddRange( GetAllLayoutContents( layoutDocumentPane ) ); + if( lastAreaTabItem != null ) + { + var lastAreaTabItemScreenArea = lastAreaTabItem.GetScreenArea(); + var newAreaTabItemScreenArea = new Rect( lastAreaTabItemScreenArea.TopRight, new Point( lastAreaTabItemScreenArea.Right + lastAreaTabItemScreenArea.Width, lastAreaTabItemScreenArea.Bottom ) ); + if( newAreaTabItemScreenArea.Right < dropAreaDocumentPane.AreaElement.GetScreenArea().Right ) + yield return new DocumentPaneDropTarget( dropAreaDocumentPane.AreaElement, newAreaTabItemScreenArea, DropTargetType.DocumentPaneDockInside, parentPaneModel.Children.Count ); + } + } } - } - - var anchorablePaneGroup = source as LayoutAnchorablePaneGroup; - if( anchorablePaneGroup != null ) - { - foreach( var layoutDocumentPane in anchorablePaneGroup.Children ) + break; + case DropAreaType.DocumentPaneGroup: { - result.AddRange( GetAllLayoutContents( layoutDocumentPane ) ); + var dropAreaDocumentPane = visibleArea as DropArea; + if( _documentPaneDropTargetInto.IsVisible ) + yield return new DocumentPaneGroupDropTarget( dropAreaDocumentPane.AreaElement, _documentPaneDropTargetInto.GetScreenArea(), DropTargetType.DocumentPaneGroupDockInside ); } - } + break; + } - var documentPane = source as LayoutDocumentPane; - if( documentPane != null ) - { - foreach( var layoutContent in documentPane.Children ) - { - result.Add( layoutContent ); - } - } + } + yield break; + } - var anchorablePane = source as LayoutAnchorablePane; - if( anchorablePane != null ) - { - foreach( var layoutContent in anchorablePane.Children ) - { - result.Add( layoutContent ); - } - } + void IOverlayWindow.DragEnter( LayoutFloatingWindowControl floatingWindow ) + { + _floatingWindow = floatingWindow; + EnableDropTargets(); + } - var document = source as LayoutDocument; - if( document != null ) - { - result.Add( document ); - } + void IOverlayWindow.DragLeave( LayoutFloatingWindowControl floatingWindow ) + { + Visibility = System.Windows.Visibility.Hidden; + _floatingWindow = null; + } - var anchorable = source as LayoutAnchorable; - if( anchorable != null ) + void IOverlayWindow.DragEnter( IDropArea area ) + { + _visibleAreas.Add( area ); + + FrameworkElement areaElement; + switch( area.Type ) + { + case DropAreaType.DockingManager: + areaElement = _gridDockingManagerDropTargets; + break; + case DropAreaType.AnchorablePane: + areaElement = _gridAnchorablePaneDropTargets; + + var dropAreaAnchorablePaneGroup = area as DropArea; + var layoutAnchorablePane = dropAreaAnchorablePaneGroup.AreaElement.Model as LayoutAnchorablePane; + SetDropTargetIntoVisibility( layoutAnchorablePane ); + break; + case DropAreaType.DocumentPaneGroup: { - result.Add( anchorable ); + areaElement = _gridDocumentPaneDropTargets; + var dropAreaDocumentPaneGroup = area as DropArea; + var layoutDocumentPane = ( dropAreaDocumentPaneGroup.AreaElement.Model as LayoutDocumentPaneGroup ).Children.First() as LayoutDocumentPane; + var parentDocumentPaneGroup = layoutDocumentPane.Parent as LayoutDocumentPaneGroup; + + _documentPaneDropTargetLeft.Visibility = Visibility.Hidden; + _documentPaneDropTargetRight.Visibility = Visibility.Hidden; + _documentPaneDropTargetTop.Visibility = Visibility.Hidden; + _documentPaneDropTargetBottom.Visibility = Visibility.Hidden; } + break; + case DropAreaType.DocumentPane: + default: + { + bool isDraggingAnchorables = _floatingWindow.Model is LayoutAnchorableFloatingWindow; + if( isDraggingAnchorables && _gridDocumentPaneFullDropTargets != null ) + { + areaElement = _gridDocumentPaneFullDropTargets; + var dropAreaDocumentPaneGroup = area as DropArea; + var layoutDocumentPane = dropAreaDocumentPaneGroup.AreaElement.Model as LayoutDocumentPane; + var parentDocumentPaneGroup = layoutDocumentPane.Parent as LayoutDocumentPaneGroup; - return result; - } - - - protected override void OnClosing(System.ComponentModel.CancelEventArgs e) - { - base.OnClosing(e); - } + SetDropTargetIntoVisibility( layoutDocumentPane ); + if( parentDocumentPaneGroup != null && + parentDocumentPaneGroup.Children.Where( c => c.IsVisible ).Count() > 1 ) + { + var manager = parentDocumentPaneGroup.Root.Manager; + if( !manager.AllowMixedOrientation ) + { + _documentPaneFullDropTargetLeft.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; + _documentPaneFullDropTargetRight.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; + _documentPaneFullDropTargetTop.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; + _documentPaneFullDropTargetBottom.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; + } + else + { + _documentPaneFullDropTargetLeft.Visibility = Visibility.Visible; + _documentPaneFullDropTargetRight.Visibility = Visibility.Visible; + _documentPaneFullDropTargetTop.Visibility = Visibility.Visible; + _documentPaneFullDropTargetBottom.Visibility = Visibility.Visible; + } + } + else if( parentDocumentPaneGroup == null && + layoutDocumentPane != null && + layoutDocumentPane.ChildrenCount == 0 ) + { + _documentPaneFullDropTargetLeft.Visibility = Visibility.Hidden; + _documentPaneFullDropTargetRight.Visibility = Visibility.Hidden; + _documentPaneFullDropTargetTop.Visibility = Visibility.Hidden; + _documentPaneFullDropTargetBottom.Visibility = Visibility.Hidden; + } + else + { + _documentPaneFullDropTargetLeft.Visibility = Visibility.Visible; + _documentPaneFullDropTargetRight.Visibility = Visibility.Visible; + _documentPaneFullDropTargetTop.Visibility = Visibility.Visible; + _documentPaneFullDropTargetBottom.Visibility = Visibility.Visible; + } - List _visibleAreas = new List(); - void IOverlayWindow.DragEnter(IDropArea area) - { - _visibleAreas.Add(area); + if( parentDocumentPaneGroup != null && + parentDocumentPaneGroup.Children.Where( c => c.IsVisible ).Count() > 1 ) + { + int indexOfDocumentPane = parentDocumentPaneGroup.Children.Where( ch => ch.IsVisible ).ToList().IndexOf( layoutDocumentPane ); + bool isFirstChild = indexOfDocumentPane == 0; + bool isLastChild = indexOfDocumentPane == parentDocumentPaneGroup.ChildrenCount - 1; - FrameworkElement areaElement; - switch (area.Type) - { - case DropAreaType.DockingManager: - areaElement = _gridDockingManagerDropTargets; - break; - case DropAreaType.AnchorablePane: - areaElement = _gridAnchorablePaneDropTargets; - - var dropAreaAnchorablePaneGroup = area as DropArea; - var layoutAnchorablePane = dropAreaAnchorablePaneGroup.AreaElement.Model as LayoutAnchorablePane; - SetDropTargetIntoVisibility( layoutAnchorablePane ); - break; - case DropAreaType.DocumentPaneGroup: - { - areaElement = _gridDocumentPaneDropTargets; - var dropAreaDocumentPaneGroup = area as DropArea; - var layoutDocumentPane = (dropAreaDocumentPaneGroup.AreaElement.Model as LayoutDocumentPaneGroup).Children.First() as LayoutDocumentPane; - var parentDocumentPaneGroup = layoutDocumentPane.Parent as LayoutDocumentPaneGroup; - - _documentPaneDropTargetLeft.Visibility = Visibility.Hidden; - _documentPaneDropTargetRight.Visibility = Visibility.Hidden; - _documentPaneDropTargetTop.Visibility = Visibility.Hidden; - _documentPaneDropTargetBottom.Visibility = Visibility.Hidden; - } - break; - case DropAreaType.DocumentPane: - default: - { - bool isDraggingAnchorables = _floatingWindow.Model is LayoutAnchorableFloatingWindow; - if (isDraggingAnchorables && _gridDocumentPaneFullDropTargets != null) - { - areaElement = _gridDocumentPaneFullDropTargets; - var dropAreaDocumentPaneGroup = area as DropArea; - var layoutDocumentPane = dropAreaDocumentPaneGroup.AreaElement.Model as LayoutDocumentPane; - var parentDocumentPaneGroup = layoutDocumentPane.Parent as LayoutDocumentPaneGroup; - - SetDropTargetIntoVisibility( layoutDocumentPane ); - - if (parentDocumentPaneGroup != null && - parentDocumentPaneGroup.Children.Where(c => c.IsVisible).Count() > 1) - { - var manager = parentDocumentPaneGroup.Root.Manager; - if (!manager.AllowMixedOrientation) - { - _documentPaneFullDropTargetLeft.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; - _documentPaneFullDropTargetRight.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; - _documentPaneFullDropTargetTop.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; - _documentPaneFullDropTargetBottom.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; - } - else - { - _documentPaneFullDropTargetLeft.Visibility = Visibility.Visible; - _documentPaneFullDropTargetRight.Visibility = Visibility.Visible; - _documentPaneFullDropTargetTop.Visibility = Visibility.Visible; - _documentPaneFullDropTargetBottom.Visibility = Visibility.Visible; - } - } - else if (parentDocumentPaneGroup == null && - layoutDocumentPane != null && - layoutDocumentPane.ChildrenCount == 0) - { - _documentPaneFullDropTargetLeft.Visibility = Visibility.Hidden; - _documentPaneFullDropTargetRight.Visibility = Visibility.Hidden; - _documentPaneFullDropTargetTop.Visibility = Visibility.Hidden; - _documentPaneFullDropTargetBottom.Visibility = Visibility.Hidden; - } - else - { - _documentPaneFullDropTargetLeft.Visibility = Visibility.Visible; - _documentPaneFullDropTargetRight.Visibility = Visibility.Visible; - _documentPaneFullDropTargetTop.Visibility = Visibility.Visible; - _documentPaneFullDropTargetBottom.Visibility = Visibility.Visible; - } - - if (parentDocumentPaneGroup != null && - parentDocumentPaneGroup.Children.Where(c => c.IsVisible).Count() > 1) - { - int indexOfDocumentPane = parentDocumentPaneGroup.Children.Where(ch => ch.IsVisible).ToList().IndexOf(layoutDocumentPane); - bool isFirstChild = indexOfDocumentPane == 0; - bool isLastChild = indexOfDocumentPane == parentDocumentPaneGroup.ChildrenCount - 1; - - var manager = parentDocumentPaneGroup.Root.Manager; - if (!manager.AllowMixedOrientation) - { - _documentPaneDropTargetBottomAsAnchorablePane.Visibility = - parentDocumentPaneGroup.Orientation == Orientation.Vertical ? - (isLastChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden) : - System.Windows.Visibility.Hidden; - _documentPaneDropTargetTopAsAnchorablePane.Visibility = - parentDocumentPaneGroup.Orientation == Orientation.Vertical ? - (isFirstChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden) : - System.Windows.Visibility.Hidden; - - _documentPaneDropTargetLeftAsAnchorablePane.Visibility = - parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? - (isFirstChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden) : - System.Windows.Visibility.Hidden; - - - _documentPaneDropTargetRightAsAnchorablePane.Visibility = - parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? - (isLastChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden) : - System.Windows.Visibility.Hidden; - } - else - { - _documentPaneDropTargetBottomAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - _documentPaneDropTargetLeftAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - _documentPaneDropTargetRightAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - _documentPaneDropTargetTopAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - } - } - else - { - _documentPaneDropTargetBottomAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - _documentPaneDropTargetLeftAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - _documentPaneDropTargetRightAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - _documentPaneDropTargetTopAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - } - } - else - { - areaElement = _gridDocumentPaneDropTargets; - var dropAreaDocumentPaneGroup = area as DropArea; - var layoutDocumentPane = dropAreaDocumentPaneGroup.AreaElement.Model as LayoutDocumentPane; - var parentDocumentPaneGroup = layoutDocumentPane.Parent as LayoutDocumentPaneGroup; - - SetDropTargetIntoVisibility( layoutDocumentPane ); - - if (parentDocumentPaneGroup != null && - parentDocumentPaneGroup.Children.Where(c => c.IsVisible).Count() > 1) - { - var manager = parentDocumentPaneGroup.Root.Manager; - if (!manager.AllowMixedOrientation) - { - _documentPaneDropTargetLeft.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; - _documentPaneDropTargetRight.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; - _documentPaneDropTargetTop.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; - _documentPaneDropTargetBottom.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; - } - else - { - _documentPaneDropTargetLeft.Visibility = Visibility.Visible; - _documentPaneDropTargetRight.Visibility = Visibility.Visible; - _documentPaneDropTargetTop.Visibility = Visibility.Visible; - _documentPaneDropTargetBottom.Visibility = Visibility.Visible; - } - - } - else if (parentDocumentPaneGroup == null && - layoutDocumentPane != null && - layoutDocumentPane.ChildrenCount == 0) - { - _documentPaneDropTargetLeft.Visibility = Visibility.Hidden; - _documentPaneDropTargetRight.Visibility = Visibility.Hidden; - _documentPaneDropTargetTop.Visibility = Visibility.Hidden; - _documentPaneDropTargetBottom.Visibility = Visibility.Hidden; - } - else - { - _documentPaneDropTargetLeft.Visibility = Visibility.Visible; - _documentPaneDropTargetRight.Visibility = Visibility.Visible; - _documentPaneDropTargetTop.Visibility = Visibility.Visible; - _documentPaneDropTargetBottom.Visibility = Visibility.Visible; - } - } - } - break; + var manager = parentDocumentPaneGroup.Root.Manager; + if( !manager.AllowMixedOrientation ) + { + _documentPaneDropTargetBottomAsAnchorablePane.Visibility = + parentDocumentPaneGroup.Orientation == Orientation.Vertical ? + ( isLastChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden ) : + System.Windows.Visibility.Hidden; + _documentPaneDropTargetTopAsAnchorablePane.Visibility = + parentDocumentPaneGroup.Orientation == Orientation.Vertical ? + ( isFirstChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden ) : + System.Windows.Visibility.Hidden; + + _documentPaneDropTargetLeftAsAnchorablePane.Visibility = + parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? + ( isFirstChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden ) : + System.Windows.Visibility.Hidden; + + + _documentPaneDropTargetRightAsAnchorablePane.Visibility = + parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? + ( isLastChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden ) : + System.Windows.Visibility.Hidden; + } + else + { + _documentPaneDropTargetBottomAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + _documentPaneDropTargetLeftAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + _documentPaneDropTargetRightAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + _documentPaneDropTargetTopAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + } + } + else + { + _documentPaneDropTargetBottomAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + _documentPaneDropTargetLeftAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + _documentPaneDropTargetRightAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + _documentPaneDropTargetTopAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + } } + else + { + areaElement = _gridDocumentPaneDropTargets; + var dropAreaDocumentPaneGroup = area as DropArea; + var layoutDocumentPane = dropAreaDocumentPaneGroup.AreaElement.Model as LayoutDocumentPane; + var parentDocumentPaneGroup = layoutDocumentPane.Parent as LayoutDocumentPaneGroup; - Canvas.SetLeft(areaElement, area.DetectionRect.Left - Left); - Canvas.SetTop(areaElement, area.DetectionRect.Top - Top); - areaElement.Width = area.DetectionRect.Width; - areaElement.Height = area.DetectionRect.Height; - areaElement.Visibility = System.Windows.Visibility.Visible; - } + SetDropTargetIntoVisibility( layoutDocumentPane ); - void IOverlayWindow.DragLeave(IDropArea area) - { - _visibleAreas.Remove(area); + if( parentDocumentPaneGroup != null && + parentDocumentPaneGroup.Children.Where( c => c.IsVisible ).Count() > 1 ) + { + var manager = parentDocumentPaneGroup.Root.Manager; + if( !manager.AllowMixedOrientation ) + { + _documentPaneDropTargetLeft.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; + _documentPaneDropTargetRight.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; + _documentPaneDropTargetTop.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; + _documentPaneDropTargetBottom.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; + } + else + { + _documentPaneDropTargetLeft.Visibility = Visibility.Visible; + _documentPaneDropTargetRight.Visibility = Visibility.Visible; + _documentPaneDropTargetTop.Visibility = Visibility.Visible; + _documentPaneDropTargetBottom.Visibility = Visibility.Visible; + } - FrameworkElement areaElement; - switch (area.Type) - { - case DropAreaType.DockingManager: - areaElement = _gridDockingManagerDropTargets; - break; - case DropAreaType.AnchorablePane: - areaElement = _gridAnchorablePaneDropTargets; - break; - case DropAreaType.DocumentPaneGroup: - areaElement = _gridDocumentPaneDropTargets; - break; - case DropAreaType.DocumentPane: - default: - { - bool isDraggingAnchorables = _floatingWindow.Model is LayoutAnchorableFloatingWindow; - if (isDraggingAnchorables && _gridDocumentPaneFullDropTargets != null) - areaElement = _gridDocumentPaneFullDropTargets; - else - areaElement = _gridDocumentPaneDropTargets; - } - break; + } + else if( parentDocumentPaneGroup == null && + layoutDocumentPane != null && + layoutDocumentPane.ChildrenCount == 0 ) + { + _documentPaneDropTargetLeft.Visibility = Visibility.Hidden; + _documentPaneDropTargetRight.Visibility = Visibility.Hidden; + _documentPaneDropTargetTop.Visibility = Visibility.Hidden; + _documentPaneDropTargetBottom.Visibility = Visibility.Hidden; + } + else + { + _documentPaneDropTargetLeft.Visibility = Visibility.Visible; + _documentPaneDropTargetRight.Visibility = Visibility.Visible; + _documentPaneDropTargetTop.Visibility = Visibility.Visible; + _documentPaneDropTargetBottom.Visibility = Visibility.Visible; + } } + } + break; + } + + Canvas.SetLeft( areaElement, area.DetectionRect.Left - Left ); + Canvas.SetTop( areaElement, area.DetectionRect.Top - Top ); + areaElement.Width = area.DetectionRect.Width; + areaElement.Height = area.DetectionRect.Height; + areaElement.Visibility = System.Windows.Visibility.Visible; + } - areaElement.Visibility = System.Windows.Visibility.Hidden; - } - - void IOverlayWindow.DragEnter(IDropTarget target) - { - var previewBoxPath = target.GetPreviewPath(this, _floatingWindow.Model as LayoutFloatingWindow); - if (previewBoxPath != null) - { - _previewBox.Data = previewBoxPath; - _previewBox.Visibility = System.Windows.Visibility.Visible; - } - } + void IOverlayWindow.DragLeave( IDropArea area ) + { + _visibleAreas.Remove( area ); + + FrameworkElement areaElement; + switch( area.Type ) + { + case DropAreaType.DockingManager: + areaElement = _gridDockingManagerDropTargets; + break; + case DropAreaType.AnchorablePane: + areaElement = _gridAnchorablePaneDropTargets; + break; + case DropAreaType.DocumentPaneGroup: + areaElement = _gridDocumentPaneDropTargets; + break; + case DropAreaType.DocumentPane: + default: + { + bool isDraggingAnchorables = _floatingWindow.Model is LayoutAnchorableFloatingWindow; + if( isDraggingAnchorables && _gridDocumentPaneFullDropTargets != null ) + areaElement = _gridDocumentPaneFullDropTargets; + else + areaElement = _gridDocumentPaneDropTargets; + } + break; + } - void IOverlayWindow.DragLeave(IDropTarget target) - { - _previewBox.Visibility = System.Windows.Visibility.Hidden; - } + areaElement.Visibility = System.Windows.Visibility.Hidden; + } - void IOverlayWindow.DragDrop(IDropTarget target) - { - target.Drop(_floatingWindow.Model as LayoutFloatingWindow); - } + void IOverlayWindow.DragEnter( IDropTarget target ) + { + var previewBoxPath = target.GetPreviewPath( this, _floatingWindow.Model as LayoutFloatingWindow ); + if( previewBoxPath != null ) + { + _previewBox.Data = previewBoxPath; + _previewBox.Visibility = System.Windows.Visibility.Visible; + } + } + void IOverlayWindow.DragLeave( IDropTarget target ) + { + _previewBox.Visibility = System.Windows.Visibility.Hidden; + } + void IOverlayWindow.DragDrop( IDropTarget target ) + { + target.Drop( _floatingWindow.Model as LayoutFloatingWindow ); } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindowDropTarget.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindowDropTarget.cs index 50b0468d..f84f87af 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindowDropTarget.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindowDropTarget.cs @@ -14,42 +14,51 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Controls; using System.Windows; namespace Xceed.Wpf.AvalonDock.Controls { - public class OverlayWindowDropTarget : IOverlayWindowDropTarget + public class OverlayWindowDropTarget : IOverlayWindowDropTarget + { + #region Members + + private IOverlayWindowArea _overlayArea; + private Rect _screenDetectionArea; + private OverlayWindowDropTargetType _type; + + #endregion + + #region Constructors + + internal OverlayWindowDropTarget( IOverlayWindowArea overlayArea, OverlayWindowDropTargetType targetType, FrameworkElement element ) { - internal OverlayWindowDropTarget(IOverlayWindowArea overlayArea, OverlayWindowDropTargetType targetType, FrameworkElement element) - { - _overlayArea = overlayArea; - _type = targetType; - _screenDetectionArea = new Rect(element.TransformToDeviceDPI(new Point()), element.TransformActualSizeToAncestor()); - } + _overlayArea = overlayArea; + _type = targetType; + _screenDetectionArea = new Rect( element.TransformToDeviceDPI( new Point() ), element.TransformActualSizeToAncestor() ); + } - IOverlayWindowArea _overlayArea; + #endregion - Rect _screenDetectionArea; - Rect IOverlayWindowDropTarget.ScreenDetectionArea - { - get - { - return _screenDetectionArea; - } - } + #region IOverlayWindowDropTarget - OverlayWindowDropTargetType _type; - OverlayWindowDropTargetType IOverlayWindowDropTarget.Type - { - get { return _type; } - } + Rect IOverlayWindowDropTarget.ScreenDetectionArea + { + get + { + return _screenDetectionArea; + } + } + OverlayWindowDropTargetType IOverlayWindowDropTarget.Type + { + get + { + return _type; + } } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindowDropTargetType.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindowDropTargetType.cs index 72e7a8c6..38019274 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindowDropTargetType.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindowDropTargetType.cs @@ -14,31 +14,26 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - namespace Xceed.Wpf.AvalonDock.Controls { - public enum OverlayWindowDropTargetType - { - DockingManagerDockLeft, - DockingManagerDockTop, - DockingManagerDockRight, - DockingManagerDockBottom, - - DocumentPaneDockLeft, - DocumentPaneDockTop, - DocumentPaneDockRight, - DocumentPaneDockBottom, - DocumentPaneDockInside, - - AnchorablePaneDockLeft, - AnchorablePaneDockTop, - AnchorablePaneDockRight, - AnchorablePaneDockBottom, - AnchorablePaneDockInside, - - } + public enum OverlayWindowDropTargetType + { + DockingManagerDockLeft, + DockingManagerDockTop, + DockingManagerDockRight, + DockingManagerDockBottom, + + DocumentPaneDockLeft, + DocumentPaneDockTop, + DocumentPaneDockRight, + DocumentPaneDockBottom, + DocumentPaneDockInside, + + AnchorablePaneDockLeft, + AnchorablePaneDockTop, + AnchorablePaneDockRight, + AnchorablePaneDockBottom, + AnchorablePaneDockInside, + + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/ReentrantFlag.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/ReentrantFlag.cs index d37b569d..9da6440d 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/ReentrantFlag.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/ReentrantFlag.cs @@ -15,42 +15,57 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Xceed.Wpf.AvalonDock.Controls { - class ReentrantFlag + internal class ReentrantFlag + { + #region Members + + private bool _flag = false; + + #endregion + + #region Properties + + public bool CanEnter { - public class _ReentrantFlagHandler : IDisposable - { - ReentrantFlag _owner; - public _ReentrantFlagHandler(ReentrantFlag owner) - { - _owner = owner; - _owner._flag = true; - } - - public void Dispose() - { - _owner._flag = false; - } - } - - bool _flag = false; - - public _ReentrantFlagHandler Enter() - { - if (_flag) - throw new InvalidOperationException(); - return new _ReentrantFlagHandler(this); - } - - public bool CanEnter - { - get { return !_flag; } - } + get + { + return !_flag; + } + } + + #endregion + #region Public Methods + + public _ReentrantFlagHandler Enter() + { + if( _flag ) + throw new InvalidOperationException(); + return new _ReentrantFlagHandler( this ); } + + #endregion + + #region Internal Classes + + public class _ReentrantFlagHandler : IDisposable + { + private ReentrantFlag _owner; + public _ReentrantFlagHandler( ReentrantFlag owner ) + { + _owner = owner; + _owner._flag = true; + } + + public void Dispose() + { + _owner._flag = false; + } + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/ComGuids.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/ComGuids.cs index c84fbb18..b2890ef8 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/ComGuids.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/ComGuids.cs @@ -20,92 +20,92 @@ namespace Standard { - internal static partial class IID + internal static partial class IID + { + /// IID_IEnumIDList + public const string EnumIdList = "000214F2-0000-0000-C000-000000000046"; + /// IID_IEnumObjects + public const string EnumObjects = "2c1c7e2e-2d0e-4059-831e-1e6f82335c2e"; + /// IID_IHTMLDocument2 + public const string HtmlDocument2 = "332C4425-26CB-11D0-B483-00C04FD90119"; + /// IID_IModalWindow + public const string ModalWindow = "b4db1657-70d7-485e-8e3e-6fcb5a5c1802"; + /// IID_IObjectArray + public const string ObjectArray = "92CA9DCD-5622-4bba-A805-5E9F541BD8C9"; + /// IID_IObjectCollection + public const string ObjectCollection = "5632b1a4-e38a-400a-928a-d4cd63230295"; + /// IID_IPropertyNotifySink + public const string PropertyNotifySink = "9BFBBC02-EFF1-101A-84ED-00AA00341D07"; + /// IID_IPropertyStore + public const string PropertyStore = "886d8eeb-8cf2-4446-8d02-cdba1dbdcf99"; + /// IID_IServiceProvider + public const string ServiceProvider = "6d5140c1-7436-11ce-8034-00aa006009fa"; + /// IID_IShellFolder + public const string ShellFolder = "000214E6-0000-0000-C000-000000000046"; + /// IID_IShellLink + public const string ShellLink = "000214F9-0000-0000-C000-000000000046"; + /// IID_IShellItem + public const string ShellItem = "43826d1e-e718-42ee-bc55-a1e261c37bfe"; + /// IID_IShellItem2 + public const string ShellItem2 = "7e9fb0d3-919f-4307-ab2e-9b1860310c93"; + /// IID_IShellItemArray + public const string ShellItemArray = "B63EA76D-1F85-456F-A19C-48159EFA858B"; + /// IID_ITaskbarList + public const string TaskbarList = "56FDF342-FD6D-11d0-958A-006097C9A090"; + /// IID_ITaskbarList2 + public const string TaskbarList2 = "602D4995-B13A-429b-A66E-1935E44F4317"; + /// IID_IUnknown + public const string Unknown = "00000000-0000-0000-C000-000000000046"; + + #region Win7 IIDs + + /// IID_IApplicationDestinations + public const string ApplicationDestinations = "12337d35-94c6-48a0-bce7-6a9c69d4d600"; + /// IID_IApplicationDocumentLists + public const string ApplicationDocumentLists = "3c594f9f-9f30-47a1-979a-c9e83d3d0a06"; + /// IID_ICustomDestinationList + public const string CustomDestinationList = "6332debf-87b5-4670-90c0-5e57b408a49e"; + /// IID_IObjectWithAppUserModelID + public const string ObjectWithAppUserModelId = "36db0196-9665-46d1-9ba7-d3709eecf9ed"; + /// IID_IObjectWithProgID + public const string ObjectWithProgId = "71e806fb-8dee-46fc-bf8c-7748a8a1ae13"; + /// IID_ITaskbarList3 + public const string TaskbarList3 = "ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf"; + /// IID_ITaskbarList4 + public const string TaskbarList4 = "c43dc798-95d1-4bea-9030-bb99e2983a1a"; + + #endregion + } + + internal static partial class CLSID + { + public static T CoCreateInstance( string clsid ) { - /// IID_IEnumIDList - public const string EnumIdList = "000214F2-0000-0000-C000-000000000046"; - /// IID_IEnumObjects - public const string EnumObjects = "2c1c7e2e-2d0e-4059-831e-1e6f82335c2e"; - /// IID_IHTMLDocument2 - public const string HtmlDocument2 = "332C4425-26CB-11D0-B483-00C04FD90119"; - /// IID_IModalWindow - public const string ModalWindow = "b4db1657-70d7-485e-8e3e-6fcb5a5c1802"; - /// IID_IObjectArray - public const string ObjectArray = "92CA9DCD-5622-4bba-A805-5E9F541BD8C9"; - /// IID_IObjectCollection - public const string ObjectCollection = "5632b1a4-e38a-400a-928a-d4cd63230295"; - /// IID_IPropertyNotifySink - public const string PropertyNotifySink = "9BFBBC02-EFF1-101A-84ED-00AA00341D07"; - /// IID_IPropertyStore - public const string PropertyStore = "886d8eeb-8cf2-4446-8d02-cdba1dbdcf99"; - /// IID_IServiceProvider - public const string ServiceProvider = "6d5140c1-7436-11ce-8034-00aa006009fa"; - /// IID_IShellFolder - public const string ShellFolder = "000214E6-0000-0000-C000-000000000046"; - /// IID_IShellLink - public const string ShellLink = "000214F9-0000-0000-C000-000000000046"; - /// IID_IShellItem - public const string ShellItem = "43826d1e-e718-42ee-bc55-a1e261c37bfe"; - /// IID_IShellItem2 - public const string ShellItem2 = "7e9fb0d3-919f-4307-ab2e-9b1860310c93"; - /// IID_IShellItemArray - public const string ShellItemArray = "B63EA76D-1F85-456F-A19C-48159EFA858B"; - /// IID_ITaskbarList - public const string TaskbarList = "56FDF342-FD6D-11d0-958A-006097C9A090"; - /// IID_ITaskbarList2 - public const string TaskbarList2 = "602D4995-B13A-429b-A66E-1935E44F4317"; - /// IID_IUnknown - public const string Unknown = "00000000-0000-0000-C000-000000000046"; - - #region Win7 IIDs - - /// IID_IApplicationDestinations - public const string ApplicationDestinations = "12337d35-94c6-48a0-bce7-6a9c69d4d600"; - /// IID_IApplicationDocumentLists - public const string ApplicationDocumentLists = "3c594f9f-9f30-47a1-979a-c9e83d3d0a06"; - /// IID_ICustomDestinationList - public const string CustomDestinationList = "6332debf-87b5-4670-90c0-5e57b408a49e"; - /// IID_IObjectWithAppUserModelID - public const string ObjectWithAppUserModelId = "36db0196-9665-46d1-9ba7-d3709eecf9ed"; - /// IID_IObjectWithProgID - public const string ObjectWithProgId = "71e806fb-8dee-46fc-bf8c-7748a8a1ae13"; - /// IID_ITaskbarList3 - public const string TaskbarList3 = "ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf"; - /// IID_ITaskbarList4 - public const string TaskbarList4 = "c43dc798-95d1-4bea-9030-bb99e2983a1a"; - - #endregion + return ( T )System.Activator.CreateInstance( System.Type.GetTypeFromCLSID( new System.Guid( clsid ) ) ); } - internal static partial class CLSID - { - public static T CoCreateInstance(string clsid) - { - return (T)System.Activator.CreateInstance(System.Type.GetTypeFromCLSID(new System.Guid(clsid))); - } - - /// CLSID_TaskbarList - /// IID_ITaskbarList - public const string TaskbarList = "56FDF344-FD6D-11d0-958A-006097C9A090"; - /// CLSID_EnumerableObjectCollection - /// IID_IEnumObjects. - public const string EnumerableObjectCollection = "2d3468c1-36a7-43b6-ac24-d3f02fd9607a"; - /// CLSID_ShellLink - /// IID_IShellLink - public const string ShellLink = "00021401-0000-0000-C000-000000000046"; - - #region Win7 CLSIDs - - /// CLSID_DestinationList - /// IID_ICustomDestinationList - public const string DestinationList = "77f10cf0-3db5-4966-b520-b7c54fd35ed6"; - /// CLSID_ApplicationDestinations - /// IID_IApplicationDestinations - public const string ApplicationDestinations = "86c14003-4d6b-4ef3-a7b4-0506663b2e68"; - /// CLSID_ApplicationDocumentLists - /// IID_IApplicationDocumentLists - public const string ApplicationDocumentLists = "86bec222-30f2-47e0-9f25-60d11cd75c28"; - - #endregion - } + /// CLSID_TaskbarList + /// IID_ITaskbarList + public const string TaskbarList = "56FDF344-FD6D-11d0-958A-006097C9A090"; + /// CLSID_EnumerableObjectCollection + /// IID_IEnumObjects. + public const string EnumerableObjectCollection = "2d3468c1-36a7-43b6-ac24-d3f02fd9607a"; + /// CLSID_ShellLink + /// IID_IShellLink + public const string ShellLink = "00021401-0000-0000-C000-000000000046"; + + #region Win7 CLSIDs + + /// CLSID_DestinationList + /// IID_ICustomDestinationList + public const string DestinationList = "77f10cf0-3db5-4966-b520-b7c54fd35ed6"; + /// CLSID_ApplicationDestinations + /// IID_IApplicationDestinations + public const string ApplicationDestinations = "86c14003-4d6b-4ef3-a7b4-0506663b2e68"; + /// CLSID_ApplicationDocumentLists + /// IID_IApplicationDocumentLists + public const string ApplicationDocumentLists = "86bec222-30f2-47e0-9f25-60d11cd75c28"; + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/Debug.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/Debug.cs index fb4dd759..29f1dd8b 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/Debug.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/Debug.cs @@ -29,361 +29,361 @@ // might be included in multiple assemblies. namespace Standard { - using System; - using System.Diagnostics; - using System.Threading; - - /// A static class for verifying assumptions. - internal static class Assert + using System; + using System.Diagnostics; + using System.Threading; + + /// A static class for verifying assumptions. + internal static class Assert + { + private static void _Break() { - private static void _Break() - { #if DEV_DEBUG - Debugger.Break(); + Debugger.Break(); #else Debug.Assert(false); #endif - } + } - /// A function signature for Assert.Evaluate. - public delegate void EvaluateFunction(); + /// A function signature for Assert.Evaluate. + public delegate void EvaluateFunction(); - /// A function signature for Assert.Implies. - /// Returns the truth of a predicate. - public delegate bool ImplicationFunction(); + /// A function signature for Assert.Implies. + /// Returns the truth of a predicate. + public delegate bool ImplicationFunction(); - /// - /// Executes the specified argument. - /// - /// The function to execute. - [Conditional("DEBUG")] - public static void Evaluate(EvaluateFunction argument) - { - IsNotNull(argument); - argument(); - } + /// + /// Executes the specified argument. + /// + /// The function to execute. + [Conditional( "DEBUG" )] + public static void Evaluate( EvaluateFunction argument ) + { + IsNotNull( argument ); + argument(); + } - /// Obsolete: Use Standard.Assert.AreEqual instead of Assert.Equals - /// The generic type to compare for equality. - /// The first generic type data to compare. This is is the expected value. - /// The second generic type data to compare. This is the actual value. - [ - Obsolete("Use Assert.AreEqual instead of Assert.Equals", false), - Conditional("DEBUG") - ] - public static void Equals(T expected, T actual) - { - AreEqual(expected, actual); - } + /// Obsolete: Use Standard.Assert.AreEqual instead of Assert.Equals + /// The generic type to compare for equality. + /// The first generic type data to compare. This is is the expected value. + /// The second generic type data to compare. This is the actual value. + [ + Obsolete( "Use Assert.AreEqual instead of Assert.Equals", false ), + Conditional( "DEBUG" ) + ] + public static void Equals( T expected, T actual ) + { + AreEqual( expected, actual ); + } - /// - /// Verifies that two generic type data are equal. The assertion fails if they are not. - /// - /// The generic type to compare for equality. - /// The first generic type data to compare. This is is the expected value. - /// The second generic type data to compare. This is the actual value. - /// This breaks into the debugger in the case of a failed assertion. - [Conditional("DEBUG")] - public static void AreEqual(T expected, T actual) + /// + /// Verifies that two generic type data are equal. The assertion fails if they are not. + /// + /// The generic type to compare for equality. + /// The first generic type data to compare. This is is the expected value. + /// The second generic type data to compare. This is the actual value. + /// This breaks into the debugger in the case of a failed assertion. + [Conditional( "DEBUG" )] + public static void AreEqual( T expected, T actual ) + { + if( null == expected ) + { + // Two nulls are considered equal, regardless of type semantics. + if( null != actual && !actual.Equals( expected ) ) { - 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(); - } + _Break(); } + } + else if( !expected.Equals( actual ) ) + { + _Break(); + } + } - /// - /// Verifies that two generic type data are not equal. The assertion fails if they are. - /// - /// The generic type to compare for inequality. - /// The first generic type data to compare. This is is the value that's not expected. - /// The second generic type data to compare. This is the actual value. - /// This breaks into the debugger in the case of a failed assertion. - [Conditional("DEBUG")] - public static void AreNotEqual(T notExpected, T actual) + /// + /// Verifies that two generic type data are not equal. The assertion fails if they are. + /// + /// The generic type to compare for inequality. + /// The first generic type data to compare. This is is the value that's not expected. + /// The second generic type data to compare. This is the actual value. + /// This breaks into the debugger in the case of a failed assertion. + [Conditional( "DEBUG" )] + public static void AreNotEqual( T notExpected, T actual ) + { + if( null == notExpected ) + { + // Two nulls are considered equal, regardless of type semantics. + if( null == actual || actual.Equals( notExpected ) ) { - 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(); - } + _Break(); } + } + else if( notExpected.Equals( actual ) ) + { + _Break(); + } + } - /// - /// 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. - /// - /// if set to true [condition]. - /// - /// 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. - /// - /// This breaks into the debugger in the case of a failed assertion. - [Conditional("DEBUG")] - public static void Implies(bool condition, bool result) - { - if (condition && !result) - { - _Break(); - } - } + /// + /// 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. + /// + /// if set to true [condition]. + /// + /// 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. + /// + /// This breaks into the debugger in the case of a failed assertion. + [Conditional( "DEBUG" )] + public static void Implies( bool condition, bool result ) + { + if( condition && !result ) + { + _Break(); + } + } - /// - /// Lazy evaluation overload. Verifies that if a condition is true, then so is a secondary value. - /// - /// The conditional value. - /// A function to be evaluated for truth if the condition argument is true. - /// - /// This overload only evaluates the result if the first condition is true. - /// - [Conditional("DEBUG")] - public static void Implies(bool condition, ImplicationFunction result) - { - if (condition && !result()) - { - _Break(); - } - } + /// + /// Lazy evaluation overload. Verifies that if a condition is true, then so is a secondary value. + /// + /// The conditional value. + /// A function to be evaluated for truth if the condition argument is true. + /// + /// This overload only evaluates the result if the first condition is true. + /// + [Conditional( "DEBUG" )] + public static void Implies( bool condition, ImplicationFunction result ) + { + if( condition && !result() ) + { + _Break(); + } + } - /// - /// Verifies that a string has content. I.e. it is not null and it is not empty. - /// - /// The string to verify. - [Conditional("DEBUG")] - public static void IsNeitherNullNorEmpty(string value) - { - IsFalse(string.IsNullOrEmpty(value)); - } + /// + /// Verifies that a string has content. I.e. it is not null and it is not empty. + /// + /// The string to verify. + [Conditional( "DEBUG" )] + public static void IsNeitherNullNorEmpty( string value ) + { + IsFalse( string.IsNullOrEmpty( value ) ); + } - /// - /// Verifies that a string has content. I.e. it is not null and it is not purely whitespace. - /// - /// The string to verify. - [Conditional("DEBUG")] - public static void IsNeitherNullNorWhitespace(string value) - { - if (string.IsNullOrEmpty(value)) - { - _Break(); - } - - if (value.Trim().Length == 0) - { - _Break(); - } - } + /// + /// Verifies that a string has content. I.e. it is not null and it is not purely whitespace. + /// + /// The string to verify. + [Conditional( "DEBUG" )] + public static void IsNeitherNullNorWhitespace( string value ) + { + if( string.IsNullOrEmpty( value ) ) + { + _Break(); + } + + if( value.Trim().Length == 0 ) + { + _Break(); + } + } - /// - /// Verifies the specified value is not null. The assertion fails if it is. - /// - /// The generic reference type. - /// The value to check for nullness. - /// This breaks into the debugger in the case of a failed assertion. - [Conditional("DEBUG")] - public static void IsNotNull(T value) where T : class - { - if (null == value) - { - _Break(); - } - } + /// + /// Verifies the specified value is not null. The assertion fails if it is. + /// + /// The generic reference type. + /// The value to check for nullness. + /// This breaks into the debugger in the case of a failed assertion. + [Conditional( "DEBUG" )] + public static void IsNotNull( T value ) where T : class + { + if( null == value ) + { + _Break(); + } + } - [Conditional("DEBUG")] - public static void IsDefault(T value) where T : struct - { - if (!value.Equals(default(T))) - { - Assert.Fail(); - } - } + [Conditional( "DEBUG" )] + public static void IsDefault( T value ) where T : struct + { + if( !value.Equals( default( T ) ) ) + { + Assert.Fail(); + } + } - [Conditional("DEBUG")] - public static void IsNotDefault(T value) where T : struct - { - if (value.Equals(default(T))) - { - Assert.Fail(); - } - } + [Conditional( "DEBUG" )] + public static void IsNotDefault( T value ) where T : struct + { + if( value.Equals( default( T ) ) ) + { + Assert.Fail(); + } + } - /// - /// Verifies that the specified condition is false. The assertion fails if it is true. - /// - /// The expression that should be false. - /// This breaks into the debugger in the case of a failed assertion. - [Conditional("DEBUG")] - public static void IsFalse(bool condition) - { - if (condition) - { - _Break(); - } - } + /// + /// Verifies that the specified condition is false. The assertion fails if it is true. + /// + /// The expression that should be false. + /// This breaks into the debugger in the case of a failed assertion. + [Conditional( "DEBUG" )] + public static void IsFalse( bool condition ) + { + if( condition ) + { + _Break(); + } + } - /// - /// Verifies that the specified condition is false. The assertion fails if it is true. - /// - /// The expression that should be false. - /// The message to display if the condition is true. - /// This breaks into the debugger in the case of a failed assertion. - [Conditional("DEBUG")] - public static void IsFalse(bool condition, string message) - { - if (condition) - { - _Break(); - } - } + /// + /// Verifies that the specified condition is false. The assertion fails if it is true. + /// + /// The expression that should be false. + /// The message to display if the condition is true. + /// This breaks into the debugger in the case of a failed assertion. + [Conditional( "DEBUG" )] + public static void IsFalse( bool condition, string message ) + { + if( condition ) + { + _Break(); + } + } - /// - /// Verifies that the specified condition is true. The assertion fails if it is not. - /// - /// A condition that is expected to be true. - /// This breaks into the debugger in the case of a failed assertion. - [Conditional("DEBUG")] - public static void IsTrue(bool condition) - { - if (!condition) - { - _Break(); - } - } + /// + /// Verifies that the specified condition is true. The assertion fails if it is not. + /// + /// A condition that is expected to be true. + /// This breaks into the debugger in the case of a failed assertion. + [Conditional( "DEBUG" )] + public static void IsTrue( bool condition ) + { + if( !condition ) + { + _Break(); + } + } - /// - /// Verifies that the specified condition is true. The assertion fails if it is not. - /// - /// A condition that is expected to be true. - /// The message to write in case the condition is false. - /// This breaks into the debugger in the case of a failed assertion. - [Conditional("DEBUG")] - public static void IsTrue(bool condition, string message) - { - if (!condition) - { - _Break(); - } - } + /// + /// Verifies that the specified condition is true. The assertion fails if it is not. + /// + /// A condition that is expected to be true. + /// The message to write in case the condition is false. + /// This breaks into the debugger in the case of a failed assertion. + [Conditional( "DEBUG" )] + public static void IsTrue( bool condition, string message ) + { + if( !condition ) + { + _Break(); + } + } - /// - /// This line should never be executed. The assertion always fails. - /// - /// This breaks into the debugger in the case of a failed assertion. - [Conditional("DEBUG")] - public static void Fail() - { - _Break(); - } + /// + /// This line should never be executed. The assertion always fails. + /// + /// This breaks into the debugger in the case of a failed assertion. + [Conditional( "DEBUG" )] + public static void Fail() + { + _Break(); + } - /// - /// This line should never be executed. The assertion always fails. - /// - /// The message to display if this function is executed. - /// This breaks into the debugger in the case of a failed assertion. - [Conditional("DEBUG")] - public static void Fail(string message) - { - _Break(); - } + /// + /// This line should never be executed. The assertion always fails. + /// + /// The message to display if this function is executed. + /// This breaks into the debugger in the case of a failed assertion. + [Conditional( "DEBUG" )] + public static void Fail( string message ) + { + _Break(); + } - /// - /// Verifies that the specified object is null. The assertion fails if it is not. - /// - /// The item to verify is null. - [Conditional("DEBUG")] - public static void IsNull(T item) where T : class - { - if (null != item) - { - _Break(); - } - } + /// + /// Verifies that the specified object is null. The assertion fails if it is not. + /// + /// The item to verify is null. + [Conditional( "DEBUG" )] + public static void IsNull( T item ) where T : class + { + if( null != item ) + { + _Break(); + } + } - /// - /// Verifies that the specified value is within the expected range. The assertion fails if it isn't. - /// - /// The lower bound inclusive value. - /// The value to verify. - /// The upper bound inclusive value. - [Conditional("DEBUG")] - public static void BoundedDoubleInc(double lowerBoundInclusive, double value, double upperBoundInclusive) - { - if (value < lowerBoundInclusive || value > upperBoundInclusive) - { - _Break(); - } - } + /// + /// Verifies that the specified value is within the expected range. The assertion fails if it isn't. + /// + /// The lower bound inclusive value. + /// The value to verify. + /// The upper bound inclusive value. + [Conditional( "DEBUG" )] + public static void BoundedDoubleInc( double lowerBoundInclusive, double value, double upperBoundInclusive ) + { + if( value < lowerBoundInclusive || value > upperBoundInclusive ) + { + _Break(); + } + } - /// - /// Verifies that the specified value is within the expected range. The assertion fails if it isn't. - /// - /// The lower bound inclusive value. - /// The value to verify. - /// The upper bound exclusive value. - [Conditional("DEBUG")] - public static void BoundedInteger(int lowerBoundInclusive, int value, int upperBoundExclusive) - { - if (value < lowerBoundInclusive || value >= upperBoundExclusive) - { - _Break(); - } - } + /// + /// Verifies that the specified value is within the expected range. The assertion fails if it isn't. + /// + /// The lower bound inclusive value. + /// The value to verify. + /// The upper bound exclusive value. + [Conditional( "DEBUG" )] + public static void BoundedInteger( int lowerBoundInclusive, int value, int upperBoundExclusive ) + { + if( value < lowerBoundInclusive || value >= upperBoundExclusive ) + { + _Break(); + } + } - /// - /// Verify the current thread's apartment state is what's expected. The assertion fails if it isn't - /// - /// - /// The expected apartment state for the current thread. - /// - /// This breaks into the debugger in the case of a failed assertion. - [Conditional("DEBUG")] - public static void IsApartmentState(ApartmentState expectedState) - { - if (Thread.CurrentThread.GetApartmentState() != expectedState) - { - _Break(); - } - } + /// + /// Verify the current thread's apartment state is what's expected. The assertion fails if it isn't + /// + /// + /// The expected apartment state for the current thread. + /// + /// This breaks into the debugger in the case of a failed assertion. + [Conditional( "DEBUG" )] + public static void IsApartmentState( ApartmentState expectedState ) + { + if( Thread.CurrentThread.GetApartmentState() != expectedState ) + { + _Break(); + } + } - [Conditional("DEBUG")] - public static void NullableIsNotNull(T? value) where T : struct - { - if (null == value) - { - _Break(); - } - } + [Conditional( "DEBUG" )] + public static void NullableIsNotNull( T? value ) where T : struct + { + if( null == value ) + { + _Break(); + } + } - [Conditional("DEBUG")] - public static void NullableIsNull(T? value) where T : struct - { - if (null != value) - { - _Break(); - } - } + [Conditional( "DEBUG" )] + public static void NullableIsNull( T? value ) where T : struct + { + if( null != value ) + { + _Break(); + } + } - [Conditional("DEBUG")] - public static void IsNotOnMainThread() - { - if (System.Windows.Application.Current.Dispatcher.CheckAccess()) - { - _Break(); - } - } + [Conditional( "DEBUG" )] + public static void IsNotOnMainThread() + { + if( System.Windows.Application.Current.Dispatcher.CheckAccess() ) + { + _Break(); + } } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/DoubleUtil.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/DoubleUtil.cs index 29e25ee5..d4a955bc 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/DoubleUtil.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/DoubleUtil.cs @@ -17,132 +17,132 @@ namespace Standard { - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; + + /// + /// 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. + /// + internal static class DoubleUtilities + { + /// + /// Epsilon - more or less random, more or less small number. + /// + private const double Epsilon = 0.00000153; + + /// + /// 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. + /// + /// The first double to compare. + /// The second double to compare. + /// The result of the AreClose comparision. + [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 ); + } + + /// + /// 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. + /// + /// The first double to compare. + /// The second double to compare. + /// The result of the LessThan comparision. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool LessThan( double value1, double value2 ) + { + return ( value1 < value2 ) && !AreClose( value1, value2 ); + } + + /// + /// 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. + /// + /// The first double to compare. + /// The second double to compare. + /// The result of the GreaterThan comparision. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool GreaterThan( double value1, double value2 ) + { + return ( value1 > value2 ) && !AreClose( value1, value2 ); + } + + /// + /// 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. + /// + /// The first double to compare. + /// The second double to compare. + /// The result of the LessThanOrClose comparision. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool LessThanOrClose( double value1, double value2 ) + { + return ( value1 < value2 ) || AreClose( value1, value2 ); + } + + /// + /// 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. + /// + /// The first double to compare. + /// The second double to compare. + /// The result of the GreaterThanOrClose comparision. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool GreaterThanOrClose( double value1, double value2 ) + { + return ( value1 > value2 ) || AreClose( value1, value2 ); + } + + /// + /// Test to see if a double is a finite number (is not NaN or Infinity). + /// + /// The value to test. + /// Whether or not the value is a finite number. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool IsFinite( double value ) + { + return !double.IsNaN( value ) && !double.IsInfinity( value ); + } /// - /// 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. + /// Test to see if a double a valid size value (is finite and > 0). /// - internal static class DoubleUtilities + /// The value to test. + /// Whether or not the value is a valid size value. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool IsValidSize( double value ) { - /// - /// Epsilon - more or less random, more or less small number. - /// - private const double Epsilon = 0.00000153; - - /// - /// 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. - /// - /// The first double to compare. - /// The second double to compare. - /// The result of the AreClose comparision. - [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); - } - - /// - /// 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. - /// - /// The first double to compare. - /// The second double to compare. - /// The result of the LessThan comparision. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool LessThan(double value1, double value2) - { - return (value1 < value2) && !AreClose(value1, value2); - } - - /// - /// 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. - /// - /// The first double to compare. - /// The second double to compare. - /// The result of the GreaterThan comparision. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool GreaterThan(double value1, double value2) - { - return (value1 > value2) && !AreClose(value1, value2); - } - - /// - /// 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. - /// - /// The first double to compare. - /// The second double to compare. - /// The result of the LessThanOrClose comparision. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool LessThanOrClose(double value1, double value2) - { - return (value1 < value2) || AreClose(value1, value2); - } - - /// - /// 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. - /// - /// The first double to compare. - /// The second double to compare. - /// The result of the GreaterThanOrClose comparision. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool GreaterThanOrClose(double value1, double value2) - { - return (value1 > value2) || AreClose(value1, value2); - } - - /// - /// Test to see if a double is a finite number (is not NaN or Infinity). - /// - /// The value to test. - /// Whether or not the value is a finite number. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool IsFinite(double value) - { - return !double.IsNaN(value) && !double.IsInfinity(value); - } - - /// - /// Test to see if a double a valid size value (is finite and > 0). - /// - /// The value to test. - /// Whether or not the value is a valid size value. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool IsValidSize(double value) - { - return IsFinite(value) && GreaterThanOrClose(value, 0); - } + return IsFinite( value ) && GreaterThanOrClose( value, 0 ); } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/DpiHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/DpiHelper.cs index 98398098..3f056311 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/DpiHelper.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/DpiHelper.cs @@ -20,83 +20,82 @@ namespace Standard { - using System; - using System.Diagnostics.CodeAnalysis; - using System.Windows; - using System.Windows.Media; + using System.Diagnostics.CodeAnalysis; + using System.Windows; + using System.Windows.Media; - internal static class DpiHelper + 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 ); + } + } + + /// + /// Convert a point in device independent pixels (1/96") to a point in the system coordinates. + /// + /// A point in the logical coordinate system. + /// Returns the parameter converted to the system's coordinates. + public static Point LogicalPixelsToDevice( Point logicalPoint ) + { + return _transformToDevice.Transform( logicalPoint ); + } + + /// + /// Convert a point in system coordinates to a point in device independent pixels (1/96"). + /// + /// A point in the physical coordinate system. + /// Returns the parameter converted to the device independent coordinate system. + public static Point DevicePixelsToLogical( Point devicePoint ) + { + return _transformToDip.Transform( devicePoint ); + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static Rect LogicalRectToDevice( Rect logicalRectangle ) { - 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); - } - } - - /// - /// Convert a point in device independent pixels (1/96") to a point in the system coordinates. - /// - /// A point in the logical coordinate system. - /// Returns the parameter converted to the system's coordinates. - public static Point LogicalPixelsToDevice(Point logicalPoint) - { - return _transformToDevice.Transform(logicalPoint); - } - - /// - /// Convert a point in system coordinates to a point in device independent pixels (1/96"). - /// - /// A point in the physical coordinate system. - /// Returns the parameter converted to the device independent coordinate system. - 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); - } + 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 ); } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/ErrorCodes.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/ErrorCodes.cs index 24e9fb5a..c58f5321 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/ErrorCodes.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/ErrorCodes.cs @@ -20,505 +20,511 @@ namespace Standard { - using System; - using System.ComponentModel; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Reflection; - using System.Runtime.InteropServices; + using System; + using System.ComponentModel; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.Reflection; + using System.Runtime.InteropServices; + + /// + /// Wrapper for common Win32 status codes. + /// + [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. + + /// The operation completed successfully. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_SUCCESS = new Win32Error( 0 ); + /// Incorrect function. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_INVALID_FUNCTION = new Win32Error( 1 ); + /// The system cannot find the file specified. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_FILE_NOT_FOUND = new Win32Error( 2 ); + /// The system cannot find the path specified. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_PATH_NOT_FOUND = new Win32Error( 3 ); + /// The system cannot open the file. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_TOO_MANY_OPEN_FILES = new Win32Error( 4 ); + /// Access is denied. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_ACCESS_DENIED = new Win32Error( 5 ); + /// The handle is invalid. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_INVALID_HANDLE = new Win32Error( 6 ); + /// Not enough storage is available to complete this operation. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_OUTOFMEMORY = new Win32Error( 14 ); + /// There are no more files. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_NO_MORE_FILES = new Win32Error( 18 ); + /// The process cannot access the file because it is being used by another process. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_SHARING_VIOLATION = new Win32Error( 32 ); + /// The parameter is incorrect. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_INVALID_PARAMETER = new Win32Error( 87 ); + /// The data area passed to a system call is too small. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_INSUFFICIENT_BUFFER = new Win32Error( 122 ); + /// Cannot nest calls to LoadModule. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_NESTING_NOT_ALLOWED = new Win32Error( 215 ); + /// Illegal operation attempted on a registry key that has been marked for deletion. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_KEY_DELETED = new Win32Error( 1018 ); + /// Element not found. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_NOT_FOUND = new Win32Error( 1168 ); + /// There was no match for the specified key in the index. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_NO_MATCH = new Win32Error( 1169 ); + /// An invalid device was specified. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_BAD_DEVICE = new Win32Error( 1200 ); + /// The operation was canceled by the user. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_CANCELLED = new Win32Error( 1223 ); + /// The window class was already registered. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_CLASS_ALREADY_EXISTS = new Win32Error( 1410 ); + /// The specified datatype is invalid. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly Win32Error ERROR_INVALID_DATATYPE = new Win32Error( 1804 ); /// - /// Wrapper for common Win32 status codes. + /// Create a new Win32 error. /// - [StructLayout(LayoutKind.Explicit)] - internal struct Win32Error + /// The integer value of the error. + public Win32Error( int i ) { - [FieldOffset(0)] - private readonly int _value; - - // NOTE: These public static field declarations are automatically - // picked up by (HRESULT's) ToString through reflection. - - /// The operation completed successfully. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_SUCCESS = new Win32Error(0); - /// Incorrect function. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_INVALID_FUNCTION = new Win32Error(1); - /// The system cannot find the file specified. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_FILE_NOT_FOUND = new Win32Error(2); - /// The system cannot find the path specified. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_PATH_NOT_FOUND = new Win32Error(3); - /// The system cannot open the file. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_TOO_MANY_OPEN_FILES = new Win32Error(4); - /// Access is denied. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_ACCESS_DENIED = new Win32Error(5); - /// The handle is invalid. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_INVALID_HANDLE = new Win32Error(6); - /// Not enough storage is available to complete this operation. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_OUTOFMEMORY = new Win32Error(14); - /// There are no more files. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_NO_MORE_FILES = new Win32Error(18); - /// The process cannot access the file because it is being used by another process. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_SHARING_VIOLATION = new Win32Error(32); - /// The parameter is incorrect. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_INVALID_PARAMETER = new Win32Error(87); - /// The data area passed to a system call is too small. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_INSUFFICIENT_BUFFER = new Win32Error(122); - /// Cannot nest calls to LoadModule. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_NESTING_NOT_ALLOWED = new Win32Error(215); - /// Illegal operation attempted on a registry key that has been marked for deletion. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_KEY_DELETED = new Win32Error(1018); - /// Element not found. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_NOT_FOUND = new Win32Error(1168); - /// There was no match for the specified key in the index. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_NO_MATCH = new Win32Error(1169); - /// An invalid device was specified. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_BAD_DEVICE = new Win32Error(1200); - /// The operation was canceled by the user. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_CANCELLED = new Win32Error(1223); - /// The window class was already registered. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_CLASS_ALREADY_EXISTS = new Win32Error(1410); - /// The specified datatype is invalid. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly Win32Error ERROR_INVALID_DATATYPE = new Win32Error(1804); - - /// - /// Create a new Win32 error. - /// - /// The integer value of the error. - public Win32Error(int i) - { - _value = i; - } + _value = i; + } - /// Performs HRESULT_FROM_WIN32 conversion. - /// The Win32 error being converted to an HRESULT. - /// The equivilent HRESULT value. - 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); - } + /// Performs HRESULT_FROM_WIN32 conversion. + /// The Win32 error being converted to an HRESULT. + /// The equivilent HRESULT value. + 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 - /// Performs HRESULT_FROM_WIN32 conversion. - /// The Win32 error being converted to an HRESULT. - /// The equivilent HRESULT value. - public HRESULT ToHRESULT() - { - return (HRESULT)this; - } + // Method version of the cast operation + /// Performs HRESULT_FROM_WIN32 conversion. + /// The Win32 error being converted to an HRESULT. + /// The equivilent HRESULT value. + public HRESULT ToHRESULT() + { + return ( HRESULT )this; + } - /// Performs the equivalent of Win32's GetLastError() - /// A Win32Error instance with the result of the native GetLastError - [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] - public static Win32Error GetLastError() - { - return new Win32Error(Marshal.GetLastWin32Error()); - } + /// Performs the equivalent of Win32's GetLastError() + /// A Win32Error instance with the result of the native GetLastError + [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 bool Equals( object obj ) + { + try + { + return ( ( Win32Error )obj )._value == _value; + } + catch( InvalidCastException ) + { + return false; + } + } - public override int GetHashCode() - { - return _value.GetHashCode(); - } + public override int GetHashCode() + { + return _value.GetHashCode(); + } - /// - /// Compare two Win32 error codes for equality. - /// - /// The first error code to compare. - /// The second error code to compare. - /// Whether the two error codes are the same. - public static bool operator ==(Win32Error errLeft, Win32Error errRight) - { - return errLeft._value == errRight._value; - } + /// + /// Compare two Win32 error codes for equality. + /// + /// The first error code to compare. + /// The second error code to compare. + /// Whether the two error codes are the same. + public static bool operator ==( Win32Error errLeft, Win32Error errRight ) + { + return errLeft._value == errRight._value; + } - /// - /// Compare two Win32 error codes for inequality. - /// - /// The first error code to compare. - /// The second error code to compare. - /// Whether the two error codes are not the same. - public static bool operator !=(Win32Error errLeft, Win32Error errRight) - { - return !(errLeft == errRight); - } + /// + /// Compare two Win32 error codes for inequality. + /// + /// The first error code to compare. + /// The second error code to compare. + /// Whether the two error codes are not the same. + public static bool operator !=( Win32Error errLeft, Win32Error errRight ) + { + return !( errLeft == errRight ); } + } + + internal enum Facility + { + /// FACILITY_NULL + Null = 0, + /// FACILITY_RPC + Rpc = 1, + /// FACILITY_DISPATCH + Dispatch = 2, + /// FACILITY_STORAGE + Storage = 3, + /// FACILITY_ITF + Itf = 4, + /// FACILITY_WIN32 + Win32 = 7, + /// FACILITY_WINDOWS + Windows = 8, + /// FACILITY_CONTROL + Control = 10, + /// MSDN doced facility code for ESE errors. + Ese = 0xE5E, + /// FACILITY_WINCODEC (WIC) + WinCodec = 0x898, + } + + /// Wrapper for HRESULT status codes. + [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. + /// S_OK + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT S_OK = new HRESULT( 0x00000000 ); + /// S_FALSE + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT S_FALSE = new HRESULT( 0x00000001 ); + /// E_PENDING + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT E_PENDING = new HRESULT( 0x8000000A ); + /// E_NOTIMPL + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT E_NOTIMPL = new HRESULT( 0x80004001 ); + /// E_NOINTERFACE + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT E_NOINTERFACE = new HRESULT( 0x80004002 ); + /// E_POINTER + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT E_POINTER = new HRESULT( 0x80004003 ); + /// E_ABORT + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT E_ABORT = new HRESULT( 0x80004004 ); + /// E_FAIL + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT E_FAIL = new HRESULT( 0x80004005 ); + /// E_UNEXPECTED + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT E_UNEXPECTED = new HRESULT( 0x8000FFFF ); + /// STG_E_INVALIDFUNCTION + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT STG_E_INVALIDFUNCTION = new HRESULT( 0x80030001 ); + /// REGDB_E_CLASSNOTREG + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT REGDB_E_CLASSNOTREG = new HRESULT( 0x80040154 ); + + /// DESTS_E_NO_MATCHING_ASSOC_HANDLER. Win7 internal error code for Jump Lists. + /// There is no Assoc Handler for the given item registered by the specified application. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT DESTS_E_NO_MATCHING_ASSOC_HANDLER = new HRESULT( 0x80040F03 ); + /// DESTS_E_NORECDOCS. Win7 internal error code for Jump Lists. + /// The given item is excluded from the recent docs folder by the NoRecDocs bit on its registration. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT DESTS_E_NORECDOCS = new HRESULT( 0x80040F04 ); + /// DESTS_E_NOTALLCLEARED. Win7 internal error code for Jump Lists. + /// Not all of the items were successfully cleared + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT DESTS_E_NOTALLCLEARED = new HRESULT( 0x80040F05 ); + + /// E_ACCESSDENIED + /// Win32Error ERROR_ACCESS_DENIED. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT E_ACCESSDENIED = new HRESULT( 0x80070005 ); + /// E_OUTOFMEMORY + /// Win32Error ERROR_OUTOFMEMORY. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT E_OUTOFMEMORY = new HRESULT( 0x8007000E ); + /// E_INVALIDARG + /// Win32Error ERROR_INVALID_PARAMETER. + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT E_INVALIDARG = new HRESULT( 0x80070057 ); + /// INTSAFE_E_ARITHMETIC_OVERFLOW + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT INTSAFE_E_ARITHMETIC_OVERFLOW = new HRESULT( 0x80070216 ); + /// COR_E_OBJECTDISPOSED + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT COR_E_OBJECTDISPOSED = new HRESULT( 0x80131622 ); + /// WC_E_GREATERTHAN + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT WC_E_GREATERTHAN = new HRESULT( 0xC00CEE23 ); + /// WC_E_SYNTAX + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + public static readonly HRESULT WC_E_SYNTAX = new HRESULT( 0xC00CEE2D ); - internal enum Facility + /// + /// Create an HRESULT from an integer value. + /// + /// + public HRESULT( uint i ) { - /// FACILITY_NULL - Null = 0, - /// FACILITY_RPC - Rpc = 1, - /// FACILITY_DISPATCH - Dispatch = 2, - /// FACILITY_STORAGE - Storage = 3, - /// FACILITY_ITF - Itf = 4, - /// FACILITY_WIN32 - Win32 = 7, - /// FACILITY_WINDOWS - Windows = 8, - /// FACILITY_CONTROL - Control = 10, - /// MSDN doced facility code for ESE errors. - Ese = 0xE5E, - /// FACILITY_WINCODEC (WIC) - WinCodec = 0x898, + _value = i; } - /// Wrapper for HRESULT status codes. - [StructLayout(LayoutKind.Explicit)] - internal struct HRESULT + public static HRESULT Make( bool severe, Facility facility, int code ) { - [FieldOffset(0)] - private readonly uint _value; - - // NOTE: These public static field declarations are automatically - // picked up by ToString through reflection. - /// S_OK - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT S_OK = new HRESULT(0x00000000); - /// S_FALSE - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT S_FALSE = new HRESULT(0x00000001); - /// E_PENDING - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT E_PENDING = new HRESULT(0x8000000A); - /// E_NOTIMPL - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT E_NOTIMPL = new HRESULT(0x80004001); - /// E_NOINTERFACE - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT E_NOINTERFACE = new HRESULT(0x80004002); - /// E_POINTER - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT E_POINTER = new HRESULT(0x80004003); - /// E_ABORT - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT E_ABORT = new HRESULT(0x80004004); - /// E_FAIL - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT E_FAIL = new HRESULT(0x80004005); - /// E_UNEXPECTED - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT E_UNEXPECTED = new HRESULT(0x8000FFFF); - /// STG_E_INVALIDFUNCTION - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT STG_E_INVALIDFUNCTION = new HRESULT(0x80030001); - /// REGDB_E_CLASSNOTREG - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT REGDB_E_CLASSNOTREG = new HRESULT(0x80040154); - - /// DESTS_E_NO_MATCHING_ASSOC_HANDLER. Win7 internal error code for Jump Lists. - /// There is no Assoc Handler for the given item registered by the specified application. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT DESTS_E_NO_MATCHING_ASSOC_HANDLER = new HRESULT(0x80040F03); - /// DESTS_E_NORECDOCS. Win7 internal error code for Jump Lists. - /// The given item is excluded from the recent docs folder by the NoRecDocs bit on its registration. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT DESTS_E_NORECDOCS = new HRESULT(0x80040F04); - /// DESTS_E_NOTALLCLEARED. Win7 internal error code for Jump Lists. - /// Not all of the items were successfully cleared - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT DESTS_E_NOTALLCLEARED = new HRESULT(0x80040F05); - - /// E_ACCESSDENIED - /// Win32Error ERROR_ACCESS_DENIED. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT E_ACCESSDENIED = new HRESULT(0x80070005); - /// E_OUTOFMEMORY - /// Win32Error ERROR_OUTOFMEMORY. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT E_OUTOFMEMORY = new HRESULT(0x8007000E); - /// E_INVALIDARG - /// Win32Error ERROR_INVALID_PARAMETER. - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT E_INVALIDARG = new HRESULT(0x80070057); - /// INTSAFE_E_ARITHMETIC_OVERFLOW - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT INTSAFE_E_ARITHMETIC_OVERFLOW = new HRESULT(0x80070216); - /// COR_E_OBJECTDISPOSED - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT COR_E_OBJECTDISPOSED = new HRESULT(0x80131622); - /// WC_E_GREATERTHAN - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT WC_E_GREATERTHAN = new HRESULT(0xC00CEE23); - /// WC_E_SYNTAX - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - public static readonly HRESULT WC_E_SYNTAX = new HRESULT(0xC00CEE2D); - - /// - /// Create an HRESULT from an integer value. - /// - /// - public HRESULT(uint i) - { - _value = i; - } + // #define MAKE_HRESULT(sev,fac,code) \ + // ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) ) - 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. - // 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 ); - // 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 ) ); + } - return new HRESULT((uint)((severe ? (1 << 31) : 0) | ((int)facility << 16) | code)); - } + /// + /// retrieve HRESULT_FACILITY + /// + public Facility Facility + { + get + { + return GetFacility( ( int )_value ); + } + } - /// - /// retrieve HRESULT_FACILITY - /// - 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 ); + } - public static Facility GetFacility(int errorCode) + /// + /// retrieve HRESULT_CODE + /// + 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 + + /// + /// Get a string representation of this HRESULT. + /// + /// + 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 ) ) { - // #define HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff) - return (Facility)((errorCode >> 16) & 0x1fff); + var hr = ( HRESULT )publicStaticField.GetValue( null ); + if( hr == this ) + { + return publicStaticField.Name; + } } + } - /// - /// retrieve HRESULT_CODE - /// - public int Code + // Try Win32 error codes also + if( Facility == Facility.Win32 ) + { + foreach( FieldInfo publicStaticField in typeof( Win32Error ).GetFields( BindingFlags.Static | BindingFlags.Public ) ) { - get + if( publicStaticField.FieldType == typeof( Win32Error ) ) + { + var error = ( Win32Error )publicStaticField.GetValue( null ); + if( ( HRESULT )error == this ) { - return GetCode((int)_value); + return "HRESULT_FROM_WIN32(" + publicStaticField.Name + ")"; } + } } + } - public static int GetCode(int error) - { - // #define HRESULT_CODE(hr) ((hr) & 0xFFFF) - return (int)(error & 0xFFFF); - } - - #region Object class override members + // 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 ); + } - /// - /// Get a string representation of this HRESULT. - /// - /// - 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; - } - } - } + public override bool Equals( object obj ) + { + try + { + return ( ( HRESULT )obj )._value == _value; + } + catch( InvalidCastException ) + { + return false; + } + } - // 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 + ")"; - } - } - } - } + public override int GetHashCode() + { + return _value.GetHashCode(); + } - // 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); - } + #endregion - public override bool Equals(object obj) - { - try - { - return ((HRESULT)obj)._value == _value; - } - catch (InvalidCastException) - { - return false; - } - } + public static bool operator ==( HRESULT hrLeft, HRESULT hrRight ) + { + return hrLeft._value == hrRight._value; + } - public override int GetHashCode() - { - return _value.GetHashCode(); - } + public static bool operator !=( HRESULT hrLeft, HRESULT hrRight ) + { + return !( hrLeft == hrRight ); + } - #endregion + public bool Succeeded + { + get + { + return ( int )_value >= 0; + } + } - public static bool operator ==(HRESULT hrLeft, HRESULT hrRight) - { - return hrLeft._value == hrRight._value; - } + public bool Failed + { + get + { + return ( int )_value < 0; + } + } - public static bool operator !=(HRESULT hrLeft, HRESULT hrRight) - { - return !(hrLeft == hrRight); - } + public void ThrowIfFailed() + { + ThrowIfFailed( null ); + } - public bool Succeeded + [ + 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 ) ) { - get { return (int)_value >= 0; } + message = ToString(); } - - public bool Failed +#if DEBUG + else { - get { return (int)_value < 0; } + message += " (" + ToString() + ")"; } - - public void ThrowIfFailed() +#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 ) ) { - ThrowIfFailed(null); + switch( Facility ) + { + case Facility.Win32: + e = new Win32Exception( Code, message ); + break; + default: + e = new COMException( message, ( int )_value ); + break; + } } - - [ - SuppressMessage( - "Microsoft.Usage", - "CA2201:DoNotRaiseReservedExceptionTypes", - Justification="Only recreating Exceptions that were already raised."), - SuppressMessage( - "Microsoft.Security", - "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands") - ] - public void ThrowIfFailed(string message) + else { - 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; - } + ConstructorInfo cons = e.GetType().GetConstructor( new[] { typeof( string ) } ); + if( null != cons ) + { + e = cons.Invoke( new object[] { message } ) as Exception; + Assert.IsNotNull( e ); + } } + throw e; + } + } - /// - /// Convert the result of Win32 GetLastError() into a raised exception. - /// - public static void ThrowLastError() - { - ((HRESULT)Win32Error.GetLastError()).ThrowIfFailed(); - // Only expecting to call this when we're expecting a failed GetLastError() - Assert.Fail(); - } + /// + /// Convert the result of Win32 GetLastError() into a raised exception. + /// + public static void ThrowLastError() + { + ( ( HRESULT )Win32Error.GetLastError() ).ThrowIfFailed(); + // Only expecting to call this when we're expecting a failed GetLastError() + Assert.Fail(); } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/MessageWindow.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/MessageWindow.cs index a4128748..f15b715a 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/MessageWindow.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/MessageWindow.cs @@ -20,166 +20,169 @@ 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 + 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 s_windowLookup = new Dictionary(); + + private WndProc _wndProcCallback; + private string _className; + private bool _isDisposed; + + public IntPtr Handle { - // 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 s_windowLookup = new Dictionary(); + get; private set; + } - private WndProc _wndProcCallback; - private string _className; - private bool _isDisposed; + [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(); + } + } - public IntPtr Handle { get; private set; } + ~MessageWindow() + { + _Dispose( false, false ); + } - [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(); - } - } + public void Dispose() + { + _Dispose( true, false ); + GC.SuppressFinalize( this ); + } - ~MessageWindow() + // 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() ) { - _Dispose(false, false); + _DestroyWindow( hwnd, className ); } - - public void Dispose() + else { - _Dispose(true, false); - GC.SuppressFinalize(this); + Dispatcher.BeginInvoke( DispatcherPriority.Normal, ( DispatcherOperationCallback )( arg => _DestroyWindow( hwnd, className ) ) ); } + } - // 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; - } + s_windowLookup.Remove( hwnd ); - [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; - } + _className = null; + Handle = IntPtr.Zero; + } - private static object _DestroyWindow(IntPtr hwnd, string className) + [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 ) ) { - Utility.SafeDestroyWindow(ref hwnd); - NativeMethods.UnregisterClass(className, NativeMethods.GetModuleHandle(null)); - return null; + 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; } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/NativeMethods.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/NativeMethods.cs index 5faa9412..ab3ca01f 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/NativeMethods.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/NativeMethods.cs @@ -20,3455 +20,3526 @@ namespace Standard { - using System; - using System.ComponentModel; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Runtime.ConstrainedExecution; - using System.Runtime.InteropServices; - using System.Runtime.InteropServices.ComTypes; - using System.Security.Permissions; - using System.Text; - using Microsoft.Win32.SafeHandles; - - // Some COM interfaces and Win32 structures are already declared in the framework. - // Interesting ones to remember in System.Runtime.InteropServices.ComTypes are: - using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; - using IPersistFile = System.Runtime.InteropServices.ComTypes.IPersistFile; - using IStream = System.Runtime.InteropServices.ComTypes.IStream; - - #region Native Values - - internal static class Win32Value - { - public const uint MAX_PATH = 260; - public const uint INFOTIPSIZE = 1024; - public const uint TRUE = 1; - public const uint FALSE = 0; - public const uint sizeof_WCHAR = 2; - public const uint sizeof_CHAR = 1; - public const uint sizeof_BOOL = 4; - } - + using System; + using System.ComponentModel; + using System.Diagnostics.CodeAnalysis; + using System.IO; + using System.Runtime.ConstrainedExecution; + using System.Runtime.InteropServices; + using System.Runtime.InteropServices.ComTypes; + using System.Security.Permissions; + using System.Text; + using Microsoft.Win32.SafeHandles; + + // Some COM interfaces and Win32 structures are already declared in the framework. + // Interesting ones to remember in System.Runtime.InteropServices.ComTypes are: + using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; + using IPersistFile = System.Runtime.InteropServices.ComTypes.IPersistFile; + using IStream = System.Runtime.InteropServices.ComTypes.IStream; + + #region Native Values + + internal static class Win32Value + { + public const uint MAX_PATH = 260; + public const uint INFOTIPSIZE = 1024; + public const uint TRUE = 1; + public const uint FALSE = 0; + public const uint sizeof_WCHAR = 2; + public const uint sizeof_CHAR = 1; + public const uint sizeof_BOOL = 4; + } + + /// + /// HIGHCONTRAST flags + /// + [Flags] + internal enum HCF + { + HIGHCONTRASTON = 0x00000001, + AVAILABLE = 0x00000002, + HOTKEYACTIVE = 0x00000004, + CONFIRMHOTKEY = 0x00000008, + HOTKEYSOUND = 0x00000010, + INDICATOR = 0x00000020, + HOTKEYAVAILABLE = 0x00000040, + } + + /// + /// BITMAPINFOHEADER Compression type. BI_*. + /// + internal enum BI + { + RGB = 0, + } + + /// + /// CombingRgn flags. RGN_* + /// + internal enum RGN + { /// - /// HIGHCONTRAST flags + /// Creates the intersection of the two combined regions. /// - [Flags] - internal enum HCF - { - HIGHCONTRASTON = 0x00000001, - AVAILABLE = 0x00000002, - HOTKEYACTIVE = 0x00000004, - CONFIRMHOTKEY = 0x00000008, - HOTKEYSOUND = 0x00000010, - INDICATOR = 0x00000020, - HOTKEYAVAILABLE = 0x00000040, - } - - /// - /// BITMAPINFOHEADER Compression type. BI_*. - /// - internal enum BI - { - RGB = 0, - } - + AND = 1, /// - /// CombingRgn flags. RGN_* + /// Creates the union of two combined regions. /// - internal enum RGN - { - /// - /// Creates the intersection of the two combined regions. - /// - AND = 1, - /// - /// Creates the union of two combined regions. - /// - OR = 2, - /// - /// Creates the union of two combined regions except for any overlapping areas. - /// - XOR = 3, - /// - /// Combines the parts of hrgnSrc1 that are not part of hrgnSrc2. - /// - DIFF = 4, - /// - /// Creates a copy of the region identified by hrgnSrc1. - /// - COPY = 5, - } - - internal enum CombineRgnResult - { - ERROR = 0, - NULLREGION = 1, - SIMPLEREGION = 2, - COMPLEXREGION = 3, - } - + OR = 2, /// - /// For IWebBrowser2. OLECMDEXECOPT_* + /// Creates the union of two combined regions except for any overlapping areas. /// - internal enum OLECMDEXECOPT - { - DODEFAULT = 0, - PROMPTUSER = 1, - DONTPROMPTUSER = 2, - SHOWHELP = 3 - } - + XOR = 3, /// - /// For IWebBrowser2. OLECMDF_* + /// Combines the parts of hrgnSrc1 that are not part of hrgnSrc2. /// - internal enum OLECMDF - { - SUPPORTED = 1, - ENABLED = 2, - LATCHED = 4, - NINCHED = 8, - INVISIBLE = 16, - DEFHIDEONCTXTMENU = 32 - } - + DIFF = 4, /// - /// For IWebBrowser2. OLECMDID_* + /// Creates a copy of the region identified by hrgnSrc1. /// - internal enum OLECMDID - { - OPEN = 1, - NEW = 2, - SAVE = 3, - SAVEAS = 4, - SAVECOPYAS = 5, - PRINT = 6, - PRINTPREVIEW = 7, - PAGESETUP = 8, - SPELL = 9, - PROPERTIES = 10, - CUT = 11, - COPY = 12, - PASTE = 13, - PASTESPECIAL = 14, - UNDO = 15, - REDO = 16, - SELECTALL = 17, - CLEARSELECTION = 18, - ZOOM = 19, - GETZOOMRANGE = 20, - UPDATECOMMANDS = 21, - REFRESH = 22, - STOP = 23, - HIDETOOLBARS = 24, - SETPROGRESSMAX = 25, - SETPROGRESSPOS = 26, - SETPROGRESSTEXT = 27, - SETTITLE = 28, - SETDOWNLOADSTATE = 29, - STOPDOWNLOAD = 30, - ONTOOLBARACTIVATED = 31, - FIND = 32, - DELETE = 33, - HTTPEQUIV = 34, - HTTPEQUIV_DONE = 35, - ENABLE_INTERACTION = 36, - ONUNLOAD = 37, - PROPERTYBAG2 = 38, - PREREFRESH = 39, - SHOWSCRIPTERROR = 40, - SHOWMESSAGE = 41, - SHOWFIND = 42, - SHOWPAGESETUP = 43, - SHOWPRINT = 44, - CLOSE = 45, - ALLOWUILESSSAVEAS = 46, - DONTDOWNLOADCSS = 47, - UPDATEPAGESTATUS = 48, - PRINT2 = 49, - PRINTPREVIEW2 = 50, - SETPRINTTEMPLATE = 51, - GETPRINTTEMPLATE = 52, - PAGEACTIONBLOCKED = 55, - PAGEACTIONUIQUERY = 56, - FOCUSVIEWCONTROLS = 57, - FOCUSVIEWCONTROLSQUERY = 58, - SHOWPAGEACTIONMENU = 59 - } - + COPY = 5, + } + + internal enum CombineRgnResult + { + ERROR = 0, + NULLREGION = 1, + SIMPLEREGION = 2, + COMPLEXREGION = 3, + } + + /// + /// For IWebBrowser2. OLECMDEXECOPT_* + /// + internal enum OLECMDEXECOPT + { + DODEFAULT = 0, + PROMPTUSER = 1, + DONTPROMPTUSER = 2, + SHOWHELP = 3 + } + + /// + /// For IWebBrowser2. OLECMDF_* + /// + internal enum OLECMDF + { + SUPPORTED = 1, + ENABLED = 2, + LATCHED = 4, + NINCHED = 8, + INVISIBLE = 16, + DEFHIDEONCTXTMENU = 32 + } + + /// + /// For IWebBrowser2. OLECMDID_* + /// + internal enum OLECMDID + { + OPEN = 1, + NEW = 2, + SAVE = 3, + SAVEAS = 4, + SAVECOPYAS = 5, + PRINT = 6, + PRINTPREVIEW = 7, + PAGESETUP = 8, + SPELL = 9, + PROPERTIES = 10, + CUT = 11, + COPY = 12, + PASTE = 13, + PASTESPECIAL = 14, + UNDO = 15, + REDO = 16, + SELECTALL = 17, + CLEARSELECTION = 18, + ZOOM = 19, + GETZOOMRANGE = 20, + UPDATECOMMANDS = 21, + REFRESH = 22, + STOP = 23, + HIDETOOLBARS = 24, + SETPROGRESSMAX = 25, + SETPROGRESSPOS = 26, + SETPROGRESSTEXT = 27, + SETTITLE = 28, + SETDOWNLOADSTATE = 29, + STOPDOWNLOAD = 30, + ONTOOLBARACTIVATED = 31, + FIND = 32, + DELETE = 33, + HTTPEQUIV = 34, + HTTPEQUIV_DONE = 35, + ENABLE_INTERACTION = 36, + ONUNLOAD = 37, + PROPERTYBAG2 = 38, + PREREFRESH = 39, + SHOWSCRIPTERROR = 40, + SHOWMESSAGE = 41, + SHOWFIND = 42, + SHOWPAGESETUP = 43, + SHOWPRINT = 44, + CLOSE = 45, + ALLOWUILESSSAVEAS = 46, + DONTDOWNLOADCSS = 47, + UPDATEPAGESTATUS = 48, + PRINT2 = 49, + PRINTPREVIEW2 = 50, + SETPRINTTEMPLATE = 51, + GETPRINTTEMPLATE = 52, + PAGEACTIONBLOCKED = 55, + PAGEACTIONUIQUERY = 56, + FOCUSVIEWCONTROLS = 57, + FOCUSVIEWCONTROLSQUERY = 58, + SHOWPAGEACTIONMENU = 59 + } + + /// + /// For IWebBrowser2. READYSTATE_* + /// + enum READYSTATE + { + UNINITIALIZED = 0, + LOADING = 1, + LOADED = 2, + INTERACTIVE = 3, + COMPLETE = 4 + } + + /// + /// DATAOBJ_GET_ITEM_FLAGS. DOGIF_*. + /// + internal enum DOGIF + { + DEFAULT = 0x0000, + TRAVERSE_LINK = 0x0001, // if the item is a link get the target + NO_HDROP = 0x0002, // don't fallback and use CF_HDROP clipboard format + NO_URL = 0x0004, // don't fallback and use URL clipboard format + ONLY_IF_ONE = 0x0008, // only return the item if there is one item in the array + } + + internal enum DWM_SIT + { + None, + DISPLAYFRAME = 1, + } + + [Flags] + internal enum ErrorModes + { + /// Use the system default, which is to display all error dialog boxes. + Default = 0x0, /// - /// For IWebBrowser2. READYSTATE_* + /// The system does not display the critical-error-handler message box. + /// Instead, the system sends the error to the calling process. /// - enum READYSTATE - { - UNINITIALIZED = 0, - LOADING = 1, - LOADED = 2, - INTERACTIVE = 3, - COMPLETE = 4 - } - + FailCriticalErrors = 0x1, /// - /// DATAOBJ_GET_ITEM_FLAGS. DOGIF_*. + /// 64-bit Windows: The system automatically fixes memory alignment faults and makes them + /// invisible to the application. It does this for the calling process and any descendant processes. + /// After this value is set for a process, subsequent attempts to clear the value are ignored. /// - internal enum DOGIF - { - DEFAULT = 0x0000, - TRAVERSE_LINK = 0x0001, // if the item is a link get the target - NO_HDROP = 0x0002, // don't fallback and use CF_HDROP clipboard format - NO_URL = 0x0004, // don't fallback and use URL clipboard format - ONLY_IF_ONE = 0x0008, // only return the item if there is one item in the array - } - - internal enum DWM_SIT - { - None, - DISPLAYFRAME = 1, - } - - [Flags] - internal enum ErrorModes - { - /// Use the system default, which is to display all error dialog boxes. - Default = 0x0, - /// - /// The system does not display the critical-error-handler message box. - /// Instead, the system sends the error to the calling process. - /// - FailCriticalErrors = 0x1, - /// - /// 64-bit Windows: The system automatically fixes memory alignment faults and makes them - /// invisible to the application. It does this for the calling process and any descendant processes. - /// After this value is set for a process, subsequent attempts to clear the value are ignored. - /// - NoGpFaultErrorBox = 0x2, - /// - /// The system does not display the general-protection-fault message box. - /// This flag should only be set by debugging applications that handle general - /// protection (GP) faults themselves with an exception handler. - /// - NoAlignmentFaultExcept = 0x4, - /// - /// The system does not display a message box when it fails to find a file. - /// Instead, the error is returned to the calling process. - /// - NoOpenFileErrorBox = 0x8000 - } - + NoGpFaultErrorBox = 0x2, /// - /// Non-client hit test values, HT* + /// The system does not display the general-protection-fault message box. + /// This flag should only be set by debugging applications that handle general + /// protection (GP) faults themselves with an exception handler. /// - internal enum HT - { - ERROR = -2, - TRANSPARENT = -1, - NOWHERE = 0, - CLIENT = 1, - CAPTION = 2, - SYSMENU = 3, - GROWBOX = 4, - SIZE = GROWBOX, - MENU = 5, - HSCROLL = 6, - VSCROLL = 7, - MINBUTTON = 8, - MAXBUTTON = 9, - LEFT = 10, - RIGHT = 11, - TOP = 12, - TOPLEFT = 13, - TOPRIGHT = 14, - BOTTOM = 15, - BOTTOMLEFT = 16, - BOTTOMRIGHT = 17, - BORDER = 18, - REDUCE = MINBUTTON, - ZOOM = MAXBUTTON, - SIZEFIRST = LEFT, - SIZELAST = BOTTOMRIGHT, - OBJECT = 19, - CLOSE = 20, - HELP = 21 - } - + NoAlignmentFaultExcept = 0x4, /// - /// GetClassLongPtr values, GCLP_* + /// The system does not display a message box when it fails to find a file. + /// Instead, the error is returned to the calling process. /// - internal enum GCLP - { - HBRBACKGROUND = -10, - } + NoOpenFileErrorBox = 0x8000 + } + + /// + /// Non-client hit test values, HT* + /// + internal enum HT + { + ERROR = -2, + TRANSPARENT = -1, + NOWHERE = 0, + CLIENT = 1, + CAPTION = 2, + SYSMENU = 3, + GROWBOX = 4, + SIZE = GROWBOX, + MENU = 5, + HSCROLL = 6, + VSCROLL = 7, + MINBUTTON = 8, + MAXBUTTON = 9, + LEFT = 10, + RIGHT = 11, + TOP = 12, + TOPLEFT = 13, + TOPRIGHT = 14, + BOTTOM = 15, + BOTTOMLEFT = 16, + BOTTOMRIGHT = 17, + BORDER = 18, + REDUCE = MINBUTTON, + ZOOM = MAXBUTTON, + SIZEFIRST = LEFT, + SIZELAST = BOTTOMRIGHT, + OBJECT = 19, + CLOSE = 20, + HELP = 21 + } + + /// + /// GetClassLongPtr values, GCLP_* + /// + internal enum GCLP + { + HBRBACKGROUND = -10, + } + + /// + /// GetWindowLongPtr values, GWL_* + /// + internal enum GWL + { + WNDPROC = ( -4 ), + HINSTANCE = ( -6 ), + HWNDPARENT = ( -8 ), + STYLE = ( -16 ), + EXSTYLE = ( -20 ), + USERDATA = ( -21 ), + ID = ( -12 ) + } + + /// + /// SystemMetrics. SM_* + /// + internal enum SM + { + CXSCREEN = 0, + CYSCREEN = 1, + CXVSCROLL = 2, + CYHSCROLL = 3, + CYCAPTION = 4, + CXBORDER = 5, + CYBORDER = 6, + CXFIXEDFRAME = 7, + CYFIXEDFRAME = 8, + CYVTHUMB = 9, + CXHTHUMB = 10, + CXICON = 11, + CYICON = 12, + CXCURSOR = 13, + CYCURSOR = 14, + CYMENU = 15, + CXFULLSCREEN = 16, + CYFULLSCREEN = 17, + CYKANJIWINDOW = 18, + MOUSEPRESENT = 19, + CYVSCROLL = 20, + CXHSCROLL = 21, + DEBUG = 22, + SWAPBUTTON = 23, + CXMIN = 28, + CYMIN = 29, + CXSIZE = 30, + CYSIZE = 31, + CXFRAME = 32, + CXSIZEFRAME = CXFRAME, + CYFRAME = 33, + CYSIZEFRAME = CYFRAME, + CXMINTRACK = 34, + CYMINTRACK = 35, + CXDOUBLECLK = 36, + CYDOUBLECLK = 37, + CXICONSPACING = 38, + CYICONSPACING = 39, + MENUDROPALIGNMENT = 40, + PENWINDOWS = 41, + DBCSENABLED = 42, + CMOUSEBUTTONS = 43, + SECURE = 44, + CXEDGE = 45, + CYEDGE = 46, + CXMINSPACING = 47, + CYMINSPACING = 48, + CXSMICON = 49, + CYSMICON = 50, + CYSMCAPTION = 51, + CXSMSIZE = 52, + CYSMSIZE = 53, + CXMENUSIZE = 54, + CYMENUSIZE = 55, + ARRANGE = 56, + CXMINIMIZED = 57, + CYMINIMIZED = 58, + CXMAXTRACK = 59, + CYMAXTRACK = 60, + CXMAXIMIZED = 61, + CYMAXIMIZED = 62, + NETWORK = 63, + CLEANBOOT = 67, + CXDRAG = 68, + CYDRAG = 69, + SHOWSOUNDS = 70, + CXMENUCHECK = 71, + CYMENUCHECK = 72, + SLOWMACHINE = 73, + MIDEASTENABLED = 74, + MOUSEWHEELPRESENT = 75, + XVIRTUALSCREEN = 76, + YVIRTUALSCREEN = 77, + CXVIRTUALSCREEN = 78, + CYVIRTUALSCREEN = 79, + CMONITORS = 80, + SAMEDISPLAYFORMAT = 81, + IMMENABLED = 82, + CXFOCUSBORDER = 83, + CYFOCUSBORDER = 84, + TABLETPC = 86, + MEDIACENTER = 87, + REMOTESESSION = 0x1000, + REMOTECONTROL = 0x2001, + } + + /// + /// SystemParameterInfo values, SPI_* + /// + internal enum SPI + { + GETBEEP = 0x0001, + SETBEEP = 0x0002, + GETMOUSE = 0x0003, + SETMOUSE = 0x0004, + GETBORDER = 0x0005, + SETBORDER = 0x0006, + GETKEYBOARDSPEED = 0x000A, + SETKEYBOARDSPEED = 0x000B, + LANGDRIVER = 0x000C, + ICONHORIZONTALSPACING = 0x000D, + GETSCREENSAVETIMEOUT = 0x000E, + SETSCREENSAVETIMEOUT = 0x000F, + GETSCREENSAVEACTIVE = 0x0010, + SETSCREENSAVEACTIVE = 0x0011, + GETGRIDGRANULARITY = 0x0012, + SETGRIDGRANULARITY = 0x0013, + SETDESKWALLPAPER = 0x0014, + SETDESKPATTERN = 0x0015, + GETKEYBOARDDELAY = 0x0016, + SETKEYBOARDDELAY = 0x0017, + ICONVERTICALSPACING = 0x0018, + GETICONTITLEWRAP = 0x0019, + SETICONTITLEWRAP = 0x001A, + GETMENUDROPALIGNMENT = 0x001B, + SETMENUDROPALIGNMENT = 0x001C, + SETDOUBLECLKWIDTH = 0x001D, + SETDOUBLECLKHEIGHT = 0x001E, + GETICONTITLELOGFONT = 0x001F, + SETDOUBLECLICKTIME = 0x0020, + SETMOUSEBUTTONSWAP = 0x0021, + SETICONTITLELOGFONT = 0x0022, + GETFASTTASKSWITCH = 0x0023, + SETFASTTASKSWITCH = 0x0024, + + SETDRAGFULLWINDOWS = 0x0025, + GETDRAGFULLWINDOWS = 0x0026, + GETNONCLIENTMETRICS = 0x0029, + SETNONCLIENTMETRICS = 0x002A, + GETMINIMIZEDMETRICS = 0x002B, + SETMINIMIZEDMETRICS = 0x002C, + GETICONMETRICS = 0x002D, + SETICONMETRICS = 0x002E, + SETWORKAREA = 0x002F, + GETWORKAREA = 0x0030, + SETPENWINDOWS = 0x0031, + GETHIGHCONTRAST = 0x0042, + SETHIGHCONTRAST = 0x0043, + GETKEYBOARDPREF = 0x0044, + SETKEYBOARDPREF = 0x0045, + GETSCREENREADER = 0x0046, + SETSCREENREADER = 0x0047, + GETANIMATION = 0x0048, + SETANIMATION = 0x0049, + GETFONTSMOOTHING = 0x004A, + SETFONTSMOOTHING = 0x004B, + SETDRAGWIDTH = 0x004C, + SETDRAGHEIGHT = 0x004D, + SETHANDHELD = 0x004E, + GETLOWPOWERTIMEOUT = 0x004F, + GETPOWEROFFTIMEOUT = 0x0050, + SETLOWPOWERTIMEOUT = 0x0051, + SETPOWEROFFTIMEOUT = 0x0052, + GETLOWPOWERACTIVE = 0x0053, + GETPOWEROFFACTIVE = 0x0054, + SETLOWPOWERACTIVE = 0x0055, + SETPOWEROFFACTIVE = 0x0056, + SETCURSORS = 0x0057, + SETICONS = 0x0058, + GETDEFAULTINPUTLANG = 0x0059, + SETDEFAULTINPUTLANG = 0x005A, + SETLANGTOGGLE = 0x005B, + GETWINDOWSEXTENSION = 0x005C, + SETMOUSETRAILS = 0x005D, + GETMOUSETRAILS = 0x005E, + SETSCREENSAVERRUNNING = 0x0061, + SCREENSAVERRUNNING = SETSCREENSAVERRUNNING, + GETFILTERKEYS = 0x0032, + SETFILTERKEYS = 0x0033, + GETTOGGLEKEYS = 0x0034, + SETTOGGLEKEYS = 0x0035, + GETMOUSEKEYS = 0x0036, + SETMOUSEKEYS = 0x0037, + GETSHOWSOUNDS = 0x0038, + SETSHOWSOUNDS = 0x0039, + GETSTICKYKEYS = 0x003A, + SETSTICKYKEYS = 0x003B, + GETACCESSTIMEOUT = 0x003C, + SETACCESSTIMEOUT = 0x003D, + + GETSERIALKEYS = 0x003E, + SETSERIALKEYS = 0x003F, + GETSOUNDSENTRY = 0x0040, + SETSOUNDSENTRY = 0x0041, + GETSNAPTODEFBUTTON = 0x005F, + SETSNAPTODEFBUTTON = 0x0060, + GETMOUSEHOVERWIDTH = 0x0062, + SETMOUSEHOVERWIDTH = 0x0063, + GETMOUSEHOVERHEIGHT = 0x0064, + SETMOUSEHOVERHEIGHT = 0x0065, + GETMOUSEHOVERTIME = 0x0066, + SETMOUSEHOVERTIME = 0x0067, + GETWHEELSCROLLLINES = 0x0068, + SETWHEELSCROLLLINES = 0x0069, + GETMENUSHOWDELAY = 0x006A, + SETMENUSHOWDELAY = 0x006B, + + GETWHEELSCROLLCHARS = 0x006C, + SETWHEELSCROLLCHARS = 0x006D, + + GETSHOWIMEUI = 0x006E, + SETSHOWIMEUI = 0x006F, + + GETMOUSESPEED = 0x0070, + SETMOUSESPEED = 0x0071, + GETSCREENSAVERRUNNING = 0x0072, + GETDESKWALLPAPER = 0x0073, + + GETAUDIODESCRIPTION = 0x0074, + SETAUDIODESCRIPTION = 0x0075, + + GETSCREENSAVESECURE = 0x0076, + SETSCREENSAVESECURE = 0x0077, + + GETHUNGAPPTIMEOUT = 0x0078, + SETHUNGAPPTIMEOUT = 0x0079, + GETWAITTOKILLTIMEOUT = 0x007A, + SETWAITTOKILLTIMEOUT = 0x007B, + GETWAITTOKILLSERVICETIMEOUT = 0x007C, + SETWAITTOKILLSERVICETIMEOUT = 0x007D, + GETMOUSEDOCKTHRESHOLD = 0x007E, + SETMOUSEDOCKTHRESHOLD = 0x007F, + GETPENDOCKTHRESHOLD = 0x0080, + SETPENDOCKTHRESHOLD = 0x0081, + GETWINARRANGING = 0x0082, + SETWINARRANGING = 0x0083, + GETMOUSEDRAGOUTTHRESHOLD = 0x0084, + SETMOUSEDRAGOUTTHRESHOLD = 0x0085, + GETPENDRAGOUTTHRESHOLD = 0x0086, + SETPENDRAGOUTTHRESHOLD = 0x0087, + GETMOUSESIDEMOVETHRESHOLD = 0x0088, + SETMOUSESIDEMOVETHRESHOLD = 0x0089, + GETPENSIDEMOVETHRESHOLD = 0x008A, + SETPENSIDEMOVETHRESHOLD = 0x008B, + GETDRAGFROMMAXIMIZE = 0x008C, + SETDRAGFROMMAXIMIZE = 0x008D, + GETSNAPSIZING = 0x008E, + SETSNAPSIZING = 0x008F, + GETDOCKMOVING = 0x0090, + SETDOCKMOVING = 0x0091, + + GETACTIVEWINDOWTRACKING = 0x1000, + SETACTIVEWINDOWTRACKING = 0x1001, + GETMENUANIMATION = 0x1002, + SETMENUANIMATION = 0x1003, + GETCOMBOBOXANIMATION = 0x1004, + SETCOMBOBOXANIMATION = 0x1005, + GETLISTBOXSMOOTHSCROLLING = 0x1006, + SETLISTBOXSMOOTHSCROLLING = 0x1007, + GETGRADIENTCAPTIONS = 0x1008, + SETGRADIENTCAPTIONS = 0x1009, + GETKEYBOARDCUES = 0x100A, + SETKEYBOARDCUES = 0x100B, + GETMENUUNDERLINES = GETKEYBOARDCUES, + SETMENUUNDERLINES = SETKEYBOARDCUES, + GETACTIVEWNDTRKZORDER = 0x100C, + SETACTIVEWNDTRKZORDER = 0x100D, + GETHOTTRACKING = 0x100E, + SETHOTTRACKING = 0x100F, + GETMENUFADE = 0x1012, + SETMENUFADE = 0x1013, + GETSELECTIONFADE = 0x1014, + SETSELECTIONFADE = 0x1015, + GETTOOLTIPANIMATION = 0x1016, + SETTOOLTIPANIMATION = 0x1017, + GETTOOLTIPFADE = 0x1018, + SETTOOLTIPFADE = 0x1019, + GETCURSORSHADOW = 0x101A, + SETCURSORSHADOW = 0x101B, + GETMOUSESONAR = 0x101C, + SETMOUSESONAR = 0x101D, + GETMOUSECLICKLOCK = 0x101E, + SETMOUSECLICKLOCK = 0x101F, + GETMOUSEVANISH = 0x1020, + SETMOUSEVANISH = 0x1021, + GETFLATMENU = 0x1022, + SETFLATMENU = 0x1023, + GETDROPSHADOW = 0x1024, + SETDROPSHADOW = 0x1025, + GETBLOCKSENDINPUTRESETS = 0x1026, + SETBLOCKSENDINPUTRESETS = 0x1027, + + GETUIEFFECTS = 0x103E, + SETUIEFFECTS = 0x103F, + + GETDISABLEOVERLAPPEDCONTENT = 0x1040, + SETDISABLEOVERLAPPEDCONTENT = 0x1041, + GETCLIENTAREAANIMATION = 0x1042, + SETCLIENTAREAANIMATION = 0x1043, + GETCLEARTYPE = 0x1048, + SETCLEARTYPE = 0x1049, + GETSPEECHRECOGNITION = 0x104A, + SETSPEECHRECOGNITION = 0x104B, + + GETFOREGROUNDLOCKTIMEOUT = 0x2000, + SETFOREGROUNDLOCKTIMEOUT = 0x2001, + GETACTIVEWNDTRKTIMEOUT = 0x2002, + SETACTIVEWNDTRKTIMEOUT = 0x2003, + GETFOREGROUNDFLASHCOUNT = 0x2004, + SETFOREGROUNDFLASHCOUNT = 0x2005, + GETCARETWIDTH = 0x2006, + SETCARETWIDTH = 0x2007, + + GETMOUSECLICKLOCKTIME = 0x2008, + SETMOUSECLICKLOCKTIME = 0x2009, + GETFONTSMOOTHINGTYPE = 0x200A, + SETFONTSMOOTHINGTYPE = 0x200B, + + GETFONTSMOOTHINGCONTRAST = 0x200C, + SETFONTSMOOTHINGCONTRAST = 0x200D, + + GETFOCUSBORDERWIDTH = 0x200E, + SETFOCUSBORDERWIDTH = 0x200F, + GETFOCUSBORDERHEIGHT = 0x2010, + SETFOCUSBORDERHEIGHT = 0x2011, + + GETFONTSMOOTHINGORIENTATION = 0x2012, + SETFONTSMOOTHINGORIENTATION = 0x2013, + + GETMINIMUMHITRADIUS = 0x2014, + SETMINIMUMHITRADIUS = 0x2015, + GETMESSAGEDURATION = 0x2016, + SETMESSAGEDURATION = 0x2017, + } + + /// + /// SystemParameterInfo flag values, SPIF_* + /// + [Flags] + internal enum SPIF + { + None = 0, + UPDATEINIFILE = 0x01, + SENDCHANGE = 0x02, + SENDWININICHANGE = SENDCHANGE, + } + + [Flags] + internal enum STATE_SYSTEM + { + UNAVAILABLE = 0x00000001, // Disabled + SELECTED = 0x00000002, + FOCUSED = 0x00000004, + PRESSED = 0x00000008, + CHECKED = 0x00000010, + MIXED = 0x00000020, // 3-state checkbox or toolbar button + INDETERMINATE = MIXED, + READONLY = 0x00000040, + HOTTRACKED = 0x00000080, + DEFAULT = 0x00000100, + EXPANDED = 0x00000200, + COLLAPSED = 0x00000400, + BUSY = 0x00000800, + FLOATING = 0x00001000, // Children "owned" not "contained" by parent + MARQUEED = 0x00002000, + ANIMATED = 0x00004000, + INVISIBLE = 0x00008000, + OFFSCREEN = 0x00010000, + SIZEABLE = 0x00020000, + MOVEABLE = 0x00040000, + SELFVOICING = 0x00080000, + FOCUSABLE = 0x00100000, + SELECTABLE = 0x00200000, + LINKED = 0x00400000, + TRAVERSED = 0x00800000, + MULTISELECTABLE = 0x01000000, // Supports multiple selection + EXTSELECTABLE = 0x02000000, // Supports extended selection + ALERT_LOW = 0x04000000, // This information is of low priority + ALERT_MEDIUM = 0x08000000, // This information is of medium priority + ALERT_HIGH = 0x10000000, // This information is of high priority + PROTECTED = 0x20000000, // access to this is restricted + VALID = 0x3FFFFFFF, + } + + internal enum StockObject : int + { + WHITE_BRUSH = 0, + LTGRAY_BRUSH = 1, + GRAY_BRUSH = 2, + DKGRAY_BRUSH = 3, + BLACK_BRUSH = 4, + NULL_BRUSH = 5, + HOLLOW_BRUSH = NULL_BRUSH, + WHITE_PEN = 6, + BLACK_PEN = 7, + NULL_PEN = 8, + SYSTEM_FONT = 13, + DEFAULT_PALETTE = 15, + } + + /// + /// CS_* + /// + [Flags] + internal enum CS : uint + { + VREDRAW = 0x0001, + HREDRAW = 0x0002, + DBLCLKS = 0x0008, + OWNDC = 0x0020, + CLASSDC = 0x0040, + PARENTDC = 0x0080, + NOCLOSE = 0x0200, + SAVEBITS = 0x0800, + BYTEALIGNCLIENT = 0x1000, + BYTEALIGNWINDOW = 0x2000, + GLOBALCLASS = 0x4000, + IME = 0x00010000, + DROPSHADOW = 0x00020000 + } + + /// + /// WindowStyle values, WS_* + /// + [Flags] + internal enum WS : uint + { + OVERLAPPED = 0x00000000, + POPUP = 0x80000000, + CHILD = 0x40000000, + MINIMIZE = 0x20000000, + VISIBLE = 0x10000000, + DISABLED = 0x08000000, + CLIPSIBLINGS = 0x04000000, + CLIPCHILDREN = 0x02000000, + MAXIMIZE = 0x01000000, + BORDER = 0x00800000, + DLGFRAME = 0x00400000, + VSCROLL = 0x00200000, + HSCROLL = 0x00100000, + SYSMENU = 0x00080000, + THICKFRAME = 0x00040000, + GROUP = 0x00020000, + TABSTOP = 0x00010000, + + MINIMIZEBOX = 0x00020000, + MAXIMIZEBOX = 0x00010000, + + CAPTION = BORDER | DLGFRAME, + TILED = OVERLAPPED, + ICONIC = MINIMIZE, + SIZEBOX = THICKFRAME, + TILEDWINDOW = OVERLAPPEDWINDOW, + + OVERLAPPEDWINDOW = OVERLAPPED | CAPTION | SYSMENU | THICKFRAME | MINIMIZEBOX | MAXIMIZEBOX, + POPUPWINDOW = POPUP | BORDER | SYSMENU, + CHILDWINDOW = CHILD, + } + + /// + /// Window message values, WM_* + /// + internal enum WM + { + NULL = 0x0000, + CREATE = 0x0001, + DESTROY = 0x0002, + MOVE = 0x0003, + SIZE = 0x0005, + ACTIVATE = 0x0006, + SETFOCUS = 0x0007, + KILLFOCUS = 0x0008, + ENABLE = 0x000A, + SETREDRAW = 0x000B, + SETTEXT = 0x000C, + GETTEXT = 0x000D, + GETTEXTLENGTH = 0x000E, + PAINT = 0x000F, + CLOSE = 0x0010, + QUERYENDSESSION = 0x0011, + QUIT = 0x0012, + QUERYOPEN = 0x0013, + ERASEBKGND = 0x0014, + SYSCOLORCHANGE = 0x0015, + SHOWWINDOW = 0x0018, + CTLCOLOR = 0x0019, + WININICHANGE = 0x001A, + SETTINGCHANGE = 0x001A, + ACTIVATEAPP = 0x001C, + SETCURSOR = 0x0020, + MOUSEACTIVATE = 0x0021, + CHILDACTIVATE = 0x0022, + QUEUESYNC = 0x0023, + GETMINMAXINFO = 0x0024, + + WINDOWPOSCHANGING = 0x0046, + WINDOWPOSCHANGED = 0x0047, + + CONTEXTMENU = 0x007B, + STYLECHANGING = 0x007C, + STYLECHANGED = 0x007D, + DISPLAYCHANGE = 0x007E, + GETICON = 0x007F, + SETICON = 0x0080, + NCCREATE = 0x0081, + NCDESTROY = 0x0082, + NCCALCSIZE = 0x0083, + NCHITTEST = 0x0084, + NCPAINT = 0x0085, + NCACTIVATE = 0x0086, + GETDLGCODE = 0x0087, + SYNCPAINT = 0x0088, + NCMOUSEMOVE = 0x00A0, + NCLBUTTONDOWN = 0x00A1, + NCLBUTTONUP = 0x00A2, + NCLBUTTONDBLCLK = 0x00A3, + NCRBUTTONDOWN = 0x00A4, + NCRBUTTONUP = 0x00A5, + NCRBUTTONDBLCLK = 0x00A6, + NCMBUTTONDOWN = 0x00A7, + NCMBUTTONUP = 0x00A8, + NCMBUTTONDBLCLK = 0x00A9, + + SYSKEYDOWN = 0x0104, + SYSKEYUP = 0x0105, + SYSCHAR = 0x0106, + SYSDEADCHAR = 0x0107, + COMMAND = 0x0111, + SYSCOMMAND = 0x0112, + + MOUSEMOVE = 0x0200, + LBUTTONDOWN = 0x0201, + LBUTTONUP = 0x0202, + LBUTTONDBLCLK = 0x0203, + RBUTTONDOWN = 0x0204, + RBUTTONUP = 0x0205, + RBUTTONDBLCLK = 0x0206, + MBUTTONDOWN = 0x0207, + MBUTTONUP = 0x0208, + MBUTTONDBLCLK = 0x0209, + MOUSEWHEEL = 0x020A, + XBUTTONDOWN = 0x020B, + XBUTTONUP = 0x020C, + XBUTTONDBLCLK = 0x020D, + MOUSEHWHEEL = 0x020E, + PARENTNOTIFY = 0x0210, + + CAPTURECHANGED = 0x0215, + POWERBROADCAST = 0x0218, + DEVICECHANGE = 0x0219, + + ENTERSIZEMOVE = 0x0231, + EXITSIZEMOVE = 0x0232, + + IME_SETCONTEXT = 0x0281, + IME_NOTIFY = 0x0282, + IME_CONTROL = 0x0283, + IME_COMPOSITIONFULL = 0x0284, + IME_SELECT = 0x0285, + IME_CHAR = 0x0286, + IME_REQUEST = 0x0288, + IME_KEYDOWN = 0x0290, + IME_KEYUP = 0x0291, + + NCMOUSELEAVE = 0x02A2, + + TABLET_DEFBASE = 0x02C0, + //WM_TABLET_MAXOFFSET = 0x20, + + TABLET_ADDED = TABLET_DEFBASE + 8, + TABLET_DELETED = TABLET_DEFBASE + 9, + TABLET_FLICK = TABLET_DEFBASE + 11, + TABLET_QUERYSYSTEMGESTURESTATUS = TABLET_DEFBASE + 12, + + CUT = 0x0300, + COPY = 0x0301, + PASTE = 0x0302, + CLEAR = 0x0303, + UNDO = 0x0304, + RENDERFORMAT = 0x0305, + RENDERALLFORMATS = 0x0306, + DESTROYCLIPBOARD = 0x0307, + DRAWCLIPBOARD = 0x0308, + PAINTCLIPBOARD = 0x0309, + VSCROLLCLIPBOARD = 0x030A, + SIZECLIPBOARD = 0x030B, + ASKCBFORMATNAME = 0x030C, + CHANGECBCHAIN = 0x030D, + HSCROLLCLIPBOARD = 0x030E, + QUERYNEWPALETTE = 0x030F, + PALETTEISCHANGING = 0x0310, + PALETTECHANGED = 0x0311, + HOTKEY = 0x0312, + PRINT = 0x0317, + PRINTCLIENT = 0x0318, + APPCOMMAND = 0x0319, + THEMECHANGED = 0x031A, + + DWMCOMPOSITIONCHANGED = 0x031E, + DWMNCRENDERINGCHANGED = 0x031F, + DWMCOLORIZATIONCOLORCHANGED = 0x0320, + DWMWINDOWMAXIMIZEDCHANGE = 0x0321, + + GETTITLEBARINFOEX = 0x033F, + #region Windows 7 + DWMSENDICONICTHUMBNAIL = 0x0323, + DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326, + #endregion - /// - /// GetWindowLongPtr values, GWL_* + USER = 0x0400, + + // This is the hard-coded message value used by WinForms for Shell_NotifyIcon. + // It's relatively safe to reuse. + TRAYMOUSEMESSAGE = 0x800, //WM_USER + 1024 + APP = 0x8000, + } + + /// + /// Window style extended values, WS_EX_* + /// + [Flags] + internal enum WS_EX : uint + { + None = 0, + DLGMODALFRAME = 0x00000001, + NOPARENTNOTIFY = 0x00000004, + TOPMOST = 0x00000008, + ACCEPTFILES = 0x00000010, + TRANSPARENT = 0x00000020, + MDICHILD = 0x00000040, + TOOLWINDOW = 0x00000080, + WINDOWEDGE = 0x00000100, + CLIENTEDGE = 0x00000200, + CONTEXTHELP = 0x00000400, + RIGHT = 0x00001000, + LEFT = 0x00000000, + RTLREADING = 0x00002000, + LTRREADING = 0x00000000, + LEFTSCROLLBAR = 0x00004000, + RIGHTSCROLLBAR = 0x00000000, + CONTROLPARENT = 0x00010000, + STATICEDGE = 0x00020000, + APPWINDOW = 0x00040000, + LAYERED = 0x00080000, + NOINHERITLAYOUT = 0x00100000, // Disable inheritence of mirroring by children + LAYOUTRTL = 0x00400000, // Right to left mirroring + COMPOSITED = 0x02000000, + NOACTIVATE = 0x08000000, + OVERLAPPEDWINDOW = ( WINDOWEDGE | CLIENTEDGE ), + PALETTEWINDOW = ( WINDOWEDGE | TOOLWINDOW | TOPMOST ), + } + + /// + /// GetDeviceCaps nIndex values. + /// + internal enum DeviceCap + { + /// Number of bits per pixel /// - internal enum GWL - { - WNDPROC = (-4), - HINSTANCE = (-6), - HWNDPARENT = (-8), - STYLE = (-16), - EXSTYLE = (-20), - USERDATA = (-21), - ID = (-12) - } - + BITSPIXEL = 12, /// - /// SystemMetrics. SM_* + /// Number of planes /// - internal enum SM - { - CXSCREEN = 0, - CYSCREEN = 1, - CXVSCROLL = 2, - CYHSCROLL = 3, - CYCAPTION = 4, - CXBORDER = 5, - CYBORDER = 6, - CXFIXEDFRAME = 7, - CYFIXEDFRAME = 8, - CYVTHUMB = 9, - CXHTHUMB = 10, - CXICON = 11, - CYICON = 12, - CXCURSOR = 13, - CYCURSOR = 14, - CYMENU = 15, - CXFULLSCREEN = 16, - CYFULLSCREEN = 17, - CYKANJIWINDOW = 18, - MOUSEPRESENT = 19, - CYVSCROLL = 20, - CXHSCROLL = 21, - DEBUG = 22, - SWAPBUTTON = 23, - CXMIN = 28, - CYMIN = 29, - CXSIZE = 30, - CYSIZE = 31, - CXFRAME = 32, - CXSIZEFRAME = CXFRAME, - CYFRAME = 33, - CYSIZEFRAME = CYFRAME, - CXMINTRACK = 34, - CYMINTRACK = 35, - CXDOUBLECLK = 36, - CYDOUBLECLK = 37, - CXICONSPACING = 38, - CYICONSPACING = 39, - MENUDROPALIGNMENT = 40, - PENWINDOWS = 41, - DBCSENABLED = 42, - CMOUSEBUTTONS = 43, - SECURE = 44, - CXEDGE = 45, - CYEDGE = 46, - CXMINSPACING = 47, - CYMINSPACING = 48, - CXSMICON = 49, - CYSMICON = 50, - CYSMCAPTION = 51, - CXSMSIZE = 52, - CYSMSIZE = 53, - CXMENUSIZE = 54, - CYMENUSIZE = 55, - ARRANGE = 56, - CXMINIMIZED = 57, - CYMINIMIZED = 58, - CXMAXTRACK = 59, - CYMAXTRACK = 60, - CXMAXIMIZED = 61, - CYMAXIMIZED = 62, - NETWORK = 63, - CLEANBOOT = 67, - CXDRAG = 68, - CYDRAG = 69, - SHOWSOUNDS = 70, - CXMENUCHECK = 71, - CYMENUCHECK = 72, - SLOWMACHINE = 73, - MIDEASTENABLED = 74, - MOUSEWHEELPRESENT = 75, - XVIRTUALSCREEN = 76, - YVIRTUALSCREEN = 77, - CXVIRTUALSCREEN = 78, - CYVIRTUALSCREEN = 79, - CMONITORS = 80, - SAMEDISPLAYFORMAT = 81, - IMMENABLED = 82, - CXFOCUSBORDER = 83, - CYFOCUSBORDER = 84, - TABLETPC = 86, - MEDIACENTER = 87, - REMOTESESSION = 0x1000, - REMOTECONTROL = 0x2001, - } - + PLANES = 14, /// - /// SystemParameterInfo values, SPI_* + /// Logical pixels inch in X /// - internal enum SPI - { - GETBEEP = 0x0001, - SETBEEP = 0x0002, - GETMOUSE = 0x0003, - SETMOUSE = 0x0004, - GETBORDER = 0x0005, - SETBORDER = 0x0006, - GETKEYBOARDSPEED = 0x000A, - SETKEYBOARDSPEED = 0x000B, - LANGDRIVER = 0x000C, - ICONHORIZONTALSPACING = 0x000D, - GETSCREENSAVETIMEOUT = 0x000E, - SETSCREENSAVETIMEOUT = 0x000F, - GETSCREENSAVEACTIVE = 0x0010, - SETSCREENSAVEACTIVE = 0x0011, - GETGRIDGRANULARITY = 0x0012, - SETGRIDGRANULARITY = 0x0013, - SETDESKWALLPAPER = 0x0014, - SETDESKPATTERN = 0x0015, - GETKEYBOARDDELAY = 0x0016, - SETKEYBOARDDELAY = 0x0017, - ICONVERTICALSPACING = 0x0018, - GETICONTITLEWRAP = 0x0019, - SETICONTITLEWRAP = 0x001A, - GETMENUDROPALIGNMENT = 0x001B, - SETMENUDROPALIGNMENT = 0x001C, - SETDOUBLECLKWIDTH = 0x001D, - SETDOUBLECLKHEIGHT = 0x001E, - GETICONTITLELOGFONT = 0x001F, - SETDOUBLECLICKTIME = 0x0020, - SETMOUSEBUTTONSWAP = 0x0021, - SETICONTITLELOGFONT = 0x0022, - GETFASTTASKSWITCH = 0x0023, - SETFASTTASKSWITCH = 0x0024, - - SETDRAGFULLWINDOWS = 0x0025, - GETDRAGFULLWINDOWS = 0x0026, - GETNONCLIENTMETRICS = 0x0029, - SETNONCLIENTMETRICS = 0x002A, - GETMINIMIZEDMETRICS = 0x002B, - SETMINIMIZEDMETRICS = 0x002C, - GETICONMETRICS = 0x002D, - SETICONMETRICS = 0x002E, - SETWORKAREA = 0x002F, - GETWORKAREA = 0x0030, - SETPENWINDOWS = 0x0031, - GETHIGHCONTRAST = 0x0042, - SETHIGHCONTRAST = 0x0043, - GETKEYBOARDPREF = 0x0044, - SETKEYBOARDPREF = 0x0045, - GETSCREENREADER = 0x0046, - SETSCREENREADER = 0x0047, - GETANIMATION = 0x0048, - SETANIMATION = 0x0049, - GETFONTSMOOTHING = 0x004A, - SETFONTSMOOTHING = 0x004B, - SETDRAGWIDTH = 0x004C, - SETDRAGHEIGHT = 0x004D, - SETHANDHELD = 0x004E, - GETLOWPOWERTIMEOUT = 0x004F, - GETPOWEROFFTIMEOUT = 0x0050, - SETLOWPOWERTIMEOUT = 0x0051, - SETPOWEROFFTIMEOUT = 0x0052, - GETLOWPOWERACTIVE = 0x0053, - GETPOWEROFFACTIVE = 0x0054, - SETLOWPOWERACTIVE = 0x0055, - SETPOWEROFFACTIVE = 0x0056, - SETCURSORS = 0x0057, - SETICONS = 0x0058, - GETDEFAULTINPUTLANG = 0x0059, - SETDEFAULTINPUTLANG = 0x005A, - SETLANGTOGGLE = 0x005B, - GETWINDOWSEXTENSION = 0x005C, - SETMOUSETRAILS = 0x005D, - GETMOUSETRAILS = 0x005E, - SETSCREENSAVERRUNNING = 0x0061, - SCREENSAVERRUNNING = SETSCREENSAVERRUNNING, - GETFILTERKEYS = 0x0032, - SETFILTERKEYS = 0x0033, - GETTOGGLEKEYS = 0x0034, - SETTOGGLEKEYS = 0x0035, - GETMOUSEKEYS = 0x0036, - SETMOUSEKEYS = 0x0037, - GETSHOWSOUNDS = 0x0038, - SETSHOWSOUNDS = 0x0039, - GETSTICKYKEYS = 0x003A, - SETSTICKYKEYS = 0x003B, - GETACCESSTIMEOUT = 0x003C, - SETACCESSTIMEOUT = 0x003D, - - GETSERIALKEYS = 0x003E, - SETSERIALKEYS = 0x003F, - GETSOUNDSENTRY = 0x0040, - SETSOUNDSENTRY = 0x0041, - GETSNAPTODEFBUTTON = 0x005F, - SETSNAPTODEFBUTTON = 0x0060, - GETMOUSEHOVERWIDTH = 0x0062, - SETMOUSEHOVERWIDTH = 0x0063, - GETMOUSEHOVERHEIGHT = 0x0064, - SETMOUSEHOVERHEIGHT = 0x0065, - GETMOUSEHOVERTIME = 0x0066, - SETMOUSEHOVERTIME = 0x0067, - GETWHEELSCROLLLINES = 0x0068, - SETWHEELSCROLLLINES = 0x0069, - GETMENUSHOWDELAY = 0x006A, - SETMENUSHOWDELAY = 0x006B, - - GETWHEELSCROLLCHARS = 0x006C, - SETWHEELSCROLLCHARS = 0x006D, - - GETSHOWIMEUI = 0x006E, - SETSHOWIMEUI = 0x006F, - - GETMOUSESPEED = 0x0070, - SETMOUSESPEED = 0x0071, - GETSCREENSAVERRUNNING = 0x0072, - GETDESKWALLPAPER = 0x0073, - - GETAUDIODESCRIPTION = 0x0074, - SETAUDIODESCRIPTION = 0x0075, - - GETSCREENSAVESECURE = 0x0076, - SETSCREENSAVESECURE = 0x0077, - - GETHUNGAPPTIMEOUT = 0x0078, - SETHUNGAPPTIMEOUT = 0x0079, - GETWAITTOKILLTIMEOUT = 0x007A, - SETWAITTOKILLTIMEOUT = 0x007B, - GETWAITTOKILLSERVICETIMEOUT = 0x007C, - SETWAITTOKILLSERVICETIMEOUT = 0x007D, - GETMOUSEDOCKTHRESHOLD = 0x007E, - SETMOUSEDOCKTHRESHOLD = 0x007F, - GETPENDOCKTHRESHOLD = 0x0080, - SETPENDOCKTHRESHOLD = 0x0081, - GETWINARRANGING = 0x0082, - SETWINARRANGING = 0x0083, - GETMOUSEDRAGOUTTHRESHOLD = 0x0084, - SETMOUSEDRAGOUTTHRESHOLD = 0x0085, - GETPENDRAGOUTTHRESHOLD = 0x0086, - SETPENDRAGOUTTHRESHOLD = 0x0087, - GETMOUSESIDEMOVETHRESHOLD = 0x0088, - SETMOUSESIDEMOVETHRESHOLD = 0x0089, - GETPENSIDEMOVETHRESHOLD = 0x008A, - SETPENSIDEMOVETHRESHOLD = 0x008B, - GETDRAGFROMMAXIMIZE = 0x008C, - SETDRAGFROMMAXIMIZE = 0x008D, - GETSNAPSIZING = 0x008E, - SETSNAPSIZING = 0x008F, - GETDOCKMOVING = 0x0090, - SETDOCKMOVING = 0x0091, - - GETACTIVEWINDOWTRACKING = 0x1000, - SETACTIVEWINDOWTRACKING = 0x1001, - GETMENUANIMATION = 0x1002, - SETMENUANIMATION = 0x1003, - GETCOMBOBOXANIMATION = 0x1004, - SETCOMBOBOXANIMATION = 0x1005, - GETLISTBOXSMOOTHSCROLLING = 0x1006, - SETLISTBOXSMOOTHSCROLLING = 0x1007, - GETGRADIENTCAPTIONS = 0x1008, - SETGRADIENTCAPTIONS = 0x1009, - GETKEYBOARDCUES = 0x100A, - SETKEYBOARDCUES = 0x100B, - GETMENUUNDERLINES = GETKEYBOARDCUES, - SETMENUUNDERLINES = SETKEYBOARDCUES, - GETACTIVEWNDTRKZORDER = 0x100C, - SETACTIVEWNDTRKZORDER = 0x100D, - GETHOTTRACKING = 0x100E, - SETHOTTRACKING = 0x100F, - GETMENUFADE = 0x1012, - SETMENUFADE = 0x1013, - GETSELECTIONFADE = 0x1014, - SETSELECTIONFADE = 0x1015, - GETTOOLTIPANIMATION = 0x1016, - SETTOOLTIPANIMATION = 0x1017, - GETTOOLTIPFADE = 0x1018, - SETTOOLTIPFADE = 0x1019, - GETCURSORSHADOW = 0x101A, - SETCURSORSHADOW = 0x101B, - GETMOUSESONAR = 0x101C, - SETMOUSESONAR = 0x101D, - GETMOUSECLICKLOCK = 0x101E, - SETMOUSECLICKLOCK = 0x101F, - GETMOUSEVANISH = 0x1020, - SETMOUSEVANISH = 0x1021, - GETFLATMENU = 0x1022, - SETFLATMENU = 0x1023, - GETDROPSHADOW = 0x1024, - SETDROPSHADOW = 0x1025, - GETBLOCKSENDINPUTRESETS = 0x1026, - SETBLOCKSENDINPUTRESETS = 0x1027, - - GETUIEFFECTS = 0x103E, - SETUIEFFECTS = 0x103F, - - GETDISABLEOVERLAPPEDCONTENT = 0x1040, - SETDISABLEOVERLAPPEDCONTENT = 0x1041, - GETCLIENTAREAANIMATION = 0x1042, - SETCLIENTAREAANIMATION = 0x1043, - GETCLEARTYPE = 0x1048, - SETCLEARTYPE = 0x1049, - GETSPEECHRECOGNITION = 0x104A, - SETSPEECHRECOGNITION = 0x104B, - - GETFOREGROUNDLOCKTIMEOUT = 0x2000, - SETFOREGROUNDLOCKTIMEOUT = 0x2001, - GETACTIVEWNDTRKTIMEOUT = 0x2002, - SETACTIVEWNDTRKTIMEOUT = 0x2003, - GETFOREGROUNDFLASHCOUNT = 0x2004, - SETFOREGROUNDFLASHCOUNT = 0x2005, - GETCARETWIDTH = 0x2006, - SETCARETWIDTH = 0x2007, - - GETMOUSECLICKLOCKTIME = 0x2008, - SETMOUSECLICKLOCKTIME = 0x2009, - GETFONTSMOOTHINGTYPE = 0x200A, - SETFONTSMOOTHINGTYPE = 0x200B, - - GETFONTSMOOTHINGCONTRAST = 0x200C, - SETFONTSMOOTHINGCONTRAST = 0x200D, - - GETFOCUSBORDERWIDTH = 0x200E, - SETFOCUSBORDERWIDTH = 0x200F, - GETFOCUSBORDERHEIGHT = 0x2010, - SETFOCUSBORDERHEIGHT = 0x2011, - - GETFONTSMOOTHINGORIENTATION = 0x2012, - SETFONTSMOOTHINGORIENTATION = 0x2013, - - GETMINIMUMHITRADIUS = 0x2014, - SETMINIMUMHITRADIUS = 0x2015, - GETMESSAGEDURATION = 0x2016, - SETMESSAGEDURATION = 0x2017, - } - + LOGPIXELSX = 88, /// - /// SystemParameterInfo flag values, SPIF_* + /// Logical pixels inch in Y /// - [Flags] - internal enum SPIF - { - None = 0, - UPDATEINIFILE = 0x01, - SENDCHANGE = 0x02, - SENDWININICHANGE = SENDCHANGE, - } - - [Flags] - internal enum STATE_SYSTEM - { - UNAVAILABLE = 0x00000001, // Disabled - SELECTED = 0x00000002, - FOCUSED = 0x00000004, - PRESSED = 0x00000008, - CHECKED = 0x00000010, - MIXED = 0x00000020, // 3-state checkbox or toolbar button - INDETERMINATE = MIXED, - READONLY = 0x00000040, - HOTTRACKED = 0x00000080, - DEFAULT = 0x00000100, - EXPANDED = 0x00000200, - COLLAPSED = 0x00000400, - BUSY = 0x00000800, - FLOATING = 0x00001000, // Children "owned" not "contained" by parent - MARQUEED = 0x00002000, - ANIMATED = 0x00004000, - INVISIBLE = 0x00008000, - OFFSCREEN = 0x00010000, - SIZEABLE = 0x00020000, - MOVEABLE = 0x00040000, - SELFVOICING = 0x00080000, - FOCUSABLE = 0x00100000, - SELECTABLE = 0x00200000, - LINKED = 0x00400000, - TRAVERSED = 0x00800000, - MULTISELECTABLE = 0x01000000, // Supports multiple selection - EXTSELECTABLE = 0x02000000, // Supports extended selection - ALERT_LOW = 0x04000000, // This information is of low priority - ALERT_MEDIUM = 0x08000000, // This information is of medium priority - ALERT_HIGH = 0x10000000, // This information is of high priority - PROTECTED = 0x20000000, // access to this is restricted - VALID = 0x3FFFFFFF, - } - - internal enum StockObject : int - { - WHITE_BRUSH = 0, - LTGRAY_BRUSH = 1, - GRAY_BRUSH = 2, - DKGRAY_BRUSH = 3, - BLACK_BRUSH = 4, - NULL_BRUSH = 5, - HOLLOW_BRUSH = NULL_BRUSH, - WHITE_PEN = 6, - BLACK_PEN = 7, - NULL_PEN = 8, - SYSTEM_FONT = 13, - DEFAULT_PALETTE = 15, - } - + LOGPIXELSY = 90, + } + + internal enum FO : int + { + MOVE = 0x0001, + COPY = 0x0002, + DELETE = 0x0003, + RENAME = 0x0004, + } + + /// + /// "FILEOP_FLAGS", FOF_*. + /// + internal enum FOF : ushort + { + MULTIDESTFILES = 0x0001, + CONFIRMMOUSE = 0x0002, + SILENT = 0x0004, + RENAMEONCOLLISION = 0x0008, + NOCONFIRMATION = 0x0010, + WANTMAPPINGHANDLE = 0x0020, + ALLOWUNDO = 0x0040, + FILESONLY = 0x0080, + SIMPLEPROGRESS = 0x0100, + NOCONFIRMMKDIR = 0x0200, + NOERRORUI = 0x0400, + NOCOPYSECURITYATTRIBS = 0x0800, + NORECURSION = 0x1000, + NO_CONNECTED_ELEMENTS = 0x2000, + WANTNUKEWARNING = 0x4000, + NORECURSEREPARSE = 0x8000, + } + + /// + /// EnableMenuItem uEnable values, MF_* + /// + [Flags] + internal enum MF : uint + { /// - /// CS_* + /// Possible return value for EnableMenuItem /// - [Flags] - internal enum CS : uint - { - VREDRAW = 0x0001, - HREDRAW = 0x0002, - DBLCLKS = 0x0008, - OWNDC = 0x0020, - CLASSDC = 0x0040, - PARENTDC = 0x0080, - NOCLOSE = 0x0200, - SAVEBITS = 0x0800, - BYTEALIGNCLIENT = 0x1000, - BYTEALIGNWINDOW = 0x2000, - GLOBALCLASS = 0x4000, - IME = 0x00010000, - DROPSHADOW = 0x00020000 - } - + DOES_NOT_EXIST = unchecked(( uint )-1), + ENABLED = 0, + BYCOMMAND = 0, + GRAYED = 1, + DISABLED = 2, + } + + /// Specifies the type of visual style attribute to set on a window. + internal enum WINDOWTHEMEATTRIBUTETYPE : uint + { + /// Non-client area window attributes will be set. + WTA_NONCLIENT = 1, + } + + /// + /// DWMFLIP3DWINDOWPOLICY. DWMFLIP3D_* + /// + internal enum DWMFLIP3D + { + DEFAULT, + EXCLUDEBELOW, + EXCLUDEABOVE, + //LAST + } + + /// + /// DWMNCRENDERINGPOLICY. DWMNCRP_* + /// + internal enum DWMNCRP + { + USEWINDOWSTYLE, + DISABLED, + ENABLED, + //LAST + } + + /// + /// DWMWINDOWATTRIBUTE. DWMWA_* + /// + internal enum DWMWA + { + NCRENDERING_ENABLED = 1, + NCRENDERING_POLICY, + TRANSITIONS_FORCEDISABLED, + ALLOW_NCPAINT, + CAPTION_BUTTON_BOUNDS, + NONCLIENT_RTL_LAYOUT, + FORCE_ICONIC_REPRESENTATION, + FLIP3D_POLICY, + EXTENDED_FRAME_BOUNDS, + + // New to Windows 7: + + HAS_ICONIC_BITMAP, + DISALLOW_PEEK, + EXCLUDED_FROM_PEEK, + + // LAST + } + + /// + /// WindowThemeNonClientAttributes + /// + [Flags] + internal enum WTNCA : uint + { + /// Prevents the window caption from being drawn. + NODRAWCAPTION = 0x00000001, + /// Prevents the system icon from being drawn. + NODRAWICON = 0x00000002, + /// Prevents the system icon menu from appearing. + NOSYSMENU = 0x00000004, + /// Prevents mirroring of the question mark, even in right-to-left (RTL) layout. + NOMIRRORHELP = 0x00000008, + /// A mask that contains all the valid bits. + VALIDBITS = NODRAWCAPTION | NODRAWICON | NOMIRRORHELP | NOSYSMENU, + } + + /// + /// SetWindowPos options + /// + [Flags] + internal enum SWP + { + ASYNCWINDOWPOS = 0x4000, + DEFERERASE = 0x2000, + DRAWFRAME = 0x0020, + FRAMECHANGED = 0x0020, + HIDEWINDOW = 0x0080, + NOACTIVATE = 0x0010, + NOCOPYBITS = 0x0100, + NOMOVE = 0x0002, + NOOWNERZORDER = 0x0200, + NOREDRAW = 0x0008, + NOREPOSITION = 0x0200, + NOSENDCHANGING = 0x0400, + NOSIZE = 0x0001, + NOZORDER = 0x0004, + SHOWWINDOW = 0x0040, + } + + /// + /// ShowWindow options + /// + internal enum SW + { + HIDE = 0, + SHOWNORMAL = 1, + NORMAL = 1, + SHOWMINIMIZED = 2, + SHOWMAXIMIZED = 3, + MAXIMIZE = 3, + SHOWNOACTIVATE = 4, + SHOW = 5, + MINIMIZE = 6, + SHOWMINNOACTIVE = 7, + SHOWNA = 8, + RESTORE = 9, + SHOWDEFAULT = 10, + FORCEMINIMIZE = 11, + } + + internal enum SC + { + SIZE = 0xF000, + MOVE = 0xF010, + MINIMIZE = 0xF020, + MAXIMIZE = 0xF030, + NEXTWINDOW = 0xF040, + PREVWINDOW = 0xF050, + CLOSE = 0xF060, + VSCROLL = 0xF070, + HSCROLL = 0xF080, + MOUSEMENU = 0xF090, + KEYMENU = 0xF100, + ARRANGE = 0xF110, + RESTORE = 0xF120, + TASKLIST = 0xF130, + SCREENSAVE = 0xF140, + HOTKEY = 0xF150, + DEFAULT = 0xF160, + MONITORPOWER = 0xF170, + CONTEXTHELP = 0xF180, + SEPARATOR = 0xF00F, /// - /// WindowStyle values, WS_* + /// SCF_ISSECURE /// - [Flags] - internal enum WS : uint - { - OVERLAPPED = 0x00000000, - POPUP = 0x80000000, - CHILD = 0x40000000, - MINIMIZE = 0x20000000, - VISIBLE = 0x10000000, - DISABLED = 0x08000000, - CLIPSIBLINGS = 0x04000000, - CLIPCHILDREN = 0x02000000, - MAXIMIZE = 0x01000000, - BORDER = 0x00800000, - DLGFRAME = 0x00400000, - VSCROLL = 0x00200000, - HSCROLL = 0x00100000, - SYSMENU = 0x00080000, - THICKFRAME = 0x00040000, - GROUP = 0x00020000, - TABSTOP = 0x00010000, - - MINIMIZEBOX = 0x00020000, - MAXIMIZEBOX = 0x00010000, - - CAPTION = BORDER | DLGFRAME, - TILED = OVERLAPPED, - ICONIC = MINIMIZE, - SIZEBOX = THICKFRAME, - TILEDWINDOW = OVERLAPPEDWINDOW, - - OVERLAPPEDWINDOW = OVERLAPPED | CAPTION | SYSMENU | THICKFRAME | MINIMIZEBOX | MAXIMIZEBOX, - POPUPWINDOW = POPUP | BORDER | SYSMENU, - CHILDWINDOW = CHILD, - } + F_ISSECURE = 0x00000001, + ICON = MINIMIZE, + ZOOM = MAXIMIZE, + } + + /// + /// GDI+ Status codes + /// + internal enum Status + { + Ok = 0, + GenericError = 1, + InvalidParameter = 2, + OutOfMemory = 3, + ObjectBusy = 4, + InsufficientBuffer = 5, + NotImplemented = 6, + Win32Error = 7, + WrongState = 8, + Aborted = 9, + FileNotFound = 10, + ValueOverflow = 11, + AccessDenied = 12, + UnknownImageFormat = 13, + FontFamilyNotFound = 14, + FontStyleNotFound = 15, + NotTrueTypeFont = 16, + UnsupportedGdiplusVersion = 17, + GdiplusNotInitialized = 18, + PropertyNotFound = 19, + PropertyNotSupported = 20, + ProfileNotFound = 21, + } + + internal enum MOUSEEVENTF : int + { + //mouse event constants + LEFTDOWN = 2, + LEFTUP = 4 + } + + /// + /// MSGFLT_*. New in Vista. Realiased in Windows 7. + /// + internal enum MSGFLT + { + // Win7 versions of this enum: + RESET = 0, + ALLOW = 1, + DISALLOW = 2, + + // Vista versions of this enum: + // ADD = 1, + // REMOVE = 2, + } + + internal enum MSGFLTINFO + { + NONE = 0, + ALREADYALLOWED_FORWND = 1, + ALREADYDISALLOWED_FORWND = 2, + ALLOWED_HIGHER = 3, + } + + internal enum INPUT_TYPE : uint + { + MOUSE = 0, + } + + /// + /// Shell_NotifyIcon messages. NIM_* + /// + internal enum NIM : uint + { + ADD = 0, + MODIFY = 1, + DELETE = 2, + SETFOCUS = 3, + SETVERSION = 4, + } + + /// + /// SHAddToRecentDocuments flags. SHARD_* + /// + internal enum SHARD + { + PIDL = 0x00000001, + PATHA = 0x00000002, + PATHW = 0x00000003, + APPIDINFO = 0x00000004, // indicates the data type is a pointer to a SHARDAPPIDINFO structure + APPIDINFOIDLIST = 0x00000005, // indicates the data type is a pointer to a SHARDAPPIDINFOIDLIST structure + LINK = 0x00000006, // indicates the data type is a pointer to an IShellLink instance + APPIDINFOLINK = 0x00000007, // indicates the data type is a pointer to a SHARDAPPIDINFOLINK structure + } + + [Flags] + enum SLGP + { + SHORTPATH = 0x1, + UNCPRIORITY = 0x2, + RAWPATH = 0x4 + } + + /// + /// Shell_NotifyIcon flags. NIF_* + /// + [Flags] + internal enum NIF : uint + { + MESSAGE = 0x0001, + ICON = 0x0002, + TIP = 0x0004, + STATE = 0x0008, + INFO = 0x0010, + GUID = 0x0020, /// - /// Window message values, WM_* + /// Vista only. /// - internal enum WM - { - NULL = 0x0000, - CREATE = 0x0001, - DESTROY = 0x0002, - MOVE = 0x0003, - SIZE = 0x0005, - ACTIVATE = 0x0006, - SETFOCUS = 0x0007, - KILLFOCUS = 0x0008, - ENABLE = 0x000A, - SETREDRAW = 0x000B, - SETTEXT = 0x000C, - GETTEXT = 0x000D, - GETTEXTLENGTH = 0x000E, - PAINT = 0x000F, - CLOSE = 0x0010, - QUERYENDSESSION = 0x0011, - QUIT = 0x0012, - QUERYOPEN = 0x0013, - ERASEBKGND = 0x0014, - SYSCOLORCHANGE = 0x0015, - SHOWWINDOW = 0x0018, - CTLCOLOR = 0x0019, - WININICHANGE = 0x001A, - SETTINGCHANGE = 0x001A, - ACTIVATEAPP = 0x001C, - SETCURSOR = 0x0020, - MOUSEACTIVATE = 0x0021, - CHILDACTIVATE = 0x0022, - QUEUESYNC = 0x0023, - GETMINMAXINFO = 0x0024, - - WINDOWPOSCHANGING = 0x0046, - WINDOWPOSCHANGED = 0x0047, - - CONTEXTMENU = 0x007B, - STYLECHANGING = 0x007C, - STYLECHANGED = 0x007D, - DISPLAYCHANGE = 0x007E, - GETICON = 0x007F, - SETICON = 0x0080, - NCCREATE = 0x0081, - NCDESTROY = 0x0082, - NCCALCSIZE = 0x0083, - NCHITTEST = 0x0084, - NCPAINT = 0x0085, - NCACTIVATE = 0x0086, - GETDLGCODE = 0x0087, - SYNCPAINT = 0x0088, - NCMOUSEMOVE = 0x00A0, - NCLBUTTONDOWN = 0x00A1, - NCLBUTTONUP = 0x00A2, - NCLBUTTONDBLCLK = 0x00A3, - NCRBUTTONDOWN = 0x00A4, - NCRBUTTONUP = 0x00A5, - NCRBUTTONDBLCLK = 0x00A6, - NCMBUTTONDOWN = 0x00A7, - NCMBUTTONUP = 0x00A8, - NCMBUTTONDBLCLK = 0x00A9, - - SYSKEYDOWN = 0x0104, - SYSKEYUP = 0x0105, - SYSCHAR = 0x0106, - SYSDEADCHAR = 0x0107, - COMMAND = 0x0111, - SYSCOMMAND = 0x0112, - - MOUSEMOVE = 0x0200, - LBUTTONDOWN = 0x0201, - LBUTTONUP = 0x0202, - LBUTTONDBLCLK = 0x0203, - RBUTTONDOWN = 0x0204, - RBUTTONUP = 0x0205, - RBUTTONDBLCLK = 0x0206, - MBUTTONDOWN = 0x0207, - MBUTTONUP = 0x0208, - MBUTTONDBLCLK = 0x0209, - MOUSEWHEEL = 0x020A, - XBUTTONDOWN = 0x020B, - XBUTTONUP = 0x020C, - XBUTTONDBLCLK = 0x020D, - MOUSEHWHEEL = 0x020E, - PARENTNOTIFY = 0x0210, - - CAPTURECHANGED = 0x0215, - POWERBROADCAST = 0x0218, - DEVICECHANGE = 0x0219, - - ENTERSIZEMOVE = 0x0231, - EXITSIZEMOVE = 0x0232, - - IME_SETCONTEXT = 0x0281, - IME_NOTIFY = 0x0282, - IME_CONTROL = 0x0283, - IME_COMPOSITIONFULL = 0x0284, - IME_SELECT = 0x0285, - IME_CHAR = 0x0286, - IME_REQUEST = 0x0288, - IME_KEYDOWN = 0x0290, - IME_KEYUP = 0x0291, - - NCMOUSELEAVE = 0x02A2, - - TABLET_DEFBASE = 0x02C0, - //WM_TABLET_MAXOFFSET = 0x20, - - TABLET_ADDED = TABLET_DEFBASE + 8, - TABLET_DELETED = TABLET_DEFBASE + 9, - TABLET_FLICK = TABLET_DEFBASE + 11, - TABLET_QUERYSYSTEMGESTURESTATUS = TABLET_DEFBASE + 12, - - CUT = 0x0300, - COPY = 0x0301, - PASTE = 0x0302, - CLEAR = 0x0303, - UNDO = 0x0304, - RENDERFORMAT = 0x0305, - RENDERALLFORMATS = 0x0306, - DESTROYCLIPBOARD = 0x0307, - DRAWCLIPBOARD = 0x0308, - PAINTCLIPBOARD = 0x0309, - VSCROLLCLIPBOARD = 0x030A, - SIZECLIPBOARD = 0x030B, - ASKCBFORMATNAME = 0x030C, - CHANGECBCHAIN = 0x030D, - HSCROLLCLIPBOARD = 0x030E, - QUERYNEWPALETTE = 0x030F, - PALETTEISCHANGING = 0x0310, - PALETTECHANGED = 0x0311, - HOTKEY = 0x0312, - PRINT = 0x0317, - PRINTCLIENT = 0x0318, - APPCOMMAND = 0x0319, - THEMECHANGED = 0x031A, - - DWMCOMPOSITIONCHANGED = 0x031E, - DWMNCRENDERINGCHANGED = 0x031F, - DWMCOLORIZATIONCOLORCHANGED = 0x0320, - DWMWINDOWMAXIMIZEDCHANGE = 0x0321, - - GETTITLEBARINFOEX = 0x033F, - #region Windows 7 - DWMSENDICONICTHUMBNAIL = 0x0323, - DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326, - #endregion - - USER = 0x0400, - - // This is the hard-coded message value used by WinForms for Shell_NotifyIcon. - // It's relatively safe to reuse. - TRAYMOUSEMESSAGE = 0x800, //WM_USER + 1024 - APP = 0x8000, - } - + REALTIME = 0x0040, /// - /// Window style extended values, WS_EX_* + /// Vista only. /// - [Flags] - internal enum WS_EX : uint - { - None = 0, - DLGMODALFRAME = 0x00000001, - NOPARENTNOTIFY = 0x00000004, - TOPMOST = 0x00000008, - ACCEPTFILES = 0x00000010, - TRANSPARENT = 0x00000020, - MDICHILD = 0x00000040, - TOOLWINDOW = 0x00000080, - WINDOWEDGE = 0x00000100, - CLIENTEDGE = 0x00000200, - CONTEXTHELP = 0x00000400, - RIGHT = 0x00001000, - LEFT = 0x00000000, - RTLREADING = 0x00002000, - LTRREADING = 0x00000000, - LEFTSCROLLBAR = 0x00004000, - RIGHTSCROLLBAR = 0x00000000, - CONTROLPARENT = 0x00010000, - STATICEDGE = 0x00020000, - APPWINDOW = 0x00040000, - LAYERED = 0x00080000, - NOINHERITLAYOUT = 0x00100000, // Disable inheritence of mirroring by children - LAYOUTRTL = 0x00400000, // Right to left mirroring - COMPOSITED = 0x02000000, - NOACTIVATE = 0x08000000, - OVERLAPPEDWINDOW = (WINDOWEDGE | CLIENTEDGE), - PALETTEWINDOW = (WINDOWEDGE | TOOLWINDOW | TOPMOST), - } + SHOWTIP = 0x0080, + + XP_MASK = MESSAGE | ICON | STATE | INFO | GUID, + VISTA_MASK = XP_MASK | REALTIME | SHOWTIP, + } + + /// + /// Shell_NotifyIcon info flags. NIIF_* + /// + internal enum NIIF + { + NONE = 0x00000000, + INFO = 0x00000001, + WARNING = 0x00000002, + ERROR = 0x00000003, + /// XP SP2 and later. + USER = 0x00000004, + /// XP and later. + NOSOUND = 0x00000010, + /// Vista and later. + LARGE_ICON = 0x00000020, + /// Windows 7 and later + NIIF_RESPECT_QUIET_TIME = 0x00000080, + /// XP and later. Native version called NIIF_ICON_MASK. + XP_ICON_MASK = 0x0000000F, + } + + /// + /// AC_* + /// + internal enum AC : byte + { + SRC_OVER = 0, + SRC_ALPHA = 1, + } + + internal enum ULW + { + ALPHA = 2, + COLORKEY = 1, + OPAQUE = 4, + } + + internal enum WVR + { + ALIGNTOP = 0x0010, + ALIGNLEFT = 0x0020, + ALIGNBOTTOM = 0x0040, + ALIGNRIGHT = 0x0080, + HREDRAW = 0x0100, + VREDRAW = 0x0200, + VALIDRECTS = 0x0400, + REDRAW = HREDRAW | VREDRAW, + } + + #endregion + + #region SafeHandles + + internal sealed class SafeFindHandle : SafeHandleZeroOrMinusOneIsInvalid + { + [SecurityPermission( SecurityAction.LinkDemand, UnmanagedCode = true )] + private SafeFindHandle() : base( true ) { } + + protected override bool ReleaseHandle() + { + return NativeMethods.FindClose( handle ); + } + } + + internal sealed class SafeDC : SafeHandleZeroOrMinusOneIsInvalid + { + private static class NativeMethods + { + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll" )] + public static extern int ReleaseDC( IntPtr hWnd, IntPtr hDC ); - /// - /// GetDeviceCaps nIndex values. - /// - internal enum DeviceCap - { - /// Number of bits per pixel - /// - BITSPIXEL = 12, - /// - /// Number of planes - /// - PLANES = 14, - /// - /// Logical pixels inch in X - /// - LOGPIXELSX = 88, - /// - /// Logical pixels inch in Y - /// - LOGPIXELSY = 90, - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll" )] + public static extern SafeDC GetDC( IntPtr hwnd ); + + // Weird legacy function, documentation is unclear about how to use it... + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdi32.dll", CharSet = CharSet.Unicode )] + public static extern SafeDC CreateDC( [MarshalAs( UnmanagedType.LPWStr )] string lpszDriver, [MarshalAs( UnmanagedType.LPWStr )] string lpszDevice, IntPtr lpszOutput, IntPtr lpInitData ); - internal enum FO : int - { - MOVE = 0x0001, - COPY = 0x0002, - DELETE = 0x0003, - RENAME = 0x0004, - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdi32.dll", CharSet = CharSet.Unicode, SetLastError = true )] + public static extern SafeDC CreateCompatibleDC( IntPtr hdc ); - /// - /// "FILEOP_FLAGS", FOF_*. - /// - internal enum FOF : ushort - { - MULTIDESTFILES = 0x0001, - CONFIRMMOUSE = 0x0002, - SILENT = 0x0004, - RENAMEONCOLLISION = 0x0008, - NOCONFIRMATION = 0x0010, - WANTMAPPINGHANDLE = 0x0020, - ALLOWUNDO = 0x0040, - FILESONLY = 0x0080, - SIMPLEPROGRESS = 0x0100, - NOCONFIRMMKDIR = 0x0200, - NOERRORUI = 0x0400, - NOCOPYSECURITYATTRIBS = 0x0800, - NORECURSION = 0x1000, - NO_CONNECTED_ELEMENTS = 0x2000, - WANTNUKEWARNING = 0x4000, - NORECURSEREPARSE = 0x8000, - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdi32.dll" )] + [return: MarshalAs( UnmanagedType.Bool )] + public static extern bool DeleteDC( IntPtr hdc ); + } + + private IntPtr? _hwnd; + private bool _created; - /// - /// EnableMenuItem uEnable values, MF_* - /// - [Flags] - internal enum MF : uint + public IntPtr Hwnd { - /// - /// Possible return value for EnableMenuItem - /// - DOES_NOT_EXIST = unchecked((uint)-1), - ENABLED = 0, - BYCOMMAND = 0, - GRAYED = 1, - DISABLED = 2, + set + { + Assert.NullableIsNull( _hwnd ); + _hwnd = value; + } } - /// Specifies the type of visual style attribute to set on a window. - internal enum WINDOWTHEMEATTRIBUTETYPE : uint - { - /// Non-client area window attributes will be set. - WTA_NONCLIENT = 1, - } + private SafeDC() : base( true ) { } - /// - /// DWMFLIP3DWINDOWPOLICY. DWMFLIP3D_* - /// - internal enum DWMFLIP3D + [ReliabilityContract( Consistency.WillNotCorruptState, Cer.MayFail )] + protected override bool ReleaseHandle() { - DEFAULT, - EXCLUDEBELOW, - EXCLUDEABOVE, - //LAST - } + if( _created ) + { + return NativeMethods.DeleteDC( handle ); + } - /// - /// DWMNCRENDERINGPOLICY. DWMNCRP_* - /// - internal enum DWMNCRP - { - USEWINDOWSTYLE, - DISABLED, - ENABLED, - //LAST + if( !_hwnd.HasValue || _hwnd.Value == IntPtr.Zero ) + { + return true; + } + + return NativeMethods.ReleaseDC( _hwnd.Value, handle ) == 1; } - /// - /// DWMWINDOWATTRIBUTE. DWMWA_* - /// - internal enum DWMWA + [SuppressMessage( "Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes" ), SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static SafeDC CreateDC( string deviceName ) { - NCRENDERING_ENABLED = 1, - NCRENDERING_POLICY, - TRANSITIONS_FORCEDISABLED, - ALLOW_NCPAINT, - CAPTION_BUTTON_BOUNDS, - NONCLIENT_RTL_LAYOUT, - FORCE_ICONIC_REPRESENTATION, - FLIP3D_POLICY, - EXTENDED_FRAME_BOUNDS, - - // New to Windows 7: + SafeDC dc = null; + try + { + // Should this really be on the driver parameter? + dc = NativeMethods.CreateDC( deviceName, null, IntPtr.Zero, IntPtr.Zero ); + } + finally + { + if( dc != null ) + { + dc._created = true; + } + } - HAS_ICONIC_BITMAP, - DISALLOW_PEEK, - EXCLUDED_FROM_PEEK, + if( dc.IsInvalid ) + { + dc.Dispose(); + throw new SystemException( "Unable to create a device context from the specified device information." ); + } - // LAST + return dc; } - /// - /// WindowThemeNonClientAttributes - /// - [Flags] - internal enum WTNCA : uint + [SuppressMessage( "Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes" ), SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static SafeDC CreateCompatibleDC( SafeDC hdc ) { - /// Prevents the window caption from being drawn. - NODRAWCAPTION = 0x00000001, - /// Prevents the system icon from being drawn. - NODRAWICON = 0x00000002, - /// Prevents the system icon menu from appearing. - NOSYSMENU = 0x00000004, - /// Prevents mirroring of the question mark, even in right-to-left (RTL) layout. - NOMIRRORHELP = 0x00000008, - /// A mask that contains all the valid bits. - VALIDBITS = NODRAWCAPTION | NODRAWICON | NOMIRRORHELP | NOSYSMENU, - } + SafeDC dc = null; + try + { + IntPtr hPtr = IntPtr.Zero; + if( hdc != null ) + { + hPtr = hdc.handle; + } + dc = NativeMethods.CreateCompatibleDC( hPtr ); + if( dc == null ) + { + HRESULT.ThrowLastError(); + } + } + finally + { + if( dc != null ) + { + dc._created = true; + } + } - /// - /// SetWindowPos options - /// - [Flags] - internal enum SWP - { - ASYNCWINDOWPOS = 0x4000, - DEFERERASE = 0x2000, - DRAWFRAME = 0x0020, - FRAMECHANGED = 0x0020, - HIDEWINDOW = 0x0080, - NOACTIVATE = 0x0010, - NOCOPYBITS = 0x0100, - NOMOVE = 0x0002, - NOOWNERZORDER = 0x0200, - NOREDRAW = 0x0008, - NOREPOSITION = 0x0200, - NOSENDCHANGING = 0x0400, - NOSIZE = 0x0001, - NOZORDER = 0x0004, - SHOWWINDOW = 0x0040, - } + if( dc.IsInvalid ) + { + dc.Dispose(); + throw new SystemException( "Unable to create a device context from the specified device information." ); + } - /// - /// ShowWindow options - /// - internal enum SW - { - HIDE = 0, - SHOWNORMAL = 1, - NORMAL = 1, - SHOWMINIMIZED = 2, - SHOWMAXIMIZED = 3, - MAXIMIZE = 3, - SHOWNOACTIVATE = 4, - SHOW = 5, - MINIMIZE = 6, - SHOWMINNOACTIVE = 7, - SHOWNA = 8, - RESTORE = 9, - SHOWDEFAULT = 10, - FORCEMINIMIZE = 11, - } - - internal enum SC - { - SIZE = 0xF000, - MOVE = 0xF010, - MINIMIZE = 0xF020, - MAXIMIZE = 0xF030, - NEXTWINDOW = 0xF040, - PREVWINDOW = 0xF050, - CLOSE = 0xF060, - VSCROLL = 0xF070, - HSCROLL = 0xF080, - MOUSEMENU = 0xF090, - KEYMENU = 0xF100, - ARRANGE = 0xF110, - RESTORE = 0xF120, - TASKLIST = 0xF130, - SCREENSAVE = 0xF140, - HOTKEY = 0xF150, - DEFAULT = 0xF160, - MONITORPOWER = 0xF170, - CONTEXTHELP = 0xF180, - SEPARATOR = 0xF00F, - /// - /// SCF_ISSECURE - /// - F_ISSECURE = 0x00000001, - ICON = MINIMIZE, - ZOOM = MAXIMIZE, + return dc; } - /// - /// GDI+ Status codes - /// - internal enum Status - { - Ok = 0, - GenericError = 1, - InvalidParameter = 2, - OutOfMemory = 3, - ObjectBusy = 4, - InsufficientBuffer = 5, - NotImplemented = 6, - Win32Error = 7, - WrongState = 8, - Aborted = 9, - FileNotFound = 10, - ValueOverflow = 11, - AccessDenied = 12, - UnknownImageFormat = 13, - FontFamilyNotFound = 14, - FontStyleNotFound = 15, - NotTrueTypeFont = 16, - UnsupportedGdiplusVersion = 17, - GdiplusNotInitialized = 18, - PropertyNotFound = 19, - PropertyNotSupported = 20, - ProfileNotFound = 21, - } - - internal enum MOUSEEVENTF : int - { - //mouse event constants - LEFTDOWN = 2, - LEFTUP = 4 - } - - /// - /// MSGFLT_*. New in Vista. Realiased in Windows 7. - /// - internal enum MSGFLT + public static SafeDC GetDC( IntPtr hwnd ) { - // Win7 versions of this enum: - RESET = 0, - ALLOW = 1, - DISALLOW = 2, + SafeDC dc = null; + try + { + dc = NativeMethods.GetDC( hwnd ); + } + finally + { + if( dc != null ) + { + dc.Hwnd = hwnd; + } + } - // Vista versions of this enum: - // ADD = 1, - // REMOVE = 2, - } + if( dc.IsInvalid ) + { + // GetDC does not set the last error... + HRESULT.E_FAIL.ThrowIfFailed(); + } - internal enum MSGFLTINFO - { - NONE = 0, - ALREADYALLOWED_FORWND = 1, - ALREADYDISALLOWED_FORWND = 2, - ALLOWED_HIGHER = 3, + return dc; } - internal enum INPUT_TYPE : uint + public static SafeDC GetDesktop() { - MOUSE = 0, + return GetDC( IntPtr.Zero ); } - /// - /// Shell_NotifyIcon messages. NIM_* - /// - internal enum NIM : uint + [SuppressMessage( "Microsoft.Reliability", "CA2000:Dispose objects before losing scope" )] + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static SafeDC WrapDC( IntPtr hdc ) { - ADD = 0, - MODIFY = 1, - DELETE = 2, - SETFOCUS = 3, - SETVERSION = 4, + // This won't actually get released by the class, but it allows an IntPtr to be converted for signatures. + return new SafeDC + { + handle = hdc, + _created = false, + _hwnd = IntPtr.Zero, + }; } + } - /// - /// SHAddToRecentDocuments flags. SHARD_* - /// - internal enum SHARD + internal sealed class SafeHBITMAP : SafeHandleZeroOrMinusOneIsInvalid + { + private SafeHBITMAP() : base( true ) { } + + [ReliabilityContract( Consistency.WillNotCorruptState, Cer.MayFail )] + protected override bool ReleaseHandle() { - PIDL = 0x00000001, - PATHA = 0x00000002, - PATHW = 0x00000003, - APPIDINFO = 0x00000004, // indicates the data type is a pointer to a SHARDAPPIDINFO structure - APPIDINFOIDLIST = 0x00000005, // indicates the data type is a pointer to a SHARDAPPIDINFOIDLIST structure - LINK = 0x00000006, // indicates the data type is a pointer to an IShellLink instance - APPIDINFOLINK = 0x00000007, // indicates the data type is a pointer to a SHARDAPPIDINFOLINK structure + return NativeMethods.DeleteObject( handle ); } + } + + internal sealed class SafeGdiplusStartupToken : SafeHandleZeroOrMinusOneIsInvalid + { + private SafeGdiplusStartupToken() : base( true ) { } - [Flags] - enum SLGP + [ReliabilityContract( Consistency.WillNotCorruptState, Cer.MayFail )] + protected override bool ReleaseHandle() { - SHORTPATH = 0x1, - UNCPRIORITY = 0x2, - RAWPATH = 0x4 + Status s = NativeMethods.GdiplusShutdown( this.handle ); + return s == Status.Ok; } - /// - /// Shell_NotifyIcon flags. NIF_* - /// - [Flags] - internal enum NIF : uint + [SuppressMessage( "Microsoft.Reliability", "CA2000:Dispose objects before losing scope" )] + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [SuppressMessage( "Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes" )] + public static SafeGdiplusStartupToken Startup() { - MESSAGE = 0x0001, - ICON = 0x0002, - TIP = 0x0004, - STATE = 0x0008, - INFO = 0x0010, - GUID = 0x0020, - - /// - /// Vista only. - /// - REALTIME = 0x0040, - /// - /// Vista only. - /// - SHOWTIP = 0x0080, - - XP_MASK = MESSAGE | ICON | STATE | INFO | GUID, - VISTA_MASK = XP_MASK | REALTIME | SHOWTIP, + SafeGdiplusStartupToken safeHandle = new SafeGdiplusStartupToken(); + IntPtr unsafeHandle; + StartupOutput output; + Status s = NativeMethods.GdiplusStartup( out unsafeHandle, new StartupInput(), out output ); + if( s == Status.Ok ) + { + safeHandle.handle = unsafeHandle; + return safeHandle; + } + safeHandle.Dispose(); + throw new Exception( "Unable to initialize GDI+" ); } + } - /// - /// Shell_NotifyIcon info flags. NIIF_* - /// - internal enum NIIF - { - NONE = 0x00000000, - INFO = 0x00000001, - WARNING = 0x00000002, - ERROR = 0x00000003, - /// XP SP2 and later. - USER = 0x00000004, - /// XP and later. - NOSOUND = 0x00000010, - /// Vista and later. - LARGE_ICON = 0x00000020, - /// Windows 7 and later - NIIF_RESPECT_QUIET_TIME = 0x00000080, - /// XP and later. Native version called NIIF_ICON_MASK. - XP_ICON_MASK = 0x0000000F, - } + internal sealed class SafeConnectionPointCookie : SafeHandleZeroOrMinusOneIsInvalid + { + private IConnectionPoint _cp; + // handle holds the cookie value. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [SuppressMessage( "Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "IConnectionPoint" )] + public SafeConnectionPointCookie( IConnectionPointContainer target, object sink, Guid eventId ) + : base( true ) + { + Verify.IsNotNull( target, "target" ); + Verify.IsNotNull( sink, "sink" ); + Verify.IsNotDefault( eventId, "eventId" ); + + handle = IntPtr.Zero; + + IConnectionPoint cp = null; + try + { + int dwCookie; + target.FindConnectionPoint( ref eventId, out cp ); + cp.Advise( sink, out dwCookie ); + if( dwCookie == 0 ) + { + throw new InvalidOperationException( "IConnectionPoint::Advise returned an invalid cookie." ); + } + handle = new IntPtr( dwCookie ); + _cp = cp; + cp = null; + } + finally + { + Utility.SafeRelease( ref cp ); + } + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public void Disconnect() + { + ReleaseHandle(); + } + + [SuppressMessage( "Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes" )] + [ReliabilityContract( Consistency.WillNotCorruptState, Cer.MayFail )] + protected override bool ReleaseHandle() + { + try + { + if( !this.IsInvalid ) + { + int dwCookie = handle.ToInt32(); + handle = IntPtr.Zero; + + Assert.IsNotNull( _cp ); + try + { + _cp.Unadvise( dwCookie ); + } + finally + { + Utility.SafeRelease( ref _cp ); + } + } + return true; + } + catch + { + return false; + } + } + } + + #endregion + + #region Native Types + + [StructLayout( LayoutKind.Sequential )] + internal struct BLENDFUNCTION + { + // Must be AC_SRC_OVER + public AC BlendOp; + // Must be 0. + public byte BlendFlags; + // Alpha transparency between 0 (transparent) - 255 (opaque) + public byte SourceConstantAlpha; + // Must be AC_SRC_ALPHA + public AC AlphaFormat; + } + + [StructLayout( LayoutKind.Sequential )] + internal struct HIGHCONTRAST + { + public int cbSize; + public HCF dwFlags; + //[MarshalAs(UnmanagedType.LPWStr, SizeConst=80)] + //public String lpszDefaultScheme; + public IntPtr lpszDefaultScheme; + } + + [StructLayout( LayoutKind.Sequential )] + internal struct RGBQUAD + { + public byte rgbBlue; + public byte rgbGreen; + public byte rgbRed; + public byte rgbReserved; + } + + [StructLayout( LayoutKind.Sequential, Pack = 2 )] + internal struct BITMAPINFOHEADER + { + public int biSize; + public int biWidth; + public int biHeight; + public short biPlanes; + public short biBitCount; + public BI biCompression; + public int biSizeImage; + public int biXPelsPerMeter; + public int biYPelsPerMeter; + public int biClrUsed; + public int biClrImportant; + } + + [StructLayout( LayoutKind.Sequential )] + internal struct BITMAPINFO + { + public BITMAPINFOHEADER bmiHeader; + public RGBQUAD bmiColors; + } + + // Win7 only. + [StructLayout( LayoutKind.Sequential )] + internal struct CHANGEFILTERSTRUCT + { + public uint cbSize; + public MSGFLTINFO ExtStatus; + } + + [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Unicode )] + internal struct CREATESTRUCT + { + public IntPtr lpCreateParams; + public IntPtr hInstance; + public IntPtr hMenu; + public IntPtr hwndParent; + public int cy; + public int cx; + public int y; + public int x; + public WS style; + [MarshalAs( UnmanagedType.LPWStr )] + public string lpszName; + [MarshalAs( UnmanagedType.LPWStr )] + public string lpszClass; + public WS_EX dwExStyle; + } + + [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1 )] + internal struct SHFILEOPSTRUCT + { + public IntPtr hwnd; + [MarshalAs( UnmanagedType.U4 )] + public FO wFunc; + // double-null terminated arrays of LPWSTRS + public string pFrom; + public string pTo; + [MarshalAs( UnmanagedType.U2 )] + public FOF fFlags; + [MarshalAs( UnmanagedType.Bool )] + public int fAnyOperationsAborted; + public IntPtr hNameMappings; + public string lpszProgressTitle; + } + + [StructLayout( LayoutKind.Sequential )] + internal struct TITLEBARINFO + { + public int cbSize; + public RECT rcTitleBar; + public STATE_SYSTEM rgstate_TitleBar; + public STATE_SYSTEM rgstate_Reserved; + public STATE_SYSTEM rgstate_MinimizeButton; + public STATE_SYSTEM rgstate_MaximizeButton; + public STATE_SYSTEM rgstate_HelpButton; + public STATE_SYSTEM rgstate_CloseButton; + } + + // New to Vista. + [StructLayout( LayoutKind.Sequential )] + internal struct TITLEBARINFOEX + { + public int cbSize; + public RECT rcTitleBar; + public STATE_SYSTEM rgstate_TitleBar; + public STATE_SYSTEM rgstate_Reserved; + public STATE_SYSTEM rgstate_MinimizeButton; + public STATE_SYSTEM rgstate_MaximizeButton; + public STATE_SYSTEM rgstate_HelpButton; + public STATE_SYSTEM rgstate_CloseButton; + public RECT rgrect_TitleBar; + public RECT rgrect_Reserved; + public RECT rgrect_MinimizeButton; + public RECT rgrect_MaximizeButton; + public RECT rgrect_HelpButton; + public RECT rgrect_CloseButton; + } + + [SuppressMessage( "Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses" )] + [StructLayout( LayoutKind.Sequential )] + internal class NOTIFYICONDATA + { + public int cbSize; + public IntPtr hWnd; + public int uID; + public NIF uFlags; + public int uCallbackMessage; + public IntPtr hIcon; + [MarshalAs( UnmanagedType.ByValArray, SizeConst = 128 )] + public char[] szTip = new char[ 128 ]; /// - /// AC_* + /// The state of the icon. There are two flags that can be set independently. + /// NIS_HIDDEN = 1. The icon is hidden. + /// NIS_SHAREDICON = 2. The icon is shared. /// - internal enum AC : byte - { - SRC_OVER = 0, - SRC_ALPHA = 1, - } + public uint dwState; + public uint dwStateMask; + [MarshalAs( UnmanagedType.ByValArray, SizeConst = 256 )] + public char[] szInfo = new char[ 256 ]; + // Prior to Vista this was a union of uTimeout and uVersion. As of Vista, uTimeout has been deprecated. + public uint uVersion; // Used with Shell_NotifyIcon flag NIM_SETVERSION. + [MarshalAs( UnmanagedType.ByValArray, SizeConst = 64 )] + public char[] szInfoTitle = new char[ 64 ]; + public uint dwInfoFlags; + public Guid guidItem; + // Vista only + IntPtr hBalloonIcon; + } - internal enum ULW + [SuppressMessage( "Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses" )] + [StructLayout( LayoutKind.Explicit )] + internal class PROPVARIANT : IDisposable + { + private static class NativeMethods { - ALPHA = 2, - COLORKEY = 1, - OPAQUE = 4, + [DllImport( "ole32.dll" )] + internal static extern HRESULT PropVariantClear( PROPVARIANT pvar ); } - internal enum WVR + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + [FieldOffset( 0 )] + private ushort vt; + [SuppressMessage( "Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources" )] + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + [FieldOffset( 8 )] + private IntPtr pointerVal; + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + [FieldOffset( 8 )] + private byte byteVal; + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + [FieldOffset( 8 )] + private long longVal; + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] + [FieldOffset( 8 )] + private short boolVal; + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public VarEnum VarType { - ALIGNTOP = 0x0010, - ALIGNLEFT = 0x0020, - ALIGNBOTTOM = 0x0040, - ALIGNRIGHT = 0x0080, - HREDRAW = 0x0100, - VREDRAW = 0x0200, - VALIDRECTS = 0x0400, - REDRAW = HREDRAW | VREDRAW, + get + { + return ( VarEnum )vt; + } } - #endregion - - #region SafeHandles - - internal sealed class SafeFindHandle : SafeHandleZeroOrMinusOneIsInvalid + // Right now only using this for strings. + [SuppressMessage( "Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands" )] + public string GetValue() { - [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] - private SafeFindHandle() : base(true) { } + if( vt == ( ushort )VarEnum.VT_LPWSTR ) + { + return Marshal.PtrToStringUni( pointerVal ); + } - protected override bool ReleaseHandle() - { - return NativeMethods.FindClose(handle); - } + return null; } - internal sealed class SafeDC : SafeHandleZeroOrMinusOneIsInvalid + public void SetValue( bool f ) { - private static class NativeMethods - { - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll")] - public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll")] - public static extern SafeDC GetDC(IntPtr hwnd); - - // Weird legacy function, documentation is unclear about how to use it... - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdi32.dll", CharSet = CharSet.Unicode)] - public static extern SafeDC CreateDC([MarshalAs(UnmanagedType.LPWStr)] string lpszDriver, [MarshalAs(UnmanagedType.LPWStr)] string lpszDevice, IntPtr lpszOutput, IntPtr lpInitData); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern SafeDC CreateCompatibleDC(IntPtr hdc); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdi32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool DeleteDC(IntPtr hdc); - } - - private IntPtr? _hwnd; - private bool _created; - - public IntPtr Hwnd - { - set - { - Assert.NullableIsNull(_hwnd); - _hwnd = value; - } - } - - private SafeDC() : base(true) { } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - if (_created) - { - return NativeMethods.DeleteDC(handle); - } - - if (!_hwnd.HasValue || _hwnd.Value == IntPtr.Zero) - { - return true; - } - - return NativeMethods.ReleaseDC(_hwnd.Value, handle) == 1; - } - - [SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes"), SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static SafeDC CreateDC(string deviceName) - { - SafeDC dc = null; - try - { - // Should this really be on the driver parameter? - dc = NativeMethods.CreateDC(deviceName, null, IntPtr.Zero, IntPtr.Zero); - } - finally - { - if (dc != null) - { - dc._created = true; - } - } - - if (dc.IsInvalid) - { - dc.Dispose(); - throw new SystemException("Unable to create a device context from the specified device information."); - } - - return dc; - } - - [SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes"), SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static SafeDC CreateCompatibleDC(SafeDC hdc) - { - SafeDC dc = null; - try - { - IntPtr hPtr = IntPtr.Zero; - if (hdc != null) - { - hPtr = hdc.handle; - } - dc = NativeMethods.CreateCompatibleDC(hPtr); - if (dc == null) - { - HRESULT.ThrowLastError(); - } - } - finally - { - if (dc != null) - { - dc._created = true; - } - } - - if (dc.IsInvalid) - { - dc.Dispose(); - throw new SystemException("Unable to create a device context from the specified device information."); - } - - return dc; - } - - public static SafeDC GetDC(IntPtr hwnd) - { - SafeDC dc = null; - try - { - dc = NativeMethods.GetDC(hwnd); - } - finally - { - if (dc != null) - { - dc.Hwnd = hwnd; - } - } - - if (dc.IsInvalid) - { - // GetDC does not set the last error... - HRESULT.E_FAIL.ThrowIfFailed(); - } - - return dc; - } - - public static SafeDC GetDesktop() - { - return GetDC(IntPtr.Zero); - } - - [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static SafeDC WrapDC(IntPtr hdc) - { - // This won't actually get released by the class, but it allows an IntPtr to be converted for signatures. - return new SafeDC - { - handle = hdc, - _created = false, - _hwnd = IntPtr.Zero, - }; - } + Clear(); + vt = ( ushort )VarEnum.VT_BOOL; + boolVal = ( short )( f ? -1 : 0 ); } - internal sealed class SafeHBITMAP : SafeHandleZeroOrMinusOneIsInvalid + [SuppressMessage( "Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands" )] + public void SetValue( string val ) { - private SafeHBITMAP() : base(true) { } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - return NativeMethods.DeleteObject(handle); - } + Clear(); + vt = ( ushort )VarEnum.VT_LPWSTR; + pointerVal = Marshal.StringToCoTaskMemUni( val ); } - internal sealed class SafeGdiplusStartupToken : SafeHandleZeroOrMinusOneIsInvalid + public void Clear() { - private SafeGdiplusStartupToken() : base(true) { } + HRESULT hr = NativeMethods.PropVariantClear( this ); + Assert.IsTrue( hr.Succeeded ); + } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - Status s = NativeMethods.GdiplusShutdown(this.handle); - return s == Status.Ok; - } + #region IDisposable Pattern - [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")] - public static SafeGdiplusStartupToken Startup() - { - SafeGdiplusStartupToken safeHandle = new SafeGdiplusStartupToken(); - IntPtr unsafeHandle; - StartupOutput output; - Status s = NativeMethods.GdiplusStartup(out unsafeHandle, new StartupInput(), out output); - if (s == Status.Ok) - { - safeHandle.handle = unsafeHandle; - return safeHandle; - } - safeHandle.Dispose(); - throw new Exception("Unable to initialize GDI+"); - } + public void Dispose() + { + Dispose( true ); + GC.SuppressFinalize( this ); } - internal sealed class SafeConnectionPointCookie : SafeHandleZeroOrMinusOneIsInvalid + ~PROPVARIANT() { - private IConnectionPoint _cp; - // handle holds the cookie value. - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "IConnectionPoint")] - public SafeConnectionPointCookie(IConnectionPointContainer target, object sink, Guid eventId) - : base(true) - { - Verify.IsNotNull(target, "target"); - Verify.IsNotNull(sink, "sink"); - Verify.IsNotDefault(eventId, "eventId"); - - handle = IntPtr.Zero; - - IConnectionPoint cp = null; - try - { - int dwCookie; - target.FindConnectionPoint(ref eventId, out cp); - cp.Advise(sink, out dwCookie); - if (dwCookie == 0) - { - throw new InvalidOperationException("IConnectionPoint::Advise returned an invalid cookie."); - } - handle = new IntPtr(dwCookie); - _cp = cp; - cp = null; - } - finally - { - Utility.SafeRelease(ref cp); - } - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public void Disconnect() - { - ReleaseHandle(); - } + Dispose( false ); + } - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - try - { - if (!this.IsInvalid) - { - int dwCookie = handle.ToInt32(); - handle = IntPtr.Zero; - - Assert.IsNotNull(_cp); - try - { - _cp.Unadvise(dwCookie); - } - finally - { - Utility.SafeRelease(ref _cp); - } - } - return true; - } - catch - { - return false; - } - } + [SuppressMessage( "Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "disposing" )] + private void Dispose( bool disposing ) + { + Clear(); } #endregion + } + + [SuppressMessage( "Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses" )] + [StructLayout( LayoutKind.Sequential, Pack = 4 )] + internal class SHARDAPPIDINFO + { + [MarshalAs( UnmanagedType.Interface )] + object psi; // The namespace location of the the item that should be added to the recent docs folder. + [MarshalAs( UnmanagedType.LPWStr )] + string pszAppID; // The id of the application that should be associated with this recent doc. + } + + [SuppressMessage( "Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses" )] + [StructLayout( LayoutKind.Sequential, Pack = 4 )] + internal class SHARDAPPIDINFOIDLIST + { + /// The idlist for the shell item that should be added to the recent docs folder. + IntPtr pidl; + /// The id of the application that should be associated with this recent doc. + [MarshalAs( UnmanagedType.LPWStr )] + string pszAppID; + } + + [SuppressMessage( "Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses" )] + [StructLayout( LayoutKind.Sequential, Pack = 4 )] + internal class SHARDAPPIDINFOLINK + { + IntPtr psl; // An IShellLink instance that when launched opens a recently used item in the specified + // application. This link is not added to the recent docs folder, but will be added to the + // specified application's destination list. + [MarshalAs( UnmanagedType.LPWStr )] + string pszAppID; // The id of the application that should be associated with this recent doc. + } + + + [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Unicode )] + internal struct LOGFONT + { + public int lfHeight; + public int lfWidth; + public int lfEscapement; + public int lfOrientation; + public int lfWeight; + public byte lfItalic; + public byte lfUnderline; + public byte lfStrikeOut; + public byte lfCharSet; + public byte lfOutPrecision; + public byte lfClipPrecision; + public byte lfQuality; + public byte lfPitchAndFamily; + [MarshalAs( UnmanagedType.ByValTStr, SizeConst = 32 )] + public string lfFaceName; + } + + [StructLayout( LayoutKind.Sequential )] + internal struct MINMAXINFO + { + public POINT ptReserved; + public POINT ptMaxSize; + public POINT ptMaxPosition; + public POINT ptMinTrackSize; + public POINT ptMaxTrackSize; + } + + [StructLayout( LayoutKind.Sequential )] + internal struct NONCLIENTMETRICS + { + public int cbSize; + public int iBorderWidth; + public int iScrollWidth; + public int iScrollHeight; + public int iCaptionWidth; + public int iCaptionHeight; + public LOGFONT lfCaptionFont; + public int iSmCaptionWidth; + public int iSmCaptionHeight; + public LOGFONT lfSmCaptionFont; + public int iMenuWidth; + public int iMenuHeight; + public LOGFONT lfMenuFont; + public LOGFONT lfStatusFont; + public LOGFONT lfMessageFont; + // Vista only + public int iPaddedBorderWidth; + + [SuppressMessage( "Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands" )] + public static NONCLIENTMETRICS VistaMetricsStruct + { + get + { + var ncm = new NONCLIENTMETRICS(); + ncm.cbSize = Marshal.SizeOf( typeof( NONCLIENTMETRICS ) ); + return ncm; + } + } + + [SuppressMessage( "Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands" )] + public static NONCLIENTMETRICS XPMetricsStruct + { + get + { + var ncm = new NONCLIENTMETRICS(); + // Account for the missing iPaddedBorderWidth + ncm.cbSize = Marshal.SizeOf( typeof( NONCLIENTMETRICS ) ) - sizeof( int ); + return ncm; + } + } + } + + /// Defines options that are used to set window visual style attributes. + [StructLayout( LayoutKind.Explicit )] + internal struct WTA_OPTIONS + { + // public static readonly uint Size = (uint)Marshal.SizeOf(typeof(WTA_OPTIONS)); + public const uint Size = 8; - #region Native Types + /// + /// A combination of flags that modify window visual style attributes. + /// Can be a combination of the WTNCA constants. + /// + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "Used by native code." )] + [FieldOffset( 0 )] + public WTNCA dwFlags; - [StructLayout(LayoutKind.Sequential)] - internal struct BLENDFUNCTION - { - // Must be AC_SRC_OVER - public AC BlendOp; - // Must be 0. - public byte BlendFlags; - // Alpha transparency between 0 (transparent) - 255 (opaque) - public byte SourceConstantAlpha; - // Must be AC_SRC_ALPHA - public AC AlphaFormat; + /// + /// A bitmask that describes how the values specified in dwFlags should be applied. + /// If the bit corresponding to a value in dwFlags is 0, that flag will be removed. + /// If the bit is 1, the flag will be added. + /// + [SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "Used by native code." )] + [FieldOffset( 4 )] + public WTNCA dwMask; + } + + [StructLayout( LayoutKind.Sequential )] + internal struct MARGINS + { + /// Width of left border that retains its size. + public int cxLeftWidth; + /// Width of right border that retains its size. + public int cxRightWidth; + /// Height of top border that retains its size. + public int cyTopHeight; + /// Height of bottom border that retains its size. + public int cyBottomHeight; + }; + + [StructLayout( LayoutKind.Sequential )] + internal class MONITORINFO + { + public int cbSize = Marshal.SizeOf( typeof( MONITORINFO ) ); + public RECT rcMonitor; + public RECT rcWork; + public int dwFlags; + } + + [StructLayout( LayoutKind.Sequential )] + internal struct POINT + { + public int x; + public int y; + } + + [SuppressMessage( "Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses" )] + [StructLayout( LayoutKind.Sequential )] + internal class RefPOINT + { + public int x; + public int y; + } + + [StructLayout( LayoutKind.Sequential )] + internal struct RECT + { + private int _left; + private int _top; + private int _right; + private int _bottom; + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public void Offset( int dx, int dy ) + { + _left += dx; + _top += dy; + _right += dx; + _bottom += dy; + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public int Left + { + get + { + return _left; + } + set + { + _left = value; + } + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public int Right + { + get + { + return _right; + } + set + { + _right = value; + } + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public int Top + { + get + { + return _top; + } + set + { + _top = value; + } + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public int Bottom + { + get + { + return _bottom; + } + set + { + _bottom = value; + } + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public int Width + { + get + { + return _right - _left; + } } - [StructLayout(LayoutKind.Sequential)] - internal struct HIGHCONTRAST + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public int Height { - public int cbSize; - public HCF dwFlags; - //[MarshalAs(UnmanagedType.LPWStr, SizeConst=80)] - //public String lpszDefaultScheme; - public IntPtr lpszDefaultScheme; + get + { + return _bottom - _top; + } } - [StructLayout(LayoutKind.Sequential)] - internal struct RGBQUAD + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public POINT Position { - public byte rgbBlue; - public byte rgbGreen; - public byte rgbRed; - public byte rgbReserved; + get + { + return new POINT { x = _left, y = _top }; + } } - [StructLayout(LayoutKind.Sequential, Pack = 2)] - internal struct BITMAPINFOHEADER + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public SIZE Size { - public int biSize; - public int biWidth; - public int biHeight; - public short biPlanes; - public short biBitCount; - public BI biCompression; - public int biSizeImage; - public int biXPelsPerMeter; - public int biYPelsPerMeter; - public int biClrUsed; - public int biClrImportant; + get + { + return new SIZE { cx = Width, cy = Height }; + } } - [StructLayout(LayoutKind.Sequential)] - internal struct BITMAPINFO + public static RECT Union( RECT rect1, RECT rect2 ) { - public BITMAPINFOHEADER bmiHeader; - public RGBQUAD bmiColors; + return new RECT + { + Left = Math.Min( rect1.Left, rect2.Left ), + Top = Math.Min( rect1.Top, rect2.Top ), + Right = Math.Max( rect1.Right, rect2.Right ), + Bottom = Math.Max( rect1.Bottom, rect2.Bottom ), + }; } - // Win7 only. - [StructLayout(LayoutKind.Sequential)] - internal struct CHANGEFILTERSTRUCT - { - public uint cbSize; - public MSGFLTINFO ExtStatus; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct CREATESTRUCT - { - public IntPtr lpCreateParams; - public IntPtr hInstance; - public IntPtr hMenu; - public IntPtr hwndParent; - public int cy; - public int cx; - public int y; - public int x; - public WS style; - [MarshalAs(UnmanagedType.LPWStr)] - public string lpszName; - [MarshalAs(UnmanagedType.LPWStr)] - public string lpszClass; - public WS_EX dwExStyle; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)] - internal struct SHFILEOPSTRUCT - { - public IntPtr hwnd; - [MarshalAs(UnmanagedType.U4)] - public FO wFunc; - // double-null terminated arrays of LPWSTRS - public string pFrom; - public string pTo; - [MarshalAs(UnmanagedType.U2)] - public FOF fFlags; - [MarshalAs(UnmanagedType.Bool)] - public int fAnyOperationsAborted; - public IntPtr hNameMappings; - public string lpszProgressTitle; - } - - [StructLayout(LayoutKind.Sequential)] - internal struct TITLEBARINFO - { - public int cbSize; - public RECT rcTitleBar; - public STATE_SYSTEM rgstate_TitleBar; - public STATE_SYSTEM rgstate_Reserved; - public STATE_SYSTEM rgstate_MinimizeButton; - public STATE_SYSTEM rgstate_MaximizeButton; - public STATE_SYSTEM rgstate_HelpButton; - public STATE_SYSTEM rgstate_CloseButton; - } - - // New to Vista. - [StructLayout(LayoutKind.Sequential)] - internal struct TITLEBARINFOEX - { - public int cbSize; - public RECT rcTitleBar; - public STATE_SYSTEM rgstate_TitleBar; - public STATE_SYSTEM rgstate_Reserved; - public STATE_SYSTEM rgstate_MinimizeButton; - public STATE_SYSTEM rgstate_MaximizeButton; - public STATE_SYSTEM rgstate_HelpButton; - public STATE_SYSTEM rgstate_CloseButton; - public RECT rgrect_TitleBar; - public RECT rgrect_Reserved; - public RECT rgrect_MinimizeButton; - public RECT rgrect_MaximizeButton; - public RECT rgrect_HelpButton; - public RECT rgrect_CloseButton; - } - - [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")] - [StructLayout(LayoutKind.Sequential)] - internal class NOTIFYICONDATA - { - public int cbSize; - public IntPtr hWnd; - public int uID; - public NIF uFlags; - public int uCallbackMessage; - public IntPtr hIcon; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] - public char[] szTip = new char[128]; - /// - /// The state of the icon. There are two flags that can be set independently. - /// NIS_HIDDEN = 1. The icon is hidden. - /// NIS_SHAREDICON = 2. The icon is shared. - /// - public uint dwState; - public uint dwStateMask; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] - public char[] szInfo = new char[256]; - // Prior to Vista this was a union of uTimeout and uVersion. As of Vista, uTimeout has been deprecated. - public uint uVersion; // Used with Shell_NotifyIcon flag NIM_SETVERSION. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] - public char[] szInfoTitle = new char[64]; - public uint dwInfoFlags; - public Guid guidItem; - // Vista only - IntPtr hBalloonIcon; - } - - [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")] - [StructLayout(LayoutKind.Explicit)] - internal class PROPVARIANT : IDisposable - { - private static class NativeMethods - { - [DllImport("ole32.dll")] - internal static extern HRESULT PropVariantClear(PROPVARIANT pvar); - } - - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - [FieldOffset(0)] - private ushort vt; - [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")] - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - [FieldOffset(8)] - private IntPtr pointerVal; - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - [FieldOffset(8)] - private byte byteVal; - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - [FieldOffset(8)] - private long longVal; - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - [FieldOffset(8)] - private short boolVal; - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public VarEnum VarType - { - get { return (VarEnum)vt; } - } - - // Right now only using this for strings. - [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] - public string GetValue() - { - if (vt == (ushort)VarEnum.VT_LPWSTR) - { - return Marshal.PtrToStringUni(pointerVal); - } - - return null; - } - - public void SetValue(bool f) - { - Clear(); - vt = (ushort)VarEnum.VT_BOOL; - boolVal = (short)(f ? -1 : 0); - } - - [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] - public void SetValue(string val) - { - Clear(); - vt = (ushort)VarEnum.VT_LPWSTR; - pointerVal = Marshal.StringToCoTaskMemUni(val); - } - - public void Clear() - { - HRESULT hr = NativeMethods.PropVariantClear(this); - Assert.IsTrue(hr.Succeeded); - } - - #region IDisposable Pattern - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - ~PROPVARIANT() - { - Dispose(false); - } - - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "disposing")] - private void Dispose(bool disposing) - { - Clear(); - } - - #endregion - } - - [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")] - [StructLayout(LayoutKind.Sequential, Pack = 4)] - internal class SHARDAPPIDINFO - { - [MarshalAs(UnmanagedType.Interface)] - object psi; // The namespace location of the the item that should be added to the recent docs folder. - [MarshalAs(UnmanagedType.LPWStr)] - string pszAppID; // The id of the application that should be associated with this recent doc. - } - - [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")] - [StructLayout(LayoutKind.Sequential, Pack = 4)] - internal class SHARDAPPIDINFOIDLIST - { - /// The idlist for the shell item that should be added to the recent docs folder. - IntPtr pidl; - /// The id of the application that should be associated with this recent doc. - [MarshalAs(UnmanagedType.LPWStr)] - string pszAppID; - } - - [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")] - [StructLayout(LayoutKind.Sequential, Pack = 4)] - internal class SHARDAPPIDINFOLINK - { - IntPtr psl; // An IShellLink instance that when launched opens a recently used item in the specified - // application. This link is not added to the recent docs folder, but will be added to the - // specified application's destination list. - [MarshalAs(UnmanagedType.LPWStr)] - string pszAppID; // The id of the application that should be associated with this recent doc. - } - - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct LOGFONT - { - public int lfHeight; - public int lfWidth; - public int lfEscapement; - public int lfOrientation; - public int lfWeight; - public byte lfItalic; - public byte lfUnderline; - public byte lfStrikeOut; - public byte lfCharSet; - public byte lfOutPrecision; - public byte lfClipPrecision; - public byte lfQuality; - public byte lfPitchAndFamily; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] - public string lfFaceName; - } - - [StructLayout(LayoutKind.Sequential)] - internal struct MINMAXINFO - { - public POINT ptReserved; - public POINT ptMaxSize; - public POINT ptMaxPosition; - public POINT ptMinTrackSize; - public POINT ptMaxTrackSize; - } - - [StructLayout(LayoutKind.Sequential)] - internal struct NONCLIENTMETRICS - { - public int cbSize; - public int iBorderWidth; - public int iScrollWidth; - public int iScrollHeight; - public int iCaptionWidth; - public int iCaptionHeight; - public LOGFONT lfCaptionFont; - public int iSmCaptionWidth; - public int iSmCaptionHeight; - public LOGFONT lfSmCaptionFont; - public int iMenuWidth; - public int iMenuHeight; - public LOGFONT lfMenuFont; - public LOGFONT lfStatusFont; - public LOGFONT lfMessageFont; - // Vista only - public int iPaddedBorderWidth; - - [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] - public static NONCLIENTMETRICS VistaMetricsStruct - { - get - { - var ncm = new NONCLIENTMETRICS(); - ncm.cbSize = Marshal.SizeOf(typeof(NONCLIENTMETRICS)); - return ncm; - } - } - - [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] - public static NONCLIENTMETRICS XPMetricsStruct - { - get - { - var ncm = new NONCLIENTMETRICS(); - // Account for the missing iPaddedBorderWidth - ncm.cbSize = Marshal.SizeOf(typeof(NONCLIENTMETRICS)) - sizeof(int); - return ncm; - } - } - } - - /// Defines options that are used to set window visual style attributes. - [StructLayout(LayoutKind.Explicit)] - internal struct WTA_OPTIONS + public override bool Equals( object obj ) { - // public static readonly uint Size = (uint)Marshal.SizeOf(typeof(WTA_OPTIONS)); - public const uint Size = 8; - - /// - /// A combination of flags that modify window visual style attributes. - /// Can be a combination of the WTNCA constants. - /// - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "Used by native code.")] - [FieldOffset(0)] - public WTNCA dwFlags; - - /// - /// A bitmask that describes how the values specified in dwFlags should be applied. - /// If the bit corresponding to a value in dwFlags is 0, that flag will be removed. - /// If the bit is 1, the flag will be added. - /// - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "Used by native code.")] - [FieldOffset(4)] - public WTNCA dwMask; + try + { + var rc = ( RECT )obj; + return rc._bottom == _bottom + && rc._left == _left + && rc._right == _right + && rc._top == _top; + } + catch( InvalidCastException ) + { + return false; + } } - [StructLayout(LayoutKind.Sequential)] - internal struct MARGINS + public override int GetHashCode() { - /// Width of left border that retains its size. - public int cxLeftWidth; - /// Width of right border that retains its size. - public int cxRightWidth; - /// Height of top border that retains its size. - public int cyTopHeight; - /// Height of bottom border that retains its size. - public int cyBottomHeight; - }; - - [StructLayout(LayoutKind.Sequential)] - internal class MONITORINFO - { - public int cbSize = Marshal.SizeOf(typeof(MONITORINFO)); - public RECT rcMonitor; - public RECT rcWork; - public int dwFlags; + return ( _left << 16 | Utility.LOWORD( _right ) ) ^ ( _top << 16 | Utility.LOWORD( _bottom ) ); } + } + + [SuppressMessage( "Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses" )] + [StructLayout( LayoutKind.Sequential )] + internal class RefRECT + { + private int _left; + private int _top; + private int _right; + private int _bottom; - [StructLayout(LayoutKind.Sequential)] - internal struct POINT + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public RefRECT( int left, int top, int right, int bottom ) { - public int x; - public int y; + _left = left; + _top = top; + _right = right; + _bottom = bottom; } - [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")] - [StructLayout(LayoutKind.Sequential)] - internal class RefPOINT + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public int Width { - public int x; - public int y; + get + { + return _right - _left; + } } - [StructLayout(LayoutKind.Sequential)] - internal struct RECT + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public int Height { - private int _left; - private int _top; - private int _right; - private int _bottom; - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public void Offset(int dx, int dy) - { - _left += dx; - _top += dy; - _right += dx; - _bottom += dy; - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public int Left - { - get { return _left; } - set { _left = value; } - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public int Right - { - get { return _right; } - set { _right = value; } - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public int Top - { - get { return _top; } - set { _top = value; } - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public int Bottom - { - get { return _bottom; } - set { _bottom = value; } - } + get + { + return _bottom - _top; + } + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public int Left + { + get + { + return _left; + } + set + { + _left = value; + } + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public int Right + { + get + { + return _right; + } + set + { + _right = value; + } + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public int Top + { + get + { + return _top; + } + set + { + _top = value; + } + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public int Bottom + { + get + { + return _bottom; + } + set + { + _bottom = value; + } + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public void Offset( int dx, int dy ) + { + _left += dx; + _top += dy; + _right += dx; + _bottom += dy; + } + } + + [StructLayout( LayoutKind.Sequential )] + internal struct SIZE + { + public int cx; + public int cy; + } + + [StructLayout( LayoutKind.Sequential )] + internal struct StartupOutput + { + public IntPtr hook; + public IntPtr unhook; + } + + [StructLayout( LayoutKind.Sequential )] + internal class StartupInput + { + public int GdiplusVersion = 1; + public IntPtr DebugEventCallback; + public bool SuppressBackgroundThread; + public bool SuppressExternalCodecs; + } + + [SuppressMessage( "Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses" )] + [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Unicode )] + [BestFitMapping( false )] + internal class WIN32_FIND_DATAW + { + public FileAttributes dwFileAttributes; + public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime; + public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime; + public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime; + public int nFileSizeHigh; + public int nFileSizeLow; + public int dwReserved0; + public int dwReserved1; + [MarshalAs( UnmanagedType.ByValTStr, SizeConst = 260 )] + public string cFileName; + [MarshalAs( UnmanagedType.ByValTStr, SizeConst = 14 )] + public string cAlternateFileName; + } + + [StructLayout( LayoutKind.Sequential )] + internal class WINDOWPLACEMENT + { + public int length = Marshal.SizeOf( typeof( WINDOWPLACEMENT ) ); + public int flags; + public SW showCmd; + public POINT ptMinPosition; + public POINT ptMaxPosition; + public RECT rcNormalPosition; + } + + [StructLayout( LayoutKind.Sequential )] + internal struct WINDOWPOS + { + public IntPtr hwnd; + public IntPtr hwndInsertAfter; + public int x; + public int y; + public int cx; + public int cy; + public int flags; + } + + [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Unicode )] + internal struct WNDCLASSEX + { + public int cbSize; + public CS style; + public WndProc lpfnWndProc; + public int cbClsExtra; + public int cbWndExtra; + public IntPtr hInstance; + public IntPtr hIcon; + public IntPtr hCursor; + public IntPtr hbrBackground; + [MarshalAs( UnmanagedType.LPWStr )] + public string lpszMenuName; + [MarshalAs( UnmanagedType.LPWStr )] + public string lpszClassName; + public IntPtr hIconSm; + } + + [StructLayout( LayoutKind.Sequential )] + internal struct MOUSEINPUT + { + public int dx; + public int dy; + public int mouseData; + public int dwFlags; + public int time; + public IntPtr dwExtraInfo; + } + + [StructLayout( LayoutKind.Sequential )] + internal struct INPUT + { + public uint type; + public MOUSEINPUT mi; + }; + + [StructLayout( LayoutKind.Sequential )] + internal struct UNSIGNED_RATIO + { + public uint uiNumerator; + public uint uiDenominator; + } + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + internal struct DWM_TIMING_INFO + { + public int cbSize; + public UNSIGNED_RATIO rateRefresh; + public ulong qpcRefreshPeriod; + public UNSIGNED_RATIO rateCompose; + public ulong qpcVBlank; + public ulong cRefresh; + public uint cDXRefresh; + public ulong qpcCompose; + public ulong cFrame; + public uint cDXPresent; + public ulong cRefreshFrame; + public ulong cFrameSubmitted; + public uint cDXPresentSubmitted; + public ulong cFrameConfirmed; + public uint cDXPresentConfirmed; + public ulong cRefreshConfirmed; + public uint cDXRefreshConfirmed; + public ulong cFramesLate; + public uint cFramesOutstanding; + public ulong cFrameDisplayed; + public ulong qpcFrameDisplayed; + public ulong cRefreshFrameDisplayed; + public ulong cFrameComplete; + public ulong qpcFrameComplete; + public ulong cFramePending; + public ulong qpcFramePending; + public ulong cFramesDisplayed; + public ulong cFramesComplete; + public ulong cFramesPending; + public ulong cFramesAvailable; + public ulong cFramesDropped; + public ulong cFramesMissed; + public ulong cRefreshNextDisplayed; + public ulong cRefreshNextPresented; + public ulong cRefreshesDisplayed; + public ulong cRefreshesPresented; + public ulong cRefreshStarted; + public ulong cPixelsReceived; + public ulong cPixelsDrawn; + public ulong cBuffersEmpty; + } + + #endregion + + /// Delegate declaration that matches native WndProc signatures. + internal delegate IntPtr WndProc( IntPtr hwnd, WM uMsg, IntPtr wParam, IntPtr lParam ); + + /// Delegate declaration that matches native WndProc signatures. + internal delegate IntPtr WndProcHook( IntPtr hwnd, WM uMsg, IntPtr wParam, IntPtr lParam, ref bool handled ); + + /// Delegate declaration that matches managed WndProc signatures. + internal delegate IntPtr MessageHandler( WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled ); + + // Some native methods are shimmed through public versions that handle converting failures into thrown exceptions. + internal static class NativeMethods + { + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "AdjustWindowRectEx", SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _AdjustWindowRectEx( ref RECT lpRect, WS dwStyle, [MarshalAs( UnmanagedType.Bool )] bool bMenu, WS_EX dwExStyle ); + + public static RECT AdjustWindowRectEx( RECT lpRect, WS dwStyle, bool bMenu, WS_EX dwExStyle ) + { + // Native version modifies the parameter in place. + if( !_AdjustWindowRectEx( ref lpRect, dwStyle, bMenu, dwExStyle ) ) + { + HRESULT.ThrowLastError(); + } + + return lpRect; + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "ChangeWindowMessageFilter", SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _ChangeWindowMessageFilter( WM message, MSGFLT dwFlag ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "ChangeWindowMessageFilterEx", SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _ChangeWindowMessageFilterEx( IntPtr hwnd, WM message, MSGFLT action, [In, Out, Optional] ref CHANGEFILTERSTRUCT pChangeFilterStruct ); + + // Note that processes at or below SECURITY_MANDATORY_LOW_RID are not allowed to change the message filter. + // If those processes call this function, it will fail and generate the extended error code, ERROR_ACCESS_DENIED. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static HRESULT ChangeWindowMessageFilterEx( IntPtr hwnd, WM message, MSGFLT action, out MSGFLTINFO filterInfo ) + { + filterInfo = MSGFLTINFO.NONE; + + bool ret; + + // This origins of this API were added for Vista. The Ex version was added for Windows 7. + // If we're not on either, then this message filter isolation doesn't exist. + if( !Utility.IsOSVistaOrNewer ) + { + return HRESULT.S_FALSE; + } + + // If we're on Vista rather than Win7 then we can't use the Ex version of this function. + // The Ex version is preferred if possible because this results in process-wide modifications of the filter + // and is deprecated as of Win7. + if( !Utility.IsOSWindows7OrNewer ) + { + // Note that the Win7 MSGFLT_ALLOW/DISALLOW enum values map to the Vista MSGFLT_ADD/REMOVE + ret = _ChangeWindowMessageFilter( message, action ); + if( !ret ) + { + return ( HRESULT )Win32Error.GetLastError(); + } + return HRESULT.S_OK; + } + + var filterstruct = new CHANGEFILTERSTRUCT { cbSize = ( uint )Marshal.SizeOf( typeof( CHANGEFILTERSTRUCT ) ) }; + ret = _ChangeWindowMessageFilterEx( hwnd, message, action, ref filterstruct ); + if( !ret ) + { + return ( HRESULT )Win32Error.GetLastError(); + } + + filterInfo = filterstruct.ExtStatus; + return HRESULT.S_OK; + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public int Width - { - get { return _right - _left; } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdi32.dll" )] + public static extern CombineRgnResult CombineRgn( IntPtr hrgnDest, IntPtr hrgnSrc1, IntPtr hrgnSrc2, RGN fnCombineMode ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public int Height - { - get { return _bottom - _top; } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "shell32.dll", EntryPoint = "CommandLineToArgvW", CharSet = CharSet.Unicode )] + private static extern IntPtr _CommandLineToArgvW( [MarshalAs( UnmanagedType.LPWStr )] string cmdLine, out int numArgs ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public POINT Position - { - get { return new POINT { x = _left, y = _top }; } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static string[] CommandLineToArgvW( string cmdLine ) + { + IntPtr argv = IntPtr.Zero; + try + { + int numArgs = 0; - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public SIZE Size + argv = _CommandLineToArgvW( cmdLine, out numArgs ); + if( argv == IntPtr.Zero ) { - get { return new SIZE { cx = Width, cy = Height }; } + throw new Win32Exception(); } + var result = new string[ numArgs ]; - public static RECT Union(RECT rect1, RECT rect2) + for( int i = 0; i < numArgs; i++ ) { - return new RECT - { - Left = Math.Min(rect1.Left, rect2.Left), - Top = Math.Min(rect1.Top, rect2.Top), - Right = Math.Max(rect1.Right, rect2.Right), - Bottom = Math.Max(rect1.Bottom, rect2.Bottom), - }; + IntPtr currArg = Marshal.ReadIntPtr( argv, i * Marshal.SizeOf( typeof( IntPtr ) ) ); + result[ i ] = Marshal.PtrToStringUni( currArg ); } - public override bool Equals(object obj) - { - try - { - var rc = (RECT)obj; - return rc._bottom == _bottom - && rc._left == _left - && rc._right == _right - && rc._top == _top; - } - catch (InvalidCastException) - { - return false; - } - } + return result; + } + finally + { - public override int GetHashCode() - { - return (_left << 16 | Utility.LOWORD(_right)) ^ (_top << 16 | Utility.LOWORD(_bottom)); - } + IntPtr p = _LocalFree( argv ); + // Otherwise LocalFree failed. + Assert.AreEqual( IntPtr.Zero, p ); + } } - [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")] - [StructLayout(LayoutKind.Sequential)] - internal class RefRECT - { - private int _left; - private int _top; - private int _right; - private int _bottom; + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdi32.dll", EntryPoint = "CreateDIBSection", SetLastError = true )] + private static extern SafeHBITMAP _CreateDIBSection( SafeDC hdc, [In] ref BITMAPINFO bitmapInfo, int iUsage, [Out] out IntPtr ppvBits, IntPtr hSection, int dwOffset ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdi32.dll", EntryPoint = "CreateDIBSection", SetLastError = true )] + private static extern SafeHBITMAP _CreateDIBSectionIntPtr( IntPtr hdc, [In] ref BITMAPINFO bitmapInfo, int iUsage, [Out] out IntPtr ppvBits, IntPtr hSection, int dwOffset ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static SafeHBITMAP CreateDIBSection( SafeDC hdc, ref BITMAPINFO bitmapInfo, out IntPtr ppvBits, IntPtr hSection, int dwOffset ) + { + const int DIB_RGB_COLORS = 0; + SafeHBITMAP hBitmap = null; + if( hdc == null ) + { + hBitmap = _CreateDIBSectionIntPtr( IntPtr.Zero, ref bitmapInfo, DIB_RGB_COLORS, out ppvBits, hSection, dwOffset ); + } + else + { + hBitmap = _CreateDIBSection( hdc, ref bitmapInfo, DIB_RGB_COLORS, out ppvBits, hSection, dwOffset ); + } + + if( hBitmap.IsInvalid ) + { + HRESULT.ThrowLastError(); + } + + return hBitmap; + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdi32.dll", EntryPoint = "CreateRoundRectRgn", SetLastError = true )] + private static extern IntPtr _CreateRoundRectRgn( int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static IntPtr CreateRoundRectRgn( int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse ) + { + IntPtr ret = _CreateRoundRectRgn( nLeftRect, nTopRect, nRightRect, nBottomRect, nWidthEllipse, nHeightEllipse ); + if( IntPtr.Zero == ret ) + { + throw new Win32Exception(); + } + return ret; + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdi32.dll", EntryPoint = "CreateRectRgn", SetLastError = true )] + private static extern IntPtr _CreateRectRgn( int nLeftRect, int nTopRect, int nRightRect, int nBottomRect ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static IntPtr CreateRectRgn( int nLeftRect, int nTopRect, int nRightRect, int nBottomRect ) + { + IntPtr ret = _CreateRectRgn( nLeftRect, nTopRect, nRightRect, nBottomRect ); + if( IntPtr.Zero == ret ) + { + throw new Win32Exception(); + } + return ret; + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdi32.dll", EntryPoint = "CreateRectRgnIndirect", SetLastError = true )] + private static extern IntPtr _CreateRectRgnIndirect( [In] ref RECT lprc ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static IntPtr CreateRectRgnIndirect( RECT lprc ) + { + IntPtr ret = _CreateRectRgnIndirect( ref lprc ); + if( IntPtr.Zero == ret ) + { + throw new Win32Exception(); + } + return ret; + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdi32.dll" )] + public static extern IntPtr CreateSolidBrush( int crColor ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateWindowExW" )] + private static extern IntPtr _CreateWindowEx( + WS_EX dwExStyle, + [MarshalAs( UnmanagedType.LPWStr )] string lpClassName, + [MarshalAs( UnmanagedType.LPWStr )] string lpWindowName, + WS dwStyle, + int x, + int y, + int nWidth, + int nHeight, + IntPtr hWndParent, + IntPtr hMenu, + IntPtr hInstance, + IntPtr lpParam ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static IntPtr CreateWindowEx( + WS_EX dwExStyle, + string lpClassName, + string lpWindowName, + WS dwStyle, + int x, + int y, + int nWidth, + int nHeight, + IntPtr hWndParent, + IntPtr hMenu, + IntPtr hInstance, + IntPtr lpParam ) + { + IntPtr ret = _CreateWindowEx( dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam ); + if( IntPtr.Zero == ret ) + { + HRESULT.ThrowLastError(); + } + + return ret; + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", CharSet = CharSet.Unicode, EntryPoint = "DefWindowProcW" )] + public static extern IntPtr DefWindowProc( IntPtr hWnd, WM Msg, IntPtr wParam, IntPtr lParam ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdi32.dll" )] + [return: MarshalAs( UnmanagedType.Bool )] + public static extern bool DeleteObject( IntPtr hObject ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public RefRECT(int left, int top, int right, int bottom) - { - _left = left; - _top = top; - _right = right; - _bottom = bottom; - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll" )] + [return: MarshalAs( UnmanagedType.Bool )] + public static extern bool DestroyIcon( IntPtr handle ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public int Width - { - get { return _right - _left; } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + public static extern bool DestroyWindow( IntPtr hwnd ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll" )] + [return: MarshalAs( UnmanagedType.Bool )] + public static extern bool IsWindow( IntPtr hwnd ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public int Height - { - get { return _bottom - _top; } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "dwmapi.dll", PreserveSig = false )] + public static extern void DwmExtendFrameIntoClientArea( IntPtr hwnd, ref MARGINS pMarInset ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public int Left - { - get { return _left; } - set { _left = value; } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "dwmapi.dll", EntryPoint = "DwmIsCompositionEnabled", PreserveSig = false )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _DwmIsCompositionEnabled(); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public int Right - { - get { return _right; } - set { _right = value; } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "dwmapi.dll", EntryPoint = "DwmGetColorizationColor", PreserveSig = true )] + private static extern HRESULT _DwmGetColorizationColor( out uint pcrColorization, [Out, MarshalAs( UnmanagedType.Bool )] out bool pfOpaqueBlend ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public int Top + public static bool DwmGetColorizationColor( out uint pcrColorization, out bool pfOpaqueBlend ) + { + // Make this call safe to make on downlevel OSes... + if( Utility.IsOSVistaOrNewer && IsThemeActive() ) + { + HRESULT hr = _DwmGetColorizationColor( out pcrColorization, out pfOpaqueBlend ); + if( hr.Succeeded ) { - get { return _top; } - set { _top = value; } - } + return true; + } + } + + // Default values. If for some reason the native DWM API fails it's never enough of a reason + // to bring down the app. Empirically it still sometimes returns errors even when the theme service is on. + // We'll still use the boolean return value to allow the caller to respond if they care. + pcrColorization = 0xFF000000; + pfOpaqueBlend = true; + + return false; + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool DwmIsCompositionEnabled() + { + // Make this call safe to make on downlevel OSes... + if( !Utility.IsOSVistaOrNewer ) + { + return false; + } + return _DwmIsCompositionEnabled(); + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public int Bottom - { - get { return _bottom; } - set { _bottom = value; } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "dwmapi.dll" )] + [return: MarshalAs( UnmanagedType.Bool )] + public static extern bool DwmDefWindowProc( IntPtr hwnd, WM msg, IntPtr wParam, IntPtr lParam, out IntPtr plResult ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public void Offset(int dx, int dy) - { - _left += dx; - _top += dy; - _right += dx; - _bottom += dy; - } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "dwmapi.dll", EntryPoint = "DwmSetWindowAttribute" )] + private static extern void _DwmSetWindowAttribute( IntPtr hwnd, DWMWA dwAttribute, ref int pvAttribute, int cbAttribute ); - [StructLayout(LayoutKind.Sequential)] - internal struct SIZE + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void DwmSetWindowAttributeFlip3DPolicy( IntPtr hwnd, DWMFLIP3D flip3dPolicy ) { - public int cx; - public int cy; + Assert.IsTrue( Utility.IsOSVistaOrNewer ); + var dwPolicy = ( int )flip3dPolicy; + _DwmSetWindowAttribute( hwnd, DWMWA.FLIP3D_POLICY, ref dwPolicy, sizeof( int ) ); } - [StructLayout(LayoutKind.Sequential)] - internal struct StartupOutput + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void DwmSetWindowAttributeDisallowPeek( IntPtr hwnd, bool disallowPeek ) { - public IntPtr hook; - public IntPtr unhook; + Assert.IsTrue( Utility.IsOSWindows7OrNewer ); + int dwDisallow = ( int )( disallowPeek ? Win32Value.TRUE : Win32Value.FALSE ); + _DwmSetWindowAttribute( hwnd, DWMWA.DISALLOW_PEEK, ref dwDisallow, sizeof( int ) ); } - [StructLayout(LayoutKind.Sequential)] - internal class StartupInput - { - public int GdiplusVersion = 1; - public IntPtr DebugEventCallback; - public bool SuppressBackgroundThread; - public bool SuppressExternalCodecs; - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "EnableMenuItem" )] + private static extern int _EnableMenuItem( IntPtr hMenu, SC uIDEnableItem, MF uEnable ); - [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - [BestFitMapping(false)] - internal class WIN32_FIND_DATAW + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static MF EnableMenuItem( IntPtr hMenu, SC uIDEnableItem, MF uEnable ) { - public FileAttributes dwFileAttributes; - public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime; - public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime; - public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime; - public int nFileSizeHigh; - public int nFileSizeLow; - public int dwReserved0; - public int dwReserved1; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] - public string cFileName; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] - public string cAlternateFileName; - } - - [StructLayout(LayoutKind.Sequential)] - internal class WINDOWPLACEMENT - { - public int length = Marshal.SizeOf(typeof(WINDOWPLACEMENT)); - public int flags; - public SW showCmd; - public POINT ptMinPosition; - public POINT ptMaxPosition; - public RECT rcNormalPosition; - } - - [StructLayout(LayoutKind.Sequential)] - internal struct WINDOWPOS - { - public IntPtr hwnd; - public IntPtr hwndInsertAfter; - public int x; - public int y; - public int cx; - public int cy; - public int flags; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct WNDCLASSEX - { - public int cbSize; - public CS style; - public WndProc lpfnWndProc; - public int cbClsExtra; - public int cbWndExtra; - public IntPtr hInstance; - public IntPtr hIcon; - public IntPtr hCursor; - public IntPtr hbrBackground; - [MarshalAs(UnmanagedType.LPWStr)] - public string lpszMenuName; - [MarshalAs(UnmanagedType.LPWStr)] - public string lpszClassName; - public IntPtr hIconSm; - } - - [StructLayout(LayoutKind.Sequential)] - internal struct MOUSEINPUT - { - public int dx; - public int dy; - public int mouseData; - public int dwFlags; - public int time; - public IntPtr dwExtraInfo; - } - - [StructLayout(LayoutKind.Sequential)] - internal struct INPUT - { - public uint type; - public MOUSEINPUT mi; - }; - - [StructLayout(LayoutKind.Sequential)] - internal struct UNSIGNED_RATIO - { - public uint uiNumerator; - public uint uiDenominator; - } - - [StructLayout(LayoutKind.Sequential, Pack=1)] - internal struct DWM_TIMING_INFO - { - public int cbSize; - public UNSIGNED_RATIO rateRefresh; - public ulong qpcRefreshPeriod; - public UNSIGNED_RATIO rateCompose; - public ulong qpcVBlank; - public ulong cRefresh; - public uint cDXRefresh; - public ulong qpcCompose; - public ulong cFrame; - public uint cDXPresent; - public ulong cRefreshFrame; - public ulong cFrameSubmitted; - public uint cDXPresentSubmitted; - public ulong cFrameConfirmed; - public uint cDXPresentConfirmed; - public ulong cRefreshConfirmed; - public uint cDXRefreshConfirmed; - public ulong cFramesLate; - public uint cFramesOutstanding; - public ulong cFrameDisplayed; - public ulong qpcFrameDisplayed; - public ulong cRefreshFrameDisplayed; - public ulong cFrameComplete; - public ulong qpcFrameComplete; - public ulong cFramePending; - public ulong qpcFramePending; - public ulong cFramesDisplayed; - public ulong cFramesComplete; - public ulong cFramesPending; - public ulong cFramesAvailable; - public ulong cFramesDropped; - public ulong cFramesMissed; - public ulong cRefreshNextDisplayed; - public ulong cRefreshNextPresented; - public ulong cRefreshesDisplayed; - public ulong cRefreshesPresented; - public ulong cRefreshStarted; - public ulong cPixelsReceived; - public ulong cPixelsDrawn; - public ulong cBuffersEmpty; + // Returns the previous state of the menu item, or -1 if the menu item does not exist. + int iRet = _EnableMenuItem( hMenu, uIDEnableItem, uEnable ); + return ( MF )iRet; } - #endregion - - /// Delegate declaration that matches native WndProc signatures. - internal delegate IntPtr WndProc(IntPtr hwnd, WM uMsg, IntPtr wParam, IntPtr lParam); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "RemoveMenu", SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _RemoveMenu( IntPtr hMenu, uint uPosition, uint uFlags ); - /// Delegate declaration that matches native WndProc signatures. - internal delegate IntPtr WndProcHook(IntPtr hwnd, WM uMsg, IntPtr wParam, IntPtr lParam, ref bool handled); - - /// Delegate declaration that matches managed WndProc signatures. - internal delegate IntPtr MessageHandler(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled); - - // Some native methods are shimmed through public versions that handle converting failures into thrown exceptions. - internal static class NativeMethods + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void RemoveMenu( IntPtr hMenu, SC uPosition, MF uFlags ) { - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "AdjustWindowRectEx", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _AdjustWindowRectEx(ref RECT lpRect, WS dwStyle, [MarshalAs(UnmanagedType.Bool)] bool bMenu, WS_EX dwExStyle); - - public static RECT AdjustWindowRectEx(RECT lpRect, WS dwStyle, bool bMenu, WS_EX dwExStyle) - { - // Native version modifies the parameter in place. - if (!_AdjustWindowRectEx(ref lpRect, dwStyle, bMenu, dwExStyle)) - { - HRESULT.ThrowLastError(); - } - - return lpRect; - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "ChangeWindowMessageFilter", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _ChangeWindowMessageFilter(WM message, MSGFLT dwFlag); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "ChangeWindowMessageFilterEx", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _ChangeWindowMessageFilterEx(IntPtr hwnd, WM message, MSGFLT action, [In, Out, Optional] ref CHANGEFILTERSTRUCT pChangeFilterStruct); - - // Note that processes at or below SECURITY_MANDATORY_LOW_RID are not allowed to change the message filter. - // If those processes call this function, it will fail and generate the extended error code, ERROR_ACCESS_DENIED. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static HRESULT ChangeWindowMessageFilterEx(IntPtr hwnd, WM message, MSGFLT action, out MSGFLTINFO filterInfo) - { - filterInfo = MSGFLTINFO.NONE; - - bool ret; - - // This origins of this API were added for Vista. The Ex version was added for Windows 7. - // If we're not on either, then this message filter isolation doesn't exist. - if (!Utility.IsOSVistaOrNewer) - { - return HRESULT.S_FALSE; - } - - // If we're on Vista rather than Win7 then we can't use the Ex version of this function. - // The Ex version is preferred if possible because this results in process-wide modifications of the filter - // and is deprecated as of Win7. - if (!Utility.IsOSWindows7OrNewer) - { - // Note that the Win7 MSGFLT_ALLOW/DISALLOW enum values map to the Vista MSGFLT_ADD/REMOVE - ret = _ChangeWindowMessageFilter(message, action); - if (!ret) - { - return (HRESULT)Win32Error.GetLastError(); - } - return HRESULT.S_OK; - } - - var filterstruct = new CHANGEFILTERSTRUCT { cbSize = (uint)Marshal.SizeOf(typeof(CHANGEFILTERSTRUCT)) }; - ret = _ChangeWindowMessageFilterEx(hwnd, message, action, ref filterstruct); - if (!ret) - { - return (HRESULT)Win32Error.GetLastError(); - } - - filterInfo = filterstruct.ExtStatus; - return HRESULT.S_OK; - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdi32.dll")] - public static extern CombineRgnResult CombineRgn(IntPtr hrgnDest, IntPtr hrgnSrc1, IntPtr hrgnSrc2, RGN fnCombineMode); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("shell32.dll", EntryPoint = "CommandLineToArgvW", CharSet = CharSet.Unicode)] - private static extern IntPtr _CommandLineToArgvW([MarshalAs(UnmanagedType.LPWStr)] string cmdLine, out int numArgs); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static string[] CommandLineToArgvW(string cmdLine) - { - IntPtr argv = IntPtr.Zero; - try - { - int numArgs = 0; - - argv = _CommandLineToArgvW(cmdLine, out numArgs); - if (argv == IntPtr.Zero) - { - throw new Win32Exception(); - } - var result = new string[numArgs]; - - for (int i = 0; i < numArgs; i++) - { - IntPtr currArg = Marshal.ReadIntPtr(argv, i * Marshal.SizeOf(typeof(IntPtr))); - result[i] = Marshal.PtrToStringUni(currArg); - } - - return result; - } - finally - { - - IntPtr p = _LocalFree(argv); - // Otherwise LocalFree failed. - Assert.AreEqual(IntPtr.Zero, p); - } - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdi32.dll", EntryPoint = "CreateDIBSection", SetLastError = true)] - private static extern SafeHBITMAP _CreateDIBSection(SafeDC hdc, [In] ref BITMAPINFO bitmapInfo, int iUsage, [Out] out IntPtr ppvBits, IntPtr hSection, int dwOffset); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdi32.dll", EntryPoint = "CreateDIBSection", SetLastError = true)] - private static extern SafeHBITMAP _CreateDIBSectionIntPtr(IntPtr hdc, [In] ref BITMAPINFO bitmapInfo, int iUsage, [Out] out IntPtr ppvBits, IntPtr hSection, int dwOffset); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static SafeHBITMAP CreateDIBSection(SafeDC hdc, ref BITMAPINFO bitmapInfo, out IntPtr ppvBits, IntPtr hSection, int dwOffset) - { - const int DIB_RGB_COLORS = 0; - SafeHBITMAP hBitmap = null; - if (hdc == null) - { - hBitmap = _CreateDIBSectionIntPtr(IntPtr.Zero, ref bitmapInfo, DIB_RGB_COLORS, out ppvBits, hSection, dwOffset); - } - else - { - hBitmap = _CreateDIBSection(hdc, ref bitmapInfo, DIB_RGB_COLORS, out ppvBits, hSection, dwOffset); - } - - if (hBitmap.IsInvalid) - { - HRESULT.ThrowLastError(); - } - - return hBitmap; - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdi32.dll", EntryPoint = "CreateRoundRectRgn", SetLastError = true)] - private static extern IntPtr _CreateRoundRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static IntPtr CreateRoundRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse) - { - IntPtr ret = _CreateRoundRectRgn(nLeftRect, nTopRect, nRightRect, nBottomRect, nWidthEllipse, nHeightEllipse); - if (IntPtr.Zero == ret) - { - throw new Win32Exception(); - } - return ret; - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdi32.dll", EntryPoint = "CreateRectRgn", SetLastError = true)] - private static extern IntPtr _CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect) - { - IntPtr ret = _CreateRectRgn(nLeftRect, nTopRect, nRightRect, nBottomRect); - if (IntPtr.Zero == ret) - { - throw new Win32Exception(); - } - return ret; - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdi32.dll", EntryPoint = "CreateRectRgnIndirect", SetLastError = true)] - private static extern IntPtr _CreateRectRgnIndirect([In] ref RECT lprc); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static IntPtr CreateRectRgnIndirect(RECT lprc) - { - IntPtr ret = _CreateRectRgnIndirect(ref lprc); - if (IntPtr.Zero == ret) - { - throw new Win32Exception(); - } - return ret; - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdi32.dll")] - public static extern IntPtr CreateSolidBrush(int crColor); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateWindowExW")] - private static extern IntPtr _CreateWindowEx( - WS_EX dwExStyle, - [MarshalAs(UnmanagedType.LPWStr)] string lpClassName, - [MarshalAs(UnmanagedType.LPWStr)] string lpWindowName, - WS dwStyle, - int x, - int y, - int nWidth, - int nHeight, - IntPtr hWndParent, - IntPtr hMenu, - IntPtr hInstance, - IntPtr lpParam); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static IntPtr CreateWindowEx( - WS_EX dwExStyle, - string lpClassName, - string lpWindowName, - WS dwStyle, - int x, - int y, - int nWidth, - int nHeight, - IntPtr hWndParent, - IntPtr hMenu, - IntPtr hInstance, - IntPtr lpParam) - { - IntPtr ret = _CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); - if (IntPtr.Zero == ret) - { - HRESULT.ThrowLastError(); - } - - return ret; - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "DefWindowProcW")] - public static extern IntPtr DefWindowProc(IntPtr hWnd, WM Msg, IntPtr wParam, IntPtr lParam); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdi32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool DeleteObject(IntPtr hObject); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool DestroyIcon(IntPtr handle); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool DestroyWindow(IntPtr hwnd); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool IsWindow(IntPtr hwnd); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("dwmapi.dll", PreserveSig = false)] - public static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS pMarInset); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("dwmapi.dll", EntryPoint = "DwmIsCompositionEnabled", PreserveSig = false)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _DwmIsCompositionEnabled(); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("dwmapi.dll", EntryPoint = "DwmGetColorizationColor", PreserveSig = true)] - private static extern HRESULT _DwmGetColorizationColor(out uint pcrColorization, [Out, MarshalAs(UnmanagedType.Bool)] out bool pfOpaqueBlend); - - public static bool DwmGetColorizationColor(out uint pcrColorization, out bool pfOpaqueBlend) - { - // Make this call safe to make on downlevel OSes... - if (Utility.IsOSVistaOrNewer && IsThemeActive()) - { - HRESULT hr = _DwmGetColorizationColor(out pcrColorization, out pfOpaqueBlend); - if (hr.Succeeded) - { - return true; - } - } - - // Default values. If for some reason the native DWM API fails it's never enough of a reason - // to bring down the app. Empirically it still sometimes returns errors even when the theme service is on. - // We'll still use the boolean return value to allow the caller to respond if they care. - pcrColorization = 0xFF000000; - pfOpaqueBlend = true; - - return false; - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool DwmIsCompositionEnabled() - { - // Make this call safe to make on downlevel OSes... - if (!Utility.IsOSVistaOrNewer) - { - return false; - } - return _DwmIsCompositionEnabled(); - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("dwmapi.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool DwmDefWindowProc(IntPtr hwnd, WM msg, IntPtr wParam, IntPtr lParam, out IntPtr plResult); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("dwmapi.dll", EntryPoint = "DwmSetWindowAttribute")] - private static extern void _DwmSetWindowAttribute(IntPtr hwnd, DWMWA dwAttribute, ref int pvAttribute, int cbAttribute); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void DwmSetWindowAttributeFlip3DPolicy(IntPtr hwnd, DWMFLIP3D flip3dPolicy) - { - Assert.IsTrue(Utility.IsOSVistaOrNewer); - var dwPolicy = (int)flip3dPolicy; - _DwmSetWindowAttribute(hwnd, DWMWA.FLIP3D_POLICY, ref dwPolicy, sizeof(int)); - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void DwmSetWindowAttributeDisallowPeek(IntPtr hwnd, bool disallowPeek) - { - Assert.IsTrue(Utility.IsOSWindows7OrNewer); - int dwDisallow = (int)(disallowPeek ? Win32Value.TRUE : Win32Value.FALSE); - _DwmSetWindowAttribute(hwnd, DWMWA.DISALLOW_PEEK, ref dwDisallow, sizeof(int)); - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "EnableMenuItem")] - private static extern int _EnableMenuItem(IntPtr hMenu, SC uIDEnableItem, MF uEnable); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static MF EnableMenuItem(IntPtr hMenu, SC uIDEnableItem, MF uEnable) - { - // Returns the previous state of the menu item, or -1 if the menu item does not exist. - int iRet = _EnableMenuItem(hMenu, uIDEnableItem, uEnable); - return (MF)iRet; - } + if( !_RemoveMenu( hMenu, ( uint )uPosition, ( uint )uFlags ) ) + { + throw new Win32Exception(); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "RemoveMenu", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "DrawMenuBar", SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _DrawMenuBar( IntPtr hWnd ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void RemoveMenu(IntPtr hMenu, SC uPosition, MF uFlags) - { - if (!_RemoveMenu(hMenu, (uint)uPosition, (uint)uFlags)) - { - throw new Win32Exception(); - } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void DrawMenuBar( IntPtr hWnd ) + { + if( !_DrawMenuBar( hWnd ) ) + { + throw new Win32Exception(); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "DrawMenuBar", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _DrawMenuBar(IntPtr hWnd); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "kernel32.dll" )] + [ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )] + [return: MarshalAs( UnmanagedType.Bool )] + public static extern bool FindClose( IntPtr handle ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void DrawMenuBar(IntPtr hWnd) - { - if (!_DrawMenuBar(hWnd)) - { - throw new Win32Exception(); - } - } + // Not shimming this SetLastError=true function because callers want to evaluate the reason for failure. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true )] + public static extern SafeFindHandle FindFirstFileW( string lpFileName, [In, Out, MarshalAs( UnmanagedType.LPStruct )] WIN32_FIND_DATAW lpFindFileData ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("kernel32.dll")] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool FindClose(IntPtr handle); - - // Not shimming this SetLastError=true function because callers want to evaluate the reason for failure. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern SafeFindHandle FindFirstFileW(string lpFileName, [In, Out, MarshalAs(UnmanagedType.LPStruct)] WIN32_FIND_DATAW lpFindFileData); - - // Not shimming this SetLastError=true function because callers want to evaluate the reason for failure. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("kernel32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool FindNextFileW(SafeFindHandle hndFindFile, [In, Out, MarshalAs(UnmanagedType.LPStruct)] WIN32_FIND_DATAW lpFindFileData); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "GetClientRect", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _GetClientRect(IntPtr hwnd, [Out] out RECT lpRect); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static RECT GetClientRect(IntPtr hwnd) - { - RECT rc; - if (!_GetClientRect(hwnd, out rc)) - { - HRESULT.ThrowLastError(); - } - return rc; - } + // Not shimming this SetLastError=true function because callers want to evaluate the reason for failure. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "kernel32.dll", SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + public static extern bool FindNextFileW( SafeFindHandle hndFindFile, [In, Out, MarshalAs( UnmanagedType.LPStruct )] WIN32_FIND_DATAW lpFindFileData ); - [DllImport("uxtheme.dll", EntryPoint="GetCurrentThemeName", CharSet = CharSet.Unicode)] - private static extern HRESULT _GetCurrentThemeName( - StringBuilder pszThemeFileName, - int dwMaxNameChars, - StringBuilder pszColorBuff, - int cchMaxColorChars, - StringBuilder pszSizeBuff, - int cchMaxSizeChars); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "GetClientRect", SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _GetClientRect( IntPtr hwnd, [Out] out RECT lpRect ); - public static void GetCurrentThemeName(out string themeFileName, out string color, out string size) - { - // Not expecting strings longer than MAX_PATH. We will return the error - var fileNameBuilder = new StringBuilder((int)Win32Value.MAX_PATH); - var colorBuilder = new StringBuilder((int)Win32Value.MAX_PATH); - var sizeBuilder = new StringBuilder((int)Win32Value.MAX_PATH); - - // This will throw if the theme service is not active (e.g. not UxTheme!IsThemeActive). - _GetCurrentThemeName(fileNameBuilder, fileNameBuilder.Capacity, - colorBuilder, colorBuilder.Capacity, - sizeBuilder, sizeBuilder.Capacity) - .ThrowIfFailed(); - - themeFileName = fileNameBuilder.ToString(); - color = colorBuilder.ToString(); - size = sizeBuilder.ToString(); - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static RECT GetClientRect( IntPtr hwnd ) + { + RECT rc; + if( !_GetClientRect( hwnd, out rc ) ) + { + HRESULT.ThrowLastError(); + } + return rc; + } - [DllImport("uxtheme.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool IsThemeActive(); + [DllImport( "uxtheme.dll", EntryPoint = "GetCurrentThemeName", CharSet = CharSet.Unicode )] + private static extern HRESULT _GetCurrentThemeName( + StringBuilder pszThemeFileName, + int dwMaxNameChars, + StringBuilder pszColorBuff, + int cchMaxColorChars, + StringBuilder pszSizeBuff, + int cchMaxSizeChars ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [Obsolete("Use SafeDC.GetDC instead.", true)] - public static void GetDC() { } + public static void GetCurrentThemeName( out string themeFileName, out string color, out string size ) + { + // Not expecting strings longer than MAX_PATH. We will return the error + var fileNameBuilder = new StringBuilder( ( int )Win32Value.MAX_PATH ); + var colorBuilder = new StringBuilder( ( int )Win32Value.MAX_PATH ); + var sizeBuilder = new StringBuilder( ( int )Win32Value.MAX_PATH ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdi32.dll")] - public static extern int GetDeviceCaps(SafeDC hdc, DeviceCap nIndex); + // This will throw if the theme service is not active (e.g. not UxTheme!IsThemeActive). + _GetCurrentThemeName( fileNameBuilder, fileNameBuilder.Capacity, + colorBuilder, colorBuilder.Capacity, + sizeBuilder, sizeBuilder.Capacity ) + .ThrowIfFailed(); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("kernel32.dll", EntryPoint = "GetModuleFileName", CharSet = CharSet.Unicode, SetLastError = true)] - private static extern int _GetModuleFileName(IntPtr hModule, StringBuilder lpFilename, int nSize); + themeFileName = fileNameBuilder.ToString(); + color = colorBuilder.ToString(); + size = sizeBuilder.ToString(); + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static string GetModuleFileName(IntPtr hModule) - { - var buffer = new StringBuilder((int)Win32Value.MAX_PATH); - while (true) - { - int size = _GetModuleFileName(hModule, buffer, buffer.Capacity); - if (size == 0) - { - HRESULT.ThrowLastError(); - } - - // GetModuleFileName returns nSize when it's truncated but does NOT set the last error. - // MSDN documentation says this has changed in Windows 2000+. - if (size == buffer.Capacity) - { - // Enlarge the buffer and try again. - buffer.EnsureCapacity(buffer.Capacity * 2); - continue; - } - - return buffer.ToString(); - } - } + [DllImport( "uxtheme.dll" )] + [return: MarshalAs( UnmanagedType.Bool )] + public static extern bool IsThemeActive(); - [DllImport("kernel32.dll", EntryPoint = "GetModuleHandleW", CharSet = CharSet.Unicode, SetLastError = true)] - private static extern IntPtr _GetModuleHandle([MarshalAs(UnmanagedType.LPWStr)] string lpModuleName); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [Obsolete( "Use SafeDC.GetDC instead.", true )] + public static void GetDC() + { + } - public static IntPtr GetModuleHandle(string lpModuleName) - { - IntPtr retPtr = _GetModuleHandle(lpModuleName); - if (retPtr == IntPtr.Zero) - { - HRESULT.ThrowLastError(); - } - return retPtr; - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdi32.dll" )] + public static extern int GetDeviceCaps( SafeDC hdc, DeviceCap nIndex ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "GetMonitorInfo", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _GetMonitorInfo(IntPtr hMonitor, [In, Out] MONITORINFO lpmi); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "kernel32.dll", EntryPoint = "GetModuleFileName", CharSet = CharSet.Unicode, SetLastError = true )] + private static extern int _GetModuleFileName( IntPtr hModule, StringBuilder lpFilename, int nSize ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static MONITORINFO GetMonitorInfo(IntPtr hMonitor) + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static string GetModuleFileName( IntPtr hModule ) + { + var buffer = new StringBuilder( ( int )Win32Value.MAX_PATH ); + while( true ) + { + int size = _GetModuleFileName( hModule, buffer, buffer.Capacity ); + if( size == 0 ) { - var mi = new MONITORINFO(); - if (!_GetMonitorInfo(hMonitor, mi)) - { - throw new Win32Exception(); - } - return mi; + HRESULT.ThrowLastError(); } - [DllImport("gdi32.dll", EntryPoint = "GetStockObject", SetLastError = true)] - private static extern IntPtr _GetStockObject(StockObject fnObject); - - public static IntPtr GetStockObject(StockObject fnObject) + // GetModuleFileName returns nSize when it's truncated but does NOT set the last error. + // MSDN documentation says this has changed in Windows 2000+. + if( size == buffer.Capacity ) { - IntPtr retPtr = _GetStockObject(fnObject); - if (retPtr == null) - { - HRESULT.ThrowLastError(); - } - return retPtr; + // Enlarge the buffer and try again. + buffer.EnsureCapacity( buffer.Capacity * 2 ); + continue; } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll")] - public static extern IntPtr GetSystemMenu(IntPtr hWnd, [MarshalAs(UnmanagedType.Bool)] bool bRevert); + return buffer.ToString(); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll")] - public static extern int GetSystemMetrics(SM nIndex); + [DllImport( "kernel32.dll", EntryPoint = "GetModuleHandleW", CharSet = CharSet.Unicode, SetLastError = true )] + private static extern IntPtr _GetModuleHandle( [MarshalAs( UnmanagedType.LPWStr )] string lpModuleName ); - // This is aliased as a macro in 32bit Windows. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static IntPtr GetWindowLongPtr(IntPtr hwnd, GWL nIndex) - { - IntPtr ret = IntPtr.Zero; - if (8 == IntPtr.Size) - { - ret = GetWindowLongPtr64(hwnd, nIndex); - } - else - { - ret = new IntPtr(GetWindowLongPtr32(hwnd, nIndex)); - } - if (IntPtr.Zero == ret) - { - throw new Win32Exception(); - } - return ret; - } + public static IntPtr GetModuleHandle( string lpModuleName ) + { + IntPtr retPtr = _GetModuleHandle( lpModuleName ); + if( retPtr == IntPtr.Zero ) + { + HRESULT.ThrowLastError(); + } + return retPtr; + } - /// - /// Sets attributes to control how visual styles are applied to a specified window. - /// - /// - /// Handle to a window to apply changes to. - /// - /// - /// Value of type WINDOWTHEMEATTRIBUTETYPE that specifies the type of attribute to set. - /// The value of this parameter determines the type of data that should be passed in the pvAttribute parameter. - /// Can be the following value: - /// WTA_NONCLIENT (Specifies non-client related attributes). - /// pvAttribute must be a pointer of type WTA_OPTIONS. - /// - /// - /// A pointer that specifies attributes to set. Type is determined by the value of the eAttribute value. - /// - /// - /// Specifies the size, in bytes, of the data pointed to by pvAttribute. - /// - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("uxtheme.dll", PreserveSig = false)] - public static extern void SetWindowThemeAttribute([In] IntPtr hwnd, [In] WINDOWTHEMEATTRIBUTETYPE eAttribute, [In] ref WTA_OPTIONS pvAttribute, [In] uint cbAttribute); - - [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "GetWindowLong", SetLastError = true)] - private static extern int GetWindowLongPtr32(IntPtr hWnd, GWL nIndex); - - [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", SetLastError = true)] - private static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, GWL nIndex); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool GetWindowPlacement(IntPtr hwnd, WINDOWPLACEMENT lpwndpl); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static WINDOWPLACEMENT GetWindowPlacement(IntPtr hwnd) - { - WINDOWPLACEMENT wndpl = new WINDOWPLACEMENT(); - if (GetWindowPlacement(hwnd, wndpl)) - { - return wndpl; - } - throw new Win32Exception(); - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "GetMonitorInfo", SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _GetMonitorInfo( IntPtr hMonitor, [In, Out] MONITORINFO lpmi ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "GetWindowRect", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _GetWindowRect(IntPtr hWnd, out RECT lpRect); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static MONITORINFO GetMonitorInfo( IntPtr hMonitor ) + { + var mi = new MONITORINFO(); + if( !_GetMonitorInfo( hMonitor, mi ) ) + { + throw new Win32Exception(); + } + return mi; + } - public static RECT GetWindowRect(IntPtr hwnd) - { - RECT rc; - if (!_GetWindowRect(hwnd, out rc)) - { - HRESULT.ThrowLastError(); - } - return rc; - } + [DllImport( "gdi32.dll", EntryPoint = "GetStockObject", SetLastError = true )] + private static extern IntPtr _GetStockObject( StockObject fnObject ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdiplus.dll")] - public static extern Status GdipCreateBitmapFromStream(IStream stream, out IntPtr bitmap); + public static IntPtr GetStockObject( StockObject fnObject ) + { + IntPtr retPtr = _GetStockObject( fnObject ); + if( retPtr == null ) + { + HRESULT.ThrowLastError(); + } + return retPtr; + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdiplus.dll")] - public static extern Status GdipCreateHBITMAPFromBitmap(IntPtr bitmap, out IntPtr hbmReturn, Int32 background); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll" )] + public static extern IntPtr GetSystemMenu( IntPtr hWnd, [MarshalAs( UnmanagedType.Bool )] bool bRevert ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdiplus.dll")] - public static extern Status GdipCreateHICONFromBitmap(IntPtr bitmap, out IntPtr hbmReturn); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll" )] + public static extern int GetSystemMetrics( SM nIndex ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdiplus.dll")] - public static extern Status GdipDisposeImage(IntPtr image); + // This is aliased as a macro in 32bit Windows. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static IntPtr GetWindowLongPtr( IntPtr hwnd, GWL nIndex ) + { + IntPtr ret = IntPtr.Zero; + if( 8 == IntPtr.Size ) + { + ret = GetWindowLongPtr64( hwnd, nIndex ); + } + else + { + ret = new IntPtr( GetWindowLongPtr32( hwnd, nIndex ) ); + } + if( IntPtr.Zero == ret ) + { + throw new Win32Exception(); + } + return ret; + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdiplus.dll")] - public static extern Status GdipImageForceValidation(IntPtr image); + /// + /// Sets attributes to control how visual styles are applied to a specified window. + /// + /// + /// Handle to a window to apply changes to. + /// + /// + /// Value of type WINDOWTHEMEATTRIBUTETYPE that specifies the type of attribute to set. + /// The value of this parameter determines the type of data that should be passed in the pvAttribute parameter. + /// Can be the following value: + /// WTA_NONCLIENT (Specifies non-client related attributes). + /// pvAttribute must be a pointer of type WTA_OPTIONS. + /// + /// + /// A pointer that specifies attributes to set. Type is determined by the value of the eAttribute value. + /// + /// + /// Specifies the size, in bytes, of the data pointed to by pvAttribute. + /// + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "uxtheme.dll", PreserveSig = false )] + public static extern void SetWindowThemeAttribute( [In] IntPtr hwnd, [In] WINDOWTHEMEATTRIBUTETYPE eAttribute, [In] ref WTA_OPTIONS pvAttribute, [In] uint cbAttribute ); + + [SuppressMessage( "Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist" )] + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "GetWindowLong", SetLastError = true )] + private static extern int GetWindowLongPtr32( IntPtr hWnd, GWL nIndex ); + + [SuppressMessage( "Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist" )] + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "GetWindowLongPtr", SetLastError = true )] + private static extern IntPtr GetWindowLongPtr64( IntPtr hWnd, GWL nIndex ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool GetWindowPlacement( IntPtr hwnd, WINDOWPLACEMENT lpwndpl ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static WINDOWPLACEMENT GetWindowPlacement( IntPtr hwnd ) + { + WINDOWPLACEMENT wndpl = new WINDOWPLACEMENT(); + if( GetWindowPlacement( hwnd, wndpl ) ) + { + return wndpl; + } + throw new Win32Exception(); + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "GetWindowRect", SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _GetWindowRect( IntPtr hWnd, out RECT lpRect ); + + public static RECT GetWindowRect( IntPtr hwnd ) + { + RECT rc; + if( !_GetWindowRect( hwnd, out rc ) ) + { + HRESULT.ThrowLastError(); + } + return rc; + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdiplus.dll" )] + public static extern Status GdipCreateBitmapFromStream( IStream stream, out IntPtr bitmap ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdiplus.dll" )] + public static extern Status GdipCreateHBITMAPFromBitmap( IntPtr bitmap, out IntPtr hbmReturn, Int32 background ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdiplus.dll" )] + public static extern Status GdipCreateHICONFromBitmap( IntPtr bitmap, out IntPtr hbmReturn ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdiplus.dll" )] + public static extern Status GdipDisposeImage( IntPtr image ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdiplus.dll" )] + public static extern Status GdipImageForceValidation( IntPtr image ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdiplus.dll" )] + public static extern Status GdiplusStartup( out IntPtr token, StartupInput input, out StartupOutput output ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdiplus.dll" )] + public static extern Status GdiplusShutdown( IntPtr token ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll" )] + [return: MarshalAs( UnmanagedType.Bool )] + public static extern bool IsWindowVisible( IntPtr hwnd ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "kernel32.dll", EntryPoint = "LocalFree", SetLastError = true )] + private static extern IntPtr _LocalFree( IntPtr hMem ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll" )] + public static extern IntPtr MonitorFromWindow( IntPtr hwnd, uint dwFlags ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "PostMessage", SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _PostMessage( IntPtr hWnd, WM Msg, IntPtr wParam, IntPtr lParam ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void PostMessage( IntPtr hWnd, WM Msg, IntPtr wParam, IntPtr lParam ) + { + if( !_PostMessage( hWnd, Msg, wParam, lParam ) ) + { + throw new Win32Exception(); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdiplus.dll")] - public static extern Status GdiplusStartup(out IntPtr token, StartupInput input, out StartupOutput output); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", SetLastError = true, EntryPoint = "RegisterClassExW" )] + private static extern short _RegisterClassEx( [In] ref WNDCLASSEX lpwcx ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdiplus.dll")] - public static extern Status GdiplusShutdown(IntPtr token); + // Note that this will throw HRESULT_FROM_WIN32(ERROR_CLASS_ALREADY_EXISTS) on duplicate registration. + // If needed, consider adding a Try* version of this function that returns the error code since that + // may be ignorable. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static short RegisterClassEx( ref WNDCLASSEX lpwcx ) + { + short ret = _RegisterClassEx( ref lpwcx ); + if( ret == 0 ) + { + HRESULT.ThrowLastError(); + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool IsWindowVisible(IntPtr hwnd); + return ret; + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("kernel32.dll", EntryPoint = "LocalFree", SetLastError = true)] - private static extern IntPtr _LocalFree(IntPtr hMem); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "RegisterWindowMessage", SetLastError = true, CharSet = CharSet.Unicode )] + private static extern uint _RegisterWindowMessage( [MarshalAs( UnmanagedType.LPWStr )] string lpString ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll")] - public static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static WM RegisterWindowMessage( string lpString ) + { + uint iRet = _RegisterWindowMessage( lpString ); + if( iRet == 0 ) + { + HRESULT.ThrowLastError(); + } + return ( WM )iRet; + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "PostMessage", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _PostMessage(IntPtr hWnd, WM Msg, IntPtr wParam, IntPtr lParam); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "SetActiveWindow", SetLastError = true )] + private static extern IntPtr _SetActiveWindow( IntPtr hWnd ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void PostMessage(IntPtr hWnd, WM Msg, IntPtr wParam, IntPtr lParam) - { - if (!_PostMessage(hWnd, Msg, wParam, lParam)) - { - throw new Win32Exception(); - } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static IntPtr SetActiveWindow( IntPtr hwnd ) + { + Verify.IsNotDefault( hwnd, "hwnd" ); + IntPtr ret = _SetActiveWindow( hwnd ); + if( ret == IntPtr.Zero ) + { + HRESULT.ThrowLastError(); + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", SetLastError = true, EntryPoint = "RegisterClassExW")] - private static extern short _RegisterClassEx([In] ref WNDCLASSEX lpwcx); + return ret; + } - // Note that this will throw HRESULT_FROM_WIN32(ERROR_CLASS_ALREADY_EXISTS) on duplicate registration. - // If needed, consider adding a Try* version of this function that returns the error code since that - // may be ignorable. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static short RegisterClassEx(ref WNDCLASSEX lpwcx) - { - short ret = _RegisterClassEx(ref lpwcx); - if (ret == 0) - { - HRESULT.ThrowLastError(); - } + // This is aliased as a macro in 32bit Windows. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static IntPtr SetClassLongPtr( IntPtr hwnd, GCLP nIndex, IntPtr dwNewLong ) + { + if( 8 == IntPtr.Size ) + { + return SetClassLongPtr64( hwnd, nIndex, dwNewLong ); + } + return new IntPtr( SetClassLongPtr32( hwnd, nIndex, dwNewLong.ToInt32() ) ); + } - return ret; - } + [SuppressMessage( "Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist" )] + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "SetClassLong", SetLastError = true )] + private static extern int SetClassLongPtr32( IntPtr hWnd, GCLP nIndex, int dwNewLong ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "RegisterWindowMessage", SetLastError = true, CharSet = CharSet.Unicode)] - private static extern uint _RegisterWindowMessage([MarshalAs(UnmanagedType.LPWStr)] string lpString); + [SuppressMessage( "Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist" )] + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "SetClassLongPtr", SetLastError = true )] + private static extern IntPtr SetClassLongPtr64( IntPtr hWnd, GCLP nIndex, IntPtr dwNewLong ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static WM RegisterWindowMessage(string lpString) - { - uint iRet = _RegisterWindowMessage(lpString); - if (iRet == 0) - { - HRESULT.ThrowLastError(); - } - return (WM)iRet; - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "kernel32.dll", SetLastError = true )] + public static extern ErrorModes SetErrorMode( ErrorModes newMode ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "SetActiveWindow", SetLastError = true)] - private static extern IntPtr _SetActiveWindow(IntPtr hWnd); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "kernel32.dll", SetLastError = true, EntryPoint = "SetProcessWorkingSetSize" )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _SetProcessWorkingSetSize( IntPtr hProcess, IntPtr dwMinimiumWorkingSetSize, IntPtr dwMaximumWorkingSetSize ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static IntPtr SetActiveWindow(IntPtr hwnd) - { - Verify.IsNotDefault(hwnd, "hwnd"); - IntPtr ret = _SetActiveWindow(hwnd); - if (ret == IntPtr.Zero) - { - HRESULT.ThrowLastError(); - } - - return ret; - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void SetProcessWorkingSetSize( IntPtr hProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize ) + { + if( !_SetProcessWorkingSetSize( hProcess, new IntPtr( dwMinimumWorkingSetSize ), new IntPtr( dwMaximumWorkingSetSize ) ) ) + { + throw new Win32Exception(); + } + } - // This is aliased as a macro in 32bit Windows. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static IntPtr SetClassLongPtr(IntPtr hwnd, GCLP nIndex, IntPtr dwNewLong) - { - if (8 == IntPtr.Size) - { - return SetClassLongPtr64(hwnd, nIndex, dwNewLong); - } - return new IntPtr(SetClassLongPtr32(hwnd, nIndex, dwNewLong.ToInt32())); - } + // This is aliased as a macro in 32bit Windows. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static IntPtr SetWindowLongPtr( IntPtr hwnd, GWL nIndex, IntPtr dwNewLong ) + { + if( 8 == IntPtr.Size ) + { + return SetWindowLongPtr64( hwnd, nIndex, dwNewLong ); + } + return new IntPtr( SetWindowLongPtr32( hwnd, nIndex, dwNewLong.ToInt32() ) ); + } - [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "SetClassLong", SetLastError = true)] - private static extern int SetClassLongPtr32(IntPtr hWnd, GCLP nIndex, int dwNewLong); + [SuppressMessage( "Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist" )] + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "SetWindowLong", SetLastError = true )] + private static extern int SetWindowLongPtr32( IntPtr hWnd, GWL nIndex, int dwNewLong ); - [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "SetClassLongPtr", SetLastError = true)] - private static extern IntPtr SetClassLongPtr64(IntPtr hWnd, GCLP nIndex, IntPtr dwNewLong); + [SuppressMessage( "Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist" )] + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "SetWindowLongPtr", SetLastError = true )] + private static extern IntPtr SetWindowLongPtr64( IntPtr hWnd, GWL nIndex, IntPtr dwNewLong ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("kernel32.dll", SetLastError = true)] - public static extern ErrorModes SetErrorMode(ErrorModes newMode); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "SetWindowRgn", SetLastError = true )] + private static extern int _SetWindowRgn( IntPtr hWnd, IntPtr hRgn, [MarshalAs( UnmanagedType.Bool )] bool bRedraw ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("kernel32.dll", SetLastError = true, EntryPoint = "SetProcessWorkingSetSize")] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _SetProcessWorkingSetSize(IntPtr hProcess, IntPtr dwMinimiumWorkingSetSize, IntPtr dwMaximumWorkingSetSize); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void SetWindowRgn( IntPtr hWnd, IntPtr hRgn, bool bRedraw ) + { + int err = _SetWindowRgn( hWnd, hRgn, bRedraw ); + if( 0 == err ) + { + throw new Win32Exception(); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void SetProcessWorkingSetSize(IntPtr hProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize) - { - if (!_SetProcessWorkingSetSize(hProcess, new IntPtr(dwMinimumWorkingSetSize), new IntPtr(dwMaximumWorkingSetSize))) - { - throw new Win32Exception(); - } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "SetWindowPos", SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _SetWindowPos( IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, SWP uFlags ); - // This is aliased as a macro in 32bit Windows. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static IntPtr SetWindowLongPtr(IntPtr hwnd, GWL nIndex, IntPtr dwNewLong) - { - if (8 == IntPtr.Size) - { - return SetWindowLongPtr64(hwnd, nIndex, dwNewLong); - } - return new IntPtr(SetWindowLongPtr32(hwnd, nIndex, dwNewLong.ToInt32())); - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool SetWindowPos( IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, SWP uFlags ) + { + if( !_SetWindowPos( hWnd, hWndInsertAfter, x, y, cx, cy, uFlags ) ) + { + // If this fails it's never worth taking down the process. Let the caller deal with the error if they want. + return false; + } - [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "SetWindowLong", SetLastError = true)] - private static extern int SetWindowLongPtr32(IntPtr hWnd, GWL nIndex, int dwNewLong); + return true; + } - [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", SetLastError = true)] - private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, GWL nIndex, IntPtr dwNewLong); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "shell32.dll", SetLastError = false )] + public static extern Win32Error SHFileOperation( ref SHFILEOPSTRUCT lpFileOp ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "SetWindowRgn", SetLastError = true)] - private static extern int _SetWindowRgn(IntPtr hWnd, IntPtr hRgn, [MarshalAs(UnmanagedType.Bool)] bool bRedraw); + [DllImport( "user32.dll" )] + [return: MarshalAs( UnmanagedType.Bool )] + public static extern bool ShowWindow( IntPtr hwnd, SW nCmdShow ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw) - { - int err = _SetWindowRgn(hWnd, hRgn, bRedraw); - if (0 == err) - { - throw new Win32Exception(); - } - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "SetWindowPos", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, SWP uFlags); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "SystemParametersInfoW", SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _SystemParametersInfo_String( SPI uiAction, int uiParam, [MarshalAs( UnmanagedType.LPWStr )] string pvParam, SPIF fWinIni ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, SWP uFlags) - { - if (!_SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, uFlags)) - { - // If this fails it's never worth taking down the process. Let the caller deal with the error if they want. - return false; - } + /// Overload of SystemParametersInfo for getting and setting NONCLIENTMETRICS. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "SystemParametersInfoW", SetLastError = true, CharSet = CharSet.Unicode )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _SystemParametersInfo_NONCLIENTMETRICS( SPI uiAction, int uiParam, [In, Out] ref NONCLIENTMETRICS pvParam, SPIF fWinIni ); - return true; - } + /// Overload of SystemParametersInfo for getting and setting HIGHCONTRAST. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "SystemParametersInfoW", SetLastError = true, CharSet = CharSet.Unicode )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _SystemParametersInfo_HIGHCONTRAST( SPI uiAction, int uiParam, [In, Out] ref HIGHCONTRAST pvParam, SPIF fWinIni ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("shell32.dll", SetLastError = false)] - public static extern Win32Error SHFileOperation(ref SHFILEOPSTRUCT lpFileOp); - - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool ShowWindow(IntPtr hwnd, SW nCmdShow); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "SystemParametersInfoW", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _SystemParametersInfo_String(SPI uiAction, int uiParam, [MarshalAs(UnmanagedType.LPWStr)] string pvParam, SPIF fWinIni); - - /// Overload of SystemParametersInfo for getting and setting NONCLIENTMETRICS. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "SystemParametersInfoW", SetLastError = true, CharSet = CharSet.Unicode)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _SystemParametersInfo_NONCLIENTMETRICS(SPI uiAction, int uiParam, [In, Out] ref NONCLIENTMETRICS pvParam, SPIF fWinIni); - - /// Overload of SystemParametersInfo for getting and setting HIGHCONTRAST. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "SystemParametersInfoW", SetLastError = true, CharSet = CharSet.Unicode)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _SystemParametersInfo_HIGHCONTRAST(SPI uiAction, int uiParam, [In, Out] ref HIGHCONTRAST pvParam, SPIF fWinIni); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void SystemParametersInfo(SPI uiAction, int uiParam, string pvParam, SPIF fWinIni) - { - if (!_SystemParametersInfo_String(uiAction, uiParam, pvParam, fWinIni)) - { - HRESULT.ThrowLastError(); - } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void SystemParametersInfo( SPI uiAction, int uiParam, string pvParam, SPIF fWinIni ) + { + if( !_SystemParametersInfo_String( uiAction, uiParam, pvParam, fWinIni ) ) + { + HRESULT.ThrowLastError(); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static NONCLIENTMETRICS SystemParameterInfo_GetNONCLIENTMETRICS() - { - var metrics = Utility.IsOSVistaOrNewer - ? NONCLIENTMETRICS.VistaMetricsStruct - : NONCLIENTMETRICS.XPMetricsStruct; + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static NONCLIENTMETRICS SystemParameterInfo_GetNONCLIENTMETRICS() + { + var metrics = Utility.IsOSVistaOrNewer + ? NONCLIENTMETRICS.VistaMetricsStruct + : NONCLIENTMETRICS.XPMetricsStruct; - if (!_SystemParametersInfo_NONCLIENTMETRICS(SPI.GETNONCLIENTMETRICS, metrics.cbSize, ref metrics, SPIF.None)) - { - HRESULT.ThrowLastError(); - } + if( !_SystemParametersInfo_NONCLIENTMETRICS( SPI.GETNONCLIENTMETRICS, metrics.cbSize, ref metrics, SPIF.None ) ) + { + HRESULT.ThrowLastError(); + } - return metrics; - } + return metrics; + } - [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] - public static HIGHCONTRAST SystemParameterInfo_GetHIGHCONTRAST() - { - var hc = new HIGHCONTRAST { cbSize = Marshal.SizeOf(typeof(HIGHCONTRAST)) }; + [SuppressMessage( "Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands" )] + public static HIGHCONTRAST SystemParameterInfo_GetHIGHCONTRAST() + { + var hc = new HIGHCONTRAST { cbSize = Marshal.SizeOf( typeof( HIGHCONTRAST ) ) }; - if (!_SystemParametersInfo_HIGHCONTRAST(SPI.GETHIGHCONTRAST, hc.cbSize, ref hc, SPIF.None)) - { - HRESULT.ThrowLastError(); - } + if( !_SystemParametersInfo_HIGHCONTRAST( SPI.GETHIGHCONTRAST, hc.cbSize, ref hc, SPIF.None ) ) + { + HRESULT.ThrowLastError(); + } - return hc; - } + return hc; + } - // This function is strange in that it returns a BOOL if TPM_RETURNCMD isn't specified, but otherwise the command Id. - // Currently it's only used with TPM_RETURNCMD, so making the signature match that. - [DllImport("user32.dll")] - public static extern uint TrackPopupMenuEx(IntPtr hmenu, uint fuFlags, int x, int y, IntPtr hwnd, IntPtr lptpm); + // This function is strange in that it returns a BOOL if TPM_RETURNCMD isn't specified, but otherwise the command Id. + // Currently it's only used with TPM_RETURNCMD, so making the signature match that. + [DllImport( "user32.dll" )] + public static extern uint TrackPopupMenuEx( IntPtr hmenu, uint fuFlags, int x, int y, IntPtr hwnd, IntPtr lptpm ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdi32.dll", EntryPoint = "SelectObject", SetLastError = true )] + private static extern IntPtr _SelectObject( SafeDC hdc, IntPtr hgdiobj ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static IntPtr SelectObject( SafeDC hdc, IntPtr hgdiobj ) + { + IntPtr ret = _SelectObject( hdc, hgdiobj ); + if( ret == IntPtr.Zero ) + { + HRESULT.ThrowLastError(); + } + return ret; + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "gdi32.dll", EntryPoint = "SelectObject", SetLastError = true )] + private static extern IntPtr _SelectObjectSafeHBITMAP( SafeDC hdc, SafeHBITMAP hgdiobj ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static IntPtr SelectObject( SafeDC hdc, SafeHBITMAP hgdiobj ) + { + IntPtr ret = _SelectObjectSafeHBITMAP( hdc, hgdiobj ); + if( ret == IntPtr.Zero ) + { + HRESULT.ThrowLastError(); + } + return ret; + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdi32.dll", EntryPoint = "SelectObject", SetLastError = true)] - private static extern IntPtr _SelectObject(SafeDC hdc, IntPtr hgdiobj); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", SetLastError = true )] + public static extern int SendInput( int nInputs, ref INPUT pInputs, int cbSize ); + + // Depending on the message, callers may want to call GetLastError based on the return value. + [DllImport( "user32.dll", SetLastError = true )] + public static extern IntPtr SendMessage( IntPtr hWnd, WM Msg, IntPtr wParam, IntPtr lParam ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "UnregisterClass", SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _UnregisterClassAtom( IntPtr lpClassName, IntPtr hInstance ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static IntPtr SelectObject(SafeDC hdc, IntPtr hgdiobj) - { - IntPtr ret = _SelectObject(hdc, hgdiobj); - if (ret == IntPtr.Zero) - { - HRESULT.ThrowLastError(); - } - return ret; - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", EntryPoint = "UnregisterClass", CharSet = CharSet.Unicode, SetLastError = true )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _UnregisterClassName( string lpClassName, IntPtr hInstance ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("gdi32.dll", EntryPoint = "SelectObject", SetLastError = true)] - private static extern IntPtr _SelectObjectSafeHBITMAP(SafeDC hdc, SafeHBITMAP hgdiobj); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void UnregisterClass( short atom, IntPtr hinstance ) + { + if( !_UnregisterClassAtom( new IntPtr( atom ), hinstance ) ) + { + HRESULT.ThrowLastError(); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static IntPtr SelectObject(SafeDC hdc, SafeHBITMAP hgdiobj) - { - IntPtr ret = _SelectObjectSafeHBITMAP(hdc, hgdiobj); - if (ret == IntPtr.Zero) - { - HRESULT.ThrowLastError(); - } - return ret; - } + public static void UnregisterClass( string lpClassName, IntPtr hInstance ) + { + if( !_UnregisterClassName( lpClassName, hInstance ) ) + { + HRESULT.ThrowLastError(); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", SetLastError = true)] - public static extern int SendInput(int nInputs, ref INPUT pInputs, int cbSize); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", SetLastError = true, EntryPoint = "UpdateLayeredWindow" )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _UpdateLayeredWindow( + IntPtr hwnd, + SafeDC hdcDst, + [In] ref POINT pptDst, + [In] ref SIZE psize, + SafeDC hdcSrc, + [In] ref POINT pptSrc, + int crKey, + ref BLENDFUNCTION pblend, + ULW dwFlags ); - // Depending on the message, callers may want to call GetLastError based on the return value. - [DllImport("user32.dll", SetLastError = true)] - public static extern IntPtr SendMessage(IntPtr hWnd, WM Msg, IntPtr wParam, IntPtr lParam); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "user32.dll", SetLastError = true, EntryPoint = "UpdateLayeredWindow" )] + [return: MarshalAs( UnmanagedType.Bool )] + private static extern bool _UpdateLayeredWindowIntPtr( + IntPtr hwnd, + IntPtr hdcDst, + IntPtr pptDst, + IntPtr psize, + IntPtr hdcSrc, + IntPtr pptSrc, + int crKey, + ref BLENDFUNCTION pblend, + ULW dwFlags ); + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void UpdateLayeredWindow( + IntPtr hwnd, + SafeDC hdcDst, + ref POINT pptDst, + ref SIZE psize, + SafeDC hdcSrc, + ref POINT pptSrc, + int crKey, + ref BLENDFUNCTION pblend, + ULW dwFlags ) + { + if( !_UpdateLayeredWindow( hwnd, hdcDst, ref pptDst, ref psize, hdcSrc, ref pptSrc, crKey, ref pblend, dwFlags ) ) + { + HRESULT.ThrowLastError(); + } + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void UpdateLayeredWindow( + IntPtr hwnd, + int crKey, + ref BLENDFUNCTION pblend, + ULW dwFlags ) + { + if( !_UpdateLayeredWindowIntPtr( hwnd, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, crKey, ref pblend, dwFlags ) ) + { + HRESULT.ThrowLastError(); + } + } + + #region Win7 declarations + + [DllImport( "shell32.dll", EntryPoint = "SHAddToRecentDocs" )] + private static extern void _SHAddToRecentDocs_String( SHARD uFlags, [MarshalAs( UnmanagedType.LPWStr )] string pv ); + + // This overload is required. There's a cast in the Shell code that causes the wrong vtbl to be used + // if we let the marshaller convert the parameter to an IUnknown. + [DllImport( "shell32.dll", EntryPoint = "SHAddToRecentDocs" )] + private static extern void _SHAddToRecentDocs_ShellLink( SHARD uFlags, IShellLinkW pv ); + + public static void SHAddToRecentDocs( string path ) + { + _SHAddToRecentDocs_String( SHARD.PATHW, path ); + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "UnregisterClass", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _UnregisterClassAtom(IntPtr lpClassName, IntPtr hInstance); + // Win7 only. + public static void SHAddToRecentDocs( IShellLinkW shellLink ) + { + _SHAddToRecentDocs_ShellLink( SHARD.LINK, shellLink ); + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", EntryPoint = "UnregisterClass", CharSet = CharSet.Unicode, SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _UnregisterClassName(string lpClassName, IntPtr hInstance); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void UnregisterClass(short atom, IntPtr hinstance) - { - if (!_UnregisterClassAtom(new IntPtr(atom), hinstance)) - { - HRESULT.ThrowLastError(); - } - } + // #define DWM_SIT_DISPLAYFRAME 0x00000001 // Display a window frame around the provided bitmap - public static void UnregisterClass(string lpClassName, IntPtr hInstance) - { - if (!_UnregisterClassName(lpClassName, hInstance)) - { - HRESULT.ThrowLastError(); - } - } + [DllImport( "dwmapi.dll", EntryPoint = "DwmGetCompositionTimingInfo" )] + private static extern HRESULT _DwmGetCompositionTimingInfo( IntPtr hwnd, ref DWM_TIMING_INFO pTimingInfo ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", SetLastError = true, EntryPoint = "UpdateLayeredWindow")] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _UpdateLayeredWindow( - IntPtr hwnd, - SafeDC hdcDst, - [In] ref POINT pptDst, - [In] ref SIZE psize, - SafeDC hdcSrc, - [In] ref POINT pptSrc, - int crKey, - ref BLENDFUNCTION pblend, - ULW dwFlags); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("user32.dll", SetLastError = true, EntryPoint = "UpdateLayeredWindow")] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool _UpdateLayeredWindowIntPtr( - IntPtr hwnd, - IntPtr hdcDst, - IntPtr pptDst, - IntPtr psize, - IntPtr hdcSrc, - IntPtr pptSrc, - int crKey, - ref BLENDFUNCTION pblend, - ULW dwFlags); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void UpdateLayeredWindow( - IntPtr hwnd, - SafeDC hdcDst, - ref POINT pptDst, - ref SIZE psize, - SafeDC hdcSrc, - ref POINT pptSrc, - int crKey, - ref BLENDFUNCTION pblend, - ULW dwFlags) - { - if (!_UpdateLayeredWindow(hwnd, hdcDst, ref pptDst, ref psize, hdcSrc, ref pptSrc, crKey, ref pblend, dwFlags)) - { - HRESULT.ThrowLastError(); - } - } + public static DWM_TIMING_INFO? DwmGetCompositionTimingInfo( IntPtr hwnd ) + { + if( !Utility.IsOSVistaOrNewer ) + { + // API was new to Vista. + return null; + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void UpdateLayeredWindow( - IntPtr hwnd, - int crKey, - ref BLENDFUNCTION pblend, - ULW dwFlags) - { - if (!_UpdateLayeredWindowIntPtr(hwnd, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, crKey, ref pblend, dwFlags)) - { - HRESULT.ThrowLastError(); - } - } + var dti = new DWM_TIMING_INFO { cbSize = Marshal.SizeOf( typeof( DWM_TIMING_INFO ) ) }; + HRESULT hr = _DwmGetCompositionTimingInfo( Utility.IsOSWindows8OrNewer ? IntPtr.Zero : hwnd, ref dti ); + if( hr == HRESULT.E_PENDING ) + { + // The system isn't yet ready to respond. Return null rather than throw. + return null; + } + hr.ThrowIfFailed(); - #region Win7 declarations + return dti; + } - [DllImport("shell32.dll", EntryPoint = "SHAddToRecentDocs")] - private static extern void _SHAddToRecentDocs_String(SHARD uFlags, [MarshalAs(UnmanagedType.LPWStr)] string pv); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "dwmapi.dll", PreserveSig = false )] + public static extern void DwmInvalidateIconicBitmaps( IntPtr hwnd ); - // This overload is required. There's a cast in the Shell code that causes the wrong vtbl to be used - // if we let the marshaller convert the parameter to an IUnknown. - [DllImport("shell32.dll", EntryPoint = "SHAddToRecentDocs")] - private static extern void _SHAddToRecentDocs_ShellLink(SHARD uFlags, IShellLinkW pv); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "dwmapi.dll", PreserveSig = false )] + public static extern void DwmSetIconicThumbnail( IntPtr hwnd, IntPtr hbmp, DWM_SIT dwSITFlags ); - public static void SHAddToRecentDocs(string path) - { - _SHAddToRecentDocs_String(SHARD.PATHW, path); - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "dwmapi.dll", PreserveSig = false )] + public static extern void DwmSetIconicLivePreviewBitmap( IntPtr hwnd, IntPtr hbmp, RefPOINT pptClient, DWM_SIT dwSITFlags ); - // Win7 only. - public static void SHAddToRecentDocs(IShellLinkW shellLink) - { - _SHAddToRecentDocs_ShellLink(SHARD.LINK, shellLink); - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "shell32.dll", PreserveSig = false )] + public static extern void SHGetItemFromDataObject( IDataObject pdtobj, DOGIF dwFlags, [In] ref Guid riid, [Out, MarshalAs( UnmanagedType.Interface )] out object ppv ); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "shell32.dll", PreserveSig = false )] + public static extern HRESULT SHCreateItemFromParsingName( [MarshalAs( UnmanagedType.LPWStr )] string pszPath, IBindCtx pbc, [In] ref Guid riid, [Out, MarshalAs( UnmanagedType.Interface )] out object ppv ); - // #define DWM_SIT_DISPLAYFRAME 0x00000001 // Display a window frame around the provided bitmap + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "shell32.dll" )] + [return: MarshalAs( UnmanagedType.Bool )] + public static extern bool Shell_NotifyIcon( NIM dwMessage, [In] NOTIFYICONDATA lpdata ); - [DllImport("dwmapi.dll", EntryPoint="DwmGetCompositionTimingInfo")] - private static extern HRESULT _DwmGetCompositionTimingInfo(IntPtr hwnd, ref DWM_TIMING_INFO pTimingInfo); + /// + /// Sets the User Model AppID for the current process, enabling Windows to retrieve this ID + /// + /// + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "shell32.dll", PreserveSig = false )] + public static extern void SetCurrentProcessExplicitAppUserModelID( [MarshalAs( UnmanagedType.LPWStr )] string AppID ); - public static DWM_TIMING_INFO? DwmGetCompositionTimingInfo(IntPtr hwnd) - { - if (!Utility.IsOSVistaOrNewer) - { - // API was new to Vista. - return null; - } - - var dti = new DWM_TIMING_INFO { cbSize = Marshal.SizeOf(typeof(DWM_TIMING_INFO)) }; - HRESULT hr = _DwmGetCompositionTimingInfo( Utility.IsOSWindows8OrNewer ? IntPtr.Zero : hwnd, ref dti ); - if (hr == HRESULT.E_PENDING) - { - // The system isn't yet ready to respond. Return null rather than throw. - return null; - } - hr.ThrowIfFailed(); - - return dti; - } + /// + /// Retrieves the User Model AppID that has been explicitly set for the current process via SetCurrentProcessExplicitAppUserModelID + /// + /// + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DllImport( "shell32.dll" )] + public static extern HRESULT GetCurrentProcessExplicitAppUserModelID( [Out, MarshalAs( UnmanagedType.LPWStr )] out string AppID ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("dwmapi.dll", PreserveSig = false)] - public static extern void DwmInvalidateIconicBitmaps(IntPtr hwnd); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("dwmapi.dll", PreserveSig = false)] - public static extern void DwmSetIconicThumbnail(IntPtr hwnd, IntPtr hbmp, DWM_SIT dwSITFlags); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("dwmapi.dll", PreserveSig = false)] - public static extern void DwmSetIconicLivePreviewBitmap(IntPtr hwnd, IntPtr hbmp, RefPOINT pptClient, DWM_SIT dwSITFlags); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("shell32.dll", PreserveSig = false)] - public static extern void SHGetItemFromDataObject(IDataObject pdtobj, DOGIF dwFlags, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out object ppv); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("shell32.dll", PreserveSig = false)] - public static extern HRESULT SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IBindCtx pbc, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out object ppv); - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("shell32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool Shell_NotifyIcon(NIM dwMessage, [In] NOTIFYICONDATA lpdata); - - /// - /// Sets the User Model AppID for the current process, enabling Windows to retrieve this ID - /// - /// - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("shell32.dll", PreserveSig = false)] - public static extern void SetCurrentProcessExplicitAppUserModelID([MarshalAs(UnmanagedType.LPWStr)] string AppID); - - /// - /// Retrieves the User Model AppID that has been explicitly set for the current process via SetCurrentProcessExplicitAppUserModelID - /// - /// - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DllImport("shell32.dll")] - public static extern HRESULT GetCurrentProcessExplicitAppUserModelID([Out, MarshalAs(UnmanagedType.LPWStr)] out string AppID); - - #endregion - } + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/ShellProvider.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/ShellProvider.cs index 8a1de317..2f926d80 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/ShellProvider.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/ShellProvider.cs @@ -20,964 +20,976 @@ 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 - - /// ShellItem attribute flags. SIATTRIBFLAGS_* - 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 - } - - /// - /// Flags for SetTabProperties. STPF_* - /// - /// The native enum was called STPFLAG. - [Flags] - internal enum STPF - { - NONE = 0x00000000, - USEAPPTHUMBNAILALWAYS = 0x00000001, - USEAPPTHUMBNAILWHENACTIVE = 0x00000002, - USEAPPPEEKALWAYS = 0x00000004, - USEAPPPEEKWHENACTIVE = 0x00000008, - } - - /// - /// Flags for Setting Taskbar Progress state. TBPF_* - /// + 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 + + /// ShellItem attribute flags. SIATTRIBFLAGS_* + 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 + } + + /// + /// Flags for SetTabProperties. STPF_* + /// + /// The native enum was called STPFLAG. + [Flags] + internal enum STPF + { + NONE = 0x00000000, + USEAPPTHUMBNAILALWAYS = 0x00000001, + USEAPPTHUMBNAILWHENACTIVE = 0x00000002, + USEAPPPEEKALWAYS = 0x00000004, + USEAPPPEEKWHENACTIVE = 0x00000008, + } + + /// + /// Flags for Setting Taskbar Progress state. TBPF_* + /// + /// + /// The native enum was called TBPFLAG. + /// + internal enum TBPF + { + NOPROGRESS = 0x00000000, + INDETERMINATE = 0x00000001, + NORMAL = 0x00000002, + ERROR = 0x00000004, + PAUSED = 0x00000008, + } + + /// + /// THUMBBUTTON mask. THB_* + /// + [Flags] + internal enum THB : uint + { + BITMAP = 0x0001, + ICON = 0x0002, + TOOLTIP = 0x0004, + FLAGS = 0x0008, + } + + /// + /// THUMBBUTTON flags. THBF_* + /// + [Flags] + internal enum THBF : uint + { + ENABLED = 0x0000, + DISABLED = 0x0001, + DISMISSONCLICK = 0x0002, + NOBACKGROUND = 0x0004, + HIDDEN = 0x0008, + // Added post-beta + NONINTERACTIVE = 0x0010, + } + + /// + /// GetPropertyStoreFlags. GPS_*. + /// + /// + /// These are new for Vista, but are used in downlevel components + /// + 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, + } + + /// + /// KNOWNDESTCATEGORY. KDC_* + /// + internal enum KDC + { + FREQUENT = 1, + RECENT, + } + + // IShellFolder::GetAttributesOf flags + [Flags] + internal enum SFGAO : uint + { + /// Objects can be copied + /// DROPEFFECT_COPY + CANCOPY = 0x1, + /// Objects can be moved + /// DROPEFFECT_MOVE + CANMOVE = 0x2, + /// Objects can be linked /// - /// The native enum was called TBPFLAG. + /// 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. /// - internal enum TBPF - { - NOPROGRESS = 0x00000000, - INDETERMINATE = 0x00000001, - NORMAL = 0x00000002, - ERROR = 0x00000004, - PAUSED = 0x00000008, - } - + CANLINK = 0x4, + /// supports BindToObject(IID_IStorage) + STORAGE = 0x00000008, + /// Objects can be renamed + CANRENAME = 0x00000010, + /// Objects can be deleted + CANDELETE = 0x00000020, + /// Objects have property sheets + HASPROPSHEET = 0x00000040, + + // unused = 0x00000080, + + /// Objects are drop target + DROPTARGET = 0x00000100, + CAPABILITYMASK = 0x00000177, + // unused = 0x00000200, + // unused = 0x00000400, + // unused = 0x00000800, + // unused = 0x00001000, + /// Object is encrypted (use alt color) + ENCRYPTED = 0x00002000, + /// 'Slow' object + ISSLOW = 0x00004000, + /// Ghosted icon + GHOSTED = 0x00008000, + /// Shortcut (link) + LINK = 0x00010000, + /// Shared + SHARE = 0x00020000, + /// Read-only + READONLY = 0x00040000, + /// Hidden object + HIDDEN = 0x00080000, + DISPLAYATTRMASK = 0x000FC000, + /// May contain children with SFGAO_FILESYSTEM + FILESYSANCESTOR = 0x10000000, + /// Support BindToObject(IID_IShellFolder) + FOLDER = 0x20000000, + /// Is a win32 file system object (file/folder/root) + FILESYSTEM = 0x40000000, + /// May contain children with SFGAO_FOLDER (may be slow) + HASSUBFOLDER = 0x80000000, + CONTENTSMASK = 0x80000000, + /// Invalidate cached information (may be slow) + VALIDATE = 0x01000000, + /// Is this removeable media? + REMOVABLE = 0x02000000, + /// Object is compressed (use alt color) + COMPRESSED = 0x04000000, + /// Supports IShellFolder, but only implements CreateViewObject() (non-folder view) + BROWSABLE = 0x08000000, + /// Is a non-enumerated object (should be hidden) + NONENUMERATED = 0x00100000, + /// Should show bold in explorer tree + NEWCONTENT = 0x00200000, + /// Obsolete + CANMONIKER = 0x00400000, + /// Obsolete + HASSTORAGE = 0x00400000, + /// Supports BindToObject(IID_IStream) + STREAM = 0x00400000, + /// May contain children with SFGAO_STORAGE or SFGAO_STREAM + STORAGEANCESTOR = 0x00800000, + /// For determining storage capabilities, ie for open/save semantics + STORAGECAPMASK = 0x70C50008, /// - /// THUMBBUTTON mask. THB_* + /// 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) /// - [Flags] - internal enum THB : uint - { - BITMAP = 0x0001, - ICON = 0x0002, - TOOLTIP = 0x0004, - FLAGS = 0x0008, - } - + PKEYSFGAOMASK = 0x81044000, + } + + /// + /// IShellFolder::EnumObjects grfFlags bits. Also called SHCONT + /// + 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 + } + + /// + /// IShellFolder::GetDisplayNameOf/SetNameOf uFlags. Also called SHGDNF. + /// + /// + /// For compatibility with SIGDN, these bits must all sit in the LOW word. + /// + [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() + } + + /// + /// SHELLITEMCOMPAREHINTF. SICHINT_*. + /// + internal enum SICHINT : uint + { + /// iOrder based on display in a folder view + DISPLAY = 0x00000000, + /// exact instance compare + ALLFIELDS = 0x80000000, + /// iOrder based on canonical name (better performance) + CANONICAL = 0x10000000, + TEST_FILESYSPATH_IF_NOT_EQUAL = 0x20000000, + }; + + /// + /// ShellItem enum. SIGDN_*. + /// + 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 + } + + /// + /// STR_GPS_* + /// + /// + /// 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. + /// + 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 + { /// - /// THUMBBUTTON flags. THBF_* + /// WPARAM value for a THUMBBUTTON being clicked. /// - [Flags] - internal enum THBF : uint - { - ENABLED = 0x0000, - DISABLED = 0x0001, - DISMISSONCLICK = 0x0002, - NOBACKGROUND = 0x0004, - HIDDEN = 0x0008, - // Added post-beta - NONINTERACTIVE = 0x0010, - } + 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 + { + /// fmtid + private readonly Guid _fmtid; + /// pid + private readonly uint _pid; + + public PKEY( Guid fmtid, uint pid ) + { + _fmtid = fmtid; + _pid = pid; + } + + /// PKEY_Title + public static readonly PKEY Title = new PKEY( new Guid( "F29F85E0-4FF9-1068-AB91-08002B27B3D9" ), 2 ); + /// PKEY_AppUserModel_ID + public static readonly PKEY AppUserModel_ID = new PKEY( new Guid( "9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3" ), 5 ); + /// PKEY_AppUserModel_IsDestListSeparator + public static readonly PKEY AppUserModel_IsDestListSeparator = new PKEY( new Guid( "9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3" ), 6 ); + /// PKEY_AppUserModel_RelaunchCommand + public static readonly PKEY AppUserModel_RelaunchCommand = new PKEY( new Guid( "9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3" ), 2 ); + /// PKEY_AppUserModel_RelaunchDisplayNameResource + public static readonly PKEY AppUserModel_RelaunchDisplayNameResource = new PKEY( new Guid( "9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3" ), 4 ); + /// PKEY_AppUserModel_RelaunchIconResource + 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(); + } + + /// Unknown Object Array + [ + 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 - /// - /// GetPropertyStoreFlags. GPS_*. - /// - /// - /// These are new for Vista, but are used in downlevel components - /// - 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, - } + 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 ); + } + + /// + /// Shell Namespace helper + /// + [ + 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(); + } + + /// + /// Shell Namespace helper 2 + /// + [ + 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 + { /// - /// KNOWNDESTCATEGORY. KDC_* + /// This function must be called first to validate use of other members. /// - internal enum KDC - { - FREQUENT = 1, - RECENT, - } - - // IShellFolder::GetAttributesOf flags - [Flags] - internal enum SFGAO : uint - { - /// Objects can be copied - /// DROPEFFECT_COPY - CANCOPY = 0x1, - /// Objects can be moved - /// DROPEFFECT_MOVE - CANMOVE = 0x2, - /// Objects can be linked - /// - /// 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. - /// - CANLINK = 0x4, - /// supports BindToObject(IID_IStorage) - STORAGE = 0x00000008, - /// Objects can be renamed - CANRENAME = 0x00000010, - /// Objects can be deleted - CANDELETE = 0x00000020, - /// Objects have property sheets - HASPROPSHEET = 0x00000040, - - // unused = 0x00000080, - - /// Objects are drop target - DROPTARGET = 0x00000100, - CAPABILITYMASK = 0x00000177, - // unused = 0x00000200, - // unused = 0x00000400, - // unused = 0x00000800, - // unused = 0x00001000, - /// Object is encrypted (use alt color) - ENCRYPTED = 0x00002000, - /// 'Slow' object - ISSLOW = 0x00004000, - /// Ghosted icon - GHOSTED = 0x00008000, - /// Shortcut (link) - LINK = 0x00010000, - /// Shared - SHARE = 0x00020000, - /// Read-only - READONLY = 0x00040000, - /// Hidden object - HIDDEN = 0x00080000, - DISPLAYATTRMASK = 0x000FC000, - /// May contain children with SFGAO_FILESYSTEM - FILESYSANCESTOR = 0x10000000, - /// Support BindToObject(IID_IShellFolder) - FOLDER = 0x20000000, - /// Is a win32 file system object (file/folder/root) - FILESYSTEM = 0x40000000, - /// May contain children with SFGAO_FOLDER (may be slow) - HASSUBFOLDER = 0x80000000, - CONTENTSMASK = 0x80000000, - /// Invalidate cached information (may be slow) - VALIDATE = 0x01000000, - /// Is this removeable media? - REMOVABLE = 0x02000000, - /// Object is compressed (use alt color) - COMPRESSED = 0x04000000, - /// Supports IShellFolder, but only implements CreateViewObject() (non-folder view) - BROWSABLE = 0x08000000, - /// Is a non-enumerated object (should be hidden) - NONENUMERATED = 0x00100000, - /// Should show bold in explorer tree - NEWCONTENT = 0x00200000, - /// Obsolete - CANMONIKER = 0x00400000, - /// Obsolete - HASSTORAGE = 0x00400000, - /// Supports BindToObject(IID_IStream) - STREAM = 0x00400000, - /// May contain children with SFGAO_STORAGE or SFGAO_STREAM - STORAGEANCESTOR = 0x00800000, - /// For determining storage capabilities, ie for open/save semantics - STORAGECAPMASK = 0x70C50008, - /// - /// 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) - /// - PKEYSFGAOMASK = 0x81044000, - } + void HrInit(); /// - /// IShellFolder::EnumObjects grfFlags bits. Also called SHCONT + /// This function adds a tab for hwnd to the taskbar. /// - 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 - } + /// The HWND for which to add the tab. + void AddTab( IntPtr hwnd ); /// - /// IShellFolder::GetDisplayNameOf/SetNameOf uFlags. Also called SHGDNF. + /// This function deletes a tab for hwnd from the taskbar. /// - /// - /// For compatibility with SIGDN, these bits must all sit in the LOW word. - /// - [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() - } + /// The HWND for which the tab is to be deleted. + void DeleteTab( IntPtr hwnd ); /// - /// SHELLITEMCOMPAREHINTF. SICHINT_*. + /// This function activates the tab associated with hwnd on the taskbar. /// - internal enum SICHINT : uint - { - /// iOrder based on display in a folder view - DISPLAY = 0x00000000, - /// exact instance compare - ALLFIELDS = 0x80000000, - /// iOrder based on canonical name (better performance) - CANONICAL = 0x10000000, - TEST_FILESYSPATH_IF_NOT_EQUAL = 0x20000000, - }; + /// The HWND for which the tab is to be actuvated. + void ActivateTab( IntPtr hwnd ); /// - /// ShellItem enum. SIGDN_*. + /// This function marks hwnd in the taskbar as the active tab. /// - 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 - } + /// The HWND to activate. + 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 /// - /// STR_GPS_* + /// Marks a window as full-screen. /// + /// The handle of the window to be marked. + /// A Boolean value marking the desired full-screen status of the window. /// - /// 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. + /// 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 does not 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. /// - 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 - { - /// - /// WPARAM value for a THUMBBUTTON being clicked. - /// - 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 - { - /// fmtid - private readonly Guid _fmtid; - /// pid - private readonly uint _pid; - - public PKEY(Guid fmtid, uint pid) - { - _fmtid = fmtid; - _pid = pid; - } - - /// PKEY_Title - public static readonly PKEY Title = new PKEY(new Guid("F29F85E0-4FF9-1068-AB91-08002B27B3D9"), 2); - /// PKEY_AppUserModel_ID - public static readonly PKEY AppUserModel_ID = new PKEY(new Guid("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3"), 5); - /// PKEY_AppUserModel_IsDestListSeparator - public static readonly PKEY AppUserModel_IsDestListSeparator = new PKEY(new Guid("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3"), 6); - /// PKEY_AppUserModel_RelaunchCommand - public static readonly PKEY AppUserModel_RelaunchCommand = new PKEY(new Guid("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3"), 2); - /// PKEY_AppUserModel_RelaunchDisplayNameResource - public static readonly PKEY AppUserModel_RelaunchDisplayNameResource = new PKEY(new Guid("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3"), 4); - /// PKEY_AppUserModel_RelaunchIconResource - 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(); - } - - /// Unknown Object Array - [ - 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); - } - + 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(); + } + + /// + /// Allows an application to retrieve the most recent and frequent documents opened in that app, as reported via SHAddToRecentDocs + /// + [ + ComImport, + InterfaceType( ComInterfaceType.InterfaceIsIUnknown ), + Guid( IID.ApplicationDocumentLists ) + ] + internal interface IApplicationDocumentLists + { /// - /// Shell Namespace helper + /// 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. /// - [ - 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(); - } + /// App Id. + void SetAppID( [MarshalAs( UnmanagedType.LPWStr )] string pszAppID ); /// - /// Shell Namespace helper 2 + /// Retrieve an IEnumObjects or IObjectArray for IShellItems and/or IShellLinks. + /// Items may appear in both the frequent and recent lists. /// - [ - 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); + /// + /// + [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(); + } + + /// + /// Provides access to the App User Model ID on objects supporting this value. + /// + [ + ComImport, + InterfaceType( ComInterfaceType.InterfaceIsIUnknown ), + Guid( IID.ObjectWithAppUserModelId ) + ] + internal interface IObjectWithAppUserModelId + { + void SetAppID( [MarshalAs( UnmanagedType.LPWStr )] string pszAppID ); + [return: MarshalAs( UnmanagedType.LPWStr )] + string GetAppID(); + }; + + /// + /// Provides access to the ProgID associated with an object + /// + [ + 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 - ulong GetUInt64(IntPtr key); + new void MarkFullscreenWindow( IntPtr hwnd, [MarshalAs( UnmanagedType.Bool )] bool fFullscreen ); - [return: MarshalAs(UnmanagedType.Bool)] - void GetBool(IntPtr key); - } + #endregion - [ - 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); - } + [PreserveSig] + HRESULT SetProgressValue( IntPtr hwnd, ulong ullCompleted, ulong ullTotal ); - [ - ComImport, - InterfaceType(ComInterfaceType.InterfaceIsIUnknown), - Guid(IID.TaskbarList), - ] - internal interface ITaskbarList - { - /// - /// This function must be called first to validate use of other members. - /// - void HrInit(); - - /// - /// This function adds a tab for hwnd to the taskbar. - /// - /// The HWND for which to add the tab. - void AddTab(IntPtr hwnd); - - /// - /// This function deletes a tab for hwnd from the taskbar. - /// - /// The HWND for which the tab is to be deleted. - void DeleteTab(IntPtr hwnd); - - /// - /// This function activates the tab associated with hwnd on the taskbar. - /// - /// The HWND for which the tab is to be actuvated. - void ActivateTab(IntPtr hwnd); - - /// - /// This function marks hwnd in the taskbar as the active tab. - /// - /// The HWND to activate. - void SetActiveAlt(IntPtr hwnd); - } + [PreserveSig] + HRESULT SetProgressState( IntPtr hwnd, TBPF tbpFlags ); - [ - 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 - - /// - /// Marks a window as full-screen. - /// - /// The handle of the window to be marked. - /// A Boolean value marking the desired full-screen status of the window. - /// - /// 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 does not 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. - /// - void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen); - } + [PreserveSig] + HRESULT RegisterTab( IntPtr hwndTab, IntPtr hwndMDI ); - // 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); + [PreserveSig] + HRESULT UnregisterTab( IntPtr hwndTab ); - // Remove an IShellItem or an IShellLink from the automatic destination list - void RemoveDestination([MarshalAs(UnmanagedType.IUnknown)] object punk); + [PreserveSig] + HRESULT SetTabOrder( IntPtr hwndTab, IntPtr hwndInsertBefore ); - // Clear the frequent and recent destination lists for this application. - void RemoveAllDestinations(); - } + [PreserveSig] + HRESULT SetTabActive( IntPtr hwndTab, IntPtr hwndMDI, uint dwReserved ); - /// - /// Allows an application to retrieve the most recent and frequent documents opened in that app, as reported via SHAddToRecentDocs - /// - [ - ComImport, - InterfaceType(ComInterfaceType.InterfaceIsIUnknown), - Guid(IID.ApplicationDocumentLists) - ] - internal interface IApplicationDocumentLists - { - /// - /// 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. - /// - /// App Id. - void SetAppID([MarshalAs(UnmanagedType.LPWStr)] string pszAppID); - - /// - /// Retrieve an IEnumObjects or IObjectArray for IShellItems and/or IShellLinks. - /// Items may appear in both the frequent and recent lists. - /// - /// - /// - [return: MarshalAs(UnmanagedType.IUnknown)] - object GetList([In] APPDOCLISTTYPE listtype, [In] uint cItemsDesired, [In] ref Guid riid); - } + [PreserveSig] + HRESULT ThumbBarAddButtons( IntPtr hwnd, uint cButtons, [MarshalAs( UnmanagedType.LPArray, SizeParamIndex = 1 )] THUMBBUTTON[] pButtons ); - // 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(); - } + [PreserveSig] + HRESULT ThumbBarUpdateButtons( IntPtr hwnd, uint cButtons, [MarshalAs( UnmanagedType.LPArray, SizeParamIndex = 1 )] THUMBBUTTON[] pButtons ); - /// - /// Provides access to the App User Model ID on objects supporting this value. - /// - [ - ComImport, - InterfaceType(ComInterfaceType.InterfaceIsIUnknown), - Guid(IID.ObjectWithAppUserModelId) - ] - internal interface IObjectWithAppUserModelId - { - void SetAppID([MarshalAs(UnmanagedType.LPWStr)] string pszAppID); - [return: MarshalAs(UnmanagedType.LPWStr)] - string GetAppID(); - }; - - /// - /// Provides access to the ProgID associated with an object - /// - [ - 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 ThumbBarSetImageList( IntPtr hwnd, [MarshalAs( UnmanagedType.IUnknown )] object himl ); - [PreserveSig] - HRESULT SetProgressValue(IntPtr hwnd, ulong ullCompleted, ulong ullTotal); + [PreserveSig] + HRESULT SetOverlayIcon( IntPtr hwnd, IntPtr hIcon, [MarshalAs( UnmanagedType.LPWStr )] string pszDescription ); - [PreserveSig] - HRESULT SetProgressState(IntPtr hwnd, TBPF tbpFlags); + [PreserveSig] + HRESULT SetThumbnailTooltip( IntPtr hwnd, [MarshalAs( UnmanagedType.LPWStr )] string pszTip ); - [PreserveSig] - HRESULT RegisterTab(IntPtr hwndTab, IntPtr hwndMDI); + // Using RefRECT to making passing NULL possible. Removes clipping from the HWND. + [PreserveSig] + HRESULT SetThumbnailClip( IntPtr hwnd, RefRECT prcClip ); + } - [PreserveSig] - HRESULT UnregisterTab(IntPtr hwndTab); + [ + ComImport, + InterfaceType( ComInterfaceType.InterfaceIsIUnknown ), + Guid( IID.TaskbarList3 ), + ] + internal interface ITaskbarList4 : ITaskbarList3 + { + #region ITaskbarList3 redeclaration - [PreserveSig] - HRESULT SetTabOrder(IntPtr hwndTab, IntPtr hwndInsertBefore); + #region ITaskbarList2 redeclaration - [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); + #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 - [PreserveSig] - HRESULT ThumbBarSetImageList(IntPtr hwnd, [MarshalAs(UnmanagedType.IUnknown)] object himl); + new void MarkFullscreenWindow( IntPtr hwnd, [MarshalAs( UnmanagedType.Bool )] bool fFullscreen ); - [PreserveSig] - HRESULT SetOverlayIcon(IntPtr hwnd, IntPtr hIcon, [MarshalAs(UnmanagedType.LPWStr)] string pszDescription); + #endregion - [PreserveSig] - HRESULT SetThumbnailTooltip(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)] string pszTip); + [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 ); - // Using RefRECT to making passing NULL possible. Removes clipping from the HWND. - [PreserveSig] - HRESULT SetThumbnailClip(IntPtr hwnd, RefRECT prcClip); - } + #endregion - [ - 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); - } + void SetTabProperties( IntPtr hwndTab, STPF stpFlags ); + } - #endregion + #endregion } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/StreamHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/StreamHelper.cs index 189647df..72c3f39a 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/StreamHelper.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/StreamHelper.cs @@ -20,338 +20,338 @@ namespace Standard { - using System; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Runtime.InteropServices; - using System.Runtime.InteropServices.ComTypes; + 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? + /// + /// Wraps a managed stream instance into an interface pointer consumable by COM. + /// + 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; - // disambiguate with System.Runtime.InteropServices.STATSTG - using STATSTG = System.Runtime.InteropServices.ComTypes.STATSTG; + /// + /// Initializes a new instance of the ManagedIStream class with the specified managed Stream object. + /// + /// + /// The stream that this IStream reference is wrapping. + /// + 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 - // All these methods return void. Does the standard marshaller convert them to HRESULTs? /// - /// Wraps a managed stream instance into an interface pointer consumable by COM. + /// Creates a new stream object with its own seek pointer that + /// references the same bytes as the original stream. /// - internal sealed class ManagedIStream : IStream, IDisposable + /// + /// When this method returns, contains the new stream object. This parameter is passed uninitialized. + /// + /// + /// 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. + /// + [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 ) { - private const int STGTY_STREAM = 2; - private const int STGM_READWRITE = 2; - private const int LOCK_EXCLUSIVE = 2; - - private Stream _source; - - /// - /// Initializes a new instance of the ManagedIStream class with the specified managed Stream object. - /// - /// - /// The stream that this IStream reference is wrapping. - /// - public ManagedIStream(Stream source) - { - Verify.IsNotNull(source, "source"); - _source = source; - } + ppstm = null; + HRESULT.STG_E_INVALIDFUNCTION.ThrowIfFailed( "The method is not implemented." ); + } - private void _Validate() - { - if (null == _source) - { - throw new ObjectDisposedException("this"); - } - } + /// + /// Ensures that any changes made to a stream object that is open in transacted + /// mode are reflected in the parent storage. + /// + /// + /// A value that controls how the changes for the stream object are committed. + /// + /// + /// For more information, see the existing documentation for IStream::Commit in the MSDN library. + /// + public void Commit( int grfCommitFlags ) + { + _Validate(); + _source.Flush(); + } - // Comments are taken from MSDN IStream documentation. - #region IStream Members - - /// - /// Creates a new stream object with its own seek pointer that - /// references the same bytes as the original stream. - /// - /// - /// When this method returns, contains the new stream object. This parameter is passed uninitialized. - /// - /// - /// 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. - /// - [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."); - } + /// + /// Copies a specified number of bytes from the current seek pointer in the + /// stream to the current seek pointer in another stream. + /// + /// + /// A reference to the destination stream. + /// + /// + /// The number of bytes to copy from the source stream. + /// + /// + /// 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.) + /// + /// + /// 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.) + /// + [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" ); - /// - /// Ensures that any changes made to a stream object that is open in transacted - /// mode are reflected in the parent storage. - /// - /// - /// A value that controls how the changes for the stream object are committed. - /// - /// - /// For more information, see the existing documentation for IStream::Commit in the MSDN library. - /// - public void Commit(int grfCommitFlags) - { - _Validate(); - _source.Flush(); - } + _Validate(); - /// - /// Copies a specified number of bytes from the current seek pointer in the - /// stream to the current seek pointer in another stream. - /// - /// - /// A reference to the destination stream. - /// - /// - /// The number of bytes to copy from the source stream. - /// - /// - /// 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.) - /// - /// - /// 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.) - /// - [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); - } - } + // Reasonbly sized buffer, don't try to copy large streams in bulk. + var buffer = new byte[ 4096 ]; + long cbWritten = 0; - /// - /// Restricts access to a specified range of bytes in the stream. - /// - /// - /// The byte offset for the beginning of the range. - /// - /// - /// The length of the range, in bytes, to restrict. - /// - /// - /// The requested restrictions on accessing the range. - /// - /// - /// 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. - /// - [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) + while( cbWritten < cb ) + { + int cbRead = _source.Read( buffer, 0, buffer.Length ); + if( 0 == cbRead ) { - HRESULT.STG_E_INVALIDFUNCTION.ThrowIfFailed("The method is not implemented."); + break; } - /// - /// Reads a specified number of bytes from the stream object into memory starting at the current seek pointer. - /// - /// - /// When this method returns, contains the data read from the stream. This parameter is passed uninitialized. - /// - /// - /// The number of bytes to read from the stream object. - /// - /// - /// A pointer to a ULONG variable that receives the actual number of bytes read from the stream object. - /// - /// - /// For more information, see the existing documentation for ISequentialStream::Read in the MSDN library. - /// - [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] - public void Read(byte[] pv, int cb, IntPtr pcbRead) - { - _Validate(); + // 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 ); + } + } - int cbRead = _source.Read(pv, 0, cb); + /// + /// Restricts access to a specified range of bytes in the stream. + /// + /// + /// The byte offset for the beginning of the range. + /// + /// + /// The length of the range, in bytes, to restrict. + /// + /// + /// The requested restrictions on accessing the range. + /// + /// + /// 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. + /// + [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." ); + } - if (IntPtr.Zero != pcbRead) - { - Marshal.WriteInt32(pcbRead, cbRead); - } - } + /// + /// Reads a specified number of bytes from the stream object into memory starting at the current seek pointer. + /// + /// + /// When this method returns, contains the data read from the stream. This parameter is passed uninitialized. + /// + /// + /// The number of bytes to read from the stream object. + /// + /// + /// A pointer to a ULONG variable that receives the actual number of bytes read from the stream object. + /// + /// + /// For more information, see the existing documentation for ISequentialStream::Read in the MSDN library. + /// + [SuppressMessage( "Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands" )] + public void Read( byte[] pv, int cb, IntPtr pcbRead ) + { + _Validate(); + int cbRead = _source.Read( pv, 0, cb ); - /// - /// Discards all changes that have been made to a transacted stream since the last Commit call. - /// - /// - /// This class doesn't implement Revert. A COMException is thrown if it is used. - /// - [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."); - } + if( IntPtr.Zero != pcbRead ) + { + Marshal.WriteInt32( pcbRead, cbRead ); + } + } - /// - /// 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. - /// - /// - /// The displacement to add to 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. - /// - /// - /// 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.) - /// - /// - /// For more information, see the existing documentation for IStream::Seek in the MSDN library. - /// - [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] - public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition) - { - _Validate(); - long position = _source.Seek(dlibMove, (SeekOrigin)dwOrigin); + /// + /// Discards all changes that have been made to a transacted stream since the last Commit call. + /// + /// + /// This class doesn't implement Revert. A COMException is thrown if it is used. + /// + [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." ); + } - if (IntPtr.Zero != plibNewPosition) - { - Marshal.WriteInt64(plibNewPosition, position); - } - } + /// + /// 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. + /// + /// + /// The displacement to add to 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. + /// + /// + /// 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.) + /// + /// + /// For more information, see the existing documentation for IStream::Seek in the MSDN library. + /// + [SuppressMessage( "Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands" )] + public void Seek( long dlibMove, int dwOrigin, IntPtr plibNewPosition ) + { + _Validate(); - /// - /// Changes the size of the stream object. - /// - /// - /// The new size of the stream as a number of bytes. - /// - /// - /// For more information, see the existing documentation for IStream::SetSize in the MSDN library. - /// - public void SetSize(long libNewSize) - { - _Validate(); - _source.SetLength(libNewSize); - } + long position = _source.Seek( dlibMove, ( SeekOrigin )dwOrigin ); - /// - /// Retrieves the STATSTG structure for this stream. - /// - /// - /// When this method returns, contains a STATSTG structure that describes this stream object. - /// This parameter is passed uninitialized. - /// - /// - /// Members in the STATSTG structure that this method does not return, thus saving some memory allocation operations. - /// - public void Stat(out STATSTG pstatstg, int grfStatFlag) - { - pstatstg = default(STATSTG); - _Validate(); + if( IntPtr.Zero != plibNewPosition ) + { + Marshal.WriteInt64( plibNewPosition, position ); + } + } - pstatstg.type = STGTY_STREAM; - pstatstg.cbSize = _source.Length; - pstatstg.grfMode = STGM_READWRITE; - pstatstg.grfLocksSupported = LOCK_EXCLUSIVE; - } + /// + /// Changes the size of the stream object. + /// + /// + /// The new size of the stream as a number of bytes. + /// + /// + /// For more information, see the existing documentation for IStream::SetSize in the MSDN library. + /// + public void SetSize( long libNewSize ) + { + _Validate(); + _source.SetLength( libNewSize ); + } - /// - /// Removes the access restriction on a range of bytes previously restricted with the LockRegion method. - /// - /// The byte offset for the beginning of the range. - /// - /// - /// The length, in bytes, of the range to restrict. - /// - /// - /// The access restrictions previously placed on the range. - /// - /// - /// 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. - /// - [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."); - } + /// + /// Retrieves the STATSTG structure for this stream. + /// + /// + /// When this method returns, contains a STATSTG structure that describes this stream object. + /// This parameter is passed uninitialized. + /// + /// + /// Members in the STATSTG structure that this method does not return, thus saving some memory allocation operations. + /// + public void Stat( out STATSTG pstatstg, int grfStatFlag ) + { + pstatstg = default( STATSTG ); + _Validate(); - /// - /// Writes a specified number of bytes into the stream object starting at the current seek pointer. - /// - /// - /// The buffer to write this stream to. - /// - /// - /// The number of bytes to write to the stream. - /// - /// - /// 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. - /// - [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] - public void Write(byte[] pv, int cb, IntPtr pcbWritten) - { - _Validate(); + pstatstg.type = STGTY_STREAM; + pstatstg.cbSize = _source.Length; + pstatstg.grfMode = STGM_READWRITE; + pstatstg.grfLocksSupported = LOCK_EXCLUSIVE; + } - _source.Write(pv, 0, cb); + /// + /// Removes the access restriction on a range of bytes previously restricted with the LockRegion method. + /// + /// The byte offset for the beginning of the range. + /// + /// + /// The length, in bytes, of the range to restrict. + /// + /// + /// The access restrictions previously placed on the range. + /// + /// + /// 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. + /// + [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." ); + } - if (IntPtr.Zero != pcbWritten) - { - Marshal.WriteInt32(pcbWritten, cb); - } - } + /// + /// Writes a specified number of bytes into the stream object starting at the current seek pointer. + /// + /// + /// The buffer to write this stream to. + /// + /// + /// The number of bytes to write to the stream. + /// + /// + /// 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. + /// + [SuppressMessage( "Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands" )] + public void Write( byte[] pv, int cb, IntPtr pcbWritten ) + { + _Validate(); - #endregion + _source.Write( pv, 0, cb ); - #region IDisposable Members + if( IntPtr.Zero != pcbWritten ) + { + Marshal.WriteInt32( pcbWritten, cb ); + } + } - /// - /// Releases resources controlled by this object. - /// - /// - /// Dispose can be called multiple times, but trying to use the object - /// after it has been disposed will generally throw ObjectDisposedExceptions. - /// - public void Dispose() - { - _source = null; - } + #endregion - #endregion + #region IDisposable Members + + /// + /// Releases resources controlled by this object. + /// + /// + /// Dispose can be called multiple times, but trying to use the object + /// after it has been disposed will generally throw ObjectDisposedExceptions. + /// + public void Dispose() + { + _source = null; } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/Utilities.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/Utilities.cs index c9509443..9157d939 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/Utilities.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/Utilities.cs @@ -25,1038 +25,1047 @@ // might be included in multiple assemblies. namespace Standard { - using System; - using System.Collections.Generic; - using System.ComponentModel; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.IO; - using System.Reflection; - using System.Runtime.InteropServices; - using System.Security.Cryptography; - using System.Text; - using System.Windows; - using System.Windows.Media; - using System.Windows.Media.Imaging; - - internal static partial class Utility + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.IO; + using System.Reflection; + using System.Runtime.InteropServices; + using System.Security.Cryptography; + using System.Text; + using System.Windows; + using System.Windows.Media; + using System.Windows.Media.Imaging; + + internal static partial class Utility + { + private static readonly Version _osVersion = Environment.OSVersion.Version; + private static readonly Version _presentationFrameworkVersion = Assembly.GetAssembly( typeof( Window ) ).GetName().Version; + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + private static bool _MemCmp( IntPtr left, IntPtr right, long cb ) { - private static readonly Version _osVersion = Environment.OSVersion.Version; - private static readonly Version _presentationFrameworkVersion = Assembly.GetAssembly(typeof(Window)).GetName().Version; + int offset = 0; - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - private static bool _MemCmp(IntPtr left, IntPtr right, long cb) - { - int offset = 0; - - for (; offset < (cb - sizeof(Int64)); offset += sizeof(Int64)) - { - Int64 left64 = Marshal.ReadInt64(left, offset); - Int64 right64 = Marshal.ReadInt64(right, offset); - - if (left64 != right64) - { - return false; - } - } - - for (; offset < cb; offset += sizeof(byte)) - { - byte left8 = Marshal.ReadByte(left, offset); - byte right8 = Marshal.ReadByte(right, offset); - - if (left8 != right8) - { - return false; - } - } - - return true; - } + for( ; offset < ( cb - sizeof( Int64 ) ); offset += sizeof( Int64 ) ) + { + Int64 left64 = Marshal.ReadInt64( left, offset ); + Int64 right64 = Marshal.ReadInt64( right, offset ); - /// The native RGB macro. - /// - /// - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static int RGB(Color c) + if( left64 != right64 ) { - return c.R | (c.G << 8) | (c.B << 16); + return false; } + } - /// Convert a native integer that represent a color with an alpha channel into a Color struct. - /// The integer that represents the color. Its bits are of the format 0xAARRGGBB. - /// A Color representation of the parameter. - public static Color ColorFromArgbDword(uint color) - { - return Color.FromArgb( - (byte)((color & 0xFF000000) >> 24), - (byte)((color & 0x00FF0000) >> 16), - (byte)((color & 0x0000FF00) >> 8), - (byte)((color & 0x000000FF) >> 0)); - } - - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static int GET_X_LPARAM(IntPtr lParam) - { - return LOWORD(lParam.ToInt32()); - } + for( ; offset < cb; offset += sizeof( byte ) ) + { + byte left8 = Marshal.ReadByte( left, offset ); + byte right8 = Marshal.ReadByte( right, offset ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static int GET_Y_LPARAM(IntPtr lParam) + if( left8 != right8 ) { - return HIWORD(lParam.ToInt32()); + return false; } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static int HIWORD(int i) - { - return (short)(i >> 16); - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static int LOWORD(int i) - { - return (short)(i & 0xFFFF); - } + return true; + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] - public static bool AreStreamsEqual(Stream left, Stream right) - { - if (null == left) - { - return right == null; - } - if (null == right) - { - return false; - } + /// The native RGB macro. + /// + /// + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static int RGB( Color c ) + { + return c.R | ( c.G << 8 ) | ( c.B << 16 ); + } - if (!left.CanRead || !right.CanRead) - { - throw new NotSupportedException("The streams can't be read for comparison"); - } + /// Convert a native integer that represent a color with an alpha channel into a Color struct. + /// The integer that represents the color. Its bits are of the format 0xAARRGGBB. + /// A Color representation of the parameter. + public static Color ColorFromArgbDword( uint color ) + { + return Color.FromArgb( + ( byte )( ( color & 0xFF000000 ) >> 24 ), + ( byte )( ( color & 0x00FF0000 ) >> 16 ), + ( byte )( ( color & 0x0000FF00 ) >> 8 ), + ( byte )( ( color & 0x000000FF ) >> 0 ) ); + } - if (left.Length != right.Length) - { - return false; - } - var length = (int)left.Length; + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static int GET_X_LPARAM( IntPtr lParam ) + { + return LOWORD( lParam.ToInt32() ); + } - // seek to beginning - left.Position = 0; - right.Position = 0; + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static int GET_Y_LPARAM( IntPtr lParam ) + { + return HIWORD( lParam.ToInt32() ); + } - // total bytes read - int totalReadLeft = 0; - int totalReadRight = 0; + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static int HIWORD( int i ) + { + return ( short )( i >> 16 ); + } - // bytes read on this iteration - int cbReadLeft = 0; - int cbReadRight = 0; + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static int LOWORD( int i ) + { + return ( short )( i & 0xFFFF ); + } - // where to store the read data - var leftBuffer = new byte[512]; - var rightBuffer = new byte[512]; + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [SuppressMessage( "Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands" )] + public static bool AreStreamsEqual( Stream left, Stream right ) + { + if( null == left ) + { + return right == null; + } + if( null == right ) + { + return false; + } + + if( !left.CanRead || !right.CanRead ) + { + throw new NotSupportedException( "The streams can't be read for comparison" ); + } + + if( left.Length != right.Length ) + { + return false; + } + + var length = ( int )left.Length; + + // seek to beginning + left.Position = 0; + right.Position = 0; + + // total bytes read + int totalReadLeft = 0; + int totalReadRight = 0; + + // bytes read on this iteration + int cbReadLeft = 0; + int cbReadRight = 0; + + // where to store the read data + var leftBuffer = new byte[ 512 ]; + var rightBuffer = new byte[ 512 ]; + + // pin the left buffer + GCHandle handleLeft = GCHandle.Alloc( leftBuffer, GCHandleType.Pinned ); + IntPtr ptrLeft = handleLeft.AddrOfPinnedObject(); + + // pin the right buffer + GCHandle handleRight = GCHandle.Alloc( rightBuffer, GCHandleType.Pinned ); + IntPtr ptrRight = handleRight.AddrOfPinnedObject(); + + try + { + while( totalReadLeft < length ) + { + Assert.AreEqual( totalReadLeft, totalReadRight ); - // pin the left buffer - GCHandle handleLeft = GCHandle.Alloc(leftBuffer, GCHandleType.Pinned); - IntPtr ptrLeft = handleLeft.AddrOfPinnedObject(); + cbReadLeft = left.Read( leftBuffer, 0, leftBuffer.Length ); + cbReadRight = right.Read( rightBuffer, 0, rightBuffer.Length ); - // pin the right buffer - GCHandle handleRight = GCHandle.Alloc(rightBuffer, GCHandleType.Pinned); - IntPtr ptrRight = handleRight.AddrOfPinnedObject(); + // verify the contents are an exact match + if( cbReadLeft != cbReadRight ) + { + return false; + } - try - { - while (totalReadLeft < length) - { - Assert.AreEqual(totalReadLeft, totalReadRight); + if( !_MemCmp( ptrLeft, ptrRight, cbReadLeft ) ) + { + return false; + } - cbReadLeft = left.Read(leftBuffer, 0, leftBuffer.Length); - cbReadRight = right.Read(rightBuffer, 0, rightBuffer.Length); + totalReadLeft += cbReadLeft; + totalReadRight += cbReadRight; + } - // verify the contents are an exact match - if (cbReadLeft != cbReadRight) - { - return false; - } + Assert.AreEqual( cbReadLeft, cbReadRight ); + Assert.AreEqual( totalReadLeft, totalReadRight ); + Assert.AreEqual( length, totalReadLeft ); + + return true; + } + finally + { + handleLeft.Free(); + handleRight.Free(); + } + } - if (!_MemCmp(ptrLeft, ptrRight, cbReadLeft)) - { - return false; - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool GuidTryParse( string guidString, out Guid guid ) + { + Verify.IsNeitherNullNorEmpty( guidString, "guidString" ); + + try + { + guid = new Guid( guidString ); + return true; + } + catch( FormatException ) + { + } + catch( OverflowException ) + { + } + // Doesn't seem to be a valid guid. + guid = default( Guid ); + return false; + } - totalReadLeft += cbReadLeft; - totalReadRight += cbReadRight; - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool IsFlagSet( int value, int mask ) + { + return 0 != ( value & mask ); + } - Assert.AreEqual(cbReadLeft, cbReadRight); - Assert.AreEqual(totalReadLeft, totalReadRight); - Assert.AreEqual(length, totalReadLeft); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool IsFlagSet( uint value, uint mask ) + { + return 0 != ( value & mask ); + } - return true; - } - finally - { - handleLeft.Free(); - handleRight.Free(); - } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool IsFlagSet( long value, long mask ) + { + return 0 != ( value & mask ); + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool GuidTryParse(string guidString, out Guid guid) - { - Verify.IsNeitherNullNorEmpty(guidString, "guidString"); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool IsFlagSet( ulong value, ulong mask ) + { + return 0 != ( value & mask ); + } - try - { - guid = new Guid(guidString); - return true; - } - catch (FormatException) - { - } - catch (OverflowException) - { - } - // Doesn't seem to be a valid guid. - guid = default(Guid); - return false; - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool IsOSVistaOrNewer + { + get + { + return _osVersion >= new Version( 6, 0 ); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool IsFlagSet(int value, int mask) - { - return 0 != (value & mask); - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool IsOSWindows7OrNewer + { + get + { + return _osVersion >= new Version( 6, 1 ); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool IsFlagSet(uint value, uint mask) - { - return 0 != (value & mask); - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool IsOSWindows8OrNewer + { + get + { + return _osVersion >= new Version( 6, 2 ); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool IsFlagSet(long value, long mask) - { - return 0 != (value & mask); - } + /// + /// Is this using WPF4? + /// + /// + /// There are a few specific bugs in Window in 3.5SP1 and below that require workarounds + /// when handling WM_NCCALCSIZE on the HWND. + /// + public static bool IsPresentationFrameworkVersionLessThan4 + { + get + { + return _presentationFrameworkVersion < new Version( 4, 0 ); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool IsFlagSet(ulong value, ulong mask) + // Caller is responsible for destroying the HICON + // Caller is responsible to ensure that GDI+ has been initialized. + [SuppressMessage( "Microsoft.Usage", "CA2202:Do not dispose objects multiple times" )] + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static IntPtr GenerateHICON( ImageSource image, Size dimensions ) + { + if( image == null ) + { + return IntPtr.Zero; + } + + // If we're getting this from a ".ico" resource, then it comes through as a BitmapFrame. + // We can use leverage this as a shortcut to get the right 16x16 representation + // because DrawImage doesn't do that for us. + var bf = image as BitmapFrame; + if( bf != null ) + { + bf = GetBestMatch( bf.Decoder.Frames, ( int )dimensions.Width, ( int )dimensions.Height ); + } + else + { + // Constrain the dimensions based on the aspect ratio. + var drawingDimensions = new Rect( 0, 0, dimensions.Width, dimensions.Height ); + + // There's no reason to assume that the requested image dimensions are square. + double renderRatio = dimensions.Width / dimensions.Height; + double aspectRatio = image.Width / image.Height; + + // If it's smaller than the requested size, then place it in the middle and pad the image. + if( image.Width <= dimensions.Width && image.Height <= dimensions.Height ) { - return 0 != (value & mask); + drawingDimensions = new Rect( ( dimensions.Width - image.Width ) / 2, ( dimensions.Height - image.Height ) / 2, image.Width, image.Height ); } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool IsOSVistaOrNewer + else if( renderRatio > aspectRatio ) { - get { return _osVersion >= new Version(6, 0); } + double scaledRenderWidth = ( image.Width / image.Height ) * dimensions.Width; + drawingDimensions = new Rect( ( dimensions.Width - scaledRenderWidth ) / 2, 0, scaledRenderWidth, dimensions.Height ); } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool IsOSWindows7OrNewer + else if( renderRatio < aspectRatio ) { - get { return _osVersion >= new Version(6, 1); } + double scaledRenderHeight = ( image.Height / image.Width ) * dimensions.Height; + drawingDimensions = new Rect( 0, ( dimensions.Height - scaledRenderHeight ) / 2, dimensions.Width, scaledRenderHeight ); } - [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] - public static bool IsOSWindows8OrNewer + var dv = new DrawingVisual(); + DrawingContext dc = dv.RenderOpen(); + dc.DrawImage( image, drawingDimensions ); + dc.Close(); + + var bmp = new RenderTargetBitmap( ( int )dimensions.Width, ( int )dimensions.Height, 96, 96, PixelFormats.Pbgra32 ); + bmp.Render( dv ); + bf = BitmapFrame.Create( bmp ); + } + + // Using GDI+ to convert to an HICON. + // I'd rather not duplicate their code. + using( MemoryStream memstm = new MemoryStream() ) + { + BitmapEncoder enc = new PngBitmapEncoder(); + enc.Frames.Add( bf ); + enc.Save( memstm ); + + using( var istm = new ManagedIStream( memstm ) ) { - get + // We are not bubbling out GDI+ errors when creating the native image fails. + IntPtr bitmap = IntPtr.Zero; + try { - return _osVersion >= new Version( 6, 2 ); - } - } - - /// - /// Is this using WPF4? - /// - /// - /// There are a few specific bugs in Window in 3.5SP1 and below that require workarounds - /// when handling WM_NCCALCSIZE on the HWND. - /// - public static bool IsPresentationFrameworkVersionLessThan4 - { - get { return _presentationFrameworkVersion < new Version(4, 0); } - } - - // Caller is responsible for destroying the HICON - // Caller is responsible to ensure that GDI+ has been initialized. - [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static IntPtr GenerateHICON(ImageSource image, Size dimensions) - { - if (image == null) + Status gpStatus = NativeMethods.GdipCreateBitmapFromStream( istm, out bitmap ); + if( Status.Ok != gpStatus ) { - return IntPtr.Zero; + return IntPtr.Zero; } - // If we're getting this from a ".ico" resource, then it comes through as a BitmapFrame. - // We can use leverage this as a shortcut to get the right 16x16 representation - // because DrawImage doesn't do that for us. - var bf = image as BitmapFrame; - if (bf != null) + IntPtr hicon; + gpStatus = NativeMethods.GdipCreateHICONFromBitmap( bitmap, out hicon ); + if( Status.Ok != gpStatus ) { - bf = GetBestMatch(bf.Decoder.Frames, (int)dimensions.Width, (int)dimensions.Height); - } - else - { - // Constrain the dimensions based on the aspect ratio. - var drawingDimensions = new Rect(0, 0, dimensions.Width, dimensions.Height); - - // There's no reason to assume that the requested image dimensions are square. - double renderRatio = dimensions.Width / dimensions.Height; - double aspectRatio = image.Width / image.Height; - - // If it's smaller than the requested size, then place it in the middle and pad the image. - if (image.Width <= dimensions.Width && image.Height <= dimensions.Height) - { - drawingDimensions = new Rect((dimensions.Width - image.Width) / 2, (dimensions.Height - image.Height) / 2, image.Width, image.Height); - } - else if (renderRatio > aspectRatio) - { - double scaledRenderWidth = (image.Width / image.Height) * dimensions.Width; - drawingDimensions = new Rect((dimensions.Width - scaledRenderWidth) / 2, 0, scaledRenderWidth, dimensions.Height); - } - else if (renderRatio < aspectRatio) - { - double scaledRenderHeight = (image.Height / image.Width) * dimensions.Height; - drawingDimensions = new Rect(0, (dimensions.Height - scaledRenderHeight) / 2, dimensions.Width, scaledRenderHeight); - } - - var dv = new DrawingVisual(); - DrawingContext dc = dv.RenderOpen(); - dc.DrawImage(image, drawingDimensions); - dc.Close(); - - var bmp = new RenderTargetBitmap((int)dimensions.Width, (int)dimensions.Height, 96, 96, PixelFormats.Pbgra32); - bmp.Render(dv); - bf = BitmapFrame.Create(bmp); + return IntPtr.Zero; } - // Using GDI+ to convert to an HICON. - // I'd rather not duplicate their code. - using (MemoryStream memstm = new MemoryStream()) - { - BitmapEncoder enc = new PngBitmapEncoder(); - enc.Frames.Add(bf); - enc.Save(memstm); - - using (var istm = new ManagedIStream(memstm)) - { - // We are not bubbling out GDI+ errors when creating the native image fails. - IntPtr bitmap = IntPtr.Zero; - try - { - Status gpStatus = NativeMethods.GdipCreateBitmapFromStream(istm, out bitmap); - if (Status.Ok != gpStatus) - { - return IntPtr.Zero; - } - - IntPtr hicon; - gpStatus = NativeMethods.GdipCreateHICONFromBitmap(bitmap, out hicon); - if (Status.Ok != gpStatus) - { - return IntPtr.Zero; - } - - // Caller is responsible for freeing this. - return hicon; - } - finally - { - Utility.SafeDisposeImage(ref bitmap); - } - } - } + // Caller is responsible for freeing this. + return hicon; + } + finally + { + Utility.SafeDisposeImage( ref bitmap ); + } } + } + } - public static BitmapFrame GetBestMatch(IList frames, int width, int height) - { - return _GetBestMatch(frames, _GetBitDepth(), width, height); - } + public static BitmapFrame GetBestMatch( IList frames, int width, int height ) + { + return _GetBestMatch( frames, _GetBitDepth(), width, height ); + } - private static int _MatchImage(BitmapFrame frame, int bitDepth, int width, int height, int bpp) - { - int score = 2 * _WeightedAbs(bpp, bitDepth, false) + - _WeightedAbs(frame.PixelWidth, width, true) + - _WeightedAbs(frame.PixelHeight, height, true); + private static int _MatchImage( BitmapFrame frame, int bitDepth, int width, int height, int bpp ) + { + int score = 2 * _WeightedAbs( bpp, bitDepth, false ) + + _WeightedAbs( frame.PixelWidth, width, true ) + + _WeightedAbs( frame.PixelHeight, height, true ); - return score; - } + return score; + } - private static int _WeightedAbs(int valueHave, int valueWant, bool fPunish) - { - int diff = (valueHave - valueWant); + private static int _WeightedAbs( int valueHave, int valueWant, bool fPunish ) + { + int diff = ( valueHave - valueWant ); - if (diff < 0) - { - diff = (fPunish ? -2 : -1) * diff; - } + if( diff < 0 ) + { + diff = ( fPunish ? -2 : -1 ) * diff; + } - return diff; - } + return diff; + } - /// From a list of BitmapFrames find the one that best matches the requested dimensions. - /// The methods used here are copied from Win32 sources. We want to be consistent with - /// system behaviors. - private static BitmapFrame _GetBestMatch(IList frames, int bitDepth, int width, int height) - { - int bestScore = int.MaxValue; - int bestBpp = 0; - int bestIndex = 0; + /// From a list of BitmapFrames find the one that best matches the requested dimensions. + /// The methods used here are copied from Win32 sources. We want to be consistent with + /// system behaviors. + private static BitmapFrame _GetBestMatch( IList frames, int bitDepth, int width, int height ) + { + int bestScore = int.MaxValue; + int bestBpp = 0; + int bestIndex = 0; - bool isBitmapIconDecoder = frames[0].Decoder is IconBitmapDecoder; + bool isBitmapIconDecoder = frames[ 0 ].Decoder is IconBitmapDecoder; - for (int i = 0; i < frames.Count && bestScore != 0; ++i) - { - int currentIconBitDepth = isBitmapIconDecoder ? frames[i].Thumbnail.Format.BitsPerPixel : frames[i].Format.BitsPerPixel; - - if (currentIconBitDepth == 0) - { - currentIconBitDepth = 8; - } - - int score = _MatchImage(frames[i], bitDepth, width, height, currentIconBitDepth); - if (score < bestScore) - { - bestIndex = i; - bestBpp = currentIconBitDepth; - bestScore = score; - } - else if (score == bestScore) - { - // Tie breaker: choose the higher color depth. If that fails, choose first one. - if (bestBpp < currentIconBitDepth) - { - bestIndex = i; - bestBpp = currentIconBitDepth; - } - } - } + for( int i = 0; i < frames.Count && bestScore != 0; ++i ) + { + int currentIconBitDepth = isBitmapIconDecoder ? frames[ i ].Thumbnail.Format.BitsPerPixel : frames[ i ].Format.BitsPerPixel; - return frames[bestIndex]; - } - - // This can be cached. It's not going to change under reasonable circumstances. - private static int s_bitDepth; // = 0; - private static int _GetBitDepth() + if( currentIconBitDepth == 0 ) { - if (s_bitDepth == 0) - { - using (SafeDC dc = SafeDC.GetDesktop()) - { - s_bitDepth = NativeMethods.GetDeviceCaps(dc, DeviceCap.BITSPIXEL) * NativeMethods.GetDeviceCaps(dc, DeviceCap.PLANES); - } - } - return s_bitDepth; + currentIconBitDepth = 8; } - /// - /// Simple guard against the exceptions that File.Delete throws on null and empty strings. - /// - /// The path to delete. Unlike File.Delete, this can be null or empty. - /// - /// Note that File.Delete, and by extension SafeDeleteFile, does not throw an exception - /// if the file does not exist. - /// - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void SafeDeleteFile(string path) + int score = _MatchImage( frames[ i ], bitDepth, width, height, currentIconBitDepth ); + if( score < bestScore ) { - if (!string.IsNullOrEmpty(path)) - { - - File.Delete(path); - } + bestIndex = i; + bestBpp = currentIconBitDepth; + bestScore = score; } - - /// GDI's DeleteObject - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void SafeDeleteObject(ref IntPtr gdiObject) + else if( score == bestScore ) { - IntPtr p = gdiObject; - gdiObject = IntPtr.Zero; - if (IntPtr.Zero != p) - { - NativeMethods.DeleteObject(p); - } + // Tie breaker: choose the higher color depth. If that fails, choose first one. + if( bestBpp < currentIconBitDepth ) + { + bestIndex = i; + bestBpp = currentIconBitDepth; + } } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void SafeDestroyIcon(ref IntPtr hicon) - { - IntPtr p = hicon; - hicon = IntPtr.Zero; - if (IntPtr.Zero != p) - { - NativeMethods.DestroyIcon(p); - } - } + return frames[ bestIndex ]; + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void SafeDestroyWindow(ref IntPtr hwnd) + // This can be cached. It's not going to change under reasonable circumstances. + private static int s_bitDepth; // = 0; + private static int _GetBitDepth() + { + if( s_bitDepth == 0 ) + { + using( SafeDC dc = SafeDC.GetDesktop() ) { - IntPtr p = hwnd; - hwnd = IntPtr.Zero; - if (NativeMethods.IsWindow(p)) - { - NativeMethods.DestroyWindow(p); - } + s_bitDepth = NativeMethods.GetDeviceCaps( dc, DeviceCap.BITSPIXEL ) * NativeMethods.GetDeviceCaps( dc, DeviceCap.PLANES ); } + } + return s_bitDepth; + } + /// + /// Simple guard against the exceptions that File.Delete throws on null and empty strings. + /// + /// The path to delete. Unlike File.Delete, this can be null or empty. + /// + /// Note that File.Delete, and by extension SafeDeleteFile, does not throw an exception + /// if the file does not exist. + /// + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void SafeDeleteFile( string path ) + { + if( !string.IsNullOrEmpty( path ) ) + { - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void SafeDispose(ref T disposable) where T : IDisposable - { - // Dispose can safely be called on an object multiple times. - IDisposable t = disposable; - disposable = default(T); - if (null != t) - { - t.Dispose(); - } - } - - /// GDI+'s DisposeImage - /// - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void SafeDisposeImage(ref IntPtr gdipImage) - { - IntPtr p = gdipImage; - gdipImage = IntPtr.Zero; - if (IntPtr.Zero != p) - { - NativeMethods.GdipDisposeImage(p); - } - } + File.Delete( path ); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] - public static void SafeCoTaskMemFree(ref IntPtr ptr) - { - IntPtr p = ptr; - ptr = IntPtr.Zero; - if (IntPtr.Zero != p) - { - Marshal.FreeCoTaskMem(p); - } - } + /// GDI's DeleteObject + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void SafeDeleteObject( ref IntPtr gdiObject ) + { + IntPtr p = gdiObject; + gdiObject = IntPtr.Zero; + if( IntPtr.Zero != p ) + { + NativeMethods.DeleteObject( p ); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] - public static void SafeFreeHGlobal(ref IntPtr hglobal) - { - IntPtr p = hglobal; - hglobal = IntPtr.Zero; - if (IntPtr.Zero != p) - { - Marshal.FreeHGlobal(p); - } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void SafeDestroyIcon( ref IntPtr hicon ) + { + IntPtr p = hicon; + hicon = IntPtr.Zero; + if( IntPtr.Zero != p ) + { + NativeMethods.DestroyIcon( p ); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] - public static void SafeRelease(ref T comObject) where T : class - { - T t = comObject; - comObject = default(T); - if (null != t) - { - Assert.IsTrue(Marshal.IsComObject(t)); - Marshal.ReleaseComObject(t); - } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void SafeDestroyWindow( ref IntPtr hwnd ) + { + IntPtr p = hwnd; + hwnd = IntPtr.Zero; + if( NativeMethods.IsWindow( p ) ) + { + NativeMethods.DestroyWindow( p ); + } + } - /// - /// Utility to help classes catenate their properties for implementing ToString(). - /// - /// The StringBuilder to catenate the results into. - /// The name of the property to be catenated. - /// The value of the property to be catenated. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void GeneratePropertyString(StringBuilder source, string propertyName, string value) - { - Assert.IsNotNull(source); - Assert.IsFalse(string.IsNullOrEmpty(propertyName)); - if (0 != source.Length) - { - source.Append(' '); - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void SafeDispose( ref T disposable ) where T : IDisposable + { + // Dispose can safely be called on an object multiple times. + IDisposable t = disposable; + disposable = default( T ); + if( null != t ) + { + t.Dispose(); + } + } - source.Append(propertyName); - source.Append(": "); - if (string.IsNullOrEmpty(value)) - { - source.Append(""); - } - else - { - source.Append('\"'); - source.Append(value); - source.Append('\"'); - } - } + /// GDI+'s DisposeImage + /// + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void SafeDisposeImage( ref IntPtr gdipImage ) + { + IntPtr p = gdipImage; + gdipImage = IntPtr.Zero; + if( IntPtr.Zero != p ) + { + NativeMethods.GdipDisposeImage( p ); + } + } - /// - /// Generates ToString functionality for a struct. This is an expensive way to do it, - /// it exists for the sake of debugging while classes are in flux. - /// Eventually this should just be removed and the classes should - /// do this without reflection. - /// - /// - /// - /// - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [Obsolete] - public static string GenerateToString(T @object) where T : struct - { - var sbRet = new StringBuilder(); - foreach (PropertyInfo property in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)) - { - if (0 != sbRet.Length) - { - sbRet.Append(", "); - } - Assert.AreEqual(0, property.GetIndexParameters().Length); - object value = property.GetValue(@object, null); - string format = null == value ? "{0}: " : "{0}: \"{1}\""; - sbRet.AppendFormat(format, property.Name, value); - } - return sbRet.ToString(); - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [SuppressMessage( "Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands" )] + public static void SafeCoTaskMemFree( ref IntPtr ptr ) + { + IntPtr p = ptr; + ptr = IntPtr.Zero; + if( IntPtr.Zero != p ) + { + Marshal.FreeCoTaskMem( p ); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void CopyStream(Stream destination, Stream source) - { - Assert.IsNotNull(source); - Assert.IsNotNull(destination); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [SuppressMessage( "Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands" )] + public static void SafeFreeHGlobal( ref IntPtr hglobal ) + { + IntPtr p = hglobal; + hglobal = IntPtr.Zero; + if( IntPtr.Zero != p ) + { + Marshal.FreeHGlobal( p ); + } + } - destination.Position = 0; + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [SuppressMessage( "Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands" )] + public static void SafeRelease( ref T comObject ) where T : class + { + T t = comObject; + comObject = default( T ); + if( null != t ) + { + Assert.IsTrue( Marshal.IsComObject( t ) ); + Marshal.ReleaseComObject( t ); + } + } - // If we're copying from, say, a web stream, don't fail because of this. - if (source.CanSeek) - { - source.Position = 0; + /// + /// Utility to help classes catenate their properties for implementing ToString(). + /// + /// The StringBuilder to catenate the results into. + /// The name of the property to be catenated. + /// The value of the property to be catenated. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void GeneratePropertyString( StringBuilder source, string propertyName, string value ) + { + Assert.IsNotNull( source ); + Assert.IsFalse( string.IsNullOrEmpty( propertyName ) ); + + if( 0 != source.Length ) + { + source.Append( ' ' ); + } + + source.Append( propertyName ); + source.Append( ": " ); + if( string.IsNullOrEmpty( value ) ) + { + source.Append( "" ); + } + else + { + source.Append( '\"' ); + source.Append( value ); + source.Append( '\"' ); + } + } - // Consider that this could throw because - // the source stream doesn't know it's size... - destination.SetLength(source.Length); - } + /// + /// Generates ToString functionality for a struct. This is an expensive way to do it, + /// it exists for the sake of debugging while classes are in flux. + /// Eventually this should just be removed and the classes should + /// do this without reflection. + /// + /// + /// + /// + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [Obsolete] + public static string GenerateToString( T @object ) where T : struct + { + var sbRet = new StringBuilder(); + foreach( PropertyInfo property in typeof( T ).GetProperties( BindingFlags.Public | BindingFlags.Instance ) ) + { + if( 0 != sbRet.Length ) + { + sbRet.Append( ", " ); + } + Assert.AreEqual( 0, property.GetIndexParameters().Length ); + object value = property.GetValue( @object, null ); + string format = null == value ? "{0}: " : "{0}: \"{1}\""; + sbRet.AppendFormat( format, property.Name, value ); + } + return sbRet.ToString(); + } - var buffer = new byte[4096]; - int cbRead; + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void CopyStream( Stream destination, Stream source ) + { + Assert.IsNotNull( source ); + Assert.IsNotNull( destination ); - do - { - cbRead = source.Read(buffer, 0, buffer.Length); - if (0 != cbRead) - { - destination.Write(buffer, 0, cbRead); - } - } - while (buffer.Length == cbRead); + destination.Position = 0; - // Reset the Seek pointer before returning. - destination.Position = 0; - } + // If we're copying from, say, a web stream, don't fail because of this. + if( source.CanSeek ) + { + source.Position = 0; - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static string HashStreamMD5(Stream stm) - { - stm.Position = 0; - var hashBuilder = new StringBuilder(); - using (MD5 md5 = MD5.Create()) - { - foreach (byte b in md5.ComputeHash(stm)) - { - hashBuilder.Append(b.ToString("x2", CultureInfo.InvariantCulture)); - } - } + // Consider that this could throw because + // the source stream doesn't know it's size... + destination.SetLength( source.Length ); + } - return hashBuilder.ToString(); - } + var buffer = new byte[ 4096 ]; + int cbRead; - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static void EnsureDirectory(string path) + do + { + cbRead = source.Read( buffer, 0, buffer.Length ); + if( 0 != cbRead ) { - if (!Directory.Exists(Path.GetDirectoryName(path))) - { - Directory.CreateDirectory(Path.GetDirectoryName(path)); - } + destination.Write( buffer, 0, cbRead ); } + } + while( buffer.Length == cbRead ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static bool MemCmp(byte[] left, byte[] right, int cb) - { - Assert.IsNotNull(left); - Assert.IsNotNull(right); + // Reset the Seek pointer before returning. + destination.Position = 0; + } - Assert.IsTrue(cb <= Math.Min(left.Length, right.Length)); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static string HashStreamMD5( Stream stm ) + { + stm.Position = 0; + var hashBuilder = new StringBuilder(); + using( MD5 md5 = MD5.Create() ) + { + foreach( byte b in md5.ComputeHash( stm ) ) + { + hashBuilder.Append( b.ToString( "x2", CultureInfo.InvariantCulture ) ); + } + } - // pin this buffer - GCHandle handleLeft = GCHandle.Alloc(left, GCHandleType.Pinned); - IntPtr ptrLeft = handleLeft.AddrOfPinnedObject(); + return hashBuilder.ToString(); + } - // pin the other buffer - GCHandle handleRight = GCHandle.Alloc(right, GCHandleType.Pinned); - IntPtr ptrRight = handleRight.AddrOfPinnedObject(); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static void EnsureDirectory( string path ) + { + if( !Directory.Exists( Path.GetDirectoryName( path ) ) ) + { + Directory.CreateDirectory( Path.GetDirectoryName( path ) ); + } + } - bool fRet = _MemCmp(ptrLeft, ptrRight, cb); + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static bool MemCmp( byte[] left, byte[] right, int cb ) + { + Assert.IsNotNull( left ); + Assert.IsNotNull( right ); - handleLeft.Free(); - handleRight.Free(); + Assert.IsTrue( cb <= Math.Min( left.Length, right.Length ) ); - return fRet; - } + // pin this buffer + GCHandle handleLeft = GCHandle.Alloc( left, GCHandleType.Pinned ); + IntPtr ptrLeft = handleLeft.AddrOfPinnedObject(); - private class _UrlDecoder - { - private readonly Encoding _encoding; - private readonly char[] _charBuffer; - private readonly byte[] _byteBuffer; - private int _byteCount; - private int _charCount; - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public _UrlDecoder(int size, Encoding encoding) - { - _encoding = encoding; - _charBuffer = new char[size]; - _byteBuffer = new byte[size]; - } + // pin the other buffer + GCHandle handleRight = GCHandle.Alloc( right, GCHandleType.Pinned ); + IntPtr ptrRight = handleRight.AddrOfPinnedObject(); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public void AddByte(byte b) - { - _byteBuffer[_byteCount++] = b; - } + bool fRet = _MemCmp( ptrLeft, ptrRight, cb ); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public void AddChar(char ch) - { - _FlushBytes(); - _charBuffer[_charCount++] = ch; - } + handleLeft.Free(); + handleRight.Free(); - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - private void _FlushBytes() - { - if (_byteCount > 0) - { - _charCount += _encoding.GetChars(_byteBuffer, 0, _byteCount, _charBuffer, _charCount); - _byteCount = 0; - } - } + return fRet; + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public string GetString() - { - _FlushBytes(); - if (_charCount > 0) - { - return new string(_charBuffer, 0, _charCount); - } - return ""; - } + private class _UrlDecoder + { + private readonly Encoding _encoding; + private readonly char[] _charBuffer; + private readonly byte[] _byteBuffer; + private int _byteCount; + private int _charCount; + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public _UrlDecoder( int size, Encoding encoding ) + { + _encoding = encoding; + _charBuffer = new char[ size ]; + _byteBuffer = new byte[ size ]; + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public void AddByte( byte b ) + { + _byteBuffer[ _byteCount++ ] = b; + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public void AddChar( char ch ) + { + _FlushBytes(); + _charBuffer[ _charCount++ ] = ch; + } + + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + private void _FlushBytes() + { + if( _byteCount > 0 ) + { + _charCount += _encoding.GetChars( _byteBuffer, 0, _byteCount, _charBuffer, _charCount ); + _byteCount = 0; } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static string UrlDecode(string url) + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public string GetString() + { + _FlushBytes(); + if( _charCount > 0 ) { - if (url == null) - { - return null; - } - - var decoder = new _UrlDecoder(url.Length, Encoding.UTF8); - int length = url.Length; - for (int i = 0; i < length; ++i) - { - char ch = url[i]; - - if (ch == '+') - { - decoder.AddByte((byte)' '); - continue; - } - - if (ch == '%' && i < length - 2) - { - // decode %uXXXX into a Unicode character. - if (url[i + 1] == 'u' && i < length - 5) - { - int a = _HexToInt(url[i + 2]); - int b = _HexToInt(url[i + 3]); - int c = _HexToInt(url[i + 4]); - int d = _HexToInt(url[i + 5]); - if (a >= 0 && b >= 0 && c >= 0 && d >= 0) - { - decoder.AddChar((char)((a << 12) | (b << 8) | (c << 4) | d)); - i += 5; - - continue; - } - } - else - { - // decode %XX into a Unicode character. - int a = _HexToInt(url[i + 1]); - int b = _HexToInt(url[i + 2]); - - if (a >= 0 && b >= 0) - { - decoder.AddByte((byte)((a << 4) | b)); - i += 2; - - continue; - } - } - } - - // Add any 7bit character as a byte. - if ((ch & 0xFF80) == 0) - { - decoder.AddByte((byte)ch); - } - else - { - decoder.AddChar(ch); - } - } - - return decoder.GetString(); + return new string( _charBuffer, 0, _charCount ); } + return ""; + } + } - /// - /// Encodes a URL string. Duplicated functionality from System.Web.HttpUtility.UrlEncode. - /// - /// - /// - /// - /// Duplicated from System.Web.HttpUtility because System.Web isn't part of the client profile. - /// URL Encoding replaces ' ' with '+' and unsafe ASCII characters with '%XX'. - /// Safe characters are defined in RFC2396 (http://www.ietf.org/rfc/rfc2396.txt). - /// They are the 7-bit ASCII alphanumerics and the mark characters "-_.!~*'()". - /// This implementation does not treat '~' as a safe character to be consistent with the System.Web version. - /// - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static string UrlEncode(string url) + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static string UrlDecode( string url ) + { + if( url == null ) + { + return null; + } + + var decoder = new _UrlDecoder( url.Length, Encoding.UTF8 ); + int length = url.Length; + for( int i = 0; i < length; ++i ) + { + char ch = url[ i ]; + + if( ch == '+' ) { - if (url == null) - { - return null; - } - - byte[] bytes = Encoding.UTF8.GetBytes(url); - - bool needsEncoding = false; - int unsafeCharCount = 0; - foreach (byte b in bytes) - { - if (b == ' ') - { - needsEncoding = true; - } - else if (!_UrlEncodeIsSafe(b)) - { - ++unsafeCharCount; - needsEncoding = true; - } - } - - if (needsEncoding) - { - var buffer = new byte[bytes.Length + (unsafeCharCount * 2)]; - int writeIndex = 0; - foreach (byte b in bytes) - { - if (_UrlEncodeIsSafe(b)) - { - buffer[writeIndex++] = b; - } - else if (b == ' ') - { - buffer[writeIndex++] = (byte)'+'; - } - else - { - buffer[writeIndex++] = (byte)'%'; - buffer[writeIndex++] = _IntToHex((b >> 4) & 0xF); - buffer[writeIndex++] = _IntToHex(b & 0xF); - } - } - bytes = buffer; - Assert.AreEqual(buffer.Length, writeIndex); - } - - return Encoding.ASCII.GetString(bytes); + decoder.AddByte( ( byte )' ' ); + continue; } - // HttpUtility's UrlEncode is slightly different from the RFC. - // RFC2396 describes unreserved characters as alphanumeric or - // the list "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" - // The System.Web version unnecessarily escapes '~', which should be okay... - // Keeping that same pattern here just to be consistent. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - private static bool _UrlEncodeIsSafe(byte b) + if( ch == '%' && i < length - 2 ) { - if (_IsAsciiAlphaNumeric(b)) + // decode %uXXXX into a Unicode character. + if( url[ i + 1 ] == 'u' && i < length - 5 ) + { + int a = _HexToInt( url[ i + 2 ] ); + int b = _HexToInt( url[ i + 3 ] ); + int c = _HexToInt( url[ i + 4 ] ); + int d = _HexToInt( url[ i + 5 ] ); + if( a >= 0 && b >= 0 && c >= 0 && d >= 0 ) { - return true; + decoder.AddChar( ( char )( ( a << 12 ) | ( b << 8 ) | ( c << 4 ) | d ) ); + i += 5; + + continue; } + } + else + { + // decode %XX into a Unicode character. + int a = _HexToInt( url[ i + 1 ] ); + int b = _HexToInt( url[ i + 2 ] ); - switch ((char)b) + if( a >= 0 && b >= 0 ) { - case '-': - case '_': - case '.': - case '!': - //case '~': - case '*': - case '\'': - case '(': - case ')': - return true; - } + decoder.AddByte( ( byte )( ( a << 4 ) | b ) ); + i += 2; - return false; + continue; + } + } } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - private static bool _IsAsciiAlphaNumeric(byte b) + // Add any 7bit character as a byte. + if( ( ch & 0xFF80 ) == 0 ) { - return (b >= 'a' && b <= 'z') - || (b >= 'A' && b <= 'Z') - || (b >= '0' && b <= '9'); + decoder.AddByte( ( byte )ch ); } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - private static byte _IntToHex(int n) + else { - Assert.BoundedInteger(0, n, 16); - if (n <= 9) - { - return (byte)(n + '0'); - } - return (byte)(n - 10 + 'A'); + decoder.AddChar( ch ); } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - private static int _HexToInt(char h) - { - if (h >= '0' && h <= '9') - { - return h - '0'; - } - - if (h >= 'a' && h <= 'f') - { - return h - 'a' + 10; - } - - if (h >= 'A' && h <= 'F') - { - return h - 'A' + 10; - } - - Assert.Fail("Invalid hex character " + h); - return -1; - } + return decoder.GetString(); + } - public static void AddDependencyPropertyChangeListener(object component, DependencyProperty property, EventHandler listener) + /// + /// Encodes a URL string. Duplicated functionality from System.Web.HttpUtility.UrlEncode. + /// + /// + /// + /// + /// Duplicated from System.Web.HttpUtility because System.Web isn't part of the client profile. + /// URL Encoding replaces ' ' with '+' and unsafe ASCII characters with '%XX'. + /// Safe characters are defined in RFC2396 (http://www.ietf.org/rfc/rfc2396.txt). + /// They are the 7-bit ASCII alphanumerics and the mark characters "-_.!~*'()". + /// This implementation does not treat '~' as a safe character to be consistent with the System.Web version. + /// + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + public static string UrlEncode( string url ) + { + if( url == null ) + { + return null; + } + + byte[] bytes = Encoding.UTF8.GetBytes( url ); + + bool needsEncoding = false; + int unsafeCharCount = 0; + foreach( byte b in bytes ) + { + if( b == ' ' ) { - if (component == null) - { - return; - } - Assert.IsNotNull(property); - Assert.IsNotNull(listener); - - DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(property, component.GetType()); - dpd.AddValueChanged(component, listener); + needsEncoding = true; } - - public static void RemoveDependencyPropertyChangeListener(object component, DependencyProperty property, EventHandler listener) + else if( !_UrlEncodeIsSafe( b ) ) { - if (component == null) - { - return; - } - Assert.IsNotNull(property); - Assert.IsNotNull(listener); - - DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(property, component.GetType()); - dpd.RemoveValueChanged(component, listener); + ++unsafeCharCount; + needsEncoding = true; } + } - #region Extension Methods - - public static bool IsThicknessNonNegative(Thickness thickness) + if( needsEncoding ) + { + var buffer = new byte[ bytes.Length + ( unsafeCharCount * 2 ) ]; + int writeIndex = 0; + foreach( byte b in bytes ) { - if (!IsDoubleFiniteAndNonNegative(thickness.Top)) - { - return false; - } + if( _UrlEncodeIsSafe( b ) ) + { + buffer[ writeIndex++ ] = b; + } + else if( b == ' ' ) + { + buffer[ writeIndex++ ] = ( byte )'+'; + } + else + { + buffer[ writeIndex++ ] = ( byte )'%'; + buffer[ writeIndex++ ] = _IntToHex( ( b >> 4 ) & 0xF ); + buffer[ writeIndex++ ] = _IntToHex( b & 0xF ); + } + } + bytes = buffer; + Assert.AreEqual( buffer.Length, writeIndex ); + } - if (!IsDoubleFiniteAndNonNegative(thickness.Left)) - { - return false; - } + return Encoding.ASCII.GetString( bytes ); + } - if (!IsDoubleFiniteAndNonNegative(thickness.Bottom)) - { - return false; - } + // HttpUtility's UrlEncode is slightly different from the RFC. + // RFC2396 describes unreserved characters as alphanumeric or + // the list "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" + // The System.Web version unnecessarily escapes '~', which should be okay... + // Keeping that same pattern here just to be consistent. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + private static bool _UrlEncodeIsSafe( byte b ) + { + if( _IsAsciiAlphaNumeric( b ) ) + { + return true; + } + + switch( ( char )b ) + { + case '-': + case '_': + case '.': + case '!': + //case '~': + case '*': + case '\'': + case '(': + case ')': + return true; + } + + return false; + } - if (!IsDoubleFiniteAndNonNegative(thickness.Right)) - { - return false; - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + private static bool _IsAsciiAlphaNumeric( byte b ) + { + return ( b >= 'a' && b <= 'z' ) + || ( b >= 'A' && b <= 'Z' ) + || ( b >= '0' && b <= '9' ); + } - return true; - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + private static byte _IntToHex( int n ) + { + Assert.BoundedInteger( 0, n, 16 ); + if( n <= 9 ) + { + return ( byte )( n + '0' ); + } + return ( byte )( n - 10 + 'A' ); + } - public static bool IsCornerRadiusValid(CornerRadius cornerRadius) - { - if (!IsDoubleFiniteAndNonNegative(cornerRadius.TopLeft)) - { - return false; - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + private static int _HexToInt( char h ) + { + if( h >= '0' && h <= '9' ) + { + return h - '0'; + } + + if( h >= 'a' && h <= 'f' ) + { + return h - 'a' + 10; + } + + if( h >= 'A' && h <= 'F' ) + { + return h - 'A' + 10; + } + + Assert.Fail( "Invalid hex character " + h ); + return -1; + } - if (!IsDoubleFiniteAndNonNegative(cornerRadius.TopRight)) - { - return false; - } + public static void AddDependencyPropertyChangeListener( object component, DependencyProperty property, EventHandler listener ) + { + if( component == null ) + { + return; + } + Assert.IsNotNull( property ); + Assert.IsNotNull( listener ); + + DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty( property, component.GetType() ); + dpd.AddValueChanged( component, listener ); + } - if (!IsDoubleFiniteAndNonNegative(cornerRadius.BottomLeft)) - { - return false; - } + public static void RemoveDependencyPropertyChangeListener( object component, DependencyProperty property, EventHandler listener ) + { + if( component == null ) + { + return; + } + Assert.IsNotNull( property ); + Assert.IsNotNull( listener ); + + DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty( property, component.GetType() ); + dpd.RemoveValueChanged( component, listener ); + } - if (!IsDoubleFiniteAndNonNegative(cornerRadius.BottomRight)) - { - return false; - } + #region Extension Methods - return true; - } + public static bool IsThicknessNonNegative( Thickness thickness ) + { + if( !IsDoubleFiniteAndNonNegative( thickness.Top ) ) + { + return false; + } + + if( !IsDoubleFiniteAndNonNegative( thickness.Left ) ) + { + return false; + } + + if( !IsDoubleFiniteAndNonNegative( thickness.Bottom ) ) + { + return false; + } + + if( !IsDoubleFiniteAndNonNegative( thickness.Right ) ) + { + return false; + } + + return true; + } - public static bool IsDoubleFiniteAndNonNegative(double d) - { - if (double.IsNaN(d) || double.IsInfinity(d) || d < 0) - { - return false; - } + public static bool IsCornerRadiusValid( CornerRadius cornerRadius ) + { + if( !IsDoubleFiniteAndNonNegative( cornerRadius.TopLeft ) ) + { + return false; + } + + if( !IsDoubleFiniteAndNonNegative( cornerRadius.TopRight ) ) + { + return false; + } + + if( !IsDoubleFiniteAndNonNegative( cornerRadius.BottomLeft ) ) + { + return false; + } + + if( !IsDoubleFiniteAndNonNegative( cornerRadius.BottomRight ) ) + { + return false; + } + + return true; + } - return true; - } + public static bool IsDoubleFiniteAndNonNegative( double d ) + { + if( double.IsNaN( d ) || double.IsInfinity( d ) || d < 0 ) + { + return false; + } - #endregion + return true; } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/Verify.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/Verify.cs index ea8f3bcc..1d13f3d9 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/Verify.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/Standard/Verify.cs @@ -25,304 +25,304 @@ // 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; + using System; + using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.IO; + using System.Threading; + /// + /// A static class for retail validated assertions. + /// Instead of breaking into the debugger an exception is thrown. + /// + internal static class Verify + { /// - /// A static class for retail validated assertions. - /// Instead of breaking into the debugger an exception is thrown. + /// Ensure that the current thread's apartment state is what's expected. /// - internal static class Verify + /// + /// The required apartment state for the current thread. + /// + /// + /// The message string for the exception to be thrown if the state is invalid. + /// + /// + /// Thrown if the calling thread's apartment state is not the same as the requiredState. + /// + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DebuggerStepThrough] + public static void IsApartmentState( ApartmentState requiredState, string message ) { - /// - /// Ensure that the current thread's apartment state is what's expected. - /// - /// - /// The required apartment state for the current thread. - /// - /// - /// The message string for the exception to be thrown if the state is invalid. - /// - /// - /// Thrown if the calling thread's apartment state is not the same as the requiredState. - /// - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DebuggerStepThrough] - public static void IsApartmentState(ApartmentState requiredState, string message) - { - if (Thread.CurrentThread.GetApartmentState() != requiredState) - { - throw new InvalidOperationException(message); - } - } - - /// - /// Ensure that an argument is neither null nor empty. - /// - /// The string to validate. - /// The name of the parameter that will be presented if an exception is thrown. - [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); + if( Thread.CurrentThread.GetApartmentState() != requiredState ) + { + throw new InvalidOperationException( message ); + } + } - // 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); - } - } + /// + /// Ensure that an argument is neither null nor empty. + /// + /// The string to validate. + /// The name of the parameter that will be presented if an exception is thrown. + [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 ); - /// - /// Ensure that an argument is neither null nor does it consist only of whitespace. - /// - /// The string to validate. - /// The name of the parameter that will be presented if an exception is thrown. - [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."; + if( null == value ) + { + throw new ArgumentNullException( name, errorMessage ); + } + if( "" == value ) + { + throw new ArgumentException( errorMessage, 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); - } - } + /// + /// Ensure that an argument is neither null nor does it consist only of whitespace. + /// + /// The string to validate. + /// The name of the parameter that will be presented if an exception is thrown. + [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 ); - /// Verifies that an argument is not null. - /// Type of the object to validate. Must be a class. - /// The object to validate. - /// The name of the parameter that will be presented if an exception is thrown. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DebuggerStepThrough] - public static void IsNotDefault(T obj, string name) where T : struct - { - if (default(T).Equals(obj)) - { - throw new ArgumentException("The parameter must not be the default value.", 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 ); + } + } - /// Verifies that an argument is not null. - /// Type of the object to validate. Must be a class. - /// The object to validate. - /// The name of the parameter that will be presented if an exception is thrown. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DebuggerStepThrough] - public static void IsNotNull(T obj, string name) where T : class - { - if (null == obj) - { - throw new ArgumentNullException(name); - } - } + /// Verifies that an argument is not null. + /// Type of the object to validate. Must be a class. + /// The object to validate. + /// The name of the parameter that will be presented if an exception is thrown. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DebuggerStepThrough] + public static void IsNotDefault( T obj, string name ) where T : struct + { + if( default( T ).Equals( obj ) ) + { + throw new ArgumentException( "The parameter must not be the default value.", name ); + } + } - /// Verifies that an argument is null. - /// Type of the object to validate. Must be a class. - /// The object to validate. - /// The name of the parameter that will be presented if an exception is thrown. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DebuggerStepThrough] - public static void IsNull(T obj, string name) where T : class - { - if (null != obj) - { - throw new ArgumentException("The parameter must be null.", name); - } - } + /// Verifies that an argument is not null. + /// Type of the object to validate. Must be a class. + /// The object to validate. + /// The name of the parameter that will be presented if an exception is thrown. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DebuggerStepThrough] + public static void IsNotNull( T obj, string name ) where T : class + { + if( null == obj ) + { + throw new ArgumentNullException( name ); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DebuggerStepThrough] - public static void PropertyIsNotNull(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)); - } - } + /// Verifies that an argument is null. + /// Type of the object to validate. Must be a class. + /// The object to validate. + /// The name of the parameter that will be presented if an exception is thrown. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DebuggerStepThrough] + public static void IsNull( 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 PropertyIsNull(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)); - } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DebuggerStepThrough] + public static void PropertyIsNotNull( 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 ) ); + } + } - /// - /// Verifies the specified statement is true. Throws an ArgumentException if it's not. - /// - /// The statement to be verified as true. - /// Name of the parameter to include in the ArgumentException. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DebuggerStepThrough] - public static void IsTrue(bool statement, string name) - { - if (!statement) - { - throw new ArgumentException("", name); - } - } + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DebuggerStepThrough] + public static void PropertyIsNull( 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 ) ); + } + } - /// - /// Verifies the specified statement is true. Throws an ArgumentException if it's not. - /// - /// The statement to be verified as true. - /// Name of the parameter to include in the ArgumentException. - /// The message to include in the ArgumentException. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DebuggerStepThrough] - public static void IsTrue(bool statement, string name, string message) - { - if (!statement) - { - throw new ArgumentException(message, name); - } - } + /// + /// Verifies the specified statement is true. Throws an ArgumentException if it's not. + /// + /// The statement to be verified as true. + /// Name of the parameter to include in the ArgumentException. + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DebuggerStepThrough] + public static void IsTrue( bool statement, string name ) + { + if( !statement ) + { + throw new ArgumentException( "", name ); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DebuggerStepThrough] - public static void AreEqual(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); - } - } + /// + /// Verifies the specified statement is true. Throws an ArgumentException if it's not. + /// + /// The statement to be verified as true. + /// Name of the parameter to include in the ArgumentException. + /// The message to include in the ArgumentException. + [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 AreNotEqual(T notExpected, T actual, string parameterName, string message) + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DebuggerStepThrough] + public static void AreEqual( 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 ) ) { - 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); - } + throw new ArgumentException( message, parameterName ); } + } + else if( !expected.Equals( actual ) ) + { + throw new ArgumentException( message, parameterName ); + } + } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - [DebuggerStepThrough] - public static void UriIsAbsolute(Uri uri, string parameterName) + [SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )] + [DebuggerStepThrough] + public static void AreNotEqual( 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 ) ) { - Verify.IsNotNull(uri, parameterName); - if (!uri.IsAbsoluteUri) - { - throw new ArgumentException("The URI must be absolute.", parameterName); - } + throw new ArgumentException( message, parameterName ); } + } + else if( notExpected.Equals( actual ) ) + { + throw new ArgumentException( message, parameterName ); + } + } - /// - /// Verifies that the specified value is within the expected range. The assertion fails if it isn't. - /// - /// The lower bound inclusive value. - /// The value to verify. - /// The upper bound exclusive value. - [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 UriIsAbsolute( Uri uri, string parameterName ) + { + Verify.IsNotNull( uri, parameterName ); + if( !uri.IsAbsoluteUri ) + { + throw new ArgumentException( "The URI must be absolute.", 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); - } - } + /// + /// Verifies that the specified value is within the expected range. The assertion fails if it isn't. + /// + /// The lower bound inclusive value. + /// The value to verify. + /// The upper bound exclusive value. + [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 TypeSupportsInterface(Type type, Type interfaceType, string parameterName) - { - Assert.IsNeitherNullNorEmpty(parameterName); - Verify.IsNotNull(type, "type"); - Verify.IsNotNull(interfaceType, "interfaceType"); + [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 ); + } + } - 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 TypeSupportsInterface( Type type, Type interfaceType, string parameterName ) + { + Assert.IsNeitherNullNorEmpty( parameterName ); + Verify.IsNotNull( type, "type" ); + Verify.IsNotNull( interfaceType, "interfaceType" ); - [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); - } - } + 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] - internal static void ImplementsInterface(object parameter, Type interfaceType, string parameterName) - { - Assert.IsNotNull(parameter); - Assert.IsNotNull(interfaceType); - Assert.IsTrue(interfaceType.IsInterface); + [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 ); + } + } - bool isImplemented = false; - foreach (var ifaceType in parameter.GetType().GetInterfaces()) - { - if (ifaceType == interfaceType) - { - isImplemented = true; - break; - } - } + [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 ); - if (!isImplemented) - { - throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The parameter must implement interface {0}.", interfaceType.ToString()), parameterName); - } + 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 ); + } } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/SystemCommands.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/SystemCommands.cs index 15da4b4a..793fe87a 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/SystemCommands.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/SystemCommands.cs @@ -17,91 +17,106 @@ namespace Microsoft.Windows.Shell { - using System; - using System.Windows; - using System.Windows.Input; - using System.Windows.Interop; - using Standard; + 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 ); + } + + /// Display the system menu at a specified location. + /// The location to display the system menu, in logical screen coordinates. + public static void ShowSystemMenu( Window window, Point screenLocation ) + { + Verify.IsNotNull( window, "window" ); + ShowSystemMenuPhysicalCoordinates( window, DpiHelper.LogicalPixelsToDevice( screenLocation ) ); + } - public static class SystemCommands + internal static void ShowSystemMenuPhysicalCoordinates( Window window, Point physicalScreenLocation ) { - 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); - } - - /// Display the system menu at a specified location. - /// The location to display the system menu, in logical screen coordinates. - 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); - } - } + 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 ); + } } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/SystemParameters2.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/SystemParameters2.cs index 9ce6ef42..1ef195c6 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/SystemParameters2.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/SystemParameters2.cs @@ -20,324 +20,324 @@ 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> _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(); + 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> _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(); + } - WindowGlassBrush = glassBrush; - } + private void _UpdateIsGlassEnabled( IntPtr wParam, IntPtr lParam ) + { + // Neither the wParam or lParam are used in this case. + _InitializeIsGlassEnabled(); + } - 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 _InitializeGlassColor() + { + bool isOpaque; + uint color; + NativeMethods.DwmGetColorizationColor( out color, out isOpaque ); + color |= isOpaque ? 0xFF000000 : 0; - private void _InitializeCaptionHeight() - { - Point ptCaption = new Point(0, NativeMethods.GetSystemMetrics(SM.CYCAPTION)); - WindowCaptionHeight = DpiHelper.DevicePixelsToLogical(ptCaption).Y; - } + WindowGlassColor = Utility.ColorFromArgbDword( color ); - private void _UpdateCaptionHeight(IntPtr wParam, IntPtr lParam) - { - _InitializeCaptionHeight(); - } + var glassBrush = new SolidColorBrush( WindowGlassColor ); + glassBrush.Freeze(); - 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); - } + WindowGlassBrush = glassBrush; + } - private void _UpdateWindowNonClientFrameThickness(IntPtr wParam, IntPtr lParam) - { - _InitializeWindowNonClientFrameThickness(); - } + 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 _InitializeSmallIconSize() - { - SmallIconSize = new Size( - NativeMethods.GetSystemMetrics(SM.CXSMICON), - NativeMethods.GetSystemMetrics(SM.CYSMICON)); - } + private void _InitializeCaptionHeight() + { + Point ptCaption = new Point( 0, NativeMethods.GetSystemMetrics( SM.CYCAPTION ) ); + WindowCaptionHeight = DpiHelper.DevicePixelsToLogical( ptCaption ).Y; + } - private void _UpdateSmallIconSize(IntPtr wParam, IntPtr lParam) - { - _InitializeSmallIconSize(); - } + private void _UpdateCaptionHeight( IntPtr wParam, IntPtr lParam ) + { + _InitializeCaptionHeight(); + } - 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); + 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 ); + } - int frameX = NativeMethods.GetSystemMetrics(SM.CXSIZEFRAME) + NativeMethods.GetSystemMetrics(SM.CXEDGE); - int frameY = NativeMethods.GetSystemMetrics(SM.CYSIZEFRAME) + NativeMethods.GetSystemMetrics(SM.CYEDGE); + private void _UpdateWindowResizeBorderThickness( IntPtr wParam, IntPtr lParam ) + { + _InitializeWindowResizeBorderThickness(); + } - Rect captionRect = new Rect(0, 0, captionX * 3, captionY); - captionRect.Offset(-frameX - captionRect.Width, frameY); + 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 ); + } - WindowCaptionButtonsLocation = captionRect; - } + private void _UpdateWindowNonClientFrameThickness( IntPtr wParam, IntPtr lParam ) + { + _InitializeWindowNonClientFrameThickness(); + } - [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; - } + private void _InitializeSmallIconSize() + { + SmallIconSize = new Size( + NativeMethods.GetSystemMetrics( SM.CXSMICON ), + NativeMethods.GetSystemMetrics( SM.CYSMICON ) ); + } - 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); - } + private void _UpdateSmallIconSize( IntPtr wParam, IntPtr lParam ) + { + _InitializeSmallIconSize(); + } - // 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)); + 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 ); - RECT rcWindow = NativeMethods.GetWindowRect(_messageHwnd.Handle); + int frameX = NativeMethods.GetSystemMetrics( SM.CXSIZEFRAME ) + NativeMethods.GetSystemMetrics( SM.CXEDGE ); + int frameY = NativeMethods.GetSystemMetrics( SM.CYSIZEFRAME ) + NativeMethods.GetSystemMetrics( SM.CYEDGE ); - // 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 captionRect = new Rect( 0, 0, captionX * 3, captionY ); + captionRect.Offset( -frameX - captionRect.Width, frameY ); - Rect logicalCaptionLocation = DpiHelper.DeviceRectToLogical(deviceCaptionLocation); + WindowCaptionButtonsLocation = captionRect; + } - WindowCaptionButtonsLocation = logicalCaptionLocation; - } + [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 _UpdateCaptionButtonLocation( IntPtr wParam, IntPtr lParam ) + { + _InitializeCaptionButtonLocation(); + } - private void _InitializeHighContrast() - { - HIGHCONTRAST hc = NativeMethods.SystemParameterInfo_GetHIGHCONTRAST(); - HighContrast = (hc.dwFlags & HCF.HIGHCONTRASTON) != 0; - } + private void _InitializeHighContrast() + { + HIGHCONTRAST hc = NativeMethods.SystemParameterInfo_GetHIGHCONTRAST(); + HighContrast = ( hc.dwFlags & HCF.HIGHCONTRASTON ) != 0; + } - private void _UpdateHighContrast(IntPtr wParam, IntPtr lParam) - { - _InitializeHighContrast(); - } + 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 _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 _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 _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(); - } + private void _UpdateWindowCornerRadius( IntPtr wParam, IntPtr lParam ) + { + // Neither the wParam or lParam are used in this case. + _InitializeWindowCornerRadius(); + } - #endregion + #endregion - /// - /// Private constructor. The public way to access this class is through the static Current property. - /// - 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> + /// + /// Private constructor. The public way to access this class is through the static Current property. + /// + 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.THEMECHANGED, new List<_SystemMetricUpdate> { - _UpdateThemeInfo, - _UpdateHighContrast, + _UpdateThemeInfo, + _UpdateHighContrast, _UpdateWindowCornerRadius, _UpdateCaptionButtonLocation, } }, { WM.SETTINGCHANGE, @@ -353,221 +353,254 @@ namespace Microsoft.Windows.Shell { WM.DWMCOMPOSITIONCHANGED, new List<_SystemMetricUpdate> { _UpdateIsGlassEnabled } }, { WM.DWMCOLORIZATIONCOLORCHANGED, new List<_SystemMetricUpdate> { _UpdateGlassColor } }, }; - } + } - public static SystemParameters2 Current + public static SystemParameters2 Current + { + get + { + if( _threadLocalSingleton == null ) { - get - { - if (_threadLocalSingleton == null) - { - _threadLocalSingleton = new SystemParameters2(); - } - return _threadLocalSingleton; - } + _threadLocalSingleton = new SystemParameters2(); } + return _threadLocalSingleton; + } + } - private IntPtr _WndProc(IntPtr hwnd, WM msg, IntPtr wParam, IntPtr lParam) + 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 ) ) { - // 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); + Assert.IsNotNull( handlers ); + foreach( var handler in handlers ) + { + handler( 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"); - } - } - } + return NativeMethods.DefWindowProc( hwnd, msg, wParam, lParam ); + } - 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 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 Thickness WindowResizeBorderThickness - { - get { return _windowResizeBorderThickness; } - private set - { - if (value != _windowResizeBorderThickness) - { - _windowResizeBorderThickness = value; - _NotifyPropertyChanged("WindowResizeBorderThickness"); - } - } - } + public Color WindowGlassColor + { + get + { + return _glassColor; + } + private set + { + if( value != _glassColor ) + { + _glassColor = value; + _NotifyPropertyChanged( "WindowGlassColor" ); + } + } + } - public Thickness WindowNonClientFrameThickness - { - get { return _windowNonClientFrameThickness; } - private set - { - if (value != _windowNonClientFrameThickness) - { - _windowNonClientFrameThickness = value; - _NotifyPropertyChanged("WindowNonClientFrameThickness"); - } - } - } + 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 double WindowCaptionHeight - { - get { return _captionHeight; } - private set - { - if (value != _captionHeight) - { - _captionHeight = value; - _NotifyPropertyChanged("WindowCaptionHeight"); - } - } - } + public Thickness WindowResizeBorderThickness + { + get + { + return _windowResizeBorderThickness; + } + private set + { + if( value != _windowResizeBorderThickness ) + { + _windowResizeBorderThickness = value; + _NotifyPropertyChanged( "WindowResizeBorderThickness" ); + } + } + } - public Size SmallIconSize - { - get { return new Size(_smallIconSize.Width, _smallIconSize.Height); } - private set - { - if (value != _smallIconSize) - { - _smallIconSize = value; - _NotifyPropertyChanged("SmallIconSize"); - } - } - } + public Thickness WindowNonClientFrameThickness + { + get + { + return _windowNonClientFrameThickness; + } + private set + { + if( value != _windowNonClientFrameThickness ) + { + _windowNonClientFrameThickness = value; + _NotifyPropertyChanged( "WindowNonClientFrameThickness" ); + } + } + } - [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"); - } - } - } + public double WindowCaptionHeight + { + get + { + return _captionHeight; + } + private set + { + if( value != _captionHeight ) + { + _captionHeight = value; + _NotifyPropertyChanged( "WindowCaptionHeight" ); + } + } + } - [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 Size SmallIconSize + { + get + { + return new Size( _smallIconSize.Width, _smallIconSize.Height ); + } + private set + { + if( value != _smallIconSize ) + { + _smallIconSize = value; + _NotifyPropertyChanged( "SmallIconSize" ); + } + } + } - public bool HighContrast - { - get { return _isHighContrast; } - private set - { - if (value != _isHighContrast) - { - _isHighContrast = value; - _NotifyPropertyChanged("HighContrast"); - } - } - } + [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" ); + } + } + } - public CornerRadius WindowCornerRadius - { - get { return _windowCornerRadius; } - private set - { - if (value != _windowCornerRadius) - { - _windowCornerRadius = value; - _NotifyPropertyChanged("WindowCornerRadius"); - } - } - } + [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 Rect WindowCaptionButtonsLocation - { - get { return _captionButtonLocation; } - private set - { - if (value != _captionButtonLocation) - { - _captionButtonLocation = value; - _NotifyPropertyChanged("WindowCaptionButtonsLocation"); - } - } - } + public bool HighContrast + { + get + { + return _isHighContrast; + } + private set + { + if( value != _isHighContrast ) + { + _isHighContrast = value; + _NotifyPropertyChanged( "HighContrast" ); + } + } + } - #region INotifyPropertyChanged Members + public CornerRadius WindowCornerRadius + { + get + { + return _windowCornerRadius; + } + private set + { + if( value != _windowCornerRadius ) + { + _windowCornerRadius = value; + _NotifyPropertyChanged( "WindowCornerRadius" ); + } + } + } - private void _NotifyPropertyChanged(string propertyName) - { - Assert.IsNeitherNullNorEmpty(propertyName); - var handler = PropertyChanged; - if (handler != null) - { - handler(this, new PropertyChangedEventArgs(propertyName)); - } - } + public Rect WindowCaptionButtonsLocation + { + get + { + return _captionButtonLocation; + } + private set + { + if( value != _captionButtonLocation ) + { + _captionButtonLocation = value; + _NotifyPropertyChanged( "WindowCaptionButtonsLocation" ); + } + } + } - public event PropertyChangedEventHandler PropertyChanged; + #region INotifyPropertyChanged Members - #endregion + private void _NotifyPropertyChanged( string propertyName ) + { + Assert.IsNeitherNullNorEmpty( propertyName ); + var handler = PropertyChanged; + if( handler != null ) + { + handler( this, new PropertyChangedEventArgs( propertyName ) ); + } } + + public event PropertyChangedEventHandler PropertyChanged; + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/WindowChrome.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/WindowChrome.cs index da25da6f..6aa04db8 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/WindowChrome.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/WindowChrome.cs @@ -20,208 +20,244 @@ 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 + 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 { - private struct _SystemParameterBoundProperty - { - public string SystemParameterPropertyName { get; set; } - public DependencyProperty DependencyProperty { get; set; } - } + 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); } } + // Named property available for fully extending the glass frame. + public static Thickness GlassFrameCompleteThickness + { + get + { + return new Thickness( -1 ); + } + } - #region Attached Properties + #region Attached Properties - public static readonly DependencyProperty WindowChromeProperty = DependencyProperty.RegisterAttached( - "WindowChrome", - typeof(WindowChrome), - typeof(WindowChrome), - new PropertyMetadata(null, _OnChromeChanged)); + 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; - } + 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 ); + } - var window = (Window)d; - var newChrome = (WindowChrome)e.NewValue; + [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 ); + } - Assert.IsNotNull(window); + [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 ); + } - // Update the ChromeWorker with this new object. + public static readonly DependencyProperty IsHitTestVisibleInChromeProperty = DependencyProperty.RegisterAttached( + "IsHitTestVisibleInChrome", + typeof( bool ), + typeof( WindowChrome ), + new FrameworkPropertyMetadata( false, FrameworkPropertyMetadataOptions.Inherits ) ); - // 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); - } + [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 ); + } - chromeWorker.SetWindowChrome(newChrome); - } + [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 ); + } - [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); - } + #endregion - [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); - - /// The extent of the top of the window to treat as the caption. - 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; - } + #region Dependency Properties - 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); } - } + public static readonly DependencyProperty CaptionHeightProperty = DependencyProperty.Register( + "CaptionHeight", + typeof( double ), + typeof( WindowChrome ), + new PropertyMetadata( + 0d, + ( d, e ) => ( ( WindowChrome )d )._OnPropertyChangedThatRequiresRepaint() ), + value => ( double )value >= 0d ); - #region ShowSystemMenu + /// The extent of the top of the window to treat as the caption. + public double CaptionHeight + { + get + { + return ( double )GetValue( CaptionHeightProperty ); + } + set + { + SetValue( CaptionHeightProperty, value ); + } + } - /// - /// Gets or sets the ShowSystemMenu property. This dependency property - /// indicates if the system menu should be shown at right click on the caption. - /// - public bool ShowSystemMenu - { - get; - set; - } + public static readonly DependencyProperty ResizeBorderThicknessProperty = DependencyProperty.Register( + "ResizeBorderThickness", + typeof( Thickness ), + typeof( WindowChrome ), + new PropertyMetadata( default( Thickness ) ), + ( value ) => Utility.IsThicknessNonNegative( ( Thickness )value ) ); - #endregion + 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 ); + } + } - #endregion + 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 ) ); - protected override Freezable CreateInstanceCore() - { - return new WindowChrome(); - } + public CornerRadius CornerRadius + { + get + { + return ( CornerRadius )GetValue( CornerRadiusProperty ); + } + set + { + SetValue( CornerRadiusProperty, value ); + } + } + + #region ShowSystemMenu + + /// + /// Gets or sets the ShowSystemMenu property. This dependency property + /// indicates if the system menu should be shown at right click on the caption. + /// + public bool ShowSystemMenu + { + get; + set; + } - private static readonly List<_SystemParameterBoundProperty> _BoundProperties = new List<_SystemParameterBoundProperty> + #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" }, @@ -229,39 +265,39 @@ namespace Microsoft.Windows.Shell 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) + 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 { - handler(this, EventArgs.Empty); - } - } + Source = SystemParameters2.Current, + Path = new PropertyPath( bp.SystemParameterPropertyName ), + Mode = BindingMode.OneWay, + UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged, + } ); + } + } - internal event EventHandler PropertyChangedThatRequiresRepaint; + private void _OnPropertyChangedThatRequiresRepaint() + { + var handler = PropertyChangedThatRequiresRepaint; + if( handler != null ) + { + handler( this, EventArgs.Empty ); + } } + + internal event EventHandler PropertyChangedThatRequiresRepaint; + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/WindowChromeWorker.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/WindowChromeWorker.cs index d62aed3e..732d94f1 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/WindowChromeWorker.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/Shell/WindowChromeWorker.cs @@ -20,61 +20,60 @@ namespace Microsoft.Windows.Shell { - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Runtime.InteropServices; - using System.Threading; - using System.Windows; - using System.Windows.Interop; - using System.Windows.Media; - using System.Windows.Threading; - using Standard; - - using HANDLE_MESSAGE = System.Collections.Generic.KeyValuePair; - using System.Windows.Controls.Primitives; - - internal class WindowChromeWorker : DependencyObject + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Runtime.InteropServices; + using System.Windows; + using System.Windows.Interop; + using System.Windows.Media; + using System.Windows.Threading; + using Standard; + + using HANDLE_MESSAGE = System.Collections.Generic.KeyValuePair; + using System.Windows.Controls.Primitives; + + internal class WindowChromeWorker : DependencyObject + { + // Delegate signature used for Dispatcher.BeginInvoke. + private delegate void _Action(); + + #region Fields + + private const SWP _SwpFlags = SWP.FRAMECHANGED | SWP.NOSIZE | SWP.NOMOVE | SWP.NOZORDER | SWP.NOOWNERZORDER | SWP.NOACTIVATE; + + private readonly List _messageTable; + + /// The Window that's chrome is being modified. + private Window _window; + /// Underlying HWND for the _window. + private IntPtr _hwnd; + private HwndSource _hwndSource = null; + private bool _isHooked = false; + + // These fields are for tracking workarounds for WPF 3.5SP1 behaviors. + private bool _isFixedUp = false; + private bool _isUserResizing = false; + private bool _hasUserMovedWindow = false; + private Point _windowPosAtStartOfUserMove = default( Point ); + + // Field to track attempts to force off Device Bitmaps on Win7. + private int _blackGlassFixupAttemptCount; + + /// Object that describes the current modifications being made to the chrome. + private WindowChrome _chromeInfo; + + // Keep track of this so we can detect when we need to apply changes. Tracking these separately + // as I've seen using just one cause things to get enough out of sync that occasionally the caption will redraw. + private WindowState _lastRoundingState; + private WindowState _lastMenuState; + private bool _isGlassEnabled; + + #endregion + + public WindowChromeWorker() { - // Delegate signature used for Dispatcher.BeginInvoke. - private delegate void _Action(); - - #region Fields - - private const SWP _SwpFlags = SWP.FRAMECHANGED | SWP.NOSIZE | SWP.NOMOVE | SWP.NOZORDER | SWP.NOOWNERZORDER | SWP.NOACTIVATE; - - private readonly List _messageTable; - - /// The Window that's chrome is being modified. - private Window _window; - /// Underlying HWND for the _window. - private IntPtr _hwnd; - private HwndSource _hwndSource = null; - private bool _isHooked = false; - - // These fields are for tracking workarounds for WPF 3.5SP1 behaviors. - private bool _isFixedUp = false; - private bool _isUserResizing = false; - private bool _hasUserMovedWindow = false; - private Point _windowPosAtStartOfUserMove = default(Point); - - // Field to track attempts to force off Device Bitmaps on Win7. - private int _blackGlassFixupAttemptCount; - - /// Object that describes the current modifications being made to the chrome. - private WindowChrome _chromeInfo; - - // Keep track of this so we can detect when we need to apply changes. Tracking these separately - // as I've seen using just one cause things to get enough out of sync that occasionally the caption will redraw. - private WindowState _lastRoundingState; - private WindowState _lastMenuState; - private bool _isGlassEnabled; - - #endregion - - public WindowChromeWorker() - { - _messageTable = new List + _messageTable = new List { new HANDLE_MESSAGE(WM.SETTEXT, _HandleSetTextOrIcon), new HANDLE_MESSAGE(WM.SETICON, _HandleSetTextOrIcon), @@ -84,1144 +83,1146 @@ namespace Microsoft.Windows.Shell new HANDLE_MESSAGE(WM.NCRBUTTONUP, _HandleNCRButtonUp), new HANDLE_MESSAGE(WM.SIZE, _HandleSize), new HANDLE_MESSAGE(WM.WINDOWPOSCHANGED, _HandleWindowPosChanged), - new HANDLE_MESSAGE(WM.DWMCOMPOSITIONCHANGED, _HandleDwmCompositionChanged), + new HANDLE_MESSAGE(WM.DWMCOMPOSITIONCHANGED, _HandleDwmCompositionChanged), }; - if (Utility.IsPresentationFrameworkVersionLessThan4) - { - _messageTable.AddRange(new[] - { + if( Utility.IsPresentationFrameworkVersionLessThan4 ) + { + _messageTable.AddRange( new[] + { new HANDLE_MESSAGE(WM.SETTINGCHANGE, _HandleSettingChange), new HANDLE_MESSAGE(WM.ENTERSIZEMOVE, _HandleEnterSizeMove), new HANDLE_MESSAGE(WM.EXITSIZEMOVE, _HandleExitSizeMove), new HANDLE_MESSAGE(WM.MOVE, _HandleMove), - }); - } - } + } ); + } + } - public void SetWindowChrome(WindowChrome newChrome) - { - VerifyAccess(); - Assert.IsNotNull(_window); + public void SetWindowChrome( WindowChrome newChrome ) + { + VerifyAccess(); + Assert.IsNotNull( _window ); + + if( newChrome == _chromeInfo ) + { + // Nothing's changed. + return; + } + + if( _chromeInfo != null ) + { + _chromeInfo.PropertyChangedThatRequiresRepaint -= _OnChromePropertyChangedThatRequiresRepaint; + } + + _chromeInfo = newChrome; + if( _chromeInfo != null ) + { + _chromeInfo.PropertyChangedThatRequiresRepaint += _OnChromePropertyChangedThatRequiresRepaint; + } + + _ApplyNewCustomChrome(); + } - if (newChrome == _chromeInfo) - { - // Nothing's changed. - return; - } + private void _OnChromePropertyChangedThatRequiresRepaint( object sender, EventArgs e ) + { + _UpdateFrameState( true ); + } - if (_chromeInfo != null) - { - _chromeInfo.PropertyChangedThatRequiresRepaint -= _OnChromePropertyChangedThatRequiresRepaint; - } + public static readonly DependencyProperty WindowChromeWorkerProperty = DependencyProperty.RegisterAttached( + "WindowChromeWorker", + typeof( WindowChromeWorker ), + typeof( WindowChromeWorker ), + new PropertyMetadata( null, _OnChromeWorkerChanged ) ); - _chromeInfo = newChrome; - if (_chromeInfo != null) - { - _chromeInfo.PropertyChangedThatRequiresRepaint += _OnChromePropertyChangedThatRequiresRepaint; - } + private static void _OnChromeWorkerChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + var w = ( Window )d; + var cw = ( WindowChromeWorker )e.NewValue; - _ApplyNewCustomChrome(); - } + // The WindowChromeWorker object should only be set on the window once, and never to null. + Assert.IsNotNull( w ); + Assert.IsNotNull( cw ); + Assert.IsNull( cw._window ); - private void _OnChromePropertyChangedThatRequiresRepaint(object sender, EventArgs e) + cw._SetWindow( w ); + } + + private void _SetWindow( Window window ) + { + Assert.IsNull( _window ); + Assert.IsNotNull( window ); + + _window = window; + + // There are potentially a couple funny states here. + // The window may have been shown and closed, in which case it's no longer usable. + // We shouldn't add any hooks in that case, just exit early. + // If the window hasn't yet been shown, then we need to make sure to remove hooks after it's closed. + _hwnd = new WindowInteropHelper( _window ).Handle; + + if( Utility.IsPresentationFrameworkVersionLessThan4 ) + { + // On older versions of the framework the client size of the window is incorrectly calculated. + // We need to modify the template to fix this on behalf of the user. + Utility.AddDependencyPropertyChangeListener( _window, Window.TemplateProperty, _OnWindowPropertyChangedThatRequiresTemplateFixup ); + Utility.AddDependencyPropertyChangeListener( _window, Window.FlowDirectionProperty, _OnWindowPropertyChangedThatRequiresTemplateFixup ); + } + + _window.Closed += _UnsetWindow; + + // Use whether we can get an HWND to determine if the Window has been loaded. + if( IntPtr.Zero != _hwnd ) + { + // We've seen that the HwndSource can't always be retrieved from the HWND, so cache it early. + // Specifically it seems to sometimes disappear when the OS theme is changing. + _hwndSource = HwndSource.FromHwnd( _hwnd ); + Assert.IsNotNull( _hwndSource ); + _window.ApplyTemplate(); + + if( _chromeInfo != null ) { - _UpdateFrameState(true); + _ApplyNewCustomChrome(); } + } + else + { + _window.SourceInitialized += ( sender, e ) => + { + _hwnd = new WindowInteropHelper( _window ).Handle; + Assert.IsNotDefault( _hwnd ); + _hwndSource = HwndSource.FromHwnd( _hwnd ); + Assert.IsNotNull( _hwndSource ); - public static readonly DependencyProperty WindowChromeWorkerProperty = DependencyProperty.RegisterAttached( - "WindowChromeWorker", - typeof(WindowChromeWorker), - typeof(WindowChromeWorker), - new PropertyMetadata(null, _OnChromeWorkerChanged)); + if( _chromeInfo != null ) + { + _ApplyNewCustomChrome(); + } + }; + } + } - private static void _OnChromeWorkerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var w = (Window)d; - var cw = (WindowChromeWorker)e.NewValue; + private void _UnsetWindow( object sender, EventArgs e ) + { + if( Utility.IsPresentationFrameworkVersionLessThan4 ) + { + Utility.RemoveDependencyPropertyChangeListener( _window, Window.TemplateProperty, _OnWindowPropertyChangedThatRequiresTemplateFixup ); + Utility.RemoveDependencyPropertyChangeListener( _window, Window.FlowDirectionProperty, _OnWindowPropertyChangedThatRequiresTemplateFixup ); + } + + if( _chromeInfo != null ) + { + _chromeInfo.PropertyChangedThatRequiresRepaint -= _OnChromePropertyChangedThatRequiresRepaint; + } + + _RestoreStandardChromeState( true ); + } - // The WindowChromeWorker object should only be set on the window once, and never to null. - Assert.IsNotNull(w); - Assert.IsNotNull(cw); - Assert.IsNull(cw._window); + [SuppressMessage( "Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters" )] + public static WindowChromeWorker GetWindowChromeWorker( Window window ) + { + Verify.IsNotNull( window, "window" ); + return ( WindowChromeWorker )window.GetValue( WindowChromeWorkerProperty ); + } - cw._SetWindow(w); - } + [SuppressMessage( "Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters" )] + public static void SetWindowChromeWorker( Window window, WindowChromeWorker chrome ) + { + Verify.IsNotNull( window, "window" ); + window.SetValue( WindowChromeWorkerProperty, chrome ); + } - private void _SetWindow(Window window) - { - Assert.IsNull(_window); - Assert.IsNotNull(window); + private void _OnWindowPropertyChangedThatRequiresTemplateFixup( object sender, EventArgs e ) + { + Assert.IsTrue( Utility.IsPresentationFrameworkVersionLessThan4 ); + + if( _chromeInfo != null && _hwnd != IntPtr.Zero ) + { + // Assume that when the template changes it's going to be applied. + // We don't have a good way to externally hook into the template + // actually being applied, so we asynchronously post the fixup operation + // at Loaded priority, so it's expected that the visual tree will be + // updated before _FixupFrameworkIssues is called. + _window.Dispatcher.BeginInvoke( DispatcherPriority.Loaded, ( _Action )_FixupFrameworkIssues ); + } + } - _window = window; + private void _ApplyNewCustomChrome() + { + if( _hwnd == IntPtr.Zero ) + { + // Not yet hooked. + return; + } + + if( _chromeInfo == null ) + { + _RestoreStandardChromeState( false ); + return; + } + + if( !_isHooked ) + { + _hwndSource.AddHook( _WndProc ); + _isHooked = true; + } + + _FixupFrameworkIssues(); + + // Force this the first time. + _UpdateSystemMenu( _window.WindowState ); + _UpdateFrameState( true ); + + NativeMethods.SetWindowPos( _hwnd, IntPtr.Zero, 0, 0, 0, 0, _SwpFlags ); + } - // There are potentially a couple funny states here. - // The window may have been shown and closed, in which case it's no longer usable. - // We shouldn't add any hooks in that case, just exit early. - // If the window hasn't yet been shown, then we need to make sure to remove hooks after it's closed. - _hwnd = new WindowInteropHelper(_window).Handle; + private void _FixupFrameworkIssues() + { + Assert.IsNotNull( _chromeInfo ); + Assert.IsNotNull( _window ); + + // This margin is only necessary if the client rect is going to be calculated incorrectly by WPF. + // This bug was fixed in V4 of the framework. + if( !Utility.IsPresentationFrameworkVersionLessThan4 ) + { + return; + } + + if( _window.Template == null ) + { + // Nothing to fixup yet. This will get called again when a template does get set. + return; + } + + // Guard against the visual tree being empty. + if( VisualTreeHelper.GetChildrenCount( _window ) == 0 ) + { + // The template isn't null, but we don't have a visual tree. + // Hope that ApplyTemplate is in the queue and repost this, because there's not much we can do right now. + _window.Dispatcher.BeginInvoke( DispatcherPriority.Loaded, ( _Action )_FixupFrameworkIssues ); + return; + } + + var rootElement = ( FrameworkElement )VisualTreeHelper.GetChild( _window, 0 ); + + RECT rcWindow = NativeMethods.GetWindowRect( _hwnd ); + RECT rcAdjustedClient = _GetAdjustedWindowRect( rcWindow ); + + Rect rcLogicalWindow = DpiHelper.DeviceRectToLogical( new Rect( rcWindow.Left, rcWindow.Top, rcWindow.Width, rcWindow.Height ) ); + Rect rcLogicalClient = DpiHelper.DeviceRectToLogical( new Rect( rcAdjustedClient.Left, rcAdjustedClient.Top, rcAdjustedClient.Width, rcAdjustedClient.Height ) ); + + Thickness nonClientThickness = new Thickness( + rcLogicalWindow.Left - rcLogicalClient.Left, + rcLogicalWindow.Top - rcLogicalClient.Top, + rcLogicalClient.Right - rcLogicalWindow.Right, + rcLogicalClient.Bottom - rcLogicalWindow.Bottom ); + + if( rootElement != null ) + { + rootElement.Margin = new Thickness( + 0, + 0, + -( nonClientThickness.Left + nonClientThickness.Right ), + -( nonClientThickness.Top + nonClientThickness.Bottom ) ); + } + + // The negative thickness on the margin doesn't properly get applied in RTL layouts. + // The width is right, but there is a black bar on the right. + // To fix this we just add an additional RenderTransform to the root element. + // This works fine, but if the window is dynamically changing its FlowDirection then this can have really bizarre side effects. + // This will mostly work if the FlowDirection is dynamically changed, but there aren't many real scenarios that would call for + // that so I'm not addressing the rest of the quirkiness. + if( rootElement != null ) + { + if( _window.FlowDirection == FlowDirection.RightToLeft ) + { + rootElement.RenderTransform = new MatrixTransform( 1, 0, 0, 1, -( nonClientThickness.Left + nonClientThickness.Right ), 0 ); + } + else + { + rootElement.RenderTransform = null; + } + } - if (Utility.IsPresentationFrameworkVersionLessThan4) - { - // On older versions of the framework the client size of the window is incorrectly calculated. - // We need to modify the template to fix this on behalf of the user. - Utility.AddDependencyPropertyChangeListener(_window, Window.TemplateProperty, _OnWindowPropertyChangedThatRequiresTemplateFixup); - Utility.AddDependencyPropertyChangeListener(_window, Window.FlowDirectionProperty, _OnWindowPropertyChangedThatRequiresTemplateFixup); - } + if( !_isFixedUp ) + { + _hasUserMovedWindow = false; + _window.StateChanged += _FixupRestoreBounds; - _window.Closed += _UnsetWindow; + _isFixedUp = true; + } + } - // Use whether we can get an HWND to determine if the Window has been loaded. - if (IntPtr.Zero != _hwnd) - { - // We've seen that the HwndSource can't always be retrieved from the HWND, so cache it early. - // Specifically it seems to sometimes disappear when the OS theme is changing. - _hwndSource = HwndSource.FromHwnd(_hwnd); - Assert.IsNotNull(_hwndSource); - _window.ApplyTemplate(); - - if (_chromeInfo != null) - { - _ApplyNewCustomChrome(); - } - } - else - { - _window.SourceInitialized += (sender, e) => - { - _hwnd = new WindowInteropHelper(_window).Handle; - Assert.IsNotDefault(_hwnd); - _hwndSource = HwndSource.FromHwnd(_hwnd); - Assert.IsNotNull(_hwndSource); - - if (_chromeInfo != null) - { - _ApplyNewCustomChrome(); - } - }; - } + // There was a regression in DWM in Windows 7 with regard to handling WM_NCCALCSIZE to effect custom chrome. + // When windows with glass are maximized on a multimonitor setup the glass frame tends to turn black. + // Also when windows are resized they tend to flicker black, sometimes staying that way until resized again. + // + // This appears to be a bug in DWM related to device bitmap optimizations. At least on RTM Win7 we can + // evoke a legacy code path that bypasses the bug by calling an esoteric DWM function. This doesn't affect + // the system, just the application. + // WPF also tends to call this function anyways during animations, so we're just forcing the issue + // consistently and a bit earlier. + [SuppressMessage( "Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes" )] + private void _FixupWindows7Issues() + { + if( _blackGlassFixupAttemptCount > 5 ) + { + // Don't keep trying if there's an endemic problem with this. + return; + } + + if( Utility.IsOSWindows7OrNewer && NativeMethods.DwmIsCompositionEnabled() ) + { + ++_blackGlassFixupAttemptCount; + + bool success = false; + try + { + DWM_TIMING_INFO? dti = NativeMethods.DwmGetCompositionTimingInfo( _hwnd ); + success = dti != null; } - - private void _UnsetWindow(object sender, EventArgs e) + catch( Exception ) { - if (Utility.IsPresentationFrameworkVersionLessThan4) - { - Utility.RemoveDependencyPropertyChangeListener(_window, Window.TemplateProperty, _OnWindowPropertyChangedThatRequiresTemplateFixup); - Utility.RemoveDependencyPropertyChangeListener(_window, Window.FlowDirectionProperty, _OnWindowPropertyChangedThatRequiresTemplateFixup); - } + // We aren't sure of all the reasons this could fail. + // If we find new ones we should consider making the NativeMethod swallow them as well. + // Since we have a limited number of retries and this method isn't actually critical, just repost. - if (_chromeInfo != null) - { - _chromeInfo.PropertyChangedThatRequiresRepaint -= _OnChromePropertyChangedThatRequiresRepaint; - } - - _RestoreStandardChromeState(true); + // Disabling this for the published code to reduce debug noise. This will get compiled away for retail binaries anyways. + //Assert.Fail(e.Message); } - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] - public static WindowChromeWorker GetWindowChromeWorker(Window window) + // NativeMethods.DwmGetCompositionTimingInfo swallows E_PENDING. + // If the call wasn't successful, try again later. + if( !success ) { - Verify.IsNotNull(window, "window"); - return (WindowChromeWorker)window.GetValue(WindowChromeWorkerProperty); + Dispatcher.BeginInvoke( DispatcherPriority.Loaded, ( _Action )_FixupWindows7Issues ); } - - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] - public static void SetWindowChromeWorker(Window window, WindowChromeWorker chrome) + else { - Verify.IsNotNull(window, "window"); - window.SetValue(WindowChromeWorkerProperty, chrome); + // Reset this. We will want to force this again if DWM composition changes. + _blackGlassFixupAttemptCount = 0; } + } + } - private void _OnWindowPropertyChangedThatRequiresTemplateFixup(object sender, EventArgs e) + private void _FixupRestoreBounds( object sender, EventArgs e ) + { + Assert.IsTrue( Utility.IsPresentationFrameworkVersionLessThan4 ); + if( _window.WindowState == WindowState.Maximized || _window.WindowState == WindowState.Minimized ) + { + // Old versions of WPF sometimes force their incorrect idea of the Window's location + // on the Win32 restore bounds. If we have reason to think this is the case, then + // try to undo what WPF did after it has done its thing. + if( _hasUserMovedWindow ) { - Assert.IsTrue(Utility.IsPresentationFrameworkVersionLessThan4); + _hasUserMovedWindow = false; + WINDOWPLACEMENT wp = NativeMethods.GetWindowPlacement( _hwnd ); - if (_chromeInfo != null && _hwnd != IntPtr.Zero) - { - // Assume that when the template changes it's going to be applied. - // We don't have a good way to externally hook into the template - // actually being applied, so we asynchronously post the fixup operation - // at Loaded priority, so it's expected that the visual tree will be - // updated before _FixupFrameworkIssues is called. - _window.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, (_Action)_FixupFrameworkIssues); - } - } + RECT adjustedDeviceRc = _GetAdjustedWindowRect( new RECT { Bottom = 100, Right = 100 } ); + Point adjustedTopLeft = DpiHelper.DevicePixelsToLogical( + new Point( + wp.rcNormalPosition.Left - adjustedDeviceRc.Left, + wp.rcNormalPosition.Top - adjustedDeviceRc.Top ) ); - private void _ApplyNewCustomChrome() - { - if (_hwnd == IntPtr.Zero) - { - // Not yet hooked. - return; - } + _window.Top = adjustedTopLeft.Y; + _window.Left = adjustedTopLeft.X; + } + } + } - if (_chromeInfo == null) - { - _RestoreStandardChromeState(false); - return; - } + private RECT _GetAdjustedWindowRect( RECT rcWindow ) + { + // This should only be used to work around issues in the Framework that were fixed in 4.0 + Assert.IsTrue( Utility.IsPresentationFrameworkVersionLessThan4 ); - if (!_isHooked) - { - _hwndSource.AddHook(_WndProc); - _isHooked = true; - } + var style = ( WS )NativeMethods.GetWindowLongPtr( _hwnd, GWL.STYLE ); + var exstyle = ( WS_EX )NativeMethods.GetWindowLongPtr( _hwnd, GWL.EXSTYLE ); - _FixupFrameworkIssues(); + return NativeMethods.AdjustWindowRectEx( rcWindow, style, false, exstyle ); + } - // Force this the first time. - _UpdateSystemMenu(_window.WindowState); - _UpdateFrameState(true); + // Windows tries hard to hide this state from applications. + // Generally you can tell that the window is in a docked position because the restore bounds from GetWindowPlacement + // don't match the current window location and it's not in a maximized or minimized state. + // Because this isn't doced or supported, it's also not incredibly consistent. Sometimes some things get updated in + // different orders, so this isn't absolutely reliable. + private bool _IsWindowDocked + { + get + { + // We're only detecting this state to work around .Net 3.5 issues. + // This logic won't work correctly when those issues are fixed. + Assert.IsTrue( Utility.IsPresentationFrameworkVersionLessThan4 ); - NativeMethods.SetWindowPos(_hwnd, IntPtr.Zero, 0, 0, 0, 0, _SwpFlags); + if( _window.WindowState != WindowState.Normal ) + { + return false; } - private void _FixupFrameworkIssues() - { - Assert.IsNotNull(_chromeInfo); - Assert.IsNotNull(_window); + RECT adjustedOffset = _GetAdjustedWindowRect( new RECT { Bottom = 100, Right = 100 } ); + Point windowTopLeft = new Point( _window.Left, _window.Top ); + windowTopLeft -= ( Vector )DpiHelper.DevicePixelsToLogical( new Point( adjustedOffset.Left, adjustedOffset.Top ) ); - // This margin is only necessary if the client rect is going to be calculated incorrectly by WPF. - // This bug was fixed in V4 of the framework. - if (!Utility.IsPresentationFrameworkVersionLessThan4) - { - return; - } + return _window.RestoreBounds.Location != windowTopLeft; + } + } - if (_window.Template == null) - { - // Nothing to fixup yet. This will get called again when a template does get set. - return; - } + #region WindowProc and Message Handlers - // Guard against the visual tree being empty. - if (VisualTreeHelper.GetChildrenCount(_window) == 0) - { - // The template isn't null, but we don't have a visual tree. - // Hope that ApplyTemplate is in the queue and repost this, because there's not much we can do right now. - _window.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, (_Action)_FixupFrameworkIssues); - return; - } + private IntPtr _WndProc( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled ) + { + // Only expecting messages for our cached HWND. + Assert.AreEqual( hwnd, _hwnd ); - var rootElement = (FrameworkElement)VisualTreeHelper.GetChild(_window, 0); + var message = ( WM )msg; + foreach( var handlePair in _messageTable ) + { + if( handlePair.Key == message ) + { + return handlePair.Value( message, wParam, lParam, out handled ); + } + } + return IntPtr.Zero; + } - RECT rcWindow = NativeMethods.GetWindowRect(_hwnd); - RECT rcAdjustedClient = _GetAdjustedWindowRect(rcWindow); + private IntPtr _HandleSetTextOrIcon( WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled ) + { + bool modified = _ModifyStyle( WS.VISIBLE, 0 ); + + // Setting the caption text and icon cause Windows to redraw the caption. + // Letting the default WndProc handle the message without the WS_VISIBLE + // style applied bypasses the redraw. + IntPtr lRet = NativeMethods.DefWindowProc( _hwnd, uMsg, wParam, lParam ); + + // Put back the style we removed. + if( modified ) + { + _ModifyStyle( 0, WS.VISIBLE ); + } + handled = true; + return lRet; + } - Rect rcLogicalWindow = DpiHelper.DeviceRectToLogical(new Rect(rcWindow.Left, rcWindow.Top, rcWindow.Width, rcWindow.Height)); - Rect rcLogicalClient = DpiHelper.DeviceRectToLogical(new Rect(rcAdjustedClient.Left, rcAdjustedClient.Top, rcAdjustedClient.Width, rcAdjustedClient.Height)); + private IntPtr _HandleNCActivate( WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled ) + { + // Despite MSDN's documentation of lParam not being used, + // calling DefWindowProc with lParam set to -1 causes Windows not to draw over the caption. + + // Directly call DefWindowProc with a custom parameter + // which bypasses any other handling of the message. + IntPtr lRet = NativeMethods.DefWindowProc( _hwnd, WM.NCACTIVATE, wParam, new IntPtr( -1 ) ); + handled = true; + return lRet; + } - Thickness nonClientThickness = new Thickness( - rcLogicalWindow.Left - rcLogicalClient.Left, - rcLogicalWindow.Top - rcLogicalClient.Top, - rcLogicalClient.Right - rcLogicalWindow.Right, - rcLogicalClient.Bottom - rcLogicalWindow.Bottom); + private IntPtr _HandleNCCalcSize( WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled ) + { + // lParam is an [in, out] that can be either a RECT* (wParam == FALSE) or an NCCALCSIZE_PARAMS*. + // Since the first field of NCCALCSIZE_PARAMS is a RECT and is the only field we care about + // we can unconditionally treat it as a RECT. - if( rootElement != null ) - { - rootElement.Margin = new Thickness( - 0, - 0, - -(nonClientThickness.Left + nonClientThickness.Right), - -(nonClientThickness.Top + nonClientThickness.Bottom) ); - } - - // The negative thickness on the margin doesn't properly get applied in RTL layouts. - // The width is right, but there is a black bar on the right. - // To fix this we just add an additional RenderTransform to the root element. - // This works fine, but if the window is dynamically changing its FlowDirection then this can have really bizarre side effects. - // This will mostly work if the FlowDirection is dynamically changed, but there aren't many real scenarios that would call for - // that so I'm not addressing the rest of the quirkiness. - if( rootElement != null ) - { - if (_window.FlowDirection == FlowDirection.RightToLeft) - { - rootElement.RenderTransform = new MatrixTransform(1, 0, 0, 1, -(nonClientThickness.Left + nonClientThickness.Right), 0); - } - else - { - rootElement.RenderTransform = null; - } - } - - if (!_isFixedUp) - { - _hasUserMovedWindow = false; - _window.StateChanged += _FixupRestoreBounds; + // Since we always want the client size to equal the window size, we can unconditionally handle it + // without having to modify the parameters. - _isFixedUp = true; - } - } + handled = true; + return new IntPtr( ( int )WVR.REDRAW ); + } - // There was a regression in DWM in Windows 7 with regard to handling WM_NCCALCSIZE to effect custom chrome. - // When windows with glass are maximized on a multimonitor setup the glass frame tends to turn black. - // Also when windows are resized they tend to flicker black, sometimes staying that way until resized again. - // - // This appears to be a bug in DWM related to device bitmap optimizations. At least on RTM Win7 we can - // evoke a legacy code path that bypasses the bug by calling an esoteric DWM function. This doesn't affect - // the system, just the application. - // WPF also tends to call this function anyways during animations, so we're just forcing the issue - // consistently and a bit earlier. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] - private void _FixupWindows7Issues() + private IntPtr _HandleNCHitTest( WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled ) + { + IntPtr lRet = IntPtr.Zero; + handled = false; + + // Give DWM a chance at this first. + if( Utility.IsOSVistaOrNewer && _chromeInfo.GlassFrameThickness != default( Thickness ) && _isGlassEnabled ) + { + // If we're on Vista, give the DWM a chance to handle the message first. + handled = NativeMethods.DwmDefWindowProc( _hwnd, uMsg, wParam, lParam, out lRet ); + } + + // Handle letting the system know if we consider the mouse to be in our effective non-client area. + // If DWM already handled this by way of DwmDefWindowProc, then respect their call. + if( IntPtr.Zero == lRet ) + { + var mousePosScreen = new Point( Utility.GET_X_LPARAM( lParam ), Utility.GET_Y_LPARAM( lParam ) ); + Rect windowPosition = _GetWindowRect(); + + HT ht = _HitTestNca( + DpiHelper.DeviceRectToLogical( windowPosition ), + DpiHelper.DevicePixelsToLogical( mousePosScreen ) ); + + // Don't blindly respect HTCAPTION. + // We want UIElements in the caption area to be actionable so run through a hittest first. + if( ht != HT.CLIENT ) { - if (_blackGlassFixupAttemptCount > 5) - { - // Don't keep trying if there's an endemic problem with this. - return; - } - - if (Utility.IsOSWindows7OrNewer && NativeMethods.DwmIsCompositionEnabled()) - { - ++_blackGlassFixupAttemptCount; - - bool success = false; - try - { - DWM_TIMING_INFO? dti = NativeMethods.DwmGetCompositionTimingInfo(_hwnd); - success = dti != null; - } - catch (Exception) - { - // We aren't sure of all the reasons this could fail. - // If we find new ones we should consider making the NativeMethod swallow them as well. - // Since we have a limited number of retries and this method isn't actually critical, just repost. - - // Disabling this for the published code to reduce debug noise. This will get compiled away for retail binaries anyways. - //Assert.Fail(e.Message); - } - - // NativeMethods.DwmGetCompositionTimingInfo swallows E_PENDING. - // If the call wasn't successful, try again later. - if (!success) - { - Dispatcher.BeginInvoke(DispatcherPriority.Loaded, (_Action)_FixupWindows7Issues); - } - else - { - // Reset this. We will want to force this again if DWM composition changes. - _blackGlassFixupAttemptCount = 0; - } - } + Point mousePosWindow = mousePosScreen; + mousePosWindow.Offset( -windowPosition.X, -windowPosition.Y ); + mousePosWindow = DpiHelper.DevicePixelsToLogical( mousePosWindow ); + IInputElement inputElement = _window.InputHitTest( mousePosWindow ); + if( inputElement != null && WindowChrome.GetIsHitTestVisibleInChrome( inputElement ) ) + { + ht = HT.CLIENT; + } } + handled = true; + lRet = new IntPtr( ( int )ht ); + } + return lRet; + } - private void _FixupRestoreBounds(object sender, EventArgs e) + private IntPtr _HandleNCRButtonUp( WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled ) + { + // Emulate the system behavior of clicking the right mouse button over the caption area + // to bring up the system menu. + if( HT.CAPTION == ( HT )wParam.ToInt32() ) + { + if( _window.ContextMenu != null ) { - Assert.IsTrue(Utility.IsPresentationFrameworkVersionLessThan4); - if (_window.WindowState == WindowState.Maximized || _window.WindowState == WindowState.Minimized) - { - // Old versions of WPF sometimes force their incorrect idea of the Window's location - // on the Win32 restore bounds. If we have reason to think this is the case, then - // try to undo what WPF did after it has done its thing. - if (_hasUserMovedWindow) - { - _hasUserMovedWindow = false; - WINDOWPLACEMENT wp = NativeMethods.GetWindowPlacement(_hwnd); - - RECT adjustedDeviceRc = _GetAdjustedWindowRect(new RECT { Bottom = 100, Right = 100 }); - Point adjustedTopLeft = DpiHelper.DevicePixelsToLogical( - new Point( - wp.rcNormalPosition.Left - adjustedDeviceRc.Left, - wp.rcNormalPosition.Top - adjustedDeviceRc.Top)); - - _window.Top = adjustedTopLeft.Y; - _window.Left = adjustedTopLeft.X; - } - } + _window.ContextMenu.Placement = PlacementMode.MousePoint; + _window.ContextMenu.IsOpen = true; } + else if( WindowChrome.GetWindowChrome( _window ).ShowSystemMenu ) + SystemCommands.ShowSystemMenuPhysicalCoordinates( _window, new Point( Utility.GET_X_LPARAM( lParam ), Utility.GET_Y_LPARAM( lParam ) ) ); + } + handled = false; + return IntPtr.Zero; + } - private RECT _GetAdjustedWindowRect(RECT rcWindow) - { - // This should only be used to work around issues in the Framework that were fixed in 4.0 - Assert.IsTrue(Utility.IsPresentationFrameworkVersionLessThan4); - - var style = (WS)NativeMethods.GetWindowLongPtr(_hwnd, GWL.STYLE); - var exstyle = (WS_EX)NativeMethods.GetWindowLongPtr(_hwnd, GWL.EXSTYLE); + private IntPtr _HandleSize( WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled ) + { + const int SIZE_MAXIMIZED = 2; + + // Force when maximized. + // We can tell what's happening right now, but the Window doesn't yet know it's + // maximized. Not forcing this update will eventually cause the + // default caption to be drawn. + WindowState? state = null; + if( wParam.ToInt32() == SIZE_MAXIMIZED ) + { + state = WindowState.Maximized; + } + _UpdateSystemMenu( state ); + + // Still let the default WndProc handle this. + handled = false; + return IntPtr.Zero; + } - return NativeMethods.AdjustWindowRectEx(rcWindow, style, false, exstyle); - } + private IntPtr _HandleWindowPosChanged( WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled ) + { + // http://blogs.msdn.com/oldnewthing/archive/2008/01/15/7113860.aspx + // The WM_WINDOWPOSCHANGED message is sent at the end of the window + // state change process. It sort of combines the other state change + // notifications, WM_MOVE, WM_SIZE, and WM_SHOWWINDOW. But it doesn't + // suffer from the same limitations as WM_SHOWWINDOW, so you can + // reliably use it to react to the window being shown or hidden. + + _UpdateSystemMenu( null ); + + if( !_isGlassEnabled ) + { + Assert.IsNotDefault( lParam ); + var wp = ( WINDOWPOS )Marshal.PtrToStructure( lParam, typeof( WINDOWPOS ) ); + _SetRoundingRegion( wp ); + } + + // Still want to pass this to DefWndProc + handled = false; + return IntPtr.Zero; + } - // Windows tries hard to hide this state from applications. - // Generally you can tell that the window is in a docked position because the restore bounds from GetWindowPlacement - // don't match the current window location and it's not in a maximized or minimized state. - // Because this isn't doced or supported, it's also not incredibly consistent. Sometimes some things get updated in - // different orders, so this isn't absolutely reliable. - private bool _IsWindowDocked - { - get - { - // We're only detecting this state to work around .Net 3.5 issues. - // This logic won't work correctly when those issues are fixed. - Assert.IsTrue(Utility.IsPresentationFrameworkVersionLessThan4); + private IntPtr _HandleDwmCompositionChanged( WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled ) + { + _UpdateFrameState( false ); - if (_window.WindowState != WindowState.Normal) - { - return false; - } + handled = false; + return IntPtr.Zero; + } - RECT adjustedOffset = _GetAdjustedWindowRect(new RECT { Bottom = 100, Right = 100 }); - Point windowTopLeft = new Point(_window.Left, _window.Top); - windowTopLeft -= (Vector)DpiHelper.DevicePixelsToLogical(new Point(adjustedOffset.Left, adjustedOffset.Top)); + private IntPtr _HandleSettingChange( WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled ) + { + // There are several settings that can cause fixups for the template to become invalid when changed. + // These shouldn't be required on the v4 framework. + Assert.IsTrue( Utility.IsPresentationFrameworkVersionLessThan4 ); - return _window.RestoreBounds.Location != windowTopLeft; - } - } + _FixupFrameworkIssues(); - #region WindowProc and Message Handlers + handled = false; + return IntPtr.Zero; + } - private IntPtr _WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) + private IntPtr _HandleEnterSizeMove( WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled ) + { + // This is only intercepted to deal with bugs in Window in .Net 3.5 and below. + Assert.IsTrue( Utility.IsPresentationFrameworkVersionLessThan4 ); + + _isUserResizing = true; + + // On Win7 if the user is dragging the window out of the maximized state then we don't want to use that location + // as a restore point. + Assert.Implies( _window.WindowState == WindowState.Maximized, Utility.IsOSWindows7OrNewer ); + if( _window.WindowState != WindowState.Maximized ) + { + // Check for the docked window case. The window can still be restored when it's in this position so + // try to account for that and not update the start position. + if( !_IsWindowDocked ) { - // Only expecting messages for our cached HWND. - Assert.AreEqual(hwnd, _hwnd); - - var message = (WM)msg; - foreach (var handlePair in _messageTable) - { - if (handlePair.Key == message) - { - return handlePair.Value(message, wParam, lParam, out handled); - } - } - return IntPtr.Zero; + _windowPosAtStartOfUserMove = new Point( _window.Left, _window.Top ); } + // Realistically we also don't want to update the start position when moving from one docked state to another (or to and from maximized), + // but it's tricky to detect and this is already a workaround for a bug that's fixed in newer versions of the framework. + // Not going to try to handle all cases. + } - private IntPtr _HandleSetTextOrIcon(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled) - { - bool modified = _ModifyStyle(WS.VISIBLE, 0); - - // Setting the caption text and icon cause Windows to redraw the caption. - // Letting the default WndProc handle the message without the WS_VISIBLE - // style applied bypasses the redraw. - IntPtr lRet = NativeMethods.DefWindowProc(_hwnd, uMsg, wParam, lParam); + handled = false; + return IntPtr.Zero; + } - // Put back the style we removed. - if (modified) - { - _ModifyStyle(0, WS.VISIBLE); - } - handled = true; - return lRet; - } + private IntPtr _HandleExitSizeMove( WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled ) + { + // This is only intercepted to deal with bugs in Window in .Net 3.5 and below. + Assert.IsTrue( Utility.IsPresentationFrameworkVersionLessThan4 ); + + _isUserResizing = false; + + // On Win7 the user can change the Window's state by dragging the window to the top of the monitor. + // If they did that, then we need to try to update the restore bounds or else WPF will put the window at the maximized location (e.g. (-8,-8)). + if( _window.WindowState == WindowState.Maximized ) + { + Assert.IsTrue( Utility.IsOSWindows7OrNewer ); + _window.Top = _windowPosAtStartOfUserMove.Y; + _window.Left = _windowPosAtStartOfUserMove.X; + } + + handled = false; + return IntPtr.Zero; + } - private IntPtr _HandleNCActivate(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled) - { - // Despite MSDN's documentation of lParam not being used, - // calling DefWindowProc with lParam set to -1 causes Windows not to draw over the caption. - - // Directly call DefWindowProc with a custom parameter - // which bypasses any other handling of the message. - IntPtr lRet = NativeMethods.DefWindowProc(_hwnd, WM.NCACTIVATE, wParam, new IntPtr(-1)); - handled = true; - return lRet; - } + private IntPtr _HandleMove( WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled ) + { + // This is only intercepted to deal with bugs in Window in .Net 3.5 and below. + Assert.IsTrue( Utility.IsPresentationFrameworkVersionLessThan4 ); - private IntPtr _HandleNCCalcSize(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled) - { - // lParam is an [in, out] that can be either a RECT* (wParam == FALSE) or an NCCALCSIZE_PARAMS*. - // Since the first field of NCCALCSIZE_PARAMS is a RECT and is the only field we care about - // we can unconditionally treat it as a RECT. + if( _isUserResizing ) + { + _hasUserMovedWindow = true; + } - // Since we always want the client size to equal the window size, we can unconditionally handle it - // without having to modify the parameters. + handled = false; + return IntPtr.Zero; + } - handled = true; - return new IntPtr((int)WVR.REDRAW); - } + #endregion - private IntPtr _HandleNCHitTest(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled) - { - IntPtr lRet = IntPtr.Zero; - handled = false; + /// Add and remove a native WindowStyle from the HWND. + /// The styles to be removed. These can be bitwise combined. + /// The styles to be added. These can be bitwise combined. + /// Whether the styles of the HWND were modified as a result of this call. + private bool _ModifyStyle( WS removeStyle, WS addStyle ) + { + Assert.IsNotDefault( _hwnd ); + var dwStyle = ( WS )NativeMethods.GetWindowLongPtr( _hwnd, GWL.STYLE ).ToInt32(); + var dwNewStyle = ( dwStyle & ~removeStyle ) | addStyle; + if( dwStyle == dwNewStyle ) + { + return false; + } + + NativeMethods.SetWindowLongPtr( _hwnd, GWL.STYLE, new IntPtr( ( int )dwNewStyle ) ); + return true; + } - // Give DWM a chance at this first. - if (Utility.IsOSVistaOrNewer && _chromeInfo.GlassFrameThickness != default(Thickness) && _isGlassEnabled) - { - // If we're on Vista, give the DWM a chance to handle the message first. - handled = NativeMethods.DwmDefWindowProc(_hwnd, uMsg, wParam, lParam, out lRet); - } + /// + /// Get the WindowState as the native HWND knows it to be. This isn't necessarily the same as what Window thinks. + /// + private WindowState _GetHwndState() + { + var wpl = NativeMethods.GetWindowPlacement( _hwnd ); + switch( wpl.showCmd ) + { + case SW.SHOWMINIMIZED: + return WindowState.Minimized; + case SW.SHOWMAXIMIZED: + return WindowState.Maximized; + } + return WindowState.Normal; + } - // Handle letting the system know if we consider the mouse to be in our effective non-client area. - // If DWM already handled this by way of DwmDefWindowProc, then respect their call. - if (IntPtr.Zero == lRet) - { - var mousePosScreen = new Point(Utility.GET_X_LPARAM(lParam), Utility.GET_Y_LPARAM(lParam)); - Rect windowPosition = _GetWindowRect(); - - HT ht = _HitTestNca( - DpiHelper.DeviceRectToLogical(windowPosition), - DpiHelper.DevicePixelsToLogical(mousePosScreen)); - - // Don't blindly respect HTCAPTION. - // We want UIElements in the caption area to be actionable so run through a hittest first. - if (ht != HT.CLIENT) - { - Point mousePosWindow = mousePosScreen; - mousePosWindow.Offset(-windowPosition.X, -windowPosition.Y); - mousePosWindow = DpiHelper.DevicePixelsToLogical(mousePosWindow); - IInputElement inputElement = _window.InputHitTest(mousePosWindow); - if (inputElement != null && WindowChrome.GetIsHitTestVisibleInChrome(inputElement)) - { - ht = HT.CLIENT; - } - } - handled = true; - lRet = new IntPtr((int)ht); - } - return lRet; - } + /// + /// Get the bounding rectangle for the window in physical coordinates. + /// + /// The bounding rectangle for the window. + private Rect _GetWindowRect() + { + // Get the window rectangle. + RECT windowPosition = NativeMethods.GetWindowRect( _hwnd ); + return new Rect( windowPosition.Left, windowPosition.Top, windowPosition.Width, windowPosition.Height ); + } - private IntPtr _HandleNCRButtonUp(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled) - { - // Emulate the system behavior of clicking the right mouse button over the caption area - // to bring up the system menu. - if (HT.CAPTION == (HT)wParam.ToInt32()) - { - if (_window.ContextMenu != null) - { - _window.ContextMenu.Placement = PlacementMode.MousePoint; - _window.ContextMenu.IsOpen = true; - } - else if (WindowChrome.GetWindowChrome(_window).ShowSystemMenu) - SystemCommands.ShowSystemMenuPhysicalCoordinates(_window, new Point(Utility.GET_X_LPARAM(lParam), Utility.GET_Y_LPARAM(lParam))); - } - handled = false; - return IntPtr.Zero; - } + /// + /// Update the items in the system menu based on the current, or assumed, WindowState. + /// + /// + /// The state to assume that the Window is in. This can be null to query the Window's state. + /// + /// + /// We want to update the menu while we have some control over whether the caption will be repainted. + /// + private void _UpdateSystemMenu( WindowState? assumeState ) + { + const MF mfEnabled = MF.ENABLED | MF.BYCOMMAND; + const MF mfDisabled = MF.GRAYED | MF.DISABLED | MF.BYCOMMAND; - private IntPtr _HandleSize(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled) - { - const int SIZE_MAXIMIZED = 2; - - // Force when maximized. - // We can tell what's happening right now, but the Window doesn't yet know it's - // maximized. Not forcing this update will eventually cause the - // default caption to be drawn. - WindowState? state = null; - if (wParam.ToInt32() == SIZE_MAXIMIZED) - { - state = WindowState.Maximized; - } - _UpdateSystemMenu(state); + WindowState state = assumeState ?? _GetHwndState(); - // Still let the default WndProc handle this. - handled = false; - return IntPtr.Zero; - } + if( null != assumeState || _lastMenuState != state ) + { + _lastMenuState = state; - private IntPtr _HandleWindowPosChanged(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled) + bool modified = _ModifyStyle( WS.VISIBLE, 0 ); + IntPtr hmenu = NativeMethods.GetSystemMenu( _hwnd, false ); + if( IntPtr.Zero != hmenu ) { - // http://blogs.msdn.com/oldnewthing/archive/2008/01/15/7113860.aspx - // The WM_WINDOWPOSCHANGED message is sent at the end of the window - // state change process. It sort of combines the other state change - // notifications, WM_MOVE, WM_SIZE, and WM_SHOWWINDOW. But it doesn't - // suffer from the same limitations as WM_SHOWWINDOW, so you can - // reliably use it to react to the window being shown or hidden. - - _UpdateSystemMenu(null); - - if (!_isGlassEnabled) - { - Assert.IsNotDefault(lParam); - var wp = (WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(WINDOWPOS)); - _SetRoundingRegion(wp); - } - - // Still want to pass this to DefWndProc - handled = false; - return IntPtr.Zero; + var dwStyle = ( WS )NativeMethods.GetWindowLongPtr( _hwnd, GWL.STYLE ).ToInt32(); + + bool canMinimize = Utility.IsFlagSet( ( int )dwStyle, ( int )WS.MINIMIZEBOX ); + bool canMaximize = Utility.IsFlagSet( ( int )dwStyle, ( int )WS.MAXIMIZEBOX ); + bool canSize = Utility.IsFlagSet( ( int )dwStyle, ( int )WS.THICKFRAME ); + + switch( state ) + { + case WindowState.Maximized: + NativeMethods.EnableMenuItem( hmenu, SC.RESTORE, mfEnabled ); + NativeMethods.EnableMenuItem( hmenu, SC.MOVE, mfDisabled ); + NativeMethods.EnableMenuItem( hmenu, SC.SIZE, mfDisabled ); + NativeMethods.EnableMenuItem( hmenu, SC.MINIMIZE, canMinimize ? mfEnabled : mfDisabled ); + NativeMethods.EnableMenuItem( hmenu, SC.MAXIMIZE, mfDisabled ); + break; + case WindowState.Minimized: + NativeMethods.EnableMenuItem( hmenu, SC.RESTORE, mfEnabled ); + NativeMethods.EnableMenuItem( hmenu, SC.MOVE, mfDisabled ); + NativeMethods.EnableMenuItem( hmenu, SC.SIZE, mfDisabled ); + NativeMethods.EnableMenuItem( hmenu, SC.MINIMIZE, mfDisabled ); + NativeMethods.EnableMenuItem( hmenu, SC.MAXIMIZE, canMaximize ? mfEnabled : mfDisabled ); + break; + default: + NativeMethods.EnableMenuItem( hmenu, SC.RESTORE, mfDisabled ); + NativeMethods.EnableMenuItem( hmenu, SC.MOVE, mfEnabled ); + NativeMethods.EnableMenuItem( hmenu, SC.SIZE, canSize ? mfEnabled : mfDisabled ); + NativeMethods.EnableMenuItem( hmenu, SC.MINIMIZE, canMinimize ? mfEnabled : mfDisabled ); + NativeMethods.EnableMenuItem( hmenu, SC.MAXIMIZE, canMaximize ? mfEnabled : mfDisabled ); + break; + } } - private IntPtr _HandleDwmCompositionChanged(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled) + if( modified ) { - _UpdateFrameState(false); - - handled = false; - return IntPtr.Zero; + _ModifyStyle( 0, WS.VISIBLE ); } + } + } - private IntPtr _HandleSettingChange(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled) - { - // There are several settings that can cause fixups for the template to become invalid when changed. - // These shouldn't be required on the v4 framework. - Assert.IsTrue(Utility.IsPresentationFrameworkVersionLessThan4); + private void _UpdateFrameState( bool force ) + { + if( IntPtr.Zero == _hwnd ) + { + return; + } - _FixupFrameworkIssues(); + // Don't rely on SystemParameters2 for this, just make the check ourselves. + bool frameState = NativeMethods.DwmIsCompositionEnabled(); - handled = false; - return IntPtr.Zero; - } + if( force || frameState != _isGlassEnabled ) + { + _isGlassEnabled = frameState && _chromeInfo.GlassFrameThickness != default( Thickness ); - private IntPtr _HandleEnterSizeMove(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled) + if( !_isGlassEnabled ) { - // This is only intercepted to deal with bugs in Window in .Net 3.5 and below. - Assert.IsTrue(Utility.IsPresentationFrameworkVersionLessThan4); - - _isUserResizing = true; - - // On Win7 if the user is dragging the window out of the maximized state then we don't want to use that location - // as a restore point. - Assert.Implies(_window.WindowState == WindowState.Maximized, Utility.IsOSWindows7OrNewer); - if (_window.WindowState != WindowState.Maximized) - { - // Check for the docked window case. The window can still be restored when it's in this position so - // try to account for that and not update the start position. - if (!_IsWindowDocked) - { - _windowPosAtStartOfUserMove = new Point(_window.Left, _window.Top); - } - // Realistically we also don't want to update the start position when moving from one docked state to another (or to and from maximized), - // but it's tricky to detect and this is already a workaround for a bug that's fixed in newer versions of the framework. - // Not going to try to handle all cases. - } - - handled = false; - return IntPtr.Zero; + _SetRoundingRegion( null ); } - - private IntPtr _HandleExitSizeMove(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled) + else { - // This is only intercepted to deal with bugs in Window in .Net 3.5 and below. - Assert.IsTrue(Utility.IsPresentationFrameworkVersionLessThan4); - - _isUserResizing = false; - - // On Win7 the user can change the Window's state by dragging the window to the top of the monitor. - // If they did that, then we need to try to update the restore bounds or else WPF will put the window at the maximized location (e.g. (-8,-8)). - if (_window.WindowState == WindowState.Maximized) - { - Assert.IsTrue(Utility.IsOSWindows7OrNewer); - _window.Top = _windowPosAtStartOfUserMove.Y; - _window.Left = _windowPosAtStartOfUserMove.X; - } + _ClearRoundingRegion(); + _ExtendGlassFrame(); - handled = false; - return IntPtr.Zero; + _FixupWindows7Issues(); } - private IntPtr _HandleMove(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled) - { - // This is only intercepted to deal with bugs in Window in .Net 3.5 and below. - Assert.IsTrue(Utility.IsPresentationFrameworkVersionLessThan4); - - if (_isUserResizing) - { - _hasUserMovedWindow = true; - } + NativeMethods.SetWindowPos( _hwnd, IntPtr.Zero, 0, 0, 0, 0, _SwpFlags ); + } + } - handled = false; - return IntPtr.Zero; - } + private void _ClearRoundingRegion() + { + NativeMethods.SetWindowRgn( _hwnd, IntPtr.Zero, NativeMethods.IsWindowVisible( _hwnd ) ); + } - #endregion + private void _SetRoundingRegion( WINDOWPOS? wp ) + { + const int MONITOR_DEFAULTTONEAREST = 0x00000002; - /// Add and remove a native WindowStyle from the HWND. - /// The styles to be removed. These can be bitwise combined. - /// The styles to be added. These can be bitwise combined. - /// Whether the styles of the HWND were modified as a result of this call. - private bool _ModifyStyle(WS removeStyle, WS addStyle) - { - Assert.IsNotDefault(_hwnd); - var dwStyle = (WS)NativeMethods.GetWindowLongPtr(_hwnd, GWL.STYLE).ToInt32(); - var dwNewStyle = (dwStyle & ~removeStyle) | addStyle; - if (dwStyle == dwNewStyle) - { - return false; - } + // We're early - WPF hasn't necessarily updated the state of the window. + // Need to query it ourselves. + WINDOWPLACEMENT wpl = NativeMethods.GetWindowPlacement( _hwnd ); - NativeMethods.SetWindowLongPtr(_hwnd, GWL.STYLE, new IntPtr((int)dwNewStyle)); - return true; - } + if( wpl.showCmd == SW.SHOWMAXIMIZED ) + { + int left; + int top; - /// - /// Get the WindowState as the native HWND knows it to be. This isn't necessarily the same as what Window thinks. - /// - private WindowState _GetHwndState() + if( wp.HasValue ) { - var wpl = NativeMethods.GetWindowPlacement(_hwnd); - switch (wpl.showCmd) - { - case SW.SHOWMINIMIZED: return WindowState.Minimized; - case SW.SHOWMAXIMIZED: return WindowState.Maximized; - } - return WindowState.Normal; + left = wp.Value.x; + top = wp.Value.y; } - - /// - /// Get the bounding rectangle for the window in physical coordinates. - /// - /// The bounding rectangle for the window. - private Rect _GetWindowRect() + else { - // Get the window rectangle. - RECT windowPosition = NativeMethods.GetWindowRect(_hwnd); - return new Rect(windowPosition.Left, windowPosition.Top, windowPosition.Width, windowPosition.Height); + Rect r = _GetWindowRect(); + left = ( int )r.Left; + top = ( int )r.Top; } - /// - /// Update the items in the system menu based on the current, or assumed, WindowState. - /// - /// - /// The state to assume that the Window is in. This can be null to query the Window's state. - /// - /// - /// We want to update the menu while we have some control over whether the caption will be repainted. - /// - private void _UpdateSystemMenu(WindowState? assumeState) - { - const MF mfEnabled = MF.ENABLED | MF.BYCOMMAND; - const MF mfDisabled = MF.GRAYED | MF.DISABLED | MF.BYCOMMAND; + IntPtr hMon = NativeMethods.MonitorFromWindow( _hwnd, MONITOR_DEFAULTTONEAREST ); - WindowState state = assumeState ?? _GetHwndState(); + MONITORINFO mi = NativeMethods.GetMonitorInfo( hMon ); + RECT rcMax = mi.rcWork; + // The location of maximized window takes into account the border that Windows was + // going to remove, so we also need to consider it. + rcMax.Offset( -left, -top ); - if (null != assumeState || _lastMenuState != state) - { - _lastMenuState = state; - - bool modified = _ModifyStyle(WS.VISIBLE, 0); - IntPtr hmenu = NativeMethods.GetSystemMenu(_hwnd, false); - if (IntPtr.Zero != hmenu) - { - var dwStyle = (WS)NativeMethods.GetWindowLongPtr(_hwnd, GWL.STYLE).ToInt32(); - - bool canMinimize = Utility.IsFlagSet((int)dwStyle, (int)WS.MINIMIZEBOX); - bool canMaximize = Utility.IsFlagSet((int)dwStyle, (int)WS.MAXIMIZEBOX); - bool canSize = Utility.IsFlagSet((int)dwStyle, (int)WS.THICKFRAME); - - switch (state) - { - case WindowState.Maximized: - NativeMethods.EnableMenuItem(hmenu, SC.RESTORE, mfEnabled); - NativeMethods.EnableMenuItem(hmenu, SC.MOVE, mfDisabled); - NativeMethods.EnableMenuItem(hmenu, SC.SIZE, mfDisabled); - NativeMethods.EnableMenuItem(hmenu, SC.MINIMIZE, canMinimize ? mfEnabled : mfDisabled); - NativeMethods.EnableMenuItem(hmenu, SC.MAXIMIZE, mfDisabled); - break; - case WindowState.Minimized: - NativeMethods.EnableMenuItem(hmenu, SC.RESTORE, mfEnabled); - NativeMethods.EnableMenuItem(hmenu, SC.MOVE, mfDisabled); - NativeMethods.EnableMenuItem(hmenu, SC.SIZE, mfDisabled); - NativeMethods.EnableMenuItem(hmenu, SC.MINIMIZE, mfDisabled); - NativeMethods.EnableMenuItem(hmenu, SC.MAXIMIZE, canMaximize ? mfEnabled : mfDisabled); - break; - default: - NativeMethods.EnableMenuItem(hmenu, SC.RESTORE, mfDisabled); - NativeMethods.EnableMenuItem(hmenu, SC.MOVE, mfEnabled); - NativeMethods.EnableMenuItem(hmenu, SC.SIZE, canSize ? mfEnabled : mfDisabled); - NativeMethods.EnableMenuItem(hmenu, SC.MINIMIZE, canMinimize ? mfEnabled : mfDisabled); - NativeMethods.EnableMenuItem(hmenu, SC.MAXIMIZE, canMaximize ? mfEnabled : mfDisabled); - break; - } - } - - if (modified) - { - _ModifyStyle(0, WS.VISIBLE); - } - } + IntPtr hrgn = IntPtr.Zero; + try + { + hrgn = NativeMethods.CreateRectRgnIndirect( rcMax ); + NativeMethods.SetWindowRgn( _hwnd, hrgn, NativeMethods.IsWindowVisible( _hwnd ) ); + hrgn = IntPtr.Zero; } - - private void _UpdateFrameState(bool force) + finally { - if (IntPtr.Zero == _hwnd) - { - return; - } - - // Don't rely on SystemParameters2 for this, just make the check ourselves. - bool frameState = NativeMethods.DwmIsCompositionEnabled(); - - if (force || frameState != _isGlassEnabled) - { - _isGlassEnabled = frameState && _chromeInfo.GlassFrameThickness != default(Thickness); - - if (!_isGlassEnabled) - { - _SetRoundingRegion(null); - } - else - { - _ClearRoundingRegion(); - _ExtendGlassFrame(); - - _FixupWindows7Issues(); - } - - NativeMethods.SetWindowPos(_hwnd, IntPtr.Zero, 0, 0, 0, 0, _SwpFlags); - } + Utility.SafeDeleteObject( ref hrgn ); } + } + else + { + Size windowSize; - private void _ClearRoundingRegion() + // Use the size if it's specified. + if( null != wp && !Utility.IsFlagSet( wp.Value.flags, ( int )SWP.NOSIZE ) ) { - NativeMethods.SetWindowRgn(_hwnd, IntPtr.Zero, NativeMethods.IsWindowVisible(_hwnd)); + windowSize = new Size( ( double )wp.Value.cx, ( double )wp.Value.cy ); } - - private void _SetRoundingRegion(WINDOWPOS? wp) + else if( null != wp && ( _lastRoundingState == _window.WindowState ) ) { - const int MONITOR_DEFAULTTONEAREST = 0x00000002; - - // We're early - WPF hasn't necessarily updated the state of the window. - // Need to query it ourselves. - WINDOWPLACEMENT wpl = NativeMethods.GetWindowPlacement(_hwnd); - - if (wpl.showCmd == SW.SHOWMAXIMIZED) - { - int left; - int top; - - if (wp.HasValue) - { - left = wp.Value.x; - top = wp.Value.y; - } - else - { - Rect r = _GetWindowRect(); - left = (int)r.Left; - top = (int)r.Top; - } - - IntPtr hMon = NativeMethods.MonitorFromWindow(_hwnd, MONITOR_DEFAULTTONEAREST); - - MONITORINFO mi = NativeMethods.GetMonitorInfo(hMon); - RECT rcMax = mi.rcWork; - // The location of maximized window takes into account the border that Windows was - // going to remove, so we also need to consider it. - rcMax.Offset(-left, -top); - - IntPtr hrgn = IntPtr.Zero; - try - { - hrgn = NativeMethods.CreateRectRgnIndirect(rcMax); - NativeMethods.SetWindowRgn(_hwnd, hrgn, NativeMethods.IsWindowVisible(_hwnd)); - hrgn = IntPtr.Zero; - } - finally - { - Utility.SafeDeleteObject(ref hrgn); - } - } - else - { - Size windowSize; - - // Use the size if it's specified. - if (null != wp && !Utility.IsFlagSet(wp.Value.flags, (int)SWP.NOSIZE)) - { - windowSize = new Size((double)wp.Value.cx, (double)wp.Value.cy); - } - else if (null != wp && (_lastRoundingState == _window.WindowState)) - { - return; - } - else - { - windowSize = _GetWindowRect().Size; - } - - _lastRoundingState = _window.WindowState; - - IntPtr hrgn = IntPtr.Zero; - try - { - double shortestDimension = Math.Min(windowSize.Width, windowSize.Height); - - double topLeftRadius = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.CornerRadius.TopLeft, 0)).X; - topLeftRadius = Math.Min(topLeftRadius, shortestDimension / 2); - - if (_IsUniform(_chromeInfo.CornerRadius)) - { - // RoundedRect HRGNs require an additional pixel of padding. - hrgn = _CreateRoundRectRgn(new Rect(windowSize), topLeftRadius); - } - else - { - // We need to combine HRGNs for each of the corners. - // Create one for each quadrant, but let it overlap into the two adjacent ones - // by the radius amount to ensure that there aren't corners etched into the middle - // of the window. - hrgn = _CreateRoundRectRgn(new Rect(0, 0, windowSize.Width / 2 + topLeftRadius, windowSize.Height / 2 + topLeftRadius), topLeftRadius); - - double topRightRadius = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.CornerRadius.TopRight, 0)).X; - topRightRadius = Math.Min(topRightRadius, shortestDimension / 2); - Rect topRightRegionRect = new Rect(0, 0, windowSize.Width / 2 + topRightRadius, windowSize.Height / 2 + topRightRadius); - topRightRegionRect.Offset(windowSize.Width / 2 - topRightRadius, 0); - Assert.AreEqual(topRightRegionRect.Right, windowSize.Width); - - _CreateAndCombineRoundRectRgn(hrgn, topRightRegionRect, topRightRadius); - - double bottomLeftRadius = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.CornerRadius.BottomLeft, 0)).X; - bottomLeftRadius = Math.Min(bottomLeftRadius, shortestDimension / 2); - Rect bottomLeftRegionRect = new Rect(0, 0, windowSize.Width / 2 + bottomLeftRadius, windowSize.Height / 2 + bottomLeftRadius); - bottomLeftRegionRect.Offset(0, windowSize.Height / 2 - bottomLeftRadius); - Assert.AreEqual(bottomLeftRegionRect.Bottom, windowSize.Height); - - _CreateAndCombineRoundRectRgn(hrgn, bottomLeftRegionRect, bottomLeftRadius); - - double bottomRightRadius = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.CornerRadius.BottomRight, 0)).X; - bottomRightRadius = Math.Min(bottomRightRadius, shortestDimension / 2); - Rect bottomRightRegionRect = new Rect(0, 0, windowSize.Width / 2 + bottomRightRadius, windowSize.Height / 2 + bottomRightRadius); - bottomRightRegionRect.Offset(windowSize.Width / 2 - bottomRightRadius, windowSize.Height / 2 - bottomRightRadius); - Assert.AreEqual(bottomRightRegionRect.Right, windowSize.Width); - Assert.AreEqual(bottomRightRegionRect.Bottom, windowSize.Height); - - _CreateAndCombineRoundRectRgn(hrgn, bottomRightRegionRect, bottomRightRadius); - } - - NativeMethods.SetWindowRgn(_hwnd, hrgn, NativeMethods.IsWindowVisible(_hwnd)); - hrgn = IntPtr.Zero; - } - finally - { - // Free the memory associated with the HRGN if it wasn't assigned to the HWND. - Utility.SafeDeleteObject(ref hrgn); - } - } + return; } - - private static IntPtr _CreateRoundRectRgn(Rect region, double radius) + else { - // Round outwards. - - if (DoubleUtilities.AreClose(0, radius)) - { - return NativeMethods.CreateRectRgn( - (int)Math.Floor(region.Left), - (int)Math.Floor(region.Top), - (int)Math.Ceiling(region.Right), - (int)Math.Ceiling(region.Bottom)); - } - - // RoundedRect HRGNs require an additional pixel of padding on the bottom right to look correct. - return NativeMethods.CreateRoundRectRgn( - (int)Math.Floor(region.Left), - (int)Math.Floor(region.Top), - (int)Math.Ceiling(region.Right) + 1, - (int)Math.Ceiling(region.Bottom) + 1, - (int)Math.Ceiling(radius), - (int)Math.Ceiling(radius)); + windowSize = _GetWindowRect().Size; } - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "HRGNs")] - private static void _CreateAndCombineRoundRectRgn(IntPtr hrgnSource, Rect region, double radius) + _lastRoundingState = _window.WindowState; + + IntPtr hrgn = IntPtr.Zero; + try { - IntPtr hrgn = IntPtr.Zero; - try - { - hrgn = _CreateRoundRectRgn(region, radius); - CombineRgnResult result = NativeMethods.CombineRgn(hrgnSource, hrgnSource, hrgn, RGN.OR); - if (result == CombineRgnResult.ERROR) - { - throw new InvalidOperationException("Unable to combine two HRGNs."); - } - } - catch - { - Utility.SafeDeleteObject(ref hrgn); - throw; - } + double shortestDimension = Math.Min( windowSize.Width, windowSize.Height ); + + double topLeftRadius = DpiHelper.LogicalPixelsToDevice( new Point( _chromeInfo.CornerRadius.TopLeft, 0 ) ).X; + topLeftRadius = Math.Min( topLeftRadius, shortestDimension / 2 ); + + if( _IsUniform( _chromeInfo.CornerRadius ) ) + { + // RoundedRect HRGNs require an additional pixel of padding. + hrgn = _CreateRoundRectRgn( new Rect( windowSize ), topLeftRadius ); + } + else + { + // We need to combine HRGNs for each of the corners. + // Create one for each quadrant, but let it overlap into the two adjacent ones + // by the radius amount to ensure that there aren't corners etched into the middle + // of the window. + hrgn = _CreateRoundRectRgn( new Rect( 0, 0, windowSize.Width / 2 + topLeftRadius, windowSize.Height / 2 + topLeftRadius ), topLeftRadius ); + + double topRightRadius = DpiHelper.LogicalPixelsToDevice( new Point( _chromeInfo.CornerRadius.TopRight, 0 ) ).X; + topRightRadius = Math.Min( topRightRadius, shortestDimension / 2 ); + Rect topRightRegionRect = new Rect( 0, 0, windowSize.Width / 2 + topRightRadius, windowSize.Height / 2 + topRightRadius ); + topRightRegionRect.Offset( windowSize.Width / 2 - topRightRadius, 0 ); + Assert.AreEqual( topRightRegionRect.Right, windowSize.Width ); + + _CreateAndCombineRoundRectRgn( hrgn, topRightRegionRect, topRightRadius ); + + double bottomLeftRadius = DpiHelper.LogicalPixelsToDevice( new Point( _chromeInfo.CornerRadius.BottomLeft, 0 ) ).X; + bottomLeftRadius = Math.Min( bottomLeftRadius, shortestDimension / 2 ); + Rect bottomLeftRegionRect = new Rect( 0, 0, windowSize.Width / 2 + bottomLeftRadius, windowSize.Height / 2 + bottomLeftRadius ); + bottomLeftRegionRect.Offset( 0, windowSize.Height / 2 - bottomLeftRadius ); + Assert.AreEqual( bottomLeftRegionRect.Bottom, windowSize.Height ); + + _CreateAndCombineRoundRectRgn( hrgn, bottomLeftRegionRect, bottomLeftRadius ); + + double bottomRightRadius = DpiHelper.LogicalPixelsToDevice( new Point( _chromeInfo.CornerRadius.BottomRight, 0 ) ).X; + bottomRightRadius = Math.Min( bottomRightRadius, shortestDimension / 2 ); + Rect bottomRightRegionRect = new Rect( 0, 0, windowSize.Width / 2 + bottomRightRadius, windowSize.Height / 2 + bottomRightRadius ); + bottomRightRegionRect.Offset( windowSize.Width / 2 - bottomRightRadius, windowSize.Height / 2 - bottomRightRadius ); + Assert.AreEqual( bottomRightRegionRect.Right, windowSize.Width ); + Assert.AreEqual( bottomRightRegionRect.Bottom, windowSize.Height ); + + _CreateAndCombineRoundRectRgn( hrgn, bottomRightRegionRect, bottomRightRadius ); + } + + NativeMethods.SetWindowRgn( _hwnd, hrgn, NativeMethods.IsWindowVisible( _hwnd ) ); + hrgn = IntPtr.Zero; } - - private static bool _IsUniform(CornerRadius cornerRadius) + finally { - if (!DoubleUtilities.AreClose(cornerRadius.BottomLeft, cornerRadius.BottomRight)) - { - return false; - } - - if (!DoubleUtilities.AreClose(cornerRadius.TopLeft, cornerRadius.TopRight)) - { - return false; - } - - if (!DoubleUtilities.AreClose(cornerRadius.BottomLeft, cornerRadius.TopRight)) - { - return false; - } - - return true; + // Free the memory associated with the HRGN if it wasn't assigned to the HWND. + Utility.SafeDeleteObject( ref hrgn ); } + } + } - private void _ExtendGlassFrame() + private static IntPtr _CreateRoundRectRgn( Rect region, double radius ) + { + // Round outwards. + + if( DoubleUtilities.AreClose( 0, radius ) ) + { + return NativeMethods.CreateRectRgn( + ( int )Math.Floor( region.Left ), + ( int )Math.Floor( region.Top ), + ( int )Math.Ceiling( region.Right ), + ( int )Math.Ceiling( region.Bottom ) ); + } + + // RoundedRect HRGNs require an additional pixel of padding on the bottom right to look correct. + return NativeMethods.CreateRoundRectRgn( + ( int )Math.Floor( region.Left ), + ( int )Math.Floor( region.Top ), + ( int )Math.Ceiling( region.Right ) + 1, + ( int )Math.Ceiling( region.Bottom ) + 1, + ( int )Math.Ceiling( radius ), + ( int )Math.Ceiling( radius ) ); + } + + [SuppressMessage( "Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "HRGNs" )] + private static void _CreateAndCombineRoundRectRgn( IntPtr hrgnSource, Rect region, double radius ) + { + IntPtr hrgn = IntPtr.Zero; + try + { + hrgn = _CreateRoundRectRgn( region, radius ); + CombineRgnResult result = NativeMethods.CombineRgn( hrgnSource, hrgnSource, hrgn, RGN.OR ); + if( result == CombineRgnResult.ERROR ) { - Assert.IsNotNull(_window); + throw new InvalidOperationException( "Unable to combine two HRGNs." ); + } + } + catch + { + Utility.SafeDeleteObject( ref hrgn ); + throw; + } + } - // Expect that this might be called on OSes other than Vista. - if (!Utility.IsOSVistaOrNewer) - { - // Not an error. Just not on Vista so we're not going to get glass. - return; - } + private static bool _IsUniform( CornerRadius cornerRadius ) + { + if( !DoubleUtilities.AreClose( cornerRadius.BottomLeft, cornerRadius.BottomRight ) ) + { + return false; + } + + if( !DoubleUtilities.AreClose( cornerRadius.TopLeft, cornerRadius.TopRight ) ) + { + return false; + } + + if( !DoubleUtilities.AreClose( cornerRadius.BottomLeft, cornerRadius.TopRight ) ) + { + return false; + } + + return true; + } - if (IntPtr.Zero == _hwnd) - { - // Can't do anything with this call until the Window has been shown. - return; - } + private void _ExtendGlassFrame() + { + Assert.IsNotNull( _window ); + + // Expect that this might be called on OSes other than Vista. + if( !Utility.IsOSVistaOrNewer ) + { + // Not an error. Just not on Vista so we're not going to get glass. + return; + } + + if( IntPtr.Zero == _hwnd ) + { + // Can't do anything with this call until the Window has been shown. + return; + } + + // Ensure standard HWND background painting when DWM isn't enabled. + if( !NativeMethods.DwmIsCompositionEnabled() ) + { + _hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor; + } + else + { + // This makes the glass visible at a Win32 level so long as nothing else is covering it. + // The Window's Background needs to be changed independent of this. + + // Apply the transparent background to the HWND + _hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent; + + // Thickness is going to be DIPs, need to convert to system coordinates. + Point deviceTopLeft = DpiHelper.LogicalPixelsToDevice( new Point( _chromeInfo.GlassFrameThickness.Left, _chromeInfo.GlassFrameThickness.Top ) ); + Point deviceBottomRight = DpiHelper.LogicalPixelsToDevice( new Point( _chromeInfo.GlassFrameThickness.Right, _chromeInfo.GlassFrameThickness.Bottom ) ); + + var dwmMargin = new MARGINS + { + // err on the side of pushing in glass an extra pixel. + cxLeftWidth = ( int )Math.Ceiling( deviceTopLeft.X ), + cxRightWidth = ( int )Math.Ceiling( deviceBottomRight.X ), + cyTopHeight = ( int )Math.Ceiling( deviceTopLeft.Y ), + cyBottomHeight = ( int )Math.Ceiling( deviceBottomRight.Y ), + }; - // Ensure standard HWND background painting when DWM isn't enabled. - if (!NativeMethods.DwmIsCompositionEnabled()) - { - _hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor; - } - else - { - // This makes the glass visible at a Win32 level so long as nothing else is covering it. - // The Window's Background needs to be changed independent of this. - - // Apply the transparent background to the HWND - _hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent; - - // Thickness is going to be DIPs, need to convert to system coordinates. - Point deviceTopLeft = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.GlassFrameThickness.Left, _chromeInfo.GlassFrameThickness.Top)); - Point deviceBottomRight = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.GlassFrameThickness.Right, _chromeInfo.GlassFrameThickness.Bottom)); - - var dwmMargin = new MARGINS - { - // err on the side of pushing in glass an extra pixel. - cxLeftWidth = (int)Math.Ceiling(deviceTopLeft.X), - cxRightWidth = (int)Math.Ceiling(deviceBottomRight.X), - cyTopHeight = (int)Math.Ceiling(deviceTopLeft.Y), - cyBottomHeight = (int)Math.Ceiling(deviceBottomRight.Y), - }; - - NativeMethods.DwmExtendFrameIntoClientArea(_hwnd, ref dwmMargin); - } - } + NativeMethods.DwmExtendFrameIntoClientArea( _hwnd, ref dwmMargin ); + } + } - /// - /// Matrix of the HT values to return when responding to NC window messages. - /// - [SuppressMessage("Microsoft.Performance", "CA1814:PreferJaggedArraysOverMultidimensional", MessageId = "Member")] - private static readonly HT[,] _HitTestBorders = new[,] - { + /// + /// Matrix of the HT values to return when responding to NC window messages. + /// + [SuppressMessage( "Microsoft.Performance", "CA1814:PreferJaggedArraysOverMultidimensional", MessageId = "Member" )] + private static readonly HT[,] _HitTestBorders = new[ , ] + { { HT.TOPLEFT, HT.TOP, HT.TOPRIGHT }, { HT.LEFT, HT.CLIENT, HT.RIGHT }, { HT.BOTTOMLEFT, HT.BOTTOM, HT.BOTTOMRIGHT }, }; - private HT _HitTestNca(Rect windowPosition, Point mousePosition) - { - // Determine if hit test is for resizing, default middle (1,1). - int uRow = 1; - int uCol = 1; - bool onResizeBorder = false; - - // Determine if the point is at the top or bottom of the window. - if (mousePosition.Y >= windowPosition.Top && mousePosition.Y < windowPosition.Top + _chromeInfo.ResizeBorderThickness.Top + _chromeInfo.CaptionHeight) - { - onResizeBorder = (mousePosition.Y < (windowPosition.Top + _chromeInfo.ResizeBorderThickness.Top)); - uRow = 0; // top (caption or resize border) - } - else if (mousePosition.Y < windowPosition.Bottom && mousePosition.Y >= windowPosition.Bottom - (int)_chromeInfo.ResizeBorderThickness.Bottom) - { - uRow = 2; // bottom - } - - // Determine if the point is at the left or right of the window. - if (mousePosition.X >= windowPosition.Left && mousePosition.X < windowPosition.Left + (int)_chromeInfo.ResizeBorderThickness.Left) - { - uCol = 0; // left side - } - else if (mousePosition.X < windowPosition.Right && mousePosition.X >= windowPosition.Right - _chromeInfo.ResizeBorderThickness.Right) - { - uCol = 2; // right side - } - - // If the cursor is in one of the top edges by the caption bar, but below the top resize border, - // then resize left-right rather than diagonally. - if (uRow == 0 && uCol != 1 && !onResizeBorder) - { - uRow = 1; - } - - HT ht = _HitTestBorders[uRow, uCol]; - - if (ht == HT.TOP && !onResizeBorder) - { - ht = HT.CAPTION; - } - - return ht; - } + private HT _HitTestNca( Rect windowPosition, Point mousePosition ) + { + // Determine if hit test is for resizing, default middle (1,1). + int uRow = 1; + int uCol = 1; + bool onResizeBorder = false; + + // Determine if the point is at the top or bottom of the window. + if( mousePosition.Y >= windowPosition.Top && mousePosition.Y < windowPosition.Top + _chromeInfo.ResizeBorderThickness.Top + _chromeInfo.CaptionHeight ) + { + onResizeBorder = ( mousePosition.Y < ( windowPosition.Top + _chromeInfo.ResizeBorderThickness.Top ) ); + uRow = 0; // top (caption or resize border) + } + else if( mousePosition.Y < windowPosition.Bottom && mousePosition.Y >= windowPosition.Bottom - ( int )_chromeInfo.ResizeBorderThickness.Bottom ) + { + uRow = 2; // bottom + } + + // Determine if the point is at the left or right of the window. + if( mousePosition.X >= windowPosition.Left && mousePosition.X < windowPosition.Left + ( int )_chromeInfo.ResizeBorderThickness.Left ) + { + uCol = 0; // left side + } + else if( mousePosition.X < windowPosition.Right && mousePosition.X >= windowPosition.Right - _chromeInfo.ResizeBorderThickness.Right ) + { + uCol = 2; // right side + } + + // If the cursor is in one of the top edges by the caption bar, but below the top resize border, + // then resize left-right rather than diagonally. + if( uRow == 0 && uCol != 1 && !onResizeBorder ) + { + uRow = 1; + } + + HT ht = _HitTestBorders[ uRow, uCol ]; + + if( ht == HT.TOP && !onResizeBorder ) + { + ht = HT.CAPTION; + } + + return ht; + } - #region Remove Custom Chrome Methods + #region Remove Custom Chrome Methods - private void _RestoreStandardChromeState(bool isClosing) - { - VerifyAccess(); + private void _RestoreStandardChromeState( bool isClosing ) + { + VerifyAccess(); - _UnhookCustomChrome(); + _UnhookCustomChrome(); - if (!isClosing) - { - _RestoreFrameworkIssueFixups(); - _RestoreGlassFrame(); - _RestoreHrgn(); + if( !isClosing ) + { + _RestoreFrameworkIssueFixups(); + _RestoreGlassFrame(); + _RestoreHrgn(); - _window.InvalidateMeasure(); - } - } - - private void _UnhookCustomChrome() - { - Assert.IsNotDefault(_hwnd); - Assert.IsNotNull(_window); + _window.InvalidateMeasure(); + } + } - if (_isHooked) - { - _hwndSource.RemoveHook(_WndProc); - _isHooked = false; - } - } + private void _UnhookCustomChrome() + { + Assert.IsNotDefault( _hwnd ); + Assert.IsNotNull( _window ); + + if( _isHooked ) + { + _hwndSource.RemoveHook( _WndProc ); + _isHooked = false; + } + } - private void _RestoreFrameworkIssueFixups() + private void _RestoreFrameworkIssueFixups() + { + // This margin is only necessary if the client rect is going to be calculated incorrectly by WPF. + // This bug was fixed in V4 of the framework. + if( Utility.IsPresentationFrameworkVersionLessThan4 ) + { + Assert.IsTrue( _isFixedUp ); + + var rootElement = ( FrameworkElement )VisualTreeHelper.GetChild( _window, 0 ); + if( rootElement != null ) { - // This margin is only necessary if the client rect is going to be calculated incorrectly by WPF. - // This bug was fixed in V4 of the framework. - if (Utility.IsPresentationFrameworkVersionLessThan4) - { - Assert.IsTrue(_isFixedUp); - - var rootElement = (FrameworkElement)VisualTreeHelper.GetChild(_window, 0); - if( rootElement != null ) - { - // Undo anything that was done before. - rootElement.Margin = new Thickness(); - } - - _window.StateChanged -= _FixupRestoreBounds; - _isFixedUp = false; - } + // Undo anything that was done before. + rootElement.Margin = new Thickness(); } - private void _RestoreGlassFrame() - { - Assert.IsNull(_chromeInfo); - Assert.IsNotNull(_window); - - // Expect that this might be called on OSes other than Vista - // and if the window hasn't yet been shown, then we don't need to undo anything. - if (!Utility.IsOSVistaOrNewer || _hwnd == IntPtr.Zero) - { - return; - } - - _hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor; - - if (NativeMethods.DwmIsCompositionEnabled()) - { - // If glass is enabled, push it back to the normal bounds. - var dwmMargin = new MARGINS(); - NativeMethods.DwmExtendFrameIntoClientArea(_hwnd, ref dwmMargin); - } - } + _window.StateChanged -= _FixupRestoreBounds; + _isFixedUp = false; + } + } - private void _RestoreHrgn() - { - _ClearRoundingRegion(); - NativeMethods.SetWindowPos(_hwnd, IntPtr.Zero, 0, 0, 0, 0, _SwpFlags); - } + private void _RestoreGlassFrame() + { + Assert.IsNull( _chromeInfo ); + Assert.IsNotNull( _window ); + + // Expect that this might be called on OSes other than Vista + // and if the window hasn't yet been shown, then we don't need to undo anything. + if( !Utility.IsOSVistaOrNewer || _hwnd == IntPtr.Zero ) + { + return; + } + + _hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor; + + if( NativeMethods.DwmIsCompositionEnabled() ) + { + // If glass is enabled, push it back to the normal bounds. + var dwmMargin = new MARGINS(); + NativeMethods.DwmExtendFrameIntoClientArea( _hwnd, ref dwmMargin ); + } + } - #endregion + private void _RestoreHrgn() + { + _ClearRoundingRegion(); + NativeMethods.SetWindowPos( _hwnd, IntPtr.Zero, 0, 0, 0, 0, _SwpFlags ); } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/TransformExtentions.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/TransformExtentions.cs index 71c80b99..b4b354bc 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/TransformExtentions.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/TransformExtentions.cs @@ -14,113 +14,107 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; using System.Windows.Media; namespace Xceed.Wpf.AvalonDock.Controls { - internal static class TransformExtensions + internal static class TransformExtensions + { + public static Point PointToScreenDPI( this Visual visual, Point pt ) { - public static Point PointToScreenDPI(this Visual visual, Point pt) - { - Point resultPt = visual.PointToScreen(pt); - return TransformToDeviceDPI(visual, resultPt); - } - - public static Point PointToScreenDPIWithoutFlowDirection(this FrameworkElement element, Point point) - { - if (FrameworkElement.GetFlowDirection(element) == FlowDirection.RightToLeft) - { - var actualSize = element.TransformActualSizeToAncestor(); - Point leftToRightPoint = new Point( - actualSize.Width - point.X, - point.Y); - return element.PointToScreenDPI(leftToRightPoint); - } - - return element.PointToScreenDPI(point); - } - - - - public static Rect GetScreenArea(this FrameworkElement element) - { - // return new Rect(element.PointToScreenDPI(new Point()), - // element.TransformActualSizeToAncestor()); - //} - - //public static Rect GetScreenAreaWithoutFlowDirection(this FrameworkElement element) - //{ - var point = element.PointToScreenDPI(new Point()); - if (FrameworkElement.GetFlowDirection(element) == FlowDirection.RightToLeft) - { - var actualSize = element.TransformActualSizeToAncestor(); - Point leftToRightPoint = new Point( - actualSize.Width - point.X, - point.Y); - return new Rect(leftToRightPoint, - actualSize); - } - - return new Rect(point, - element.TransformActualSizeToAncestor()); - } - - public static Point TransformToDeviceDPI(this Visual visual, Point pt) - { - Matrix m = PresentationSource.FromVisual(visual).CompositionTarget.TransformToDevice; - return new Point(pt.X / m.M11, pt.Y / m.M22); - } - - public static Size TransformFromDeviceDPI(this Visual visual, Size size) - { - Matrix m = PresentationSource.FromVisual(visual).CompositionTarget.TransformToDevice; - return new Size(size.Width * m.M11, size.Height * m.M22); - } - - public static Point TransformFromDeviceDPI(this Visual visual, Point pt) - { - Matrix m = PresentationSource.FromVisual(visual).CompositionTarget.TransformToDevice; - return new Point(pt.X * m.M11, pt.Y * m.M22); - } - - public static bool CanTransform(this Visual visual) - { - return PresentationSource.FromVisual(visual) != null; - } - - public static Size TransformActualSizeToAncestor(this FrameworkElement element) - { - if (PresentationSource.FromVisual(element) == null) - return new Size(element.ActualWidth, element.ActualHeight); - - var parentWindow = PresentationSource.FromVisual(element).RootVisual; - var transformToWindow = element.TransformToAncestor(parentWindow); - return transformToWindow.TransformBounds(new Rect(0, 0, element.ActualWidth, element.ActualHeight)).Size; - } - - public static Size TransformSizeToAncestor(this FrameworkElement element, Size sizeToTransform) - { - if (PresentationSource.FromVisual(element) == null) - return sizeToTransform; - - var parentWindow = PresentationSource.FromVisual(element).RootVisual; - var transformToWindow = element.TransformToAncestor(parentWindow); - return transformToWindow.TransformBounds(new Rect(0, 0, sizeToTransform.Width, sizeToTransform.Height)).Size; - } - - public static GeneralTransform TansformToAncestor(this FrameworkElement element) - { - if (PresentationSource.FromVisual(element) == null) - return new MatrixTransform(Matrix.Identity); - - var parentWindow = PresentationSource.FromVisual(element).RootVisual; - return element.TransformToAncestor(parentWindow); - } + Point resultPt = visual.PointToScreen( pt ); + return TransformToDeviceDPI( visual, resultPt ); + } + + public static Point PointToScreenDPIWithoutFlowDirection( this FrameworkElement element, Point point ) + { + if( FrameworkElement.GetFlowDirection( element ) == FlowDirection.RightToLeft ) + { + var actualSize = element.TransformActualSizeToAncestor(); + Point leftToRightPoint = new Point( + actualSize.Width - point.X, + point.Y ); + return element.PointToScreenDPI( leftToRightPoint ); + } + + return element.PointToScreenDPI( point ); + } + + public static Rect GetScreenArea( this FrameworkElement element ) + { + // return new Rect(element.PointToScreenDPI(new Point()), + // element.TransformActualSizeToAncestor()); + //} + + //public static Rect GetScreenAreaWithoutFlowDirection(this FrameworkElement element) + //{ + var point = element.PointToScreenDPI( new Point() ); + if( FrameworkElement.GetFlowDirection( element ) == FlowDirection.RightToLeft ) + { + var actualSize = element.TransformActualSizeToAncestor(); + Point leftToRightPoint = new Point( + actualSize.Width - point.X, + point.Y ); + return new Rect( leftToRightPoint, + actualSize ); + } + + return new Rect( point, + element.TransformActualSizeToAncestor() ); + } + + public static Point TransformToDeviceDPI( this Visual visual, Point pt ) + { + Matrix m = PresentationSource.FromVisual( visual ).CompositionTarget.TransformToDevice; + return new Point( pt.X / m.M11, pt.Y / m.M22 ); + } + + public static Size TransformFromDeviceDPI( this Visual visual, Size size ) + { + Matrix m = PresentationSource.FromVisual( visual ).CompositionTarget.TransformToDevice; + return new Size( size.Width * m.M11, size.Height * m.M22 ); + } + + public static Point TransformFromDeviceDPI( this Visual visual, Point pt ) + { + Matrix m = PresentationSource.FromVisual( visual ).CompositionTarget.TransformToDevice; + return new Point( pt.X * m.M11, pt.Y * m.M22 ); + } + + public static bool CanTransform( this Visual visual ) + { + return PresentationSource.FromVisual( visual ) != null; + } + public static Size TransformActualSizeToAncestor( this FrameworkElement element ) + { + if( PresentationSource.FromVisual( element ) == null ) + return new Size( element.ActualWidth, element.ActualHeight ); + + var parentWindow = PresentationSource.FromVisual( element ).RootVisual; + var transformToWindow = element.TransformToAncestor( parentWindow ); + return transformToWindow.TransformBounds( new Rect( 0, 0, element.ActualWidth, element.ActualHeight ) ).Size; } + + public static Size TransformSizeToAncestor( this FrameworkElement element, Size sizeToTransform ) + { + if( PresentationSource.FromVisual( element ) == null ) + return sizeToTransform; + + var parentWindow = PresentationSource.FromVisual( element ).RootVisual; + var transformToWindow = element.TransformToAncestor( parentWindow ); + return transformToWindow.TransformBounds( new Rect( 0, 0, sizeToTransform.Width, sizeToTransform.Height ) ).Size; + } + + public static GeneralTransform TansformToAncestor( this FrameworkElement element ) + { + if( PresentationSource.FromVisual( element ) == null ) + return new MatrixTransform( Matrix.Identity ); + + var parentWindow = PresentationSource.FromVisual( element ).RootVisual; + return element.TransformToAncestor( parentWindow ); + } + + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/WeakDictionary.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/WeakDictionary.cs index b87cbc7c..5de2fd00 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/WeakDictionary.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/WeakDictionary.cs @@ -16,79 +16,93 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Xceed.Wpf.AvalonDock.Controls { - class WeakDictionary where K : class + internal class WeakDictionary where K : class + { + #region Members + + private List _keys = new List(); + private List _values = new List(); + + #endregion + + #region constructors + + public WeakDictionary() { - public WeakDictionary() - {} + } - List _keys = new List(); - List _values = new List(); + #endregion - public V this[K key] - { - get - { - V valueToReturn; - if (!GetValue(key, out valueToReturn)) - throw new ArgumentException(); - return valueToReturn; - } - set - { - SetValue(key, value); - } - } + #region Public Methods - public bool ContainsKey(K key) - { - CollectGarbage(); - return -1 != _keys.FindIndex(k => k.GetValueOrDefault() == key); - } + public V this[ K key ] + { + get + { + V valueToReturn; + if( !GetValue( key, out valueToReturn ) ) + throw new ArgumentException(); + return valueToReturn; + } + set + { + SetValue( key, value ); + } + } - public void SetValue(K key, V value) - { - CollectGarbage(); - int vIndex = _keys.FindIndex(k => k.GetValueOrDefault() == key); - if (vIndex > -1) - _values[vIndex] = value; - else - { - _values.Add(value); - _keys.Add(new WeakReference(key)); - } - } + public bool ContainsKey( K key ) + { + CollectGarbage(); + return -1 != _keys.FindIndex( k => k.GetValueOrDefault() == key ); + } - public bool GetValue(K key, out V value) - { - CollectGarbage(); - int vIndex = _keys.FindIndex(k => k.GetValueOrDefault() == key); - value = default(V); - if (vIndex == -1) - return false; - value = _values[vIndex]; - return true; - } + public void SetValue( K key, V value ) + { + CollectGarbage(); + int vIndex = _keys.FindIndex( k => k.GetValueOrDefault() == key ); + if( vIndex > -1 ) + _values[ vIndex ] = value; + else + { + _values.Add( value ); + _keys.Add( new WeakReference( key ) ); + } + } + public bool GetValue( K key, out V value ) + { + CollectGarbage(); + int vIndex = _keys.FindIndex( k => k.GetValueOrDefault() == key ); + value = default( V ); + if( vIndex == -1 ) + return false; + value = _values[ vIndex ]; + return true; + } - void CollectGarbage() - { - int vIndex = 0; - - do - { - vIndex = _keys.FindIndex(vIndex, k => !k.IsAlive); - if (vIndex >= 0) - { - _keys.RemoveAt(vIndex); - _values.RemoveAt(vIndex); - } - } - while (vIndex >= 0); + #endregion + + #region Private Methods + + private void CollectGarbage() + { + int vIndex = 0; + + do + { + vIndex = _keys.FindIndex( vIndex, k => !k.IsAlive ); + if( vIndex >= 0 ) + { + _keys.RemoveAt( vIndex ); + _values.RemoveAt( vIndex ); } + } + while( vIndex >= 0 ); } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/WindowActivateEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/WindowActivateEventArgs.cs index c435cdec..e129acd5 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/WindowActivateEventArgs.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/WindowActivateEventArgs.cs @@ -15,23 +15,28 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Xceed.Wpf.AvalonDock.Controls { - class WindowActivateEventArgs : EventArgs + internal class WindowActivateEventArgs : EventArgs + { + #region Constructors + + public WindowActivateEventArgs( IntPtr hwndActivating ) { - public WindowActivateEventArgs(IntPtr hwndActivating) - { - HwndActivating = hwndActivating; - } - - public IntPtr HwndActivating - { - get; - private set; - } + HwndActivating = hwndActivating; } + + #endregion + + #region Properties + + public IntPtr HwndActivating + { + get; + private set; + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/WindowHookHandler.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/WindowHookHandler.cs index eb07e409..799cc477 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/WindowHookHandler.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/WindowHookHandler.cs @@ -15,85 +15,102 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; namespace Xceed.Wpf.AvalonDock.Controls { - class FocusChangeEventArgs : EventArgs + internal class FocusChangeEventArgs : EventArgs + { + #region Constructors + + public FocusChangeEventArgs( IntPtr gotFocusWinHandle, IntPtr lostFocusWinHandle ) { - public FocusChangeEventArgs(IntPtr gotFocusWinHandle, IntPtr lostFocusWinHandle) - { - GotFocusWinHandle = gotFocusWinHandle; - LostFocusWinHandle = lostFocusWinHandle; - } + GotFocusWinHandle = gotFocusWinHandle; + LostFocusWinHandle = lostFocusWinHandle; + } - public IntPtr GotFocusWinHandle - { - get; - private set; - } - public IntPtr LostFocusWinHandle - { - get; - private set; - } + #endregion + + #region Properties + + public IntPtr GotFocusWinHandle + { + get; + private set; + } + public IntPtr LostFocusWinHandle + { + get; + private set; } - class WindowHookHandler + #endregion + } + + internal class WindowHookHandler + { + #region Members + + private IntPtr _windowHook; + private Win32Helper.HookProc _hookProc; + private ReentrantFlag _insideActivateEvent = new ReentrantFlag(); + + #endregion + + #region Constructors + + public WindowHookHandler() { - public WindowHookHandler() - { + } - } + #endregion - IntPtr _windowHook; - Win32Helper.HookProc _hookProc; - public void Attach() - { - _hookProc = new Win32Helper.HookProc(this.HookProc); - _windowHook = Win32Helper.SetWindowsHookEx( - Win32Helper.HookType.WH_CBT, - _hookProc, - IntPtr.Zero, - (int)Win32Helper.GetCurrentThreadId()); - } + #region Public Methods + public void Attach() + { + _hookProc = new Win32Helper.HookProc( this.HookProc ); + _windowHook = Win32Helper.SetWindowsHookEx( + Win32Helper.HookType.WH_CBT, + _hookProc, + IntPtr.Zero, + ( int )Win32Helper.GetCurrentThreadId() ); + } - public void Detach() - { - Win32Helper.UnhookWindowsHookEx(_windowHook); - } + public void Detach() + { + Win32Helper.UnhookWindowsHookEx( _windowHook ); + } - public int HookProc(int code, IntPtr wParam, IntPtr lParam) + public int HookProc( int code, IntPtr wParam, IntPtr lParam ) + { + if( code == Win32Helper.HCBT_SETFOCUS ) + { + if( FocusChanged != null ) + FocusChanged( this, new FocusChangeEventArgs( wParam, lParam ) ); + } + else if( code == Win32Helper.HCBT_ACTIVATE ) + { + if( _insideActivateEvent.CanEnter ) { - if (code == Win32Helper.HCBT_SETFOCUS) - { - if (FocusChanged != null) - FocusChanged(this, new FocusChangeEventArgs(wParam, lParam)); - } - else if (code == Win32Helper.HCBT_ACTIVATE) - { - if (_insideActivateEvent.CanEnter) - { - using (_insideActivateEvent.Enter()) - { - //if (Activate != null) - // Activate(this, new WindowActivateEventArgs(wParam)); - } - } - } - - - return Win32Helper.CallNextHookEx(_windowHook, code, wParam, lParam); + using( _insideActivateEvent.Enter() ) + { + //if (Activate != null) + // Activate(this, new WindowActivateEventArgs(wParam)); + } } + } - public event EventHandler FocusChanged; - - //public event EventHandler Activate; - ReentrantFlag _insideActivateEvent = new ReentrantFlag(); + return Win32Helper.CallNextHookEx( _windowHook, code, wParam, lParam ); } + + #endregion + + #region Events + + public event EventHandler FocusChanged; + //public event EventHandler Activate; + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/ActivateCommandLayoutItemFromLayoutModelConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/ActivateCommandLayoutItemFromLayoutModelConverter.cs index 01887b1b..f9225610 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/ActivateCommandLayoutItemFromLayoutModelConverter.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/ActivateCommandLayoutItemFromLayoutModelConverter.cs @@ -15,37 +15,34 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Data; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Converters { - public class ActivateCommandLayoutItemFromLayoutModelConverter : IValueConverter + public class ActivateCommandLayoutItemFromLayoutModelConverter : IValueConverter + { + public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) { - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - //when this converter is called layout could be constructing so many properties here are potentially not valid - var layoutModel = value as LayoutContent; - if (layoutModel == null) - return null; - if (layoutModel.Root == null) - return null; - if (layoutModel.Root.Manager == null) - return null; - - var layoutItemModel = layoutModel.Root.Manager.GetLayoutItemFromModel(layoutModel); - if (layoutItemModel == null) - return Binding.DoNothing; - - return layoutItemModel.ActivateCommand; - } - - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - throw new NotImplementedException(); - } + //when this converter is called layout could be constructing so many properties here are potentially not valid + var layoutModel = value as LayoutContent; + if( layoutModel == null ) + return null; + if( layoutModel.Root == null ) + return null; + if( layoutModel.Root.Manager == null ) + return null; + + var layoutItemModel = layoutModel.Root.Manager.GetLayoutItemFromModel( layoutModel ); + if( layoutItemModel == null ) + return Binding.DoNothing; + + return layoutItemModel.ActivateCommand; } + + public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) + { + throw new NotImplementedException(); + } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AnchorSideToAngleConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AnchorSideToAngleConverter.cs index 1282a102..32af544c 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AnchorSideToAngleConverter.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AnchorSideToAngleConverter.cs @@ -15,30 +15,27 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Data; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Converters { - [ValueConversion(typeof(AnchorSide), typeof(double))] - public class AnchorSideToAngleConverter : IValueConverter + [ValueConversion( typeof( AnchorSide ), typeof( double ) )] + public class AnchorSideToAngleConverter : IValueConverter + { + public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) { - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - AnchorSide side = (AnchorSide)value; - if (side == AnchorSide.Left || - side == AnchorSide.Right) - return 90.0; - - return Binding.DoNothing; - } - - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - throw new NotImplementedException(); - } + AnchorSide side = ( AnchorSide )value; + if( side == AnchorSide.Left || + side == AnchorSide.Right ) + return 90.0; + + return Binding.DoNothing; + } + + public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) + { + throw new NotImplementedException(); } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AnchorSideToOrientationConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AnchorSideToOrientationConverter.cs index 8ab707cb..9a6e4e5f 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AnchorSideToOrientationConverter.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AnchorSideToOrientationConverter.cs @@ -15,31 +15,28 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Data; using System.Windows.Controls; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Converters { - [ValueConversion(typeof(AnchorSide), typeof(Orientation))] - public class AnchorSideToOrientationConverter : IValueConverter + [ValueConversion( typeof( AnchorSide ), typeof( Orientation ) )] + public class AnchorSideToOrientationConverter : IValueConverter + { + public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) { - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - AnchorSide side = (AnchorSide)value; - if (side == AnchorSide.Left || - side == AnchorSide.Right) - return Orientation.Vertical; - - return Orientation.Horizontal; - } - - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - throw new NotImplementedException(); - } + AnchorSide side = ( AnchorSide )value; + if( side == AnchorSide.Left || + side == AnchorSide.Right ) + return Orientation.Vertical; + + return Orientation.Horizontal; + } + + public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) + { + throw new NotImplementedException(); } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AnchorableContextMenuHideVisibilityConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AnchorableContextMenuHideVisibilityConverter.cs index 7c881eba..7fc71514 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AnchorableContextMenuHideVisibilityConverter.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AnchorableContextMenuHideVisibilityConverter.cs @@ -28,8 +28,8 @@ namespace Xceed.Wpf.AvalonDock.Converters { if( ( values.Count() == 2 ) && ( values[ 0 ] != DependencyProperty.UnsetValue ) - && ( values[ 1 ] != DependencyProperty.UnsetValue ) - && ( values[ 1 ] is bool )) + && ( values[ 1 ] != DependencyProperty.UnsetValue ) + && ( values[ 1 ] is bool ) ) { var canClose = ( bool )values[ 1 ]; diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AutoHideCommandLayoutItemFromLayoutModelConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AutoHideCommandLayoutItemFromLayoutModelConverter.cs index ca89470f..137df6c5 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AutoHideCommandLayoutItemFromLayoutModelConverter.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/AutoHideCommandLayoutItemFromLayoutModelConverter.cs @@ -15,38 +15,35 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Data; using Xceed.Wpf.AvalonDock.Layout; using Xceed.Wpf.AvalonDock.Controls; namespace Xceed.Wpf.AvalonDock.Converters { - public class AutoHideCommandLayoutItemFromLayoutModelConverter : IValueConverter + public class AutoHideCommandLayoutItemFromLayoutModelConverter : IValueConverter + { + public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) { - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - //when this converter is called layout could be constructing so many properties here are potentially not valid - var layoutModel = value as LayoutContent; - if (layoutModel == null) - return null; - if (layoutModel.Root == null) - return null; - if (layoutModel.Root.Manager == null) - return null; - - var layoutItemModel = layoutModel.Root.Manager.GetLayoutItemFromModel(layoutModel) as LayoutAnchorableItem; - if (layoutItemModel == null) - return Binding.DoNothing; - - return layoutItemModel.AutoHideCommand; - } - - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - throw new NotImplementedException(); - } + //when this converter is called layout could be constructing so many properties here are potentially not valid + var layoutModel = value as LayoutContent; + if( layoutModel == null ) + return null; + if( layoutModel.Root == null ) + return null; + if( layoutModel.Root.Manager == null ) + return null; + + var layoutItemModel = layoutModel.Root.Manager.GetLayoutItemFromModel( layoutModel ) as LayoutAnchorableItem; + if( layoutItemModel == null ) + return Binding.DoNothing; + + return layoutItemModel.AutoHideCommand; } + + public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) + { + throw new NotImplementedException(); + } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/BoolToVisibilityConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/BoolToVisibilityConverter.cs index b93e66c7..971614a0 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/BoolToVisibilityConverter.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/BoolToVisibilityConverter.cs @@ -15,78 +15,73 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Data; using System.Windows; namespace Xceed.Wpf.AvalonDock.Converters { - [ValueConversion(typeof(bool), typeof(Visibility))] - public class BoolToVisibilityConverter : IValueConverter - { + [ValueConversion( typeof( bool ), typeof( Visibility ) )] + public class BoolToVisibilityConverter : IValueConverter + { - #region IValueConverter Members - /// - /// Converts a value. - /// - /// The value produced by the binding source. - /// The type of the binding target property. - /// The converter parameter to use. - /// The culture to use in the converter. - /// - /// A converted value. If the method returns null, the valid null value is used. - /// - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - if (value is bool && targetType == typeof(Visibility)) - { - bool val = (bool)value; - if (val) - return Visibility.Visible; - else - if (parameter != null && parameter is Visibility) - return parameter; - else - return Visibility.Collapsed; - } - if (value == null) - { - if (parameter != null && parameter is Visibility) - return parameter; - else - return Visibility.Collapsed; - } - - return Visibility.Visible; - ///throw new ArgumentException("Invalid argument/return type. Expected argument: bool and return type: Visibility"); - } - - /// - /// Converts a value. - /// - /// The value that is produced by the binding target. - /// The type to convert to. - /// The converter parameter to use. - /// The culture to use in the converter. - /// - /// A converted value. If the method returns null, the valid null value is used. - /// - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - if (value is Visibility && targetType == typeof(bool)) - { - Visibility val = (Visibility)value; - if (val == Visibility.Visible) - return true; - else - return false; - } - throw new ArgumentException("Invalid argument/return type. Expected argument: Visibility and return type: bool"); - } - #endregion - } + #region IValueConverter Members + /// + /// Converts a value. + /// + /// The value produced by the binding source. + /// The type of the binding target property. + /// The converter parameter to use. + /// The culture to use in the converter. + /// + /// A converted value. If the method returns null, the valid null value is used. + /// + public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) + { + if( value is bool && targetType == typeof( Visibility ) ) + { + bool val = ( bool )value; + if( val ) + return Visibility.Visible; + else + if( parameter != null && parameter is Visibility ) + return parameter; + else + return Visibility.Collapsed; + } + if( value == null ) + { + if( parameter != null && parameter is Visibility ) + return parameter; + else + return Visibility.Collapsed; + } + return Visibility.Visible; + ///throw new ArgumentException("Invalid argument/return type. Expected argument: bool and return type: Visibility"); + } + /// + /// Converts a value. + /// + /// The value that is produced by the binding target. + /// The type to convert to. + /// The converter parameter to use. + /// The culture to use in the converter. + /// + /// A converted value. If the method returns null, the valid null value is used. + /// + public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) + { + if( value is Visibility && targetType == typeof( bool ) ) + { + Visibility val = ( Visibility )value; + if( val == Visibility.Visible ) + return true; + else + return false; + } + throw new ArgumentException( "Invalid argument/return type. Expected argument: Visibility and return type: bool" ); + } + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/HideCommandLayoutItemFromLayoutModelConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/HideCommandLayoutItemFromLayoutModelConverter.cs index d2207b14..318a08b6 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/HideCommandLayoutItemFromLayoutModelConverter.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/HideCommandLayoutItemFromLayoutModelConverter.cs @@ -15,38 +15,35 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Data; using Xceed.Wpf.AvalonDock.Layout; using Xceed.Wpf.AvalonDock.Controls; namespace Xceed.Wpf.AvalonDock.Converters { - public class HideCommandLayoutItemFromLayoutModelConverter : IValueConverter + public class HideCommandLayoutItemFromLayoutModelConverter : IValueConverter + { + public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) { - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - //when this converter is called layout could be constructing so many properties here are potentially not valid - var layoutModel = value as LayoutContent; - if (layoutModel == null) - return null; - if (layoutModel.Root == null) - return null; - if (layoutModel.Root.Manager == null) - return null; - - var layoutItemModel = layoutModel.Root.Manager.GetLayoutItemFromModel(layoutModel) as LayoutAnchorableItem; - if (layoutItemModel == null) - return Binding.DoNothing; - - return layoutItemModel.HideCommand; - } - - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - throw new NotImplementedException(); - } + //when this converter is called layout could be constructing so many properties here are potentially not valid + var layoutModel = value as LayoutContent; + if( layoutModel == null ) + return null; + if( layoutModel.Root == null ) + return null; + if( layoutModel.Root.Manager == null ) + return null; + + var layoutItemModel = layoutModel.Root.Manager.GetLayoutItemFromModel( layoutModel ) as LayoutAnchorableItem; + if( layoutItemModel == null ) + return Binding.DoNothing; + + return layoutItemModel.HideCommand; } + + public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) + { + throw new NotImplementedException(); + } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/InverseBoolToVisibilityConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/InverseBoolToVisibilityConverter.cs index 3dd40ef9..b129e989 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/InverseBoolToVisibilityConverter.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/InverseBoolToVisibilityConverter.cs @@ -15,69 +15,64 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Data; using System.Windows; namespace Xceed.Wpf.AvalonDock.Converters { - [ValueConversion(typeof(bool), typeof(Visibility))] - public class InverseBoolToVisibilityConverter : IValueConverter - { - - #region IValueConverter Members - /// - /// Converts a value. - /// - /// The value produced by the binding source. - /// The type of the binding target property. - /// The converter parameter to use. - /// The culture to use in the converter. - /// - /// A converted value. If the method returns null, the valid null value is used. - /// - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - if (value is bool && targetType == typeof(Visibility)) - { - bool val = !(bool)value; - if (val) - return Visibility.Visible; - else - if (parameter != null && parameter is Visibility ) - return parameter; - else - return Visibility.Collapsed; - } - throw new ArgumentException("Invalid argument/return type. Expected argument: bool and return type: Visibility"); - } - - /// - /// Converts a value. - /// - /// The value that is produced by the binding target. - /// The type to convert to. - /// The converter parameter to use. - /// The culture to use in the converter. - /// - /// A converted value. If the method returns null, the valid null value is used. - /// - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - if (value is Visibility && targetType == typeof(bool)) - { - Visibility val = (Visibility)value; - if (val == Visibility.Visible) - return false; - else - return true; - } - throw new ArgumentException("Invalid argument/return type. Expected argument: Visibility and return type: bool"); - } - #endregion - } + [ValueConversion( typeof( bool ), typeof( Visibility ) )] + public class InverseBoolToVisibilityConverter : IValueConverter + { + #region IValueConverter Members + /// + /// Converts a value. + /// + /// The value produced by the binding source. + /// The type of the binding target property. + /// The converter parameter to use. + /// The culture to use in the converter. + /// + /// A converted value. If the method returns null, the valid null value is used. + /// + public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) + { + if( value is bool && targetType == typeof( Visibility ) ) + { + bool val = !( bool )value; + if( val ) + return Visibility.Visible; + else + if( parameter != null && parameter is Visibility ) + return parameter; + else + return Visibility.Collapsed; + } + throw new ArgumentException( "Invalid argument/return type. Expected argument: bool and return type: Visibility" ); + } + /// + /// Converts a value. + /// + /// The value that is produced by the binding target. + /// The type to convert to. + /// The converter parameter to use. + /// The culture to use in the converter. + /// + /// A converted value. If the method returns null, the valid null value is used. + /// + public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) + { + if( value is Visibility && targetType == typeof( bool ) ) + { + Visibility val = ( Visibility )value; + if( val == Visibility.Visible ) + return false; + else + return true; + } + throw new ArgumentException( "Invalid argument/return type. Expected argument: Visibility and return type: bool" ); + } + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/LayoutItemFromLayoutModelConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/LayoutItemFromLayoutModelConverter.cs index d80e342e..1753097c 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/LayoutItemFromLayoutModelConverter.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/LayoutItemFromLayoutModelConverter.cs @@ -15,36 +15,33 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Data; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock.Converters { - public class LayoutItemFromLayoutModelConverter : IValueConverter + public class LayoutItemFromLayoutModelConverter : IValueConverter + { + public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) { - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - var layoutModel = value as LayoutContent; - if (layoutModel == null) - return null; - if (layoutModel.Root == null) - return null; - if (layoutModel.Root.Manager == null) - return null; - - var layoutItemModel = layoutModel.Root.Manager.GetLayoutItemFromModel(layoutModel); - if (layoutItemModel == null) - return Binding.DoNothing; - - return layoutItemModel; - } - - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - throw new NotImplementedException(); - } + var layoutModel = value as LayoutContent; + if( layoutModel == null ) + return null; + if( layoutModel.Root == null ) + return null; + if( layoutModel.Root.Manager == null ) + return null; + + var layoutItemModel = layoutModel.Root.Manager.GetLayoutItemFromModel( layoutModel ); + if( layoutItemModel == null ) + return Binding.DoNothing; + + return layoutItemModel; } + + public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) + { + throw new NotImplementedException(); + } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/NullToDoNothingConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/NullToDoNothingConverter.cs index 2fb9fa91..0944e155 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/NullToDoNothingConverter.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/NullToDoNothingConverter.cs @@ -15,26 +15,23 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Data; namespace Xceed.Wpf.AvalonDock.Converters { - public class NullToDoNothingConverter : IValueConverter + public class NullToDoNothingConverter : IValueConverter + { + public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) { - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - if (value == null) - return Binding.DoNothing; - - return value; - } - - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - throw new NotImplementedException(); - } + if( value == null ) + return Binding.DoNothing; + + return value; + } + + public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) + { + throw new NotImplementedException(); } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/UriSourceToBitmapImageConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/UriSourceToBitmapImageConverter.cs index 7f076bfb..64018b94 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/UriSourceToBitmapImageConverter.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Converters/UriSourceToBitmapImageConverter.cs @@ -15,28 +15,25 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Data; using System.Windows.Media.Imaging; using System.Windows.Controls; namespace Xceed.Wpf.AvalonDock.Converters { - public class UriSourceToBitmapImageConverter : IValueConverter + public class UriSourceToBitmapImageConverter : IValueConverter + { + public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) { - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - if (value == null) - return Binding.DoNothing; - //return (Uri)value; - return new Image() { Source = new BitmapImage((Uri)value) } ; - } - - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - throw new NotImplementedException(); - } + if( value == null ) + return Binding.DoNothing; + //return (Uri)value; + return new Image() { Source = new BitmapImage( ( Uri )value ) }; } + + public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) + { + throw new NotImplementedException(); + } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DockingManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DockingManager.cs index 2456e496..60ac9a05 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DockingManager.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DockingManager.cs @@ -37,7 +37,26 @@ namespace Xceed.Wpf.AvalonDock [TemplatePart( Name = "PART_AutoHideArea" )] public class DockingManager : Control, IOverlayWindowHost//, ILogicalChildrenContainer { + #region Members + private ResourceDictionary currentThemeResourceDictionary; // = null + private AutoHideWindowManager _autoHideWindowManager; + private FrameworkElement _autohideArea; + private List _fwList = new List(); + private OverlayWindow _overlayWindow = null; + private List _areas = null; + private bool _insideInternalSetActiveContent = false; + private List _layoutItems = new List(); + private bool _suspendLayoutItemCreation = false; + private DispatcherOperation _collectLayoutItemsOperations = null; + private NavigatorWindow _navigatorWindow = null; + + internal bool SuspendDocumentsSourceBinding = false; + internal bool SuspendAnchorablesSourceBinding = false; + + #endregion + + #region Constructors static DockingManager() { @@ -49,6 +68,7 @@ namespace Xceed.Wpf.AvalonDock public DockingManager() { + #if !VS2008 Layout = new LayoutRoot() { RootPanel = new LayoutPanel( new LayoutDocumentPaneGroup( new LayoutDocumentPane() ) ) }; #else @@ -58,16 +78,17 @@ namespace Xceed.Wpf.AvalonDock this.Unloaded += new RoutedEventHandler( DockingManager_Unloaded ); } + #endregion + + #region Properties + #region Layout /// /// Layout Dependency Property /// - public static readonly DependencyProperty LayoutProperty = - DependencyProperty.Register( "Layout", typeof( LayoutRoot ), typeof( DockingManager ), - new FrameworkPropertyMetadata( null, - new PropertyChangedCallback( OnLayoutChanged ), - new CoerceValueCallback( CoerceLayoutValue ) ) ); + public static readonly DependencyProperty LayoutProperty = DependencyProperty.Register( "Layout", typeof( LayoutRoot ), typeof( DockingManager ), + new FrameworkPropertyMetadata( null, new PropertyChangedCallback( OnLayoutChanged ), new CoerceValueCallback( CoerceLayoutValue ) ) ); /// /// Gets or sets the Layout property. This dependency property @@ -85,6 +106,19 @@ namespace Xceed.Wpf.AvalonDock } } + /// + /// Coerces the value. + /// + private static object CoerceLayoutValue( DependencyObject d, object value ) + { + if( value == null ) + return new LayoutRoot() { RootPanel = new LayoutPanel( new LayoutDocumentPaneGroup( new LayoutDocumentPane() ) ) }; + + ( ( DockingManager )d ).OnLayoutChanging( value as LayoutRoot ); + + return value; + } + /// /// Handles changes to the Layout property. /// @@ -165,677 +199,399 @@ namespace Xceed.Wpf.AvalonDock CommandManager.InvalidateRequerySuggested(); } - // DispatcherOperation _setFocusAsyncOperation = null; + #endregion + + #region LayoutUpdateStrategy + + /// + /// LayoutUpdateStrategy Dependency Property + /// + public static readonly DependencyProperty LayoutUpdateStrategyProperty = DependencyProperty.Register( "LayoutUpdateStrategy", typeof( ILayoutUpdateStrategy ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( ILayoutUpdateStrategy )null ) ); - void OnLayoutRootPropertyChanged( object sender, PropertyChangedEventArgs e ) + /// + /// Gets or sets the LayoutUpdateStrategy property. This dependency property + /// indicates the strategy class to call when AvalonDock needs to positionate a LayoutAnchorable inside an existing layout. + /// + /// Sometimes it's impossible to automatically insert an anchorable in the layout without specifing the target parent pane. + /// Set this property to an object that will be asked to insert the anchorable to the desidered position. + public ILayoutUpdateStrategy LayoutUpdateStrategy { - if( e.PropertyName == "RootPanel" ) + get { - if( IsInitialized ) - { - var layoutRootPanel = CreateUIElementForModel( Layout.RootPanel ) as LayoutPanelControl; - LayoutRootPanel = layoutRootPanel; - } + return ( ILayoutUpdateStrategy )GetValue( LayoutUpdateStrategyProperty ); } - else if( e.PropertyName == "ActiveContent" ) + set { - if( Layout.ActiveContent != null ) - { - //Debug.WriteLine(new StackTrace().ToString()); + SetValue( LayoutUpdateStrategyProperty, value ); + } + } - //set focus on active element only after a layout pass is completed - //it's possible that it is not yet visible in the visual tree - //if (_setFocusAsyncOperation == null) - //{ - // _setFocusAsyncOperation = Dispatcher.BeginInvoke(new Action(() => - // { - if( Layout.ActiveContent != null ) - FocusElementManager.SetFocusOnLastElement( Layout.ActiveContent ); - //_setFocusAsyncOperation = null; - // } ), DispatcherPriority.Input ); - //} - } + #endregion - //if (!_insideInternalSetActiveContent) - // ActiveContent = Layout.ActiveContent != null ? - // Layout.ActiveContent.Content : null; - if( !_insideInternalSetActiveContent && ( Layout.ActiveContent != null ) ) - { - this.ActiveContent = Layout.ActiveContent.Content; - } + #region DocumentPaneTemplate + + /// + /// DocumentPaneTemplate Dependency Property + /// + public static readonly DependencyProperty DocumentPaneTemplateProperty = DependencyProperty.Register( "DocumentPaneTemplate", typeof( ControlTemplate ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( ControlTemplate )null, new PropertyChangedCallback( OnDocumentPaneTemplateChanged ) ) ); + + /// + /// Gets or sets the DocumentPaneDataTemplate property. This dependency property + /// indicates . + /// + public ControlTemplate DocumentPaneTemplate + { + get + { + return ( ControlTemplate )GetValue( DocumentPaneTemplateProperty ); + } + set + { + SetValue( DocumentPaneTemplateProperty, value ); } } - void OnLayoutRootUpdated( object sender, EventArgs e ) + /// + /// Handles changes to the DocumentPaneTemplate property. + /// + private static void OnDocumentPaneTemplateChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( DockingManager )d ).OnDocumentPaneTemplateChanged( e ); + } + + /// + /// Provides derived classes an opportunity to handle changes to the DocumentPaneTemplate property. + /// + protected virtual void OnDocumentPaneTemplateChanged( DependencyPropertyChangedEventArgs e ) { - CommandManager.InvalidateRequerySuggested(); } + #endregion + + #region AnchorablePaneTemplate /// - /// Event fired when property changes + /// AnchorablePaneTemplate Dependency Property /// - public event EventHandler LayoutChanged; + public static readonly DependencyProperty AnchorablePaneTemplateProperty = DependencyProperty.Register( "AnchorablePaneTemplate", typeof( ControlTemplate ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( ControlTemplate )null, new PropertyChangedCallback( OnAnchorablePaneTemplateChanged ) ) ); /// - /// Coerces the value. + /// Gets or sets the AnchorablePaneTemplate property. This dependency property + /// indicates .... /// - private static object CoerceLayoutValue( DependencyObject d, object value ) + public ControlTemplate AnchorablePaneTemplate { - if( value == null ) - return new LayoutRoot() { RootPanel = new LayoutPanel( new LayoutDocumentPaneGroup( new LayoutDocumentPane() ) ) }; - - ( ( DockingManager )d ).OnLayoutChanging( value as LayoutRoot ); - - return value; + get + { + return ( ControlTemplate )GetValue( AnchorablePaneTemplateProperty ); + } + set + { + SetValue( AnchorablePaneTemplateProperty, value ); + } } /// - /// Event fired when property is about to be changed + /// Handles changes to the AnchorablePaneDataTemplate property. /// - public event EventHandler LayoutChanging; + private static void OnAnchorablePaneTemplateChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( DockingManager )d ).OnAnchorablePaneTemplateChanged( e ); + } - void OnLayoutChanging( LayoutRoot newLayout ) + /// + /// Provides derived classes an opportunity to handle changes to the AnchorablePaneDataTemplate property. + /// + protected virtual void OnAnchorablePaneTemplateChanged( DependencyPropertyChangedEventArgs e ) { - if( LayoutChanging != null ) - LayoutChanging( this, EventArgs.Empty ); } + #endregion - #region LayoutUpdateStrategy + #region AnchorSideTemplate /// - /// LayoutUpdateStrategy Dependency Property + /// AnchorSideTemplate Dependency Property /// - public static readonly DependencyProperty LayoutUpdateStrategyProperty = - DependencyProperty.Register( "LayoutUpdateStrategy", typeof( ILayoutUpdateStrategy ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( ILayoutUpdateStrategy )null ) ); + public static readonly DependencyProperty AnchorSideTemplateProperty = DependencyProperty.Register( "AnchorSideTemplate", typeof( ControlTemplate ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( ControlTemplate )null ) ); /// - /// Gets or sets the LayoutUpdateStrategy property. This dependency property - /// indicates the strategy class to call when AvalonDock needs to positionate a LayoutAnchorable inside an existing layout. + /// Gets or sets the AnchorSideTemplate property. This dependency property + /// indicates .... /// - /// Sometimes it's impossible to automatically insert an anchorable in the layout without specifing the target parent pane. - /// Set this property to an object that will be asked to insert the anchorable to the desidered position. - public ILayoutUpdateStrategy LayoutUpdateStrategy + public ControlTemplate AnchorSideTemplate { get { - return ( ILayoutUpdateStrategy )GetValue( LayoutUpdateStrategyProperty ); + return ( ControlTemplate )GetValue( AnchorSideTemplateProperty ); } set { - SetValue( LayoutUpdateStrategyProperty, value ); + SetValue( AnchorSideTemplateProperty, value ); } } #endregion + #region AnchorGroupTemplate + /// + /// AnchorGroupTemplate Dependency Property + /// + public static readonly DependencyProperty AnchorGroupTemplateProperty = DependencyProperty.Register( "AnchorGroupTemplate", typeof( ControlTemplate ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( ControlTemplate )null ) ); - #endregion - - public override void OnApplyTemplate() + /// + /// Gets or sets the AnchorGroupTemplate property. This dependency property + /// indicates the template used to render the AnchorGroup control. + /// + public ControlTemplate AnchorGroupTemplate { - base.OnApplyTemplate(); - - - _autohideArea = GetTemplateChild( "PART_AutoHideArea" ) as FrameworkElement; + get + { + return ( ControlTemplate )GetValue( AnchorGroupTemplateProperty ); + } + set + { + SetValue( AnchorGroupTemplateProperty, value ); + } } - protected override void OnInitialized( EventArgs e ) - { - base.OnInitialized( e ); - } + #endregion + + #region AnchorTemplate + /// + /// AnchorTemplate Dependency Property + /// + public static readonly DependencyProperty AnchorTemplateProperty = DependencyProperty.Register( "AnchorTemplate", typeof( ControlTemplate ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( ControlTemplate )null ) ); - void DockingManager_Loaded( object sender, RoutedEventArgs e ) + /// + /// Gets or sets the AnchorTemplate property. This dependency property + /// indicates .... + /// + public ControlTemplate AnchorTemplate { - if( !DesignerProperties.GetIsInDesignMode( this ) ) + get { - if( Layout.Manager == this ) - { - LayoutRootPanel = CreateUIElementForModel( Layout.RootPanel ) as LayoutPanelControl; - LeftSidePanel = CreateUIElementForModel( Layout.LeftSide ) as LayoutAnchorSideControl; - TopSidePanel = CreateUIElementForModel( Layout.TopSide ) as LayoutAnchorSideControl; - RightSidePanel = CreateUIElementForModel( Layout.RightSide ) as LayoutAnchorSideControl; - BottomSidePanel = CreateUIElementForModel( Layout.BottomSide ) as LayoutAnchorSideControl; - } + return ( ControlTemplate )GetValue( AnchorTemplateProperty ); + } + set + { + SetValue( AnchorTemplateProperty, value ); + } + } - SetupAutoHideWindow(); + #endregion - //load windows not already loaded! - foreach( var fw in Layout.FloatingWindows.Where( fw => !_fwList.Any( fwc => fwc.Model == fw ) ) ) - _fwList.Add( CreateUIElementForModel( fw ) as LayoutFloatingWindowControl ); + #region DocumentPaneControlStyle - //create the overlaywindow if it's possible - if( IsVisible ) - CreateOverlayWindow(); - FocusElementManager.SetupFocusManagement( this ); + /// + /// DocumentPaneControlStyle Dependency Property + /// + public static readonly DependencyProperty DocumentPaneControlStyleProperty = DependencyProperty.Register( "DocumentPaneControlStyle", typeof( Style ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( Style )null, new PropertyChangedCallback( OnDocumentPaneControlStyleChanged ) ) ); + + /// + /// Gets or sets the DocumentPaneControlStyle property. This dependency property + /// indicates .... + /// + public Style DocumentPaneControlStyle + { + get + { + return ( Style )GetValue( DocumentPaneControlStyleProperty ); + } + set + { + SetValue( DocumentPaneControlStyleProperty, value ); } } - void DockingManager_Unloaded( object sender, RoutedEventArgs e ) + /// + /// Handles changes to the DocumentPaneControlStyle property. + /// + private static void OnDocumentPaneControlStyleChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) { + ( ( DockingManager )d ).OnDocumentPaneControlStyleChanged( e ); + } - if( !DesignerProperties.GetIsInDesignMode( this ) ) - { - if( _autoHideWindowManager != null ) - { - _autoHideWindowManager.HideAutoWindow(); - } - - if( AutoHideWindow != null ) - AutoHideWindow.Dispose(); - - foreach( var fw in _fwList.ToArray() ) - { - //fw.Owner = null; - fw.SetParentWindowToNull(); - fw.KeepContentVisibleOnClose = true; - fw.Close(); - } - - DestroyOverlayWindow(); - FocusElementManager.FinalizeFocusManagement( this ); - } - } - - internal UIElement CreateUIElementForModel( ILayoutElement model ) + /// + /// Provides derived classes an opportunity to handle changes to the DocumentPaneControlStyle property. + /// + protected virtual void OnDocumentPaneControlStyleChanged( DependencyPropertyChangedEventArgs e ) { - if( model is LayoutPanel ) - return new LayoutPanelControl( model as LayoutPanel ); - if( model is LayoutAnchorablePaneGroup ) - return new LayoutAnchorablePaneGroupControl( model as LayoutAnchorablePaneGroup ); - if( model is LayoutDocumentPaneGroup ) - return new LayoutDocumentPaneGroupControl( model as LayoutDocumentPaneGroup ); - - if( model is LayoutAnchorSide ) - { - var templateModelView = new LayoutAnchorSideControl( model as LayoutAnchorSide ); - templateModelView.SetBinding( LayoutAnchorSideControl.TemplateProperty, new Binding( "AnchorSideTemplate" ) { Source = this } ); - return templateModelView; - } - if( model is LayoutAnchorGroup ) - { - var templateModelView = new LayoutAnchorGroupControl( model as LayoutAnchorGroup ); - templateModelView.SetBinding( LayoutAnchorGroupControl.TemplateProperty, new Binding( "AnchorGroupTemplate" ) { Source = this } ); - return templateModelView; - } - - if( model is LayoutDocumentPane ) - { - var templateModelView = new LayoutDocumentPaneControl( model as LayoutDocumentPane ); - templateModelView.SetBinding( LayoutDocumentPaneControl.StyleProperty, new Binding( "DocumentPaneControlStyle" ) { Source = this } ); - return templateModelView; - } - if( model is LayoutAnchorablePane ) - { - var templateModelView = new LayoutAnchorablePaneControl( model as LayoutAnchorablePane ); - templateModelView.SetBinding( LayoutAnchorablePaneControl.StyleProperty, new Binding( "AnchorablePaneControlStyle" ) { Source = this } ); - return templateModelView; - } - - if( model is LayoutAnchorableFloatingWindow ) - { - if( DesignerProperties.GetIsInDesignMode( this ) ) - return null; - var modelFW = model as LayoutAnchorableFloatingWindow; - var newFW = new LayoutAnchorableFloatingWindowControl( modelFW ) - { - //Owner = Window.GetWindow(this) - }; - newFW.SetParentToMainWindowOf( this ); - - var paneForExtensions = modelFW.RootPanel.Children.OfType().FirstOrDefault(); - if( paneForExtensions != null ) - { - //ensure that floating window position is inside current (or nearest) monitor - paneForExtensions.KeepInsideNearestMonitor(); - - newFW.Left = paneForExtensions.FloatingLeft; - newFW.Top = paneForExtensions.FloatingTop; - newFW.Width = paneForExtensions.FloatingWidth; - newFW.Height = paneForExtensions.FloatingHeight; - } - - newFW.ShowInTaskbar = false; - newFW.Show(); - // Do not set the WindowState before showing or it will be lost - if( paneForExtensions != null && paneForExtensions.IsMaximized ) - { - newFW.WindowState = WindowState.Maximized; - } - return newFW; - } - - if( model is LayoutDocumentFloatingWindow ) - { - if( DesignerProperties.GetIsInDesignMode( this ) ) - return null; - var modelFW = model as LayoutDocumentFloatingWindow; - var newFW = new LayoutDocumentFloatingWindowControl( modelFW ) - { - //Owner = Window.GetWindow(this) - }; - newFW.SetParentToMainWindowOf( this ); - - var paneForExtensions = modelFW.RootDocument; - if( paneForExtensions != null ) - { - //ensure that floating window position is inside current (or nearest) monitor - paneForExtensions.KeepInsideNearestMonitor(); - - newFW.Left = paneForExtensions.FloatingLeft; - newFW.Top = paneForExtensions.FloatingTop; - newFW.Width = paneForExtensions.FloatingWidth; - newFW.Height = paneForExtensions.FloatingHeight; - } - - newFW.ShowInTaskbar = false; - newFW.Show(); - // Do not set the WindowState before showing or it will be lost - if( paneForExtensions != null && paneForExtensions.IsMaximized ) - { - newFW.WindowState = WindowState.Maximized; - } - return newFW; - } - - if( model is LayoutDocument ) - { - var templateModelView = new LayoutDocumentControl() { Model = model as LayoutDocument }; - return templateModelView; - } - - return null; } + #endregion - - #region DocumentPaneTemplate + #region AnchorablePaneControlStyle /// - /// DocumentPaneTemplate Dependency Property + /// AnchorablePaneControlStyle Dependency Property /// - public static readonly DependencyProperty DocumentPaneTemplateProperty = - DependencyProperty.Register( "DocumentPaneTemplate", typeof( ControlTemplate ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( ControlTemplate )null, - new PropertyChangedCallback( OnDocumentPaneTemplateChanged ) ) ); + public static readonly DependencyProperty AnchorablePaneControlStyleProperty = DependencyProperty.Register( "AnchorablePaneControlStyle", typeof( Style ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( Style )null, new PropertyChangedCallback( OnAnchorablePaneControlStyleChanged ) ) ); /// - /// Gets or sets the DocumentPaneDataTemplate property. This dependency property - /// indicates . + /// Gets or sets the AnchorablePaneControlStyle property. This dependency property + /// indicates the style to apply to AnchorablePaneControl. /// - public ControlTemplate DocumentPaneTemplate + public Style AnchorablePaneControlStyle { get { - return ( ControlTemplate )GetValue( DocumentPaneTemplateProperty ); + return ( Style )GetValue( AnchorablePaneControlStyleProperty ); } set { - SetValue( DocumentPaneTemplateProperty, value ); + SetValue( AnchorablePaneControlStyleProperty, value ); } } /// - /// Handles changes to the DocumentPaneTemplate property. + /// Handles changes to the AnchorablePaneControlStyle property. /// - private static void OnDocumentPaneTemplateChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + private static void OnAnchorablePaneControlStyleChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) { - ( ( DockingManager )d ).OnDocumentPaneTemplateChanged( e ); + ( ( DockingManager )d ).OnAnchorablePaneControlStyleChanged( e ); } /// - /// Provides derived classes an opportunity to handle changes to the DocumentPaneTemplate property. + /// Provides derived classes an opportunity to handle changes to the AnchorablePaneControlStyle property. /// - protected virtual void OnDocumentPaneTemplateChanged( DependencyPropertyChangedEventArgs e ) + protected virtual void OnAnchorablePaneControlStyleChanged( DependencyPropertyChangedEventArgs e ) { } #endregion - #region AnchorablePaneTemplate + #region DocumentHeaderTemplate /// - /// AnchorablePaneTemplate Dependency Property + /// DocumentHeaderTemplate Dependency Property /// - public static readonly DependencyProperty AnchorablePaneTemplateProperty = - DependencyProperty.Register( "AnchorablePaneTemplate", typeof( ControlTemplate ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( ControlTemplate )null, - new PropertyChangedCallback( OnAnchorablePaneTemplateChanged ) ) ); + public static readonly DependencyProperty DocumentHeaderTemplateProperty = DependencyProperty.Register( "DocumentHeaderTemplate", typeof( DataTemplate ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( DataTemplate )null, new PropertyChangedCallback( OnDocumentHeaderTemplateChanged ), new CoerceValueCallback( CoerceDocumentHeaderTemplateValue ) ) ); /// - /// Gets or sets the AnchorablePaneTemplate property. This dependency property - /// indicates .... + /// Gets or sets the DocumentHeaderTemplate property. This dependency property + /// indicates data template to use for document header. /// - public ControlTemplate AnchorablePaneTemplate + public DataTemplate DocumentHeaderTemplate { get { - return ( ControlTemplate )GetValue( AnchorablePaneTemplateProperty ); + return ( DataTemplate )GetValue( DocumentHeaderTemplateProperty ); } set { - SetValue( AnchorablePaneTemplateProperty, value ); + SetValue( DocumentHeaderTemplateProperty, value ); } } /// - /// Handles changes to the AnchorablePaneDataTemplate property. + /// Handles changes to the DocumentHeaderTemplate property. /// - private static void OnAnchorablePaneTemplateChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + private static void OnDocumentHeaderTemplateChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) { - ( ( DockingManager )d ).OnAnchorablePaneTemplateChanged( e ); + ( ( DockingManager )d ).OnDocumentHeaderTemplateChanged( e ); } /// - /// Provides derived classes an opportunity to handle changes to the AnchorablePaneDataTemplate property. + /// Provides derived classes an opportunity to handle changes to the DocumentHeaderTemplate property. /// - protected virtual void OnAnchorablePaneTemplateChanged( DependencyPropertyChangedEventArgs e ) + protected virtual void OnDocumentHeaderTemplateChanged( DependencyPropertyChangedEventArgs e ) + { + } + + /// + /// Coerces the DocumentHeaderTemplate value. + /// + private static object CoerceDocumentHeaderTemplateValue( DependencyObject d, object value ) { + if( value != null && + d.GetValue( DocumentHeaderTemplateSelectorProperty ) != null ) + return null; + return value; } #endregion - #region AnchorSideTemplate + #region DocumentHeaderTemplateSelector /// - /// AnchorSideTemplate Dependency Property + /// DocumentHeaderTemplateSelector Dependency Property /// - public static readonly DependencyProperty AnchorSideTemplateProperty = - DependencyProperty.Register( "AnchorSideTemplate", typeof( ControlTemplate ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( ControlTemplate )null ) ); + public static readonly DependencyProperty DocumentHeaderTemplateSelectorProperty = DependencyProperty.Register( "DocumentHeaderTemplateSelector", typeof( DataTemplateSelector ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( DataTemplateSelector )null, new PropertyChangedCallback( OnDocumentHeaderTemplateSelectorChanged ), new CoerceValueCallback( CoerceDocumentHeaderTemplateSelectorValue ) ) ); /// - /// Gets or sets the AnchorSideTemplate property. This dependency property - /// indicates .... + /// Gets or sets the DocumentHeaderTemplateSelector property. This dependency property + /// indicates the template selector that is used when selcting the data template for the header. /// - public ControlTemplate AnchorSideTemplate + public DataTemplateSelector DocumentHeaderTemplateSelector { get { - return ( ControlTemplate )GetValue( AnchorSideTemplateProperty ); + return ( DataTemplateSelector )GetValue( DocumentHeaderTemplateSelectorProperty ); } set { - SetValue( AnchorSideTemplateProperty, value ); + SetValue( DocumentHeaderTemplateSelectorProperty, value ); } } - #endregion - - #region AnchorGroupTemplate + /// + /// Handles changes to the DocumentHeaderTemplateSelector property. + /// + private static void OnDocumentHeaderTemplateSelectorChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( DockingManager )d ).OnDocumentHeaderTemplateSelectorChanged( e ); + } /// - /// AnchorGroupTemplate Dependency Property + /// Provides derived classes an opportunity to handle changes to the DocumentHeaderTemplateSelector property. /// - public static readonly DependencyProperty AnchorGroupTemplateProperty = - DependencyProperty.Register( "AnchorGroupTemplate", typeof( ControlTemplate ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( ControlTemplate )null ) ); + protected virtual void OnDocumentHeaderTemplateSelectorChanged( DependencyPropertyChangedEventArgs e ) + { + if( e.NewValue != null && + DocumentHeaderTemplate != null ) + DocumentHeaderTemplate = null; + + if( DocumentPaneMenuItemHeaderTemplateSelector == null ) + DocumentPaneMenuItemHeaderTemplateSelector = DocumentHeaderTemplateSelector; + + } /// - /// Gets or sets the AnchorGroupTemplate property. This dependency property - /// indicates the template used to render the AnchorGroup control. + /// Coerces the DocumentHeaderTemplateSelector value. /// - public ControlTemplate AnchorGroupTemplate + private static object CoerceDocumentHeaderTemplateSelectorValue( DependencyObject d, object value ) { - get - { - return ( ControlTemplate )GetValue( AnchorGroupTemplateProperty ); - } - set - { - SetValue( AnchorGroupTemplateProperty, value ); - } + return value; } #endregion - #region AnchorTemplate + #region DocumentTitleTemplate /// - /// AnchorTemplate Dependency Property + /// DocumentTitleTemplate Dependency Property /// - public static readonly DependencyProperty AnchorTemplateProperty = - DependencyProperty.Register( "AnchorTemplate", typeof( ControlTemplate ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( ControlTemplate )null ) ); + public static readonly DependencyProperty DocumentTitleTemplateProperty = DependencyProperty.Register( "DocumentTitleTemplate", typeof( DataTemplate ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( DataTemplate )null, new PropertyChangedCallback( OnDocumentTitleTemplateChanged ), new CoerceValueCallback( CoerceDocumentTitleTemplateValue ) ) ); /// - /// Gets or sets the AnchorTemplate property. This dependency property - /// indicates .... + /// Gets or sets the DocumentTitleTemplate property. This dependency property + /// indicates the datatemplate to use when creating the title for a document. /// - public ControlTemplate AnchorTemplate - { - get - { - return ( ControlTemplate )GetValue( AnchorTemplateProperty ); - } - set - { - SetValue( AnchorTemplateProperty, value ); - } - } - - #endregion - - #region DocumentPaneControlStyle - - /// - /// DocumentPaneControlStyle Dependency Property - /// - public static readonly DependencyProperty DocumentPaneControlStyleProperty = - DependencyProperty.Register( "DocumentPaneControlStyle", typeof( Style ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( Style )null, - new PropertyChangedCallback( OnDocumentPaneControlStyleChanged ) ) ); - - /// - /// Gets or sets the DocumentPaneControlStyle property. This dependency property - /// indicates .... - /// - public Style DocumentPaneControlStyle - { - get - { - return ( Style )GetValue( DocumentPaneControlStyleProperty ); - } - set - { - SetValue( DocumentPaneControlStyleProperty, value ); - } - } - - /// - /// Handles changes to the DocumentPaneControlStyle property. - /// - private static void OnDocumentPaneControlStyleChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) - { - ( ( DockingManager )d ).OnDocumentPaneControlStyleChanged( e ); - } - - /// - /// Provides derived classes an opportunity to handle changes to the DocumentPaneControlStyle property. - /// - protected virtual void OnDocumentPaneControlStyleChanged( DependencyPropertyChangedEventArgs e ) - { - } - - #endregion - - #region AnchorablePaneControlStyle - - /// - /// AnchorablePaneControlStyle Dependency Property - /// - public static readonly DependencyProperty AnchorablePaneControlStyleProperty = - DependencyProperty.Register( "AnchorablePaneControlStyle", typeof( Style ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( Style )null, - new PropertyChangedCallback( OnAnchorablePaneControlStyleChanged ) ) ); - - /// - /// Gets or sets the AnchorablePaneControlStyle property. This dependency property - /// indicates the style to apply to AnchorablePaneControl. - /// - public Style AnchorablePaneControlStyle - { - get - { - return ( Style )GetValue( AnchorablePaneControlStyleProperty ); - } - set - { - SetValue( AnchorablePaneControlStyleProperty, value ); - } - } - - /// - /// Handles changes to the AnchorablePaneControlStyle property. - /// - private static void OnAnchorablePaneControlStyleChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) - { - ( ( DockingManager )d ).OnAnchorablePaneControlStyleChanged( e ); - } - - /// - /// Provides derived classes an opportunity to handle changes to the AnchorablePaneControlStyle property. - /// - protected virtual void OnAnchorablePaneControlStyleChanged( DependencyPropertyChangedEventArgs e ) - { - } - - #endregion - - #region DocumentHeaderTemplate - - /// - /// DocumentHeaderTemplate Dependency Property - /// - public static readonly DependencyProperty DocumentHeaderTemplateProperty = - DependencyProperty.Register( "DocumentHeaderTemplate", typeof( DataTemplate ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( DataTemplate )null, - new PropertyChangedCallback( OnDocumentHeaderTemplateChanged ), - new CoerceValueCallback( CoerceDocumentHeaderTemplateValue ) ) ); - - /// - /// Gets or sets the DocumentHeaderTemplate property. This dependency property - /// indicates data template to use for document header. - /// - public DataTemplate DocumentHeaderTemplate - { - get - { - return ( DataTemplate )GetValue( DocumentHeaderTemplateProperty ); - } - set - { - SetValue( DocumentHeaderTemplateProperty, value ); - } - } - - /// - /// Handles changes to the DocumentHeaderTemplate property. - /// - private static void OnDocumentHeaderTemplateChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) - { - ( ( DockingManager )d ).OnDocumentHeaderTemplateChanged( e ); - } - - /// - /// Provides derived classes an opportunity to handle changes to the DocumentHeaderTemplate property. - /// - protected virtual void OnDocumentHeaderTemplateChanged( DependencyPropertyChangedEventArgs e ) - { - } - - /// - /// Coerces the DocumentHeaderTemplate value. - /// - private static object CoerceDocumentHeaderTemplateValue( DependencyObject d, object value ) - { - if( value != null && - d.GetValue( DocumentHeaderTemplateSelectorProperty ) != null ) - return null; - return value; - } - - #endregion - - #region DocumentHeaderTemplateSelector - - /// - /// DocumentHeaderTemplateSelector Dependency Property - /// - public static readonly DependencyProperty DocumentHeaderTemplateSelectorProperty = - DependencyProperty.Register( "DocumentHeaderTemplateSelector", typeof( DataTemplateSelector ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( DataTemplateSelector )null, - new PropertyChangedCallback( OnDocumentHeaderTemplateSelectorChanged ), - new CoerceValueCallback( CoerceDocumentHeaderTemplateSelectorValue ) ) ); - - /// - /// Gets or sets the DocumentHeaderTemplateSelector property. This dependency property - /// indicates the template selector that is used when selcting the data template for the header. - /// - public DataTemplateSelector DocumentHeaderTemplateSelector - { - get - { - return ( DataTemplateSelector )GetValue( DocumentHeaderTemplateSelectorProperty ); - } - set - { - SetValue( DocumentHeaderTemplateSelectorProperty, value ); - } - } - - /// - /// Handles changes to the DocumentHeaderTemplateSelector property. - /// - private static void OnDocumentHeaderTemplateSelectorChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) - { - ( ( DockingManager )d ).OnDocumentHeaderTemplateSelectorChanged( e ); - } - - /// - /// Provides derived classes an opportunity to handle changes to the DocumentHeaderTemplateSelector property. - /// - protected virtual void OnDocumentHeaderTemplateSelectorChanged( DependencyPropertyChangedEventArgs e ) - { - if( e.NewValue != null && - DocumentHeaderTemplate != null ) - DocumentHeaderTemplate = null; - - if( DocumentPaneMenuItemHeaderTemplateSelector == null ) - DocumentPaneMenuItemHeaderTemplateSelector = DocumentHeaderTemplateSelector; - - } - - /// - /// Coerces the DocumentHeaderTemplateSelector value. - /// - private static object CoerceDocumentHeaderTemplateSelectorValue( DependencyObject d, object value ) - { - return value; - } - - #endregion - - #region DocumentTitleTemplate - - /// - /// DocumentTitleTemplate Dependency Property - /// - public static readonly DependencyProperty DocumentTitleTemplateProperty = - DependencyProperty.Register( "DocumentTitleTemplate", typeof( DataTemplate ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( DataTemplate )null, - new PropertyChangedCallback( OnDocumentTitleTemplateChanged ), - new CoerceValueCallback( CoerceDocumentTitleTemplateValue ) ) ); - - /// - /// Gets or sets the DocumentTitleTemplate property. This dependency property - /// indicates the datatemplate to use when creating the title for a document. - /// - public DataTemplate DocumentTitleTemplate + public DataTemplate DocumentTitleTemplate { get { @@ -881,11 +637,8 @@ namespace Xceed.Wpf.AvalonDock /// /// DocumentTitleTemplateSelector Dependency Property /// - public static readonly DependencyProperty DocumentTitleTemplateSelectorProperty = - DependencyProperty.Register( "DocumentTitleTemplateSelector", typeof( DataTemplateSelector ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( DataTemplateSelector )null, - new PropertyChangedCallback( OnDocumentTitleTemplateSelectorChanged ), - new CoerceValueCallback( CoerceDocumentTitleTemplateSelectorValue ) ) ); + public static readonly DependencyProperty DocumentTitleTemplateSelectorProperty = DependencyProperty.Register( "DocumentTitleTemplateSelector", typeof( DataTemplateSelector ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( DataTemplateSelector )null, new PropertyChangedCallback( OnDocumentTitleTemplateSelectorChanged ), new CoerceValueCallback( CoerceDocumentTitleTemplateSelectorValue ) ) ); /// /// Gets or sets the DocumentTitleTemplateSelector property. This dependency property @@ -935,11 +688,8 @@ namespace Xceed.Wpf.AvalonDock /// /// AnchorableTitleTemplate Dependency Property /// - public static readonly DependencyProperty AnchorableTitleTemplateProperty = - DependencyProperty.Register( "AnchorableTitleTemplate", typeof( DataTemplate ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( DataTemplate )null, - new PropertyChangedCallback( OnAnchorableTitleTemplateChanged ), - new CoerceValueCallback( CoerceAnchorableTitleTemplateValue ) ) ); + public static readonly DependencyProperty AnchorableTitleTemplateProperty = DependencyProperty.Register( "AnchorableTitleTemplate", typeof( DataTemplate ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( DataTemplate )null, new PropertyChangedCallback( OnAnchorableTitleTemplateChanged ), new CoerceValueCallback( CoerceAnchorableTitleTemplateValue ) ) ); /// /// Gets or sets the AnchorableTitleTemplate property. This dependency property @@ -990,10 +740,8 @@ namespace Xceed.Wpf.AvalonDock /// /// AnchorableTitleTemplateSelector Dependency Property /// - public static readonly DependencyProperty AnchorableTitleTemplateSelectorProperty = - DependencyProperty.Register( "AnchorableTitleTemplateSelector", typeof( DataTemplateSelector ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( DataTemplateSelector )null, - new PropertyChangedCallback( OnAnchorableTitleTemplateSelectorChanged ) ) ); + public static readonly DependencyProperty AnchorableTitleTemplateSelectorProperty = DependencyProperty.Register( "AnchorableTitleTemplateSelector", typeof( DataTemplateSelector ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( DataTemplateSelector )null, new PropertyChangedCallback( OnAnchorableTitleTemplateSelectorChanged ) ) ); /// /// Gets or sets the AnchorableTitleTemplateSelector property. This dependency property @@ -1036,11 +784,8 @@ namespace Xceed.Wpf.AvalonDock /// /// AnchorableHeaderTemplate Dependency Property /// - public static readonly DependencyProperty AnchorableHeaderTemplateProperty = - DependencyProperty.Register( "AnchorableHeaderTemplate", typeof( DataTemplate ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( DataTemplate )null, - new PropertyChangedCallback( OnAnchorableHeaderTemplateChanged ), - new CoerceValueCallback( CoerceAnchorableHeaderTemplateValue ) ) ); + public static readonly DependencyProperty AnchorableHeaderTemplateProperty = DependencyProperty.Register( "AnchorableHeaderTemplate", typeof( DataTemplate ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( DataTemplate )null, new PropertyChangedCallback( OnAnchorableHeaderTemplateChanged ), new CoerceValueCallback( CoerceAnchorableHeaderTemplateValue ) ) ); /// /// Gets or sets the AnchorableHeaderTemplate property. This dependency property @@ -1092,10 +837,8 @@ namespace Xceed.Wpf.AvalonDock /// /// AnchorableHeaderTemplateSelector Dependency Property /// - public static readonly DependencyProperty AnchorableHeaderTemplateSelectorProperty = - DependencyProperty.Register( "AnchorableHeaderTemplateSelector", typeof( DataTemplateSelector ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( DataTemplateSelector )null, - new PropertyChangedCallback( OnAnchorableHeaderTemplateSelectorChanged ) ) ); + public static readonly DependencyProperty AnchorableHeaderTemplateSelectorProperty = DependencyProperty.Register( "AnchorableHeaderTemplateSelector", typeof( DataTemplateSelector ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( DataTemplateSelector )null, new PropertyChangedCallback( OnAnchorableHeaderTemplateSelectorChanged ) ) ); /// /// Gets or sets the AnchorableHeaderTemplateSelector property. This dependency property @@ -1137,10 +880,8 @@ namespace Xceed.Wpf.AvalonDock /// /// LayoutRootPanel Dependency Property /// - public static readonly DependencyProperty LayoutRootPanelProperty = - DependencyProperty.Register( "LayoutRootPanel", typeof( LayoutPanelControl ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( LayoutPanelControl )null, - new PropertyChangedCallback( OnLayoutRootPanelChanged ) ) ); + public static readonly DependencyProperty LayoutRootPanelProperty = DependencyProperty.Register( "LayoutRootPanel", typeof( LayoutPanelControl ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( LayoutPanelControl )null, new PropertyChangedCallback( OnLayoutRootPanelChanged ) ) ); /// /// Gets or sets the LayoutRootPanel property. This dependency property @@ -1184,10 +925,8 @@ namespace Xceed.Wpf.AvalonDock /// /// RightSidePanel Dependency Property /// - public static readonly DependencyProperty RightSidePanelProperty = - DependencyProperty.Register( "RightSidePanel", typeof( LayoutAnchorSideControl ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( LayoutAnchorSideControl )null, - new PropertyChangedCallback( OnRightSidePanelChanged ) ) ); + public static readonly DependencyProperty RightSidePanelProperty = DependencyProperty.Register( "RightSidePanel", typeof( LayoutAnchorSideControl ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( LayoutAnchorSideControl )null, new PropertyChangedCallback( OnRightSidePanelChanged ) ) ); /// /// Gets or sets the RightSidePanel property. This dependency property @@ -1231,10 +970,8 @@ namespace Xceed.Wpf.AvalonDock /// /// LeftSidePanel Dependency Property /// - public static readonly DependencyProperty LeftSidePanelProperty = - DependencyProperty.Register( "LeftSidePanel", typeof( LayoutAnchorSideControl ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( LayoutAnchorSideControl )null, - new PropertyChangedCallback( OnLeftSidePanelChanged ) ) ); + public static readonly DependencyProperty LeftSidePanelProperty = DependencyProperty.Register( "LeftSidePanel", typeof( LayoutAnchorSideControl ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( LayoutAnchorSideControl )null, new PropertyChangedCallback( OnLeftSidePanelChanged ) ) ); /// /// Gets or sets the LeftSidePanel property. This dependency property @@ -1278,10 +1015,8 @@ namespace Xceed.Wpf.AvalonDock /// /// TopSidePanel Dependency Property /// - public static readonly DependencyProperty TopSidePanelProperty = - DependencyProperty.Register( "TopSidePanel", typeof( LayoutAnchorSideControl ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( LayoutAnchorSideControl )null, - new PropertyChangedCallback( OnTopSidePanelChanged ) ) ); + public static readonly DependencyProperty TopSidePanelProperty = DependencyProperty.Register( "TopSidePanel", typeof( LayoutAnchorSideControl ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( LayoutAnchorSideControl )null, new PropertyChangedCallback( OnTopSidePanelChanged ) ) ); /// /// Gets or sets the TopSidePanel property. This dependency property @@ -1325,10 +1060,8 @@ namespace Xceed.Wpf.AvalonDock /// /// BottomSidePanel Dependency Property /// - public static readonly DependencyProperty BottomSidePanelProperty = - DependencyProperty.Register( "BottomSidePanel", typeof( LayoutAnchorSideControl ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( LayoutAnchorSideControl )null, - new PropertyChangedCallback( OnBottomSidePanelChanged ) ) ); + public static readonly DependencyProperty BottomSidePanelProperty = DependencyProperty.Register( "BottomSidePanel", typeof( LayoutAnchorSideControl ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( LayoutAnchorSideControl )null, new PropertyChangedCallback( OnBottomSidePanelChanged ) ) ); /// /// Gets or sets the BottomSidePanel property. This dependency property @@ -1409,7 +1142,7 @@ namespace Xceed.Wpf.AvalonDock RemoveLogicalChild( element ); } - void ClearLogicalChildrenList() + private void ClearLogicalChildrenList() { foreach( var child in _logicalChildren.Select( ch => ch.GetValueOrDefault() ).ToArray() ) RemoveLogicalChild( child ); @@ -1418,65 +1151,15 @@ namespace Xceed.Wpf.AvalonDock #endregion - #region AutoHide window - internal void ShowAutoHideWindow( LayoutAnchorControl anchor ) - { - _autoHideWindowManager.ShowAutoHideWindow( anchor ); - //if (_autohideArea == null) - // return; - - //if (AutoHideWindow != null && AutoHideWindow.Model == anchor.Model) - // return; - - //Trace.WriteLine("ShowAutoHideWindow()"); - - //_currentAutohiddenAnchor = new WeakReference(anchor); - - //HideAutoHideWindow(anchor); - - //SetAutoHideWindow(new LayoutAutoHideWindowControl(anchor)); - //AutoHideWindow.Show(); - } - - internal void HideAutoHideWindow( LayoutAnchorControl anchor ) - { - _autoHideWindowManager.HideAutoWindow( anchor ); - } - - - void SetupAutoHideWindow() - { - if( _autoHideWindowManager != null ) - _autoHideWindowManager.HideAutoWindow(); - else - _autoHideWindowManager = new AutoHideWindowManager( this ); - - if( AutoHideWindow != null ) - AutoHideWindow.Dispose(); - - SetAutoHideWindow( new LayoutAutoHideWindowControl() ); - } - - AutoHideWindowManager _autoHideWindowManager; - - FrameworkElement _autohideArea; - internal FrameworkElement GetAutoHideAreaElement() - { - return _autohideArea; - } - #region AutoHideWindow /// /// AutoHideWindow Read-Only Dependency Property /// - private static readonly DependencyPropertyKey AutoHideWindowPropertyKey - = DependencyProperty.RegisterReadOnly( "AutoHideWindow", typeof( LayoutAutoHideWindowControl ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( LayoutAutoHideWindowControl )null, - new PropertyChangedCallback( OnAutoHideWindowChanged ) ) ); + private static readonly DependencyPropertyKey AutoHideWindowPropertyKey = DependencyProperty.RegisterReadOnly( "AutoHideWindow", typeof( LayoutAutoHideWindowControl ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( LayoutAutoHideWindowControl )null, new PropertyChangedCallback( OnAutoHideWindowChanged ) ) ); - public static readonly DependencyProperty AutoHideWindowProperty - = AutoHideWindowPropertyKey.DependencyProperty; + public static readonly DependencyProperty AutoHideWindowProperty = AutoHideWindowPropertyKey.DependencyProperty; /// /// Gets the AutoHideWindow property. This dependency property @@ -1522,1640 +1205,1853 @@ namespace Xceed.Wpf.AvalonDock #endregion - - - #endregion - // #region AutoHide window - //WeakReference _currentAutohiddenAnchor = null; - //internal void ShowAutoHideWindow(LayoutAnchorControl anchor) - //{ - // if (_autohideArea == null) - // return; - - // if (AutoHideWindow != null && AutoHideWindow.Model == anchor.Model) - // return; - - // Trace.WriteLine("ShowAutoHideWindow()"); - - // _currentAutohiddenAnchor = new WeakReference(anchor); - - // HideAutoHideWindow(anchor); - - // SetAutoHideWindow(new LayoutAutoHideWindowControl(anchor)); - //} - - //internal void HideAutoHideWindow(LayoutAnchorControl anchor) - //{ - // if (AutoHideWindow != null) - // { - // if (anchor == _currentAutohiddenAnchor.GetValueOrDefault()) - // { - // Trace.WriteLine("AutoHideWindow()"); - // AutoHideWindow.Dispose(); - // SetAutoHideWindow(null); - // } - // } - //} - - //FrameworkElement _autohideArea; - //internal FrameworkElement GetAutoHideAreaElement() - //{ - // return _autohideArea; - //} - - //void SetupAutoHideArea() - //{ - // _autohideArea = GetTemplateChild("PART_AutoHideArea") as FrameworkElement; - //} - - // #region AutoHideWindow - - ///// - ///// AutoHideWindow Read-Only Dependency Property - ///// - //private static readonly DependencyPropertyKey AutoHideWindowPropertyKey - // = DependencyProperty.RegisterReadOnly("AutoHideWindow", typeof(LayoutAutoHideWindowControl), typeof(DockingManager), - // new FrameworkPropertyMetadata((LayoutAutoHideWindowControl)null, - // new PropertyChangedCallback(OnAutoHideWindowChanged))); - - //public static readonly DependencyProperty AutoHideWindowProperty - // = AutoHideWindowPropertyKey.DependencyProperty; - - ///// - ///// Gets the AutoHideWindow property. This dependency property - ///// indicates the currently shown autohide window. - ///// - //public LayoutAutoHideWindowControl AutoHideWindow - //{ - // get { return (LayoutAutoHideWindowControl)GetValue(AutoHideWindowProperty); } - //} - - ///// - ///// Provides a secure method for setting the AutoHideWindow property. - ///// This dependency property indicates the currently shown autohide window. - ///// - ///// The new value for the property. - //protected void SetAutoHideWindow(LayoutAutoHideWindowControl value) - //{ - // SetValue(AutoHideWindowPropertyKey, value); - //} - - ///// - ///// Handles changes to the AutoHideWindow property. - ///// - //private static void OnAutoHideWindowChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - //{ - // ((DockingManager)d).OnAutoHideWindowChanged(e); - //} - - ///// - ///// Provides derived classes an opportunity to handle changes to the AutoHideWindow property. - ///// - //protected virtual void OnAutoHideWindowChanged(DependencyPropertyChangedEventArgs e) - //{ - // if (e.OldValue != null) - // ((ILogicalChildrenContainer)this).InternalRemoveLogicalChild(e.OldValue); - // if (e.NewValue != null) - // ((ILogicalChildrenContainer)this).InternalAddLogicalChild(e.NewValue); - //} - - // #endregion - - - - // #endregion - #region Floating Windows - List _fwList = new List(); - internal void StartDraggingFloatingWindowForContent( LayoutContent contentModel, bool startDrag = true ) + public IEnumerable FloatingWindows { - if( !contentModel.CanFloat ) - return; - var contentModelAsAnchorable = contentModel as LayoutAnchorable; - if( contentModelAsAnchorable != null && - contentModelAsAnchorable.IsAutoHidden ) - contentModelAsAnchorable.ToggleAutoHide(); - - var parentPane = contentModel.Parent as ILayoutPane; - var parentPaneAsPositionableElement = contentModel.Parent as ILayoutPositionableElement; - var parentPaneAsWithActualSize = contentModel.Parent as ILayoutPositionableElementWithActualSize; - var contentModelParentChildrenIndex = parentPane.Children.ToList().IndexOf( contentModel ); - - if( contentModel.FindParent() == null ) + get { - ( ( ILayoutPreviousContainer )contentModel ).PreviousContainer = parentPane; - contentModel.PreviousContainerIndex = contentModelParentChildrenIndex; + return _fwList; } + } - parentPane.RemoveChildAt( contentModelParentChildrenIndex ); - - double fwWidth = contentModel.FloatingWidth; - double fwHeight = contentModel.FloatingHeight; + #endregion - if( fwWidth == 0.0 ) - fwWidth = parentPaneAsPositionableElement.FloatingWidth; - if( fwHeight == 0.0 ) - fwHeight = parentPaneAsPositionableElement.FloatingHeight; + #region LayoutItemTemplate - if( fwWidth == 0.0 ) - fwWidth = parentPaneAsWithActualSize.ActualWidth + 10; //10 includes BorderThickness and Margins inside LayoutDocumentFloatingWindowControl. - if( fwHeight == 0.0 ) - fwHeight = parentPaneAsWithActualSize.ActualHeight + 10; //10 includes BorderThickness and Margins inside LayoutDocumentFloatingWindowControl. + /// + /// LayoutItemTemplate Dependency Property + /// + public static readonly DependencyProperty LayoutItemTemplateProperty = DependencyProperty.Register( "LayoutItemTemplate", typeof( DataTemplate ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( DataTemplate )null, new PropertyChangedCallback( OnLayoutItemTemplateChanged ) ) ); - LayoutFloatingWindow fw; - LayoutFloatingWindowControl fwc; - if( contentModel is LayoutAnchorable ) + /// + /// Gets or sets the AnchorableTemplate property. This dependency property + /// indicates the template to use to render anchorable and document contents. + /// + public DataTemplate LayoutItemTemplate + { + get { - var anchorableContent = contentModel as LayoutAnchorable; - fw = new LayoutAnchorableFloatingWindow() - { - RootPanel = new LayoutAnchorablePaneGroup( - new LayoutAnchorablePane( anchorableContent ) - { - DockWidth = parentPaneAsPositionableElement.DockWidth, - DockHeight = parentPaneAsPositionableElement.DockHeight, - DockMinHeight = parentPaneAsPositionableElement.DockMinHeight, - DockMinWidth = parentPaneAsPositionableElement.DockMinWidth, - FloatingLeft = parentPaneAsPositionableElement.FloatingLeft, - FloatingTop = parentPaneAsPositionableElement.FloatingTop, - FloatingWidth = parentPaneAsPositionableElement.FloatingWidth, - FloatingHeight = parentPaneAsPositionableElement.FloatingHeight, - } ) - }; - - Layout.FloatingWindows.Add( fw ); - - fwc = new LayoutAnchorableFloatingWindowControl( - fw as LayoutAnchorableFloatingWindow ) - { - Width = fwWidth, - Height = fwHeight, - Left = contentModel.FloatingLeft, - Top = contentModel.FloatingTop - }; + return ( DataTemplate )GetValue( LayoutItemTemplateProperty ); } - else + set { - var anchorableDocument = contentModel as LayoutDocument; - fw = new LayoutDocumentFloatingWindow() - { - RootDocument = anchorableDocument - }; - - Layout.FloatingWindows.Add( fw ); - - fwc = new LayoutDocumentFloatingWindowControl( - fw as LayoutDocumentFloatingWindow ) - { - Width = fwWidth, - Height = fwHeight, - Left = contentModel.FloatingLeft, - Top = contentModel.FloatingTop - }; + SetValue( LayoutItemTemplateProperty, value ); } + } + /// + /// Handles changes to the AnchorableTemplate property. + /// + private static void OnLayoutItemTemplateChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( DockingManager )d ).OnLayoutItemTemplateChanged( e ); + } - //fwc.Owner = Window.GetWindow(this); - //fwc.SetParentToMainWindowOf(this); + /// + /// Provides derived classes an opportunity to handle changes to the AnchorableTemplate property. + /// + protected virtual void OnLayoutItemTemplateChanged( DependencyPropertyChangedEventArgs e ) + { + } + #endregion - _fwList.Add( fwc ); + #region LayoutItemTemplateSelector - Layout.CollectGarbage(); + /// + /// LayoutItemTemplateSelector Dependency Property + /// + public static readonly DependencyProperty LayoutItemTemplateSelectorProperty = DependencyProperty.Register( "LayoutItemTemplateSelector", typeof( DataTemplateSelector ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( DataTemplateSelector )null, new PropertyChangedCallback( OnLayoutItemTemplateSelectorChanged ) ) ); - UpdateLayout(); + /// + /// Gets or sets the LayoutItemTemplateSelector property. This dependency property + /// indicates selector object to use for anchorable templates. + /// + public DataTemplateSelector LayoutItemTemplateSelector + { + get + { + return ( DataTemplateSelector )GetValue( LayoutItemTemplateSelectorProperty ); + } + set + { + SetValue( LayoutItemTemplateSelectorProperty, value ); + } + } - Dispatcher.BeginInvoke( new Action( () => - { - if( startDrag ) - fwc.AttachDrag(); - fwc.Show(); - } ), DispatcherPriority.Send ); + /// + /// Handles changes to the LayoutItemTemplateSelector property. + /// + private static void OnLayoutItemTemplateSelectorChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( DockingManager )d ).OnLayoutItemTemplateSelectorChanged( e ); } - internal void StartDraggingFloatingWindowForPane( LayoutAnchorablePane paneModel ) + /// + /// Provides derived classes an opportunity to handle changes to the LayoutItemTemplateSelector property. + /// + protected virtual void OnLayoutItemTemplateSelectorChanged( DependencyPropertyChangedEventArgs e ) { - if( paneModel.Children.Any( c => !c.CanFloat ) ) - return; - var paneAsPositionableElement = paneModel as ILayoutPositionableElement; - var paneAsWithActualSize = paneModel as ILayoutPositionableElementWithActualSize; + } - double fwWidth = paneAsPositionableElement.FloatingWidth; - double fwHeight = paneAsPositionableElement.FloatingHeight; - double fwLeft = paneAsPositionableElement.FloatingLeft; - double fwTop = paneAsPositionableElement.FloatingTop; + #endregion - if( fwWidth == 0.0 ) - fwWidth = paneAsWithActualSize.ActualWidth + 10; //10 includes BorderThickness and Margins inside LayoutAnchorableFloatingWindowControl. - if( fwHeight == 0.0 ) - fwHeight = paneAsWithActualSize.ActualHeight + 10; //10 includes BorderThickness and Margins inside LayoutAnchorableFloatingWindowControl. + #region DocumentsSource - var destPane = new LayoutAnchorablePane() - { - DockWidth = paneAsPositionableElement.DockWidth, - DockHeight = paneAsPositionableElement.DockHeight, - DockMinHeight = paneAsPositionableElement.DockMinHeight, - DockMinWidth = paneAsPositionableElement.DockMinWidth, - FloatingLeft = paneAsPositionableElement.FloatingLeft, - FloatingTop = paneAsPositionableElement.FloatingTop, - FloatingWidth = paneAsPositionableElement.FloatingWidth, - FloatingHeight = paneAsPositionableElement.FloatingHeight, - }; + /// + /// DocumentsSource Dependency Property + /// + public static readonly DependencyProperty DocumentsSourceProperty = DependencyProperty.Register( "DocumentsSource", typeof( IEnumerable ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( IEnumerable )null, new PropertyChangedCallback( OnDocumentsSourceChanged ) ) ); - bool savePreviousContainer = paneModel.FindParent() == null; - int currentSelectedContentIndex = paneModel.SelectedContentIndex; - while( paneModel.Children.Count > 0 ) + /// + /// Gets or sets the DocumentsSource property. This dependency property + /// indicates the source collection of documents. + /// + public IEnumerable DocumentsSource + { + get { - var contentModel = paneModel.Children[ paneModel.Children.Count - 1 ] as LayoutAnchorable; - - if( savePreviousContainer ) - { - var contentModelAsPreviousContainer = contentModel as ILayoutPreviousContainer; - contentModelAsPreviousContainer.PreviousContainer = paneModel; - contentModel.PreviousContainerIndex = paneModel.Children.Count - 1; - } - - paneModel.RemoveChildAt( paneModel.Children.Count - 1 ); - destPane.Children.Insert( 0, contentModel ); + return ( IEnumerable )GetValue( DocumentsSourceProperty ); } - - if( destPane.Children.Count > 0 ) + set { - destPane.SelectedContentIndex = currentSelectedContentIndex; + SetValue( DocumentsSourceProperty, value ); } + } + /// + /// Handles changes to the DocumentsSource property. + /// + private static void OnDocumentsSourceChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( DockingManager )d ).OnDocumentsSourceChanged( e ); + } - LayoutFloatingWindow fw; - LayoutFloatingWindowControl fwc; - fw = new LayoutAnchorableFloatingWindow() - { - RootPanel = new LayoutAnchorablePaneGroup( - destPane ) - { - DockHeight = destPane.DockHeight, - DockWidth = destPane.DockWidth, - DockMinHeight = destPane.DockMinHeight, - DockMinWidth = destPane.DockMinWidth, - } - }; + /// + /// Provides derived classes an opportunity to handle changes to the DocumentsSource property. + /// + protected virtual void OnDocumentsSourceChanged( DependencyPropertyChangedEventArgs e ) + { + DetachDocumentsSource( Layout, e.OldValue as IEnumerable ); + AttachDocumentsSource( Layout, e.NewValue as IEnumerable ); + } - Layout.FloatingWindows.Add( fw ); + #endregion - fwc = new LayoutAnchorableFloatingWindowControl( - fw as LayoutAnchorableFloatingWindow ) - { - Width = fwWidth, - Height = fwHeight - }; + #region DocumentContextMenu + /// + /// DocumentContextMenu Dependency Property + /// + public static readonly DependencyProperty DocumentContextMenuProperty = DependencyProperty.Register( "DocumentContextMenu", typeof( ContextMenu ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( ContextMenu )null ) ); + /// + /// Gets or sets the DocumentContextMenu property. This dependency property + /// indicates context menu to show for documents. + /// + public ContextMenu DocumentContextMenu + { + get + { + return ( ContextMenu )GetValue( DocumentContextMenuProperty ); + } + set + { + SetValue( DocumentContextMenuProperty, value ); + } + } - //fwc.Owner = Window.GetWindow(this); - //fwc.SetParentToMainWindowOf(this); - - - _fwList.Add( fwc ); - - Layout.CollectGarbage(); - - InvalidateArrange(); - - fwc.AttachDrag(); - fwc.Show(); - - } - - internal IEnumerable GetFloatingWindowsByZOrder() - { - var parentWindow = Window.GetWindow( this ); - - if( parentWindow == null ) - yield break; - - IntPtr windowParentHanlde = new WindowInteropHelper( parentWindow ).Handle; - - IntPtr currentHandle = Win32Helper.GetWindow( windowParentHanlde, ( uint )Win32Helper.GetWindow_Cmd.GW_HWNDFIRST ); - while( currentHandle != IntPtr.Zero ) - { - LayoutFloatingWindowControl ctrl = _fwList.FirstOrDefault( fw => new WindowInteropHelper( fw ).Handle == currentHandle ); - if( ctrl != null && ctrl.Model.Root.Manager == this ) - yield return ctrl; - - currentHandle = Win32Helper.GetWindow( currentHandle, ( uint )Win32Helper.GetWindow_Cmd.GW_HWNDNEXT ); - } - } - - internal void RemoveFloatingWindow( LayoutFloatingWindowControl floatingWindow ) - { - _fwList.Remove( floatingWindow ); - } - - public IEnumerable FloatingWindows - { - get - { - return _fwList; - } - } #endregion - #region OverlayWindow + #region AnchorablesSource - bool IOverlayWindowHost.HitTest( Point dragPoint ) - { - Rect detectionRect = new Rect( this.PointToScreenDPIWithoutFlowDirection( new Point() ), this.TransformActualSizeToAncestor() ); - return detectionRect.Contains( dragPoint ); - } + /// + /// AnchorablesSource Dependency Property + /// + public static readonly DependencyProperty AnchorablesSourceProperty = DependencyProperty.Register( "AnchorablesSource", typeof( IEnumerable ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( IEnumerable )null, new PropertyChangedCallback( OnAnchorablesSourceChanged ) ) ); - DockingManager IOverlayWindowHost.Manager + /// + /// Gets or sets the AnchorablesSource property. This dependency property + /// indicates source collection of anchorables. + /// + public IEnumerable AnchorablesSource { get { - return this; - } - } - - OverlayWindow _overlayWindow = null; - void CreateOverlayWindow() - { - if( _overlayWindow == null ) - { - _overlayWindow = new OverlayWindow( this ); + return ( IEnumerable )GetValue( AnchorablesSourceProperty ); } - Rect rectWindow = new Rect( this.PointToScreenDPIWithoutFlowDirection( new Point() ), this.TransformActualSizeToAncestor() ); - _overlayWindow.Left = rectWindow.Left; - _overlayWindow.Top = rectWindow.Top; - _overlayWindow.Width = rectWindow.Width; - _overlayWindow.Height = rectWindow.Height; - } - - void DestroyOverlayWindow() - { - if( _overlayWindow != null ) + set { - _overlayWindow.Close(); - _overlayWindow = null; + SetValue( AnchorablesSourceProperty, value ); } } - IOverlayWindow IOverlayWindowHost.ShowOverlayWindow( LayoutFloatingWindowControl draggingWindow ) + /// + /// Handles changes to the AnchorablesSource property. + /// + private static void OnAnchorablesSourceChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) { - CreateOverlayWindow(); - _overlayWindow.Owner = draggingWindow; - _overlayWindow.EnableDropTargets(); - _overlayWindow.Show(); - return _overlayWindow; + ( ( DockingManager )d ).OnAnchorablesSourceChanged( e ); } - void IOverlayWindowHost.HideOverlayWindow() + /// + /// Provides derived classes an opportunity to handle changes to the AnchorablesSource property. + /// + protected virtual void OnAnchorablesSourceChanged( DependencyPropertyChangedEventArgs e ) { - _areas = null; - _overlayWindow.Owner = null; - _overlayWindow.HideDropTargets(); + DetachAnchorablesSource( Layout, e.OldValue as IEnumerable ); + AttachAnchorablesSource( Layout, e.NewValue as IEnumerable ); } - List _areas = null; - - IEnumerable IOverlayWindowHost.GetDropAreas( LayoutFloatingWindowControl draggingWindow ) - { - if( _areas != null ) - return _areas; - - bool isDraggingDocuments = draggingWindow.Model is LayoutDocumentFloatingWindow; - - _areas = new List(); - - if( !isDraggingDocuments ) - { - _areas.Add( new DropArea( - this, - DropAreaType.DockingManager ) ); - - foreach( var areaHost in this.FindVisualChildren() ) - { - if( areaHost.Model.Descendents().Any() ) - { - _areas.Add( new DropArea( - areaHost, - DropAreaType.AnchorablePane ) ); - } - } - } - - foreach( var areaHost in this.FindVisualChildren() ) - { - _areas.Add( new DropArea( - areaHost, - DropAreaType.DocumentPane ) ); - } - - foreach( var areaHost in this.FindVisualChildren() ) - { - var documentGroupModel = areaHost.Model as LayoutDocumentPaneGroup; - if( documentGroupModel.Children.Where( c => c.IsVisible ).Count() == 0 ) - { - _areas.Add( new DropArea( - areaHost, - DropAreaType.DocumentPaneGroup ) ); - } - } - - return _areas; - } - protected override Size ArrangeOverride( Size arrangeBounds ) - { - _areas = null; - return base.ArrangeOverride( arrangeBounds ); - } #endregion - #region LayoutDocument & LayoutAnchorable Templates - - #region LayoutItemTemplate + #region ActiveContent /// - /// LayoutItemTemplate Dependency Property + /// ActiveContent Dependency Property /// - public static readonly DependencyProperty LayoutItemTemplateProperty = - DependencyProperty.Register( "LayoutItemTemplate", typeof( DataTemplate ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( DataTemplate )null, - new PropertyChangedCallback( OnLayoutItemTemplateChanged ) ) ); + public static readonly DependencyProperty ActiveContentProperty = DependencyProperty.Register( "ActiveContent", typeof( object ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( object )null, new PropertyChangedCallback( OnActiveContentChanged ) ) ); /// - /// Gets or sets the AnchorableTemplate property. This dependency property - /// indicates the template to use to render anchorable and document contents. + /// Gets or sets the ActiveContent property. This dependency property + /// indicates the content currently active. /// - public DataTemplate LayoutItemTemplate + public object ActiveContent { get { - return ( DataTemplate )GetValue( LayoutItemTemplateProperty ); + return ( object )GetValue( ActiveContentProperty ); } set { - SetValue( LayoutItemTemplateProperty, value ); + SetValue( ActiveContentProperty, value ); } } /// - /// Handles changes to the AnchorableTemplate property. + /// Handles changes to the ActiveContent property. /// - private static void OnLayoutItemTemplateChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + private static void OnActiveContentChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) { - ( ( DockingManager )d ).OnLayoutItemTemplateChanged( e ); + ( ( DockingManager )d ).InternalSetActiveContent( e.NewValue ); + ( ( DockingManager )d ).OnActiveContentChanged( e ); } /// - /// Provides derived classes an opportunity to handle changes to the AnchorableTemplate property. + /// Provides derived classes an opportunity to handle changes to the ActiveContent property. /// - protected virtual void OnLayoutItemTemplateChanged( DependencyPropertyChangedEventArgs e ) + protected virtual void OnActiveContentChanged( DependencyPropertyChangedEventArgs e ) { + if( ActiveContentChanged != null ) + ActiveContentChanged( this, EventArgs.Empty ); } #endregion - #region LayoutItemTemplateSelector + #region AnchorableContextMenu /// - /// LayoutItemTemplateSelector Dependency Property + /// AnchorableContextMenu Dependency Property /// - public static readonly DependencyProperty LayoutItemTemplateSelectorProperty = - DependencyProperty.Register( "LayoutItemTemplateSelector", typeof( DataTemplateSelector ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( DataTemplateSelector )null, - new PropertyChangedCallback( OnLayoutItemTemplateSelectorChanged ) ) ); + public static readonly DependencyProperty AnchorableContextMenuProperty = DependencyProperty.Register( "AnchorableContextMenu", typeof( ContextMenu ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( ContextMenu )null ) ); /// - /// Gets or sets the LayoutItemTemplateSelector property. This dependency property - /// indicates selector object to use for anchorable templates. + /// Gets or sets the AnchorableContextMenu property. This dependency property + /// indicates the context menu to show up for anchorables. /// - public DataTemplateSelector LayoutItemTemplateSelector + public ContextMenu AnchorableContextMenu { get { - return ( DataTemplateSelector )GetValue( LayoutItemTemplateSelectorProperty ); + return ( ContextMenu )GetValue( AnchorableContextMenuProperty ); } set { - SetValue( LayoutItemTemplateSelectorProperty, value ); + SetValue( AnchorableContextMenuProperty, value ); } } - /// - /// Handles changes to the LayoutItemTemplateSelector property. - /// - private static void OnLayoutItemTemplateSelectorChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) - { - ( ( DockingManager )d ).OnLayoutItemTemplateSelectorChanged( e ); - } - - /// - /// Provides derived classes an opportunity to handle changes to the LayoutItemTemplateSelector property. - /// - protected virtual void OnLayoutItemTemplateSelectorChanged( DependencyPropertyChangedEventArgs e ) - { - } - - #endregion - - #endregion - #region DocumentsSource + #region Theme /// - /// DocumentsSource Dependency Property + /// Theme Dependency Property /// - public static readonly DependencyProperty DocumentsSourceProperty = - DependencyProperty.Register( "DocumentsSource", typeof( IEnumerable ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( IEnumerable )null, - new PropertyChangedCallback( OnDocumentsSourceChanged ) ) ); + public static readonly DependencyProperty ThemeProperty = DependencyProperty.Register( "Theme", typeof( Theme ), typeof( DockingManager ), + new FrameworkPropertyMetadata( null, new PropertyChangedCallback( OnThemeChanged ) ) ); /// - /// Gets or sets the DocumentsSource property. This dependency property - /// indicates the source collection of documents. + /// Gets or sets the Theme property. This dependency property + /// indicates the theme to use for AvalonDock controls. /// - public IEnumerable DocumentsSource + public Theme Theme { get { - return ( IEnumerable )GetValue( DocumentsSourceProperty ); + return ( Theme )GetValue( ThemeProperty ); } set { - SetValue( DocumentsSourceProperty, value ); + SetValue( ThemeProperty, value ); } } /// - /// Handles changes to the DocumentsSource property. + /// Handles changes to the Theme property. /// - private static void OnDocumentsSourceChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + private static void OnThemeChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) { - ( ( DockingManager )d ).OnDocumentsSourceChanged( e ); + ( ( DockingManager )d ).OnThemeChanged( e ); } /// - /// Provides derived classes an opportunity to handle changes to the DocumentsSource property. + /// Provides derived classes an opportunity to handle changes to the Theme property. /// - protected virtual void OnDocumentsSourceChanged( DependencyPropertyChangedEventArgs e ) - { - DetachDocumentsSource( Layout, e.OldValue as IEnumerable ); - AttachDocumentsSource( Layout, e.NewValue as IEnumerable ); - } - - - void AttachDocumentsSource( LayoutRoot layout, IEnumerable documentsSource ) + protected virtual void OnThemeChanged( DependencyPropertyChangedEventArgs e ) { - if( documentsSource == null ) - return; - - if( layout == null ) - return; - - //if (layout.Descendents().OfType().Any()) - // throw new InvalidOperationException("Unable to set the DocumentsSource property if LayoutDocument objects are already present in the model"); - var documentsImported = layout.Descendents().OfType().Select( d => d.Content ).ToArray(); - var documents = documentsSource as IEnumerable; - var listOfDocumentsToImport = new List( documents.OfType() ); - - foreach( var document in listOfDocumentsToImport.ToArray() ) - { - if( documentsImported.Contains( document ) ) - listOfDocumentsToImport.Remove( document ); - } - - - LayoutDocumentPane documentPane = null; - if( layout.LastFocusedDocument != null ) - { - documentPane = layout.LastFocusedDocument.Parent as LayoutDocumentPane; - } - - if( documentPane == null ) - { - documentPane = layout.Descendents().OfType().FirstOrDefault(); - } - - //if (documentPane == null) - // throw new InvalidOperationException("Layout must contains at least one LayoutDocumentPane in order to host documents"); - - _suspendLayoutItemCreation = true; - foreach( var documentContentToImport in listOfDocumentsToImport ) + var oldTheme = e.OldValue as Theme; + var newTheme = e.NewValue as Theme; + var resources = this.Resources; + if( oldTheme != null ) { - - //documentPane.Children.Add(new LayoutDocument() { Content = documentToImport }); - - var documentToImport = new LayoutDocument() - { - Content = documentContentToImport - }; - - bool added = false; - if( LayoutUpdateStrategy != null ) + if( oldTheme is DictionaryTheme ) { - added = LayoutUpdateStrategy.BeforeInsertDocument( layout, documentToImport, documentPane ); + if( currentThemeResourceDictionary != null ) + { + resources.MergedDictionaries.Remove( currentThemeResourceDictionary ); + currentThemeResourceDictionary = null; + } } - - if( !added ) + else { - if( documentPane == null ) - throw new InvalidOperationException( "Layout must contains at least one LayoutDocumentPane in order to host documents" ); - - documentPane.Children.Add( documentToImport ); - added = true; + var resourceDictionaryToRemove = + resources.MergedDictionaries.FirstOrDefault( r => r.Source == oldTheme.GetResourceUri() ); + if( resourceDictionaryToRemove != null ) + resources.MergedDictionaries.Remove( + resourceDictionaryToRemove ); } - - if( LayoutUpdateStrategy != null ) - LayoutUpdateStrategy.AfterInsertDocument( layout, documentToImport ); - - - CreateDocumentLayoutItem( documentToImport ); - } - _suspendLayoutItemCreation = false; - - - var documentsSourceAsNotifier = documentsSource as INotifyCollectionChanged; - if( documentsSourceAsNotifier != null ) - documentsSourceAsNotifier.CollectionChanged += new NotifyCollectionChangedEventHandler( documentsSourceElementsChanged ); - } - - internal bool SuspendDocumentsSourceBinding = false; - - void documentsSourceElementsChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - if( Layout == null ) - return; - - //When deserializing documents are created automatically by the deserializer - if( SuspendDocumentsSourceBinding ) - return; - //handle remove - if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) + if( newTheme != null ) { - if( e.OldItems != null ) + if( newTheme is DictionaryTheme ) { - var documentsToRemove = Layout.Descendents().OfType().Where( d => e.OldItems.Contains( d.Content ) ).ToArray(); - foreach( var documentToRemove in documentsToRemove ) - { - ( documentToRemove.Parent as ILayoutContainer ).RemoveChild( - documentToRemove ); - this.RemoveViewFromLogicalChild( documentToRemove ); - } + currentThemeResourceDictionary = ( ( DictionaryTheme )newTheme ).ThemeResourceDictionary; + resources.MergedDictionaries.Add( currentThemeResourceDictionary ); } - } - - //handle add - if( e.NewItems != null && - ( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) ) - { - if( e.NewItems != null ) + else { - LayoutDocumentPane documentPane = null; - if( Layout.LastFocusedDocument != null ) - { - documentPane = Layout.LastFocusedDocument.Parent as LayoutDocumentPane; - } - - if( documentPane == null ) - { - documentPane = Layout.Descendents().OfType().FirstOrDefault(); - } - - //if (documentPane == null) - // throw new InvalidOperationException("Layout must contains at least one LayoutDocumentPane in order to host documents"); - - _suspendLayoutItemCreation = true; - - foreach( var documentContentToImport in e.NewItems ) - { - var documentToImport = new LayoutDocument() - { - Content = documentContentToImport - }; - - bool added = false; - if( LayoutUpdateStrategy != null ) - { - added = LayoutUpdateStrategy.BeforeInsertDocument( Layout, documentToImport, documentPane ); - } + resources.MergedDictionaries.Add( new ResourceDictionary() { Source = newTheme.GetResourceUri() } ); + } + } - if( !added ) - { - if( documentPane == null ) - throw new InvalidOperationException( "Layout must contains at least one LayoutDocumentPane in order to host documents" ); + foreach( var fwc in _fwList ) + fwc.UpdateThemeResources( oldTheme ); - documentPane.Children.Add( documentToImport ); - added = true; - } + if( _navigatorWindow != null ) + _navigatorWindow.UpdateThemeResources(); - if( LayoutUpdateStrategy != null ) - { - LayoutUpdateStrategy.AfterInsertDocument( Layout, documentToImport ); - } + if( _overlayWindow != null ) + _overlayWindow.UpdateThemeResources(); + } + #endregion - var root = documentToImport.Root; + #region GridSplitterWidth - if( root != null && root.Manager == this ) - { - CreateDocumentLayoutItem( documentToImport ); - } - } - _suspendLayoutItemCreation = false; - } - } + /// + /// GridSplitterWidth Dependency Property + /// + public static readonly DependencyProperty GridSplitterWidthProperty = DependencyProperty.Register( "GridSplitterWidth", typeof( double ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( double )6.0 ) ); - if( e.Action == NotifyCollectionChangedAction.Reset ) + /// + /// Gets or sets the GridSplitterWidth property. This dependency property + /// indicates width of grid splitters. + /// + public double GridSplitterWidth + { + get { - //NOTE: I'm going to clear every document present in layout but - //some documents may have been added directly to the layout, for now I clear them too - var documentsToRemove = Layout.Descendents().OfType().ToArray(); - foreach( var documentToRemove in documentsToRemove ) - { - ( documentToRemove.Parent as ILayoutContainer ).RemoveChild( - documentToRemove ); - this.RemoveViewFromLogicalChild( documentToRemove ); - } + return ( double )GetValue( GridSplitterWidthProperty ); } - - if( Layout != null ) + set { - Layout.CollectGarbage(); + SetValue( GridSplitterWidthProperty, value ); } } - void DetachDocumentsSource( LayoutRoot layout, IEnumerable documentsSource ) - { - if( documentsSource == null ) - return; + #endregion - if( layout == null ) - return; + #region GridSplitterHeight - var documentsToRemove = layout.Descendents().OfType() - .Where( d => documentsSource.Contains( d.Content ) ).ToArray(); + /// + /// GridSplitterHeight Dependency Property + /// + public static readonly DependencyProperty GridSplitterHeightProperty = DependencyProperty.Register( "GridSplitterHeight", typeof( double ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( double )6.0 ) ); - foreach( var documentToRemove in documentsToRemove ) + /// + /// Gets or sets the GridSplitterHeight property. This dependency property + /// indicates height of grid splitters. + /// + public double GridSplitterHeight + { + get { - ( documentToRemove.Parent as ILayoutContainer ).RemoveChild( - documentToRemove ); - this.RemoveViewFromLogicalChild( documentToRemove ); + return ( double )GetValue( GridSplitterHeightProperty ); + } + set + { + SetValue( GridSplitterHeightProperty, value ); } - - var documentsSourceAsNotifier = documentsSource as INotifyCollectionChanged; - if( documentsSourceAsNotifier != null ) - documentsSourceAsNotifier.CollectionChanged -= new NotifyCollectionChangedEventHandler( documentsSourceElementsChanged ); } - #endregion - #region DocumentCloseCommand + #region DocumentPaneMenuItemHeaderTemplate - internal void _ExecuteCloseCommand( LayoutDocument document ) + /// + /// DocumentPaneMenuItemHeaderTemplate Dependency Property + /// + public static readonly DependencyProperty DocumentPaneMenuItemHeaderTemplateProperty = DependencyProperty.Register( "DocumentPaneMenuItemHeaderTemplate", typeof( DataTemplate ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( DataTemplate )null, new PropertyChangedCallback( OnDocumentPaneMenuItemHeaderTemplateChanged ), new CoerceValueCallback( CoerceDocumentPaneMenuItemHeaderTemplateValue ) ) ); + + /// + /// Gets or sets the DocumentPaneMenuItemHeaderTemplate property. This dependency property + /// indicates the header template to use while creating menu items for the document panes. + /// + public DataTemplate DocumentPaneMenuItemHeaderTemplate { - if( DocumentClosing != null ) + get { - var evargs = new DocumentClosingEventArgs( document ); - DocumentClosing( this, evargs ); - if( evargs.Cancel ) - return; + return ( DataTemplate )GetValue( DocumentPaneMenuItemHeaderTemplateProperty ); } - - if( document.CloseDocument() ) + set { - this.RemoveViewFromLogicalChild( document ); + SetValue( DocumentPaneMenuItemHeaderTemplateProperty, value ); + } + } - if( DocumentClosed != null ) - { - var evargs = new DocumentClosedEventArgs( document ); - DocumentClosed( this, evargs ); - } - } + /// + /// Handles changes to the DocumentPaneMenuItemHeaderTemplate property. + /// + private static void OnDocumentPaneMenuItemHeaderTemplateChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( DockingManager )d ).OnDocumentPaneMenuItemHeaderTemplateChanged( e ); } /// - /// Event fired when a document is about to be closed + /// Provides derived classes an opportunity to handle changes to the DocumentPaneMenuItemHeaderTemplate property. /// - /// Subscribers have the opportuniy to cancel the operation. - public event EventHandler DocumentClosing; + protected virtual void OnDocumentPaneMenuItemHeaderTemplateChanged( DependencyPropertyChangedEventArgs e ) + { + } /// - /// Event fired after a document is closed + /// Coerces the DocumentPaneMenuItemHeaderTemplate value. /// - public event EventHandler DocumentClosed; - + private static object CoerceDocumentPaneMenuItemHeaderTemplateValue( DependencyObject d, object value ) + { + if( value != null && + d.GetValue( DocumentPaneMenuItemHeaderTemplateSelectorProperty ) != null ) + return null; + if( value == null ) + return d.GetValue( DocumentHeaderTemplateProperty ); + return value; + } #endregion - internal void _ExecuteCloseAllButThisCommand( LayoutContent contentSelected ) + #region DocumentPaneMenuItemHeaderTemplateSelector + + /// + /// DocumentPaneMenuItemHeaderTemplateSelector Dependency Property + /// + public static readonly DependencyProperty DocumentPaneMenuItemHeaderTemplateSelectorProperty = DependencyProperty.Register( "DocumentPaneMenuItemHeaderTemplateSelector", typeof( DataTemplateSelector ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( DataTemplateSelector )null, new PropertyChangedCallback( OnDocumentPaneMenuItemHeaderTemplateSelectorChanged ), new CoerceValueCallback( CoerceDocumentPaneMenuItemHeaderTemplateSelectorValue ) ) ); + + /// + /// Gets or sets the DocumentPaneMenuItemHeaderTemplateSelector property. This dependency property + /// indicates the data template selector to use for the menu items show when user select the DocumentPane document switch context menu. + /// + public DataTemplateSelector DocumentPaneMenuItemHeaderTemplateSelector { - foreach( var contentToClose in Layout.Descendents().OfType().Where( d => d != contentSelected && ( d.Parent is LayoutDocumentPane || d.Parent is LayoutDocumentFloatingWindow ) ).ToArray() ) + get { - this.Close( contentToClose ); + return ( DataTemplateSelector )GetValue( DocumentPaneMenuItemHeaderTemplateSelectorProperty ); + } + set + { + SetValue( DocumentPaneMenuItemHeaderTemplateSelectorProperty, value ); } } - internal void _ExecuteCloseAllCommand( LayoutContent contentSelected ) + /// + /// Handles changes to the DocumentPaneMenuItemHeaderTemplateSelector property. + /// + private static void OnDocumentPaneMenuItemHeaderTemplateSelectorChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) { - foreach( var contentToClose in Layout.Descendents().OfType().Where( d => ( d.Parent is LayoutDocumentPane || d.Parent is LayoutDocumentFloatingWindow ) ).ToArray() ) - { - this.Close( contentToClose ); - } + ( ( DockingManager )d ).OnDocumentPaneMenuItemHeaderTemplateSelectorChanged( e ); } - private void Close( LayoutContent contentToClose ) + /// + /// Provides derived classes an opportunity to handle changes to the DocumentPaneMenuItemHeaderTemplateSelector property. + /// + protected virtual void OnDocumentPaneMenuItemHeaderTemplateSelectorChanged( DependencyPropertyChangedEventArgs e ) { - if( !contentToClose.CanClose ) - return; + if( e.NewValue != null && + DocumentPaneMenuItemHeaderTemplate != null ) + DocumentPaneMenuItemHeaderTemplate = null; - var layoutItem = GetLayoutItemFromModel( contentToClose ); - if( layoutItem.CloseCommand != null ) + } + + /// + /// Coerces the DocumentPaneMenuItemHeaderTemplateSelector value. + /// + private static object CoerceDocumentPaneMenuItemHeaderTemplateSelectorValue( DependencyObject d, object value ) + { + return value; + } + + #endregion + + #region IconContentTemplate + + /// + /// IconContentTemplate Dependency Property + /// + public static readonly DependencyProperty IconContentTemplateProperty = DependencyProperty.Register( "IconContentTemplate", typeof( DataTemplate ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( DataTemplate )null ) ); + + /// + /// Gets or sets the IconContentTemplate property. This dependency property + /// indicates the data template to use while extracting the icon from model. + /// + public DataTemplate IconContentTemplate + { + get { - if( layoutItem.CloseCommand.CanExecute( null ) ) - layoutItem.CloseCommand.Execute( null ); + return ( DataTemplate )GetValue( IconContentTemplateProperty ); } - else + set { - if( contentToClose is LayoutDocument ) - _ExecuteCloseCommand( contentToClose as LayoutDocument ); - else if( contentToClose is LayoutAnchorable ) - _ExecuteCloseCommand( contentToClose as LayoutAnchorable ); + SetValue( IconContentTemplateProperty, value ); } } - #region DocumentContextMenu + #endregion + + #region IconContentTemplateSelector /// - /// DocumentContextMenu Dependency Property + /// IconContentTemplateSelector Dependency Property /// - public static readonly DependencyProperty DocumentContextMenuProperty = - DependencyProperty.Register( "DocumentContextMenu", typeof( ContextMenu ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( ContextMenu )null ) ); + public static readonly DependencyProperty IconContentTemplateSelectorProperty = DependencyProperty.Register( "IconContentTemplateSelector", typeof( DataTemplateSelector ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( DataTemplateSelector )null ) ); /// - /// Gets or sets the DocumentContextMenu property. This dependency property - /// indicates context menu to show for documents. + /// Gets or sets the IconContentTemplateSelector property. This dependency property + /// indicates data template selector to use while selecting the datatamplate for content icons. /// - public ContextMenu DocumentContextMenu + public DataTemplateSelector IconContentTemplateSelector { get { - return ( ContextMenu )GetValue( DocumentContextMenuProperty ); + return ( DataTemplateSelector )GetValue( IconContentTemplateSelectorProperty ); } set { - SetValue( DocumentContextMenuProperty, value ); + SetValue( IconContentTemplateSelectorProperty, value ); } } #endregion - #region AnchorablesSource + #region LayoutItemContainerStyle /// - /// AnchorablesSource Dependency Property + /// LayoutItemContainerStyle Dependency Property /// - public static readonly DependencyProperty AnchorablesSourceProperty = - DependencyProperty.Register( "AnchorablesSource", typeof( IEnumerable ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( IEnumerable )null, - new PropertyChangedCallback( OnAnchorablesSourceChanged ) ) ); + public static readonly DependencyProperty LayoutItemContainerStyleProperty = DependencyProperty.Register( "LayoutItemContainerStyle", typeof( Style ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( Style )null, new PropertyChangedCallback( OnLayoutItemContainerStyleChanged ) ) ); /// - /// Gets or sets the AnchorablesSource property. This dependency property - /// indicates source collection of anchorables. + /// Gets or sets the LayoutItemContainerStyle property. This dependency property + /// indicates the style to apply to LayoutDocumentItem objects. A LayoutDocumentItem object is created when a new LayoutDocument is created inside the current Layout. /// - public IEnumerable AnchorablesSource + public Style LayoutItemContainerStyle { get { - return ( IEnumerable )GetValue( AnchorablesSourceProperty ); + return ( Style )GetValue( LayoutItemContainerStyleProperty ); } set { - SetValue( AnchorablesSourceProperty, value ); + SetValue( LayoutItemContainerStyleProperty, value ); } } /// - /// Handles changes to the AnchorablesSource property. + /// Handles changes to the LayoutItemContainerStyle property. /// - private static void OnAnchorablesSourceChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + private static void OnLayoutItemContainerStyleChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) { - ( ( DockingManager )d ).OnAnchorablesSourceChanged( e ); + ( ( DockingManager )d ).OnLayoutItemContainerStyleChanged( e ); } /// - /// Provides derived classes an opportunity to handle changes to the AnchorablesSource property. + /// Provides derived classes an opportunity to handle changes to the LayoutItemContainerStyle property. /// - protected virtual void OnAnchorablesSourceChanged( DependencyPropertyChangedEventArgs e ) + protected virtual void OnLayoutItemContainerStyleChanged( DependencyPropertyChangedEventArgs e ) { - DetachAnchorablesSource( Layout, e.OldValue as IEnumerable ); - AttachAnchorablesSource( Layout, e.NewValue as IEnumerable ); + AttachLayoutItems(); } - void AttachAnchorablesSource( LayoutRoot layout, IEnumerable anchorablesSource ) - { - if( anchorablesSource == null ) - return; + #endregion - if( layout == null ) - return; + #region LayoutItemContainerStyleSelector - //if (layout.Descendents().OfType().Any()) - // throw new InvalidOperationException("Unable to set the AnchorablesSource property if LayoutAnchorable objects are already present in the model"); - var anchorablesImported = layout.Descendents().OfType().Select( d => d.Content ).ToArray(); - var anchorables = anchorablesSource as IEnumerable; - var listOfAnchorablesToImport = new List( anchorables.OfType() ); + /// + /// LayoutItemContainerStyleSelector Dependency Property + /// + public static readonly DependencyProperty LayoutItemContainerStyleSelectorProperty = DependencyProperty.Register( "LayoutItemContainerStyleSelector", typeof( StyleSelector ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( StyleSelector )null, new PropertyChangedCallback( OnLayoutItemContainerStyleSelectorChanged ) ) ); - foreach( var document in listOfAnchorablesToImport.ToArray() ) + /// + /// Gets or sets the LayoutItemContainerStyleSelector property. This dependency property + /// indicates style selector of the LayoutDocumentItemStyle. + /// + public StyleSelector LayoutItemContainerStyleSelector + { + get { - if( anchorablesImported.Contains( document ) ) - listOfAnchorablesToImport.Remove( document ); + return ( StyleSelector )GetValue( LayoutItemContainerStyleSelectorProperty ); } - - LayoutAnchorablePane anchorablePane = null; - if( layout.ActiveContent != null ) + set { - //look for active content parent pane - anchorablePane = layout.ActiveContent.Parent as LayoutAnchorablePane; + SetValue( LayoutItemContainerStyleSelectorProperty, value ); } + } - if( anchorablePane == null ) - { - //look for a pane on the right side - anchorablePane = layout.Descendents().OfType().Where( pane => !pane.IsHostedInFloatingWindow && pane.GetSide() == AnchorSide.Right ).FirstOrDefault(); - } + /// + /// Handles changes to the LayoutItemContainerStyleSelector property. + /// + private static void OnLayoutItemContainerStyleSelectorChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) + { + ( ( DockingManager )d ).OnLayoutItemContainerStyleSelectorChanged( e ); + } - if( anchorablePane == null ) + /// + /// Provides derived classes an opportunity to handle changes to the LayoutItemContainerStyleSelector property. + /// + protected virtual void OnLayoutItemContainerStyleSelectorChanged( DependencyPropertyChangedEventArgs e ) + { + AttachLayoutItems(); + } + + #endregion + + #region ShowSystemMenu + + /// + /// ShowSystemMenu Dependency Property + /// + public static readonly DependencyProperty ShowSystemMenuProperty = DependencyProperty.Register( "ShowSystemMenu", typeof( bool ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( bool )true ) ); + + /// + /// Gets or sets the ShowSystemMenu property. This dependency property + /// indicates if floating windows should show the system menu when a custom context menu is not defined. + /// + public bool ShowSystemMenu + { + get { - //look for an available pane - anchorablePane = layout.Descendents().OfType().FirstOrDefault(); + return ( bool )GetValue( ShowSystemMenuProperty ); } - - _suspendLayoutItemCreation = true; - foreach( var anchorableContentToImport in listOfAnchorablesToImport ) + set { - var anchorableToImport = new LayoutAnchorable() - { - Content = anchorableContentToImport - }; + SetValue( ShowSystemMenuProperty, value ); + } + } - bool added = false; - if( LayoutUpdateStrategy != null ) - { - added = LayoutUpdateStrategy.BeforeInsertAnchorable( layout, anchorableToImport, anchorablePane ); - } + #endregion - if( !added ) - { - if( anchorablePane == null ) - { - var mainLayoutPanel = new LayoutPanel() { Orientation = Orientation.Horizontal }; - if( layout.RootPanel != null ) - { - mainLayoutPanel.Children.Add( layout.RootPanel ); - } + #region AllowMixedOrientation - layout.RootPanel = mainLayoutPanel; - anchorablePane = new LayoutAnchorablePane() { DockWidth = new GridLength( 200.0, GridUnitType.Pixel ) }; - mainLayoutPanel.Children.Add( anchorablePane ); - } - - anchorablePane.Children.Add( anchorableToImport ); - added = true; - } - - if( LayoutUpdateStrategy != null ) - LayoutUpdateStrategy.AfterInsertAnchorable( layout, anchorableToImport ); - - - CreateAnchorableLayoutItem( anchorableToImport ); - - } - - _suspendLayoutItemCreation = false; - - var anchorablesSourceAsNotifier = anchorablesSource as INotifyCollectionChanged; - if( anchorablesSourceAsNotifier != null ) - anchorablesSourceAsNotifier.CollectionChanged += new NotifyCollectionChangedEventHandler( anchorablesSourceElementsChanged ); - } - - internal bool SuspendAnchorablesSourceBinding = false; + /// + /// AllowMixedOrientation Dependency Property + /// + public static readonly DependencyProperty AllowMixedOrientationProperty = DependencyProperty.Register( "AllowMixedOrientation", typeof( bool ), typeof( DockingManager ), + new FrameworkPropertyMetadata( ( bool )false ) ); - void anchorablesSourceElementsChanged( object sender, NotifyCollectionChangedEventArgs e ) + /// + /// Gets or sets the AllowMixedOrientation property. This dependency property + /// indicates if the manager should allow mixed orientation for document panes. + /// + public bool AllowMixedOrientation { - if( Layout == null ) - return; - - //When deserializing documents are created automatically by the deserializer - if( SuspendAnchorablesSourceBinding ) - return; - - //handle remove - if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) - { - if( e.OldItems != null ) - { - var anchorablesToRemove = Layout.Descendents().OfType().Where( d => e.OldItems.Contains( d.Content ) ).ToArray(); - foreach( var anchorableToRemove in anchorablesToRemove ) - { - anchorableToRemove.Content = null; - ( anchorableToRemove.Parent as ILayoutContainer ).RemoveChild( - anchorableToRemove ); - this.RemoveViewFromLogicalChild( anchorableToRemove ); - } - } - } - - //handle add - if( e.NewItems != null && - ( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) ) + get { - if( e.NewItems != null ) - { - LayoutAnchorablePane anchorablePane = null; - - if( Layout.ActiveContent != null ) - { - //look for active content parent pane - anchorablePane = Layout.ActiveContent.Parent as LayoutAnchorablePane; - } - - if( anchorablePane == null ) - { - //look for a pane on the right side - anchorablePane = Layout.Descendents().OfType().Where( pane => !pane.IsHostedInFloatingWindow && pane.GetSide() == AnchorSide.Right ).FirstOrDefault(); - } - - if( anchorablePane == null ) - { - //look for an available pane - anchorablePane = Layout.Descendents().OfType().FirstOrDefault(); - } - - _suspendLayoutItemCreation = true; - foreach( var anchorableContentToImport in e.NewItems ) - { - var anchorableToImport = new LayoutAnchorable() - { - Content = anchorableContentToImport - }; - - bool added = false; - if( LayoutUpdateStrategy != null ) - { - added = LayoutUpdateStrategy.BeforeInsertAnchorable( Layout, anchorableToImport, anchorablePane ); - } - - if( !added ) - { - if( anchorablePane == null ) - { - var mainLayoutPanel = new LayoutPanel() { Orientation = Orientation.Horizontal }; - if( Layout.RootPanel != null ) - { - mainLayoutPanel.Children.Add( Layout.RootPanel ); - } - - Layout.RootPanel = mainLayoutPanel; - anchorablePane = new LayoutAnchorablePane() { DockWidth = new GridLength( 200.0, GridUnitType.Pixel ) }; - mainLayoutPanel.Children.Add( anchorablePane ); - } - - anchorablePane.Children.Add( anchorableToImport ); - added = true; - } - - if( LayoutUpdateStrategy != null ) - { - LayoutUpdateStrategy.AfterInsertAnchorable( Layout, anchorableToImport ); - } - - var root = anchorableToImport.Root; - - if( root != null && root.Manager == this ) - { - CreateAnchorableLayoutItem( anchorableToImport ); - } - - } - _suspendLayoutItemCreation = false; - } + return ( bool )GetValue( AllowMixedOrientationProperty ); } - - if( e.Action == NotifyCollectionChangedAction.Reset ) + set { - //NOTE: I'm going to clear every anchorable present in layout but - //some anchorable may have been added directly to the layout, for now I clear them too - var anchorablesToRemove = Layout.Descendents().OfType().ToArray(); - foreach( var anchorableToRemove in anchorablesToRemove ) - { - ( anchorableToRemove.Parent as ILayoutContainer ).RemoveChild( - anchorableToRemove ); - this.RemoveViewFromLogicalChild( anchorableToRemove ); - } + SetValue( AllowMixedOrientationProperty, value ); } - - if( Layout != null ) - Layout.CollectGarbage(); } - void DetachAnchorablesSource( LayoutRoot layout, IEnumerable anchorablesSource ) - { - if( anchorablesSource == null ) - return; + #endregion - if( layout == null ) - return; + #endregion - var anchorablesToRemove = layout.Descendents().OfType() - .Where( d => anchorablesSource.Contains( d.Content ) ).ToArray(); + #region Private Properties - foreach( var anchorableToRemove in anchorablesToRemove ) + private bool IsNavigatorWindowActive + { + get { - ( anchorableToRemove.Parent as ILayoutContainer ).RemoveChild( - anchorableToRemove ); - this.RemoveViewFromLogicalChild( anchorableToRemove ); + return _navigatorWindow != null; } - - var anchorablesSourceAsNotifier = anchorablesSource as INotifyCollectionChanged; - if( anchorablesSourceAsNotifier != null ) - anchorablesSourceAsNotifier.CollectionChanged -= new NotifyCollectionChangedEventHandler( anchorablesSourceElementsChanged ); } #endregion - internal void _ExecuteCloseCommand( LayoutAnchorable anchorable ) - { - var model = anchorable as LayoutAnchorable; - if( model != null ) - { - model.CloseAnchorable(); - this.RemoveViewFromLogicalChild( anchorable ); - } - } + #region Overrides - internal void _ExecuteHideCommand( LayoutAnchorable anchorable ) + public override void OnApplyTemplate() { - var model = anchorable as LayoutAnchorable; - if( model != null ) - { - model.Hide(); - } - } + base.OnApplyTemplate(); - internal void _ExecuteAutoHideCommand( LayoutAnchorable _anchorable ) - { - _anchorable.ToggleAutoHide(); - } - internal void _ExecuteFloatCommand( LayoutContent contentToFloat ) - { - contentToFloat.Float(); + _autohideArea = GetTemplateChild( "PART_AutoHideArea" ) as FrameworkElement; } - internal void _ExecuteDockCommand( LayoutAnchorable anchorable ) + protected override void OnInitialized( EventArgs e ) { - anchorable.Dock(); + base.OnInitialized( e ); } - internal void _ExecuteDockAsDocumentCommand( LayoutContent content ) + + protected override Size ArrangeOverride( Size arrangeBounds ) { - content.DockAsDocument(); + _areas = null; + return base.ArrangeOverride( arrangeBounds ); } - private void RemoveViewFromLogicalChild( LayoutContent layoutContent ) + protected override void OnPreviewKeyDown( KeyEventArgs e ) { - if( layoutContent == null ) - return; - - var layoutItem = this.GetLayoutItemFromModel( layoutContent ); - if( layoutItem != null ) + if( Keyboard.IsKeyDown( Key.LeftCtrl ) || Keyboard.IsKeyDown( Key.RightCtrl ) ) { - if( layoutItem.IsViewExists() ) + if( e.IsDown && e.Key == Key.Tab ) { - this.InternalRemoveLogicalChild( layoutItem.View ); + if( !IsNavigatorWindowActive ) + { + ShowNavigatorWindow(); + e.Handled = true; + } } } + + base.OnPreviewKeyDown( e ); } - #region ActiveContent + #endregion - /// - /// ActiveContent Dependency Property - /// - public static readonly DependencyProperty ActiveContentProperty = - DependencyProperty.Register( "ActiveContent", typeof( object ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( object )null, - new PropertyChangedCallback( OnActiveContentChanged ) ) ); + #region Public Methods /// - /// Gets or sets the ActiveContent property. This dependency property - /// indicates the content currently active. + /// Return the LayoutItem wrapper for the content passed as argument /// - public object ActiveContent + /// LayoutContent to search + /// Either a LayoutAnchorableItem or LayoutDocumentItem which contains the LayoutContent passed as argument + public LayoutItem GetLayoutItemFromModel( LayoutContent content ) { - get - { - return ( object )GetValue( ActiveContentProperty ); - } - set - { - SetValue( ActiveContentProperty, value ); - } + return _layoutItems.FirstOrDefault( item => item.LayoutElement == content ); } - /// - /// Handles changes to the ActiveContent property. - /// - private static void OnActiveContentChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) - { - ( ( DockingManager )d ).InternalSetActiveContent( e.NewValue ); - ( ( DockingManager )d ).OnActiveContentChanged( e ); - } + #endregion - /// - /// Provides derived classes an opportunity to handle changes to the ActiveContent property. - /// - protected virtual void OnActiveContentChanged( DependencyPropertyChangedEventArgs e ) - { - if( ActiveContentChanged != null ) - ActiveContentChanged( this, EventArgs.Empty ); - } + #region Internal Methods - - bool _insideInternalSetActiveContent = false; - void InternalSetActiveContent( object contentObject ) + internal UIElement CreateUIElementForModel( ILayoutElement model ) { - var layoutContent = Layout.Descendents().OfType().FirstOrDefault( lc => lc == contentObject || lc.Content == contentObject ); - _insideInternalSetActiveContent = true; - Layout.ActiveContent = layoutContent; - _insideInternalSetActiveContent = false; - } - - public event EventHandler ActiveContentChanged; - - #endregion - - #region AnchorableContextMenu - - /// - /// AnchorableContextMenu Dependency Property - /// - public static readonly DependencyProperty AnchorableContextMenuProperty = - DependencyProperty.Register( "AnchorableContextMenu", typeof( ContextMenu ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( ContextMenu )null ) ); + if( model is LayoutPanel ) + return new LayoutPanelControl( model as LayoutPanel ); + if( model is LayoutAnchorablePaneGroup ) + return new LayoutAnchorablePaneGroupControl( model as LayoutAnchorablePaneGroup ); + if( model is LayoutDocumentPaneGroup ) + return new LayoutDocumentPaneGroupControl( model as LayoutDocumentPaneGroup ); - /// - /// Gets or sets the AnchorableContextMenu property. This dependency property - /// indicates the context menu to show up for anchorables. - /// - public ContextMenu AnchorableContextMenu - { - get + if( model is LayoutAnchorSide ) { - return ( ContextMenu )GetValue( AnchorableContextMenuProperty ); + var templateModelView = new LayoutAnchorSideControl( model as LayoutAnchorSide ); + templateModelView.SetBinding( LayoutAnchorSideControl.TemplateProperty, new Binding( "AnchorSideTemplate" ) { Source = this } ); + return templateModelView; } - set + if( model is LayoutAnchorGroup ) { - SetValue( AnchorableContextMenuProperty, value ); + var templateModelView = new LayoutAnchorGroupControl( model as LayoutAnchorGroup ); + templateModelView.SetBinding( LayoutAnchorGroupControl.TemplateProperty, new Binding( "AnchorGroupTemplate" ) { Source = this } ); + return templateModelView; } - } - - #endregion - - #region Theme - - /// - /// Theme Dependency Property - /// - public static readonly DependencyProperty ThemeProperty = - DependencyProperty.Register( "Theme", typeof( Theme ), typeof( DockingManager ), - new FrameworkPropertyMetadata( null, - new PropertyChangedCallback( OnThemeChanged ) ) ); - /// - /// Gets or sets the Theme property. This dependency property - /// indicates the theme to use for AvalonDock controls. - /// - public Theme Theme - { - get + if( model is LayoutDocumentPane ) { - return ( Theme )GetValue( ThemeProperty ); + var templateModelView = new LayoutDocumentPaneControl( model as LayoutDocumentPane ); + templateModelView.SetBinding( LayoutDocumentPaneControl.StyleProperty, new Binding( "DocumentPaneControlStyle" ) { Source = this } ); + return templateModelView; } - set + if( model is LayoutAnchorablePane ) { - SetValue( ThemeProperty, value ); + var templateModelView = new LayoutAnchorablePaneControl( model as LayoutAnchorablePane ); + templateModelView.SetBinding( LayoutAnchorablePaneControl.StyleProperty, new Binding( "AnchorablePaneControlStyle" ) { Source = this } ); + return templateModelView; } - } - - /// - /// Handles changes to the Theme property. - /// - private static void OnThemeChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) - { - ( ( DockingManager )d ).OnThemeChanged( e ); - } - /// - /// Provides derived classes an opportunity to handle changes to the Theme property. - /// - protected virtual void OnThemeChanged( DependencyPropertyChangedEventArgs e ) - { - var oldTheme = e.OldValue as Theme; - var newTheme = e.NewValue as Theme; - var resources = this.Resources; - if( oldTheme != null ) + if( model is LayoutAnchorableFloatingWindow ) { - if( oldTheme is DictionaryTheme ) + if( DesignerProperties.GetIsInDesignMode( this ) ) + return null; + var modelFW = model as LayoutAnchorableFloatingWindow; + var newFW = new LayoutAnchorableFloatingWindowControl( modelFW ) { - if( currentThemeResourceDictionary != null ) - { - resources.MergedDictionaries.Remove( currentThemeResourceDictionary ); - currentThemeResourceDictionary = null; - } + //Owner = Window.GetWindow(this) + }; + newFW.SetParentToMainWindowOf( this ); + + var paneForExtensions = modelFW.RootPanel.Children.OfType().FirstOrDefault(); + if( paneForExtensions != null ) + { + //ensure that floating window position is inside current (or nearest) monitor + paneForExtensions.KeepInsideNearestMonitor(); + + newFW.Left = paneForExtensions.FloatingLeft; + newFW.Top = paneForExtensions.FloatingTop; + newFW.Width = paneForExtensions.FloatingWidth; + newFW.Height = paneForExtensions.FloatingHeight; } - else + + newFW.ShowInTaskbar = false; + newFW.Show(); + // Do not set the WindowState before showing or it will be lost + if( paneForExtensions != null && paneForExtensions.IsMaximized ) { - var resourceDictionaryToRemove = - resources.MergedDictionaries.FirstOrDefault( r => r.Source == oldTheme.GetResourceUri() ); - if( resourceDictionaryToRemove != null ) - resources.MergedDictionaries.Remove( - resourceDictionaryToRemove ); + newFW.WindowState = WindowState.Maximized; } + return newFW; } - if( newTheme != null ) + if( model is LayoutDocumentFloatingWindow ) { - if( newTheme is DictionaryTheme ) + if( DesignerProperties.GetIsInDesignMode( this ) ) + return null; + var modelFW = model as LayoutDocumentFloatingWindow; + var newFW = new LayoutDocumentFloatingWindowControl( modelFW ) { - currentThemeResourceDictionary = ( ( DictionaryTheme )newTheme ).ThemeResourceDictionary; - resources.MergedDictionaries.Add( currentThemeResourceDictionary ); + //Owner = Window.GetWindow(this) + }; + newFW.SetParentToMainWindowOf( this ); + + var paneForExtensions = modelFW.RootDocument; + if( paneForExtensions != null ) + { + //ensure that floating window position is inside current (or nearest) monitor + paneForExtensions.KeepInsideNearestMonitor(); + + newFW.Left = paneForExtensions.FloatingLeft; + newFW.Top = paneForExtensions.FloatingTop; + newFW.Width = paneForExtensions.FloatingWidth; + newFW.Height = paneForExtensions.FloatingHeight; } - else + + newFW.ShowInTaskbar = false; + newFW.Show(); + // Do not set the WindowState before showing or it will be lost + if( paneForExtensions != null && paneForExtensions.IsMaximized ) { - resources.MergedDictionaries.Add( new ResourceDictionary() { Source = newTheme.GetResourceUri() } ); + newFW.WindowState = WindowState.Maximized; } + return newFW; } - foreach( var fwc in _fwList ) - fwc.UpdateThemeResources( oldTheme ); - - if( _navigatorWindow != null ) - _navigatorWindow.UpdateThemeResources(); + if( model is LayoutDocument ) + { + var templateModelView = new LayoutDocumentControl() { Model = model as LayoutDocument }; + return templateModelView; + } - if( _overlayWindow != null ) - _overlayWindow.UpdateThemeResources(); + return null; } - #endregion - - #region GridSplitterWidth + internal void ShowAutoHideWindow( LayoutAnchorControl anchor ) + { + _autoHideWindowManager.ShowAutoHideWindow( anchor ); + //if (_autohideArea == null) + // return; - /// - /// GridSplitterWidth Dependency Property - /// - public static readonly DependencyProperty GridSplitterWidthProperty = - DependencyProperty.Register( "GridSplitterWidth", typeof( double ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( double )6.0 ) ); + //if (AutoHideWindow != null && AutoHideWindow.Model == anchor.Model) + // return; - /// - /// Gets or sets the GridSplitterWidth property. This dependency property - /// indicates width of grid splitters. - /// - public double GridSplitterWidth - { - get - { - return ( double )GetValue( GridSplitterWidthProperty ); - } - set - { - SetValue( GridSplitterWidthProperty, value ); - } - } + //Trace.WriteLine("ShowAutoHideWindow()"); - #endregion + //_currentAutohiddenAnchor = new WeakReference(anchor); - #region GridSplitterHeight + //HideAutoHideWindow(anchor); - /// - /// GridSplitterHeight Dependency Property - /// - public static readonly DependencyProperty GridSplitterHeightProperty = - DependencyProperty.Register( "GridSplitterHeight", typeof( double ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( double )6.0 ) ); + //SetAutoHideWindow(new LayoutAutoHideWindowControl(anchor)); + //AutoHideWindow.Show(); + } - /// - /// Gets or sets the GridSplitterHeight property. This dependency property - /// indicates height of grid splitters. - /// - public double GridSplitterHeight + internal void HideAutoHideWindow( LayoutAnchorControl anchor ) { - get - { - return ( double )GetValue( GridSplitterHeightProperty ); - } - set - { - SetValue( GridSplitterHeightProperty, value ); - } + _autoHideWindowManager.HideAutoWindow( anchor ); } - #endregion - - internal void _ExecuteContentActivateCommand( LayoutContent content ) + internal FrameworkElement GetAutoHideAreaElement() { - content.IsActive = true; + return _autohideArea; } - #region DocumentPaneMenuItemHeaderTemplate + internal void StartDraggingFloatingWindowForContent( LayoutContent contentModel, bool startDrag = true ) + { + if( !contentModel.CanFloat ) + return; + var contentModelAsAnchorable = contentModel as LayoutAnchorable; + if( contentModelAsAnchorable != null && + contentModelAsAnchorable.IsAutoHidden ) + contentModelAsAnchorable.ToggleAutoHide(); - /// - /// DocumentPaneMenuItemHeaderTemplate Dependency Property - /// - public static readonly DependencyProperty DocumentPaneMenuItemHeaderTemplateProperty = - DependencyProperty.Register( "DocumentPaneMenuItemHeaderTemplate", typeof( DataTemplate ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( DataTemplate )null, - new PropertyChangedCallback( OnDocumentPaneMenuItemHeaderTemplateChanged ), - new CoerceValueCallback( CoerceDocumentPaneMenuItemHeaderTemplateValue ) ) ); + var parentPane = contentModel.Parent as ILayoutPane; + var parentPaneAsPositionableElement = contentModel.Parent as ILayoutPositionableElement; + var parentPaneAsWithActualSize = contentModel.Parent as ILayoutPositionableElementWithActualSize; + var contentModelParentChildrenIndex = parentPane.Children.ToList().IndexOf( contentModel ); - /// - /// Gets or sets the DocumentPaneMenuItemHeaderTemplate property. This dependency property - /// indicates the header template to use while creating menu items for the document panes. - /// - public DataTemplate DocumentPaneMenuItemHeaderTemplate + if( contentModel.FindParent() == null ) + { + ( ( ILayoutPreviousContainer )contentModel ).PreviousContainer = parentPane; + contentModel.PreviousContainerIndex = contentModelParentChildrenIndex; + } + + parentPane.RemoveChildAt( contentModelParentChildrenIndex ); + + double fwWidth = contentModel.FloatingWidth; + double fwHeight = contentModel.FloatingHeight; + + if( fwWidth == 0.0 ) + fwWidth = parentPaneAsPositionableElement.FloatingWidth; + if( fwHeight == 0.0 ) + fwHeight = parentPaneAsPositionableElement.FloatingHeight; + + if( fwWidth == 0.0 ) + fwWidth = parentPaneAsWithActualSize.ActualWidth + 10; //10 includes BorderThickness and Margins inside LayoutDocumentFloatingWindowControl. + if( fwHeight == 0.0 ) + fwHeight = parentPaneAsWithActualSize.ActualHeight + 10; //10 includes BorderThickness and Margins inside LayoutDocumentFloatingWindowControl. + + LayoutFloatingWindow fw; + LayoutFloatingWindowControl fwc; + if( contentModel is LayoutAnchorable ) + { + var anchorableContent = contentModel as LayoutAnchorable; + fw = new LayoutAnchorableFloatingWindow() + { + RootPanel = new LayoutAnchorablePaneGroup( + new LayoutAnchorablePane( anchorableContent ) + { + DockWidth = parentPaneAsPositionableElement.DockWidth, + DockHeight = parentPaneAsPositionableElement.DockHeight, + DockMinHeight = parentPaneAsPositionableElement.DockMinHeight, + DockMinWidth = parentPaneAsPositionableElement.DockMinWidth, + FloatingLeft = parentPaneAsPositionableElement.FloatingLeft, + FloatingTop = parentPaneAsPositionableElement.FloatingTop, + FloatingWidth = parentPaneAsPositionableElement.FloatingWidth, + FloatingHeight = parentPaneAsPositionableElement.FloatingHeight, + } ) + }; + + Layout.FloatingWindows.Add( fw ); + + fwc = new LayoutAnchorableFloatingWindowControl( + fw as LayoutAnchorableFloatingWindow ) + { + Width = fwWidth, + Height = fwHeight, + Left = contentModel.FloatingLeft, + Top = contentModel.FloatingTop + }; + } + else + { + var anchorableDocument = contentModel as LayoutDocument; + fw = new LayoutDocumentFloatingWindow() + { + RootDocument = anchorableDocument + }; + + Layout.FloatingWindows.Add( fw ); + + fwc = new LayoutDocumentFloatingWindowControl( + fw as LayoutDocumentFloatingWindow ) + { + Width = fwWidth, + Height = fwHeight, + Left = contentModel.FloatingLeft, + Top = contentModel.FloatingTop + }; + } + + + //fwc.Owner = Window.GetWindow(this); + //fwc.SetParentToMainWindowOf(this); + + + _fwList.Add( fwc ); + + Layout.CollectGarbage(); + + UpdateLayout(); + + Dispatcher.BeginInvoke( new Action( () => + { + if( startDrag ) + fwc.AttachDrag(); + fwc.Show(); + } ), DispatcherPriority.Send ); + } + + internal void StartDraggingFloatingWindowForPane( LayoutAnchorablePane paneModel ) + { + if( paneModel.Children.Any( c => !c.CanFloat ) ) + return; + var paneAsPositionableElement = paneModel as ILayoutPositionableElement; + var paneAsWithActualSize = paneModel as ILayoutPositionableElementWithActualSize; + + double fwWidth = paneAsPositionableElement.FloatingWidth; + double fwHeight = paneAsPositionableElement.FloatingHeight; + double fwLeft = paneAsPositionableElement.FloatingLeft; + double fwTop = paneAsPositionableElement.FloatingTop; + + if( fwWidth == 0.0 ) + fwWidth = paneAsWithActualSize.ActualWidth + 10; //10 includes BorderThickness and Margins inside LayoutAnchorableFloatingWindowControl. + if( fwHeight == 0.0 ) + fwHeight = paneAsWithActualSize.ActualHeight + 10; //10 includes BorderThickness and Margins inside LayoutAnchorableFloatingWindowControl. + + var destPane = new LayoutAnchorablePane() + { + DockWidth = paneAsPositionableElement.DockWidth, + DockHeight = paneAsPositionableElement.DockHeight, + DockMinHeight = paneAsPositionableElement.DockMinHeight, + DockMinWidth = paneAsPositionableElement.DockMinWidth, + FloatingLeft = paneAsPositionableElement.FloatingLeft, + FloatingTop = paneAsPositionableElement.FloatingTop, + FloatingWidth = paneAsPositionableElement.FloatingWidth, + FloatingHeight = paneAsPositionableElement.FloatingHeight, + }; + + bool savePreviousContainer = paneModel.FindParent() == null; + int currentSelectedContentIndex = paneModel.SelectedContentIndex; + while( paneModel.Children.Count > 0 ) + { + var contentModel = paneModel.Children[ paneModel.Children.Count - 1 ] as LayoutAnchorable; + + if( savePreviousContainer ) + { + var contentModelAsPreviousContainer = contentModel as ILayoutPreviousContainer; + contentModelAsPreviousContainer.PreviousContainer = paneModel; + contentModel.PreviousContainerIndex = paneModel.Children.Count - 1; + } + + paneModel.RemoveChildAt( paneModel.Children.Count - 1 ); + destPane.Children.Insert( 0, contentModel ); + } + + if( destPane.Children.Count > 0 ) + { + destPane.SelectedContentIndex = currentSelectedContentIndex; + } + + + LayoutFloatingWindow fw; + LayoutFloatingWindowControl fwc; + fw = new LayoutAnchorableFloatingWindow() + { + RootPanel = new LayoutAnchorablePaneGroup( + destPane ) + { + DockHeight = destPane.DockHeight, + DockWidth = destPane.DockWidth, + DockMinHeight = destPane.DockMinHeight, + DockMinWidth = destPane.DockMinWidth, + } + }; + + Layout.FloatingWindows.Add( fw ); + + fwc = new LayoutAnchorableFloatingWindowControl( + fw as LayoutAnchorableFloatingWindow ) + { + Width = fwWidth, + Height = fwHeight + }; + + + + //fwc.Owner = Window.GetWindow(this); + //fwc.SetParentToMainWindowOf(this); + + + _fwList.Add( fwc ); + + Layout.CollectGarbage(); + + InvalidateArrange(); + + fwc.AttachDrag(); + fwc.Show(); + + } + + internal IEnumerable GetFloatingWindowsByZOrder() + { + var parentWindow = Window.GetWindow( this ); + + if( parentWindow == null ) + yield break; + + IntPtr windowParentHanlde = new WindowInteropHelper( parentWindow ).Handle; + + IntPtr currentHandle = Win32Helper.GetWindow( windowParentHanlde, ( uint )Win32Helper.GetWindow_Cmd.GW_HWNDFIRST ); + while( currentHandle != IntPtr.Zero ) + { + LayoutFloatingWindowControl ctrl = _fwList.FirstOrDefault( fw => new WindowInteropHelper( fw ).Handle == currentHandle ); + if( ctrl != null && ctrl.Model.Root.Manager == this ) + yield return ctrl; + + currentHandle = Win32Helper.GetWindow( currentHandle, ( uint )Win32Helper.GetWindow_Cmd.GW_HWNDNEXT ); + } + } + + internal void RemoveFloatingWindow( LayoutFloatingWindowControl floatingWindow ) + { + _fwList.Remove( floatingWindow ); + } + + internal void _ExecuteCloseCommand( LayoutDocument document ) + { + if( DocumentClosing != null ) + { + var evargs = new DocumentClosingEventArgs( document ); + DocumentClosing( this, evargs ); + if( evargs.Cancel ) + return; + } + + if( document.CloseDocument() ) + { + this.RemoveViewFromLogicalChild( document ); + + if( DocumentClosed != null ) + { + var evargs = new DocumentClosedEventArgs( document ); + DocumentClosed( this, evargs ); + } + } + } + + internal void _ExecuteCloseAllButThisCommand( LayoutContent contentSelected ) + { + foreach( var contentToClose in Layout.Descendents().OfType().Where( d => d != contentSelected && ( d.Parent is LayoutDocumentPane || d.Parent is LayoutDocumentFloatingWindow ) ).ToArray() ) + { + this.Close( contentToClose ); + } + } + + internal void _ExecuteCloseAllCommand( LayoutContent contentSelected ) + { + foreach( var contentToClose in Layout.Descendents().OfType().Where( d => ( d.Parent is LayoutDocumentPane || d.Parent is LayoutDocumentFloatingWindow ) ).ToArray() ) + { + this.Close( contentToClose ); + } + } + + internal void _ExecuteCloseCommand( LayoutAnchorable anchorable ) + { + var model = anchorable as LayoutAnchorable; + if( model != null ) + { + model.CloseAnchorable(); + this.RemoveViewFromLogicalChild( anchorable ); + } + } + + internal void _ExecuteHideCommand( LayoutAnchorable anchorable ) + { + var model = anchorable as LayoutAnchorable; + if( model != null ) + { + model.Hide(); + } + } + + internal void _ExecuteAutoHideCommand( LayoutAnchorable _anchorable ) + { + _anchorable.ToggleAutoHide(); + } + + + internal void _ExecuteFloatCommand( LayoutContent contentToFloat ) + { + contentToFloat.Float(); + } + + internal void _ExecuteDockCommand( LayoutAnchorable anchorable ) + { + anchorable.Dock(); + } + + internal void _ExecuteDockAsDocumentCommand( LayoutContent content ) + { + content.DockAsDocument(); + } + + internal void _ExecuteContentActivateCommand( LayoutContent content ) + { + content.IsActive = true; + } + + #endregion + + #region Private Methods + + private void OnLayoutRootPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + if( e.PropertyName == "RootPanel" ) + { + if( IsInitialized ) + { + var layoutRootPanel = CreateUIElementForModel( Layout.RootPanel ) as LayoutPanelControl; + LayoutRootPanel = layoutRootPanel; + } + } + else if( e.PropertyName == "ActiveContent" ) + { + if( Layout.ActiveContent != null ) + { + //Debug.WriteLine(new StackTrace().ToString()); + + //set focus on active element only after a layout pass is completed + //it's possible that it is not yet visible in the visual tree + //if (_setFocusAsyncOperation == null) + //{ + // _setFocusAsyncOperation = Dispatcher.BeginInvoke(new Action(() => + // { + if( Layout.ActiveContent != null ) + FocusElementManager.SetFocusOnLastElement( Layout.ActiveContent ); + //_setFocusAsyncOperation = null; + // } ), DispatcherPriority.Input ); + //} + } + + //if (!_insideInternalSetActiveContent) + // ActiveContent = Layout.ActiveContent != null ? + // Layout.ActiveContent.Content : null; + if( !_insideInternalSetActiveContent && ( Layout.ActiveContent != null ) ) + { + this.ActiveContent = Layout.ActiveContent.Content; + } + } + } + + private void OnLayoutRootUpdated( object sender, EventArgs e ) + { + CommandManager.InvalidateRequerySuggested(); + } + + private void OnLayoutChanging( LayoutRoot newLayout ) + { + if( LayoutChanging != null ) + LayoutChanging( this, EventArgs.Empty ); + } + + private void DockingManager_Loaded( object sender, RoutedEventArgs e ) + { + if( !DesignerProperties.GetIsInDesignMode( this ) ) + { + if( Layout.Manager == this ) + { + LayoutRootPanel = CreateUIElementForModel( Layout.RootPanel ) as LayoutPanelControl; + LeftSidePanel = CreateUIElementForModel( Layout.LeftSide ) as LayoutAnchorSideControl; + TopSidePanel = CreateUIElementForModel( Layout.TopSide ) as LayoutAnchorSideControl; + RightSidePanel = CreateUIElementForModel( Layout.RightSide ) as LayoutAnchorSideControl; + BottomSidePanel = CreateUIElementForModel( Layout.BottomSide ) as LayoutAnchorSideControl; + } + + SetupAutoHideWindow(); + + //load windows not already loaded! + foreach( var fw in Layout.FloatingWindows.Where( fw => !_fwList.Any( fwc => fwc.Model == fw ) ) ) + _fwList.Add( CreateUIElementForModel( fw ) as LayoutFloatingWindowControl ); + + //create the overlaywindow if it's possible + if( IsVisible ) + CreateOverlayWindow(); + FocusElementManager.SetupFocusManagement( this ); + } + } + + private void DockingManager_Unloaded( object sender, RoutedEventArgs e ) + { + + if( !DesignerProperties.GetIsInDesignMode( this ) ) + { + if( _autoHideWindowManager != null ) + { + _autoHideWindowManager.HideAutoWindow(); + } + + if( AutoHideWindow != null ) + AutoHideWindow.Dispose(); + + foreach( var fw in _fwList.ToArray() ) + { + //fw.Owner = null; + fw.SetParentWindowToNull(); + fw.KeepContentVisibleOnClose = true; + fw.Close(); + } + + DestroyOverlayWindow(); + FocusElementManager.FinalizeFocusManagement( this ); + } + } + + private void SetupAutoHideWindow() + { + if( _autoHideWindowManager != null ) + _autoHideWindowManager.HideAutoWindow(); + else + _autoHideWindowManager = new AutoHideWindowManager( this ); + + if( AutoHideWindow != null ) + AutoHideWindow.Dispose(); + + SetAutoHideWindow( new LayoutAutoHideWindowControl() ); + } + + private void CreateOverlayWindow() + { + if( _overlayWindow == null ) + { + _overlayWindow = new OverlayWindow( this ); + } + Rect rectWindow = new Rect( this.PointToScreenDPIWithoutFlowDirection( new Point() ), this.TransformActualSizeToAncestor() ); + _overlayWindow.Left = rectWindow.Left; + _overlayWindow.Top = rectWindow.Top; + _overlayWindow.Width = rectWindow.Width; + _overlayWindow.Height = rectWindow.Height; + } + + private void DestroyOverlayWindow() { - get + if( _overlayWindow != null ) + { + _overlayWindow.Close(); + _overlayWindow = null; + } + } + + private void AttachDocumentsSource( LayoutRoot layout, IEnumerable documentsSource ) + { + if( documentsSource == null ) + return; + + if( layout == null ) + return; + + //if (layout.Descendents().OfType().Any()) + // throw new InvalidOperationException("Unable to set the DocumentsSource property if LayoutDocument objects are already present in the model"); + var documentsImported = layout.Descendents().OfType().Select( d => d.Content ).ToArray(); + var documents = documentsSource as IEnumerable; + var listOfDocumentsToImport = new List( documents.OfType() ); + + foreach( var document in listOfDocumentsToImport.ToArray() ) + { + if( documentsImported.Contains( document ) ) + listOfDocumentsToImport.Remove( document ); + } + + + LayoutDocumentPane documentPane = null; + if( layout.LastFocusedDocument != null ) + { + documentPane = layout.LastFocusedDocument.Parent as LayoutDocumentPane; + } + + if( documentPane == null ) + { + documentPane = layout.Descendents().OfType().FirstOrDefault(); + } + + //if (documentPane == null) + // throw new InvalidOperationException("Layout must contains at least one LayoutDocumentPane in order to host documents"); + + _suspendLayoutItemCreation = true; + foreach( var documentContentToImport in listOfDocumentsToImport ) + { + + //documentPane.Children.Add(new LayoutDocument() { Content = documentToImport }); + + var documentToImport = new LayoutDocument() + { + Content = documentContentToImport + }; + + bool added = false; + if( LayoutUpdateStrategy != null ) + { + added = LayoutUpdateStrategy.BeforeInsertDocument( layout, documentToImport, documentPane ); + } + + if( !added ) + { + if( documentPane == null ) + throw new InvalidOperationException( "Layout must contains at least one LayoutDocumentPane in order to host documents" ); + + documentPane.Children.Add( documentToImport ); + added = true; + } + + if( LayoutUpdateStrategy != null ) + LayoutUpdateStrategy.AfterInsertDocument( layout, documentToImport ); + + + CreateDocumentLayoutItem( documentToImport ); + + } + _suspendLayoutItemCreation = false; + + + var documentsSourceAsNotifier = documentsSource as INotifyCollectionChanged; + if( documentsSourceAsNotifier != null ) + documentsSourceAsNotifier.CollectionChanged += new NotifyCollectionChangedEventHandler( documentsSourceElementsChanged ); + } + + private void documentsSourceElementsChanged( object sender, NotifyCollectionChangedEventArgs e ) + { + if( Layout == null ) + return; + + //When deserializing documents are created automatically by the deserializer + if( SuspendDocumentsSourceBinding ) + return; + + //handle remove + if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) + { + if( e.OldItems != null ) + { + var documentsToRemove = Layout.Descendents().OfType().Where( d => e.OldItems.Contains( d.Content ) ).ToArray(); + foreach( var documentToRemove in documentsToRemove ) + { + ( documentToRemove.Parent as ILayoutContainer ).RemoveChild( + documentToRemove ); + this.RemoveViewFromLogicalChild( documentToRemove ); + } + } + } + + //handle add + if( e.NewItems != null && + ( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) ) + { + if( e.NewItems != null ) + { + LayoutDocumentPane documentPane = null; + if( Layout.LastFocusedDocument != null ) + { + documentPane = Layout.LastFocusedDocument.Parent as LayoutDocumentPane; + } + + if( documentPane == null ) + { + documentPane = Layout.Descendents().OfType().FirstOrDefault(); + } + + //if (documentPane == null) + // throw new InvalidOperationException("Layout must contains at least one LayoutDocumentPane in order to host documents"); + + _suspendLayoutItemCreation = true; + + foreach( var documentContentToImport in e.NewItems ) + { + var documentToImport = new LayoutDocument() + { + Content = documentContentToImport + }; + + bool added = false; + if( LayoutUpdateStrategy != null ) + { + added = LayoutUpdateStrategy.BeforeInsertDocument( Layout, documentToImport, documentPane ); + } + + if( !added ) + { + if( documentPane == null ) + throw new InvalidOperationException( "Layout must contains at least one LayoutDocumentPane in order to host documents" ); + + documentPane.Children.Add( documentToImport ); + added = true; + } + + if( LayoutUpdateStrategy != null ) + { + LayoutUpdateStrategy.AfterInsertDocument( Layout, documentToImport ); + } + + + var root = documentToImport.Root; + + if( root != null && root.Manager == this ) + { + CreateDocumentLayoutItem( documentToImport ); + } + } + _suspendLayoutItemCreation = false; + } + } + + if( e.Action == NotifyCollectionChangedAction.Reset ) + { + //NOTE: I'm going to clear every document present in layout but + //some documents may have been added directly to the layout, for now I clear them too + var documentsToRemove = Layout.Descendents().OfType().ToArray(); + foreach( var documentToRemove in documentsToRemove ) + { + ( documentToRemove.Parent as ILayoutContainer ).RemoveChild( + documentToRemove ); + this.RemoveViewFromLogicalChild( documentToRemove ); + } + } + + if( Layout != null ) + { + Layout.CollectGarbage(); + } + } + + private void DetachDocumentsSource( LayoutRoot layout, IEnumerable documentsSource ) + { + if( documentsSource == null ) + return; + + if( layout == null ) + return; + + var documentsToRemove = layout.Descendents().OfType() + .Where( d => documentsSource.Contains( d.Content ) ).ToArray(); + + foreach( var documentToRemove in documentsToRemove ) + { + ( documentToRemove.Parent as ILayoutContainer ).RemoveChild( + documentToRemove ); + this.RemoveViewFromLogicalChild( documentToRemove ); + } + + var documentsSourceAsNotifier = documentsSource as INotifyCollectionChanged; + if( documentsSourceAsNotifier != null ) + documentsSourceAsNotifier.CollectionChanged -= new NotifyCollectionChangedEventHandler( documentsSourceElementsChanged ); + } + + private void Close( LayoutContent contentToClose ) + { + if( !contentToClose.CanClose ) + return; + + var layoutItem = GetLayoutItemFromModel( contentToClose ); + if( layoutItem.CloseCommand != null ) + { + if( layoutItem.CloseCommand.CanExecute( null ) ) + layoutItem.CloseCommand.Execute( null ); + } + else + { + if( contentToClose is LayoutDocument ) + _ExecuteCloseCommand( contentToClose as LayoutDocument ); + else if( contentToClose is LayoutAnchorable ) + _ExecuteCloseCommand( contentToClose as LayoutAnchorable ); + } + } + + private void AttachAnchorablesSource( LayoutRoot layout, IEnumerable anchorablesSource ) + { + if( anchorablesSource == null ) + return; + + if( layout == null ) + return; + + //if (layout.Descendents().OfType().Any()) + // throw new InvalidOperationException("Unable to set the AnchorablesSource property if LayoutAnchorable objects are already present in the model"); + var anchorablesImported = layout.Descendents().OfType().Select( d => d.Content ).ToArray(); + var anchorables = anchorablesSource as IEnumerable; + var listOfAnchorablesToImport = new List( anchorables.OfType() ); + + foreach( var document in listOfAnchorablesToImport.ToArray() ) + { + if( anchorablesImported.Contains( document ) ) + listOfAnchorablesToImport.Remove( document ); + } + + LayoutAnchorablePane anchorablePane = null; + if( layout.ActiveContent != null ) { - return ( DataTemplate )GetValue( DocumentPaneMenuItemHeaderTemplateProperty ); + //look for active content parent pane + anchorablePane = layout.ActiveContent.Parent as LayoutAnchorablePane; } - set + + if( anchorablePane == null ) { - SetValue( DocumentPaneMenuItemHeaderTemplateProperty, value ); + //look for a pane on the right side + anchorablePane = layout.Descendents().OfType().Where( pane => !pane.IsHostedInFloatingWindow && pane.GetSide() == AnchorSide.Right ).FirstOrDefault(); } - } - /// - /// Handles changes to the DocumentPaneMenuItemHeaderTemplate property. - /// - private static void OnDocumentPaneMenuItemHeaderTemplateChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) - { - ( ( DockingManager )d ).OnDocumentPaneMenuItemHeaderTemplateChanged( e ); - } + if( anchorablePane == null ) + { + //look for an available pane + anchorablePane = layout.Descendents().OfType().FirstOrDefault(); + } - /// - /// Provides derived classes an opportunity to handle changes to the DocumentPaneMenuItemHeaderTemplate property. - /// - protected virtual void OnDocumentPaneMenuItemHeaderTemplateChanged( DependencyPropertyChangedEventArgs e ) - { - } + _suspendLayoutItemCreation = true; + foreach( var anchorableContentToImport in listOfAnchorablesToImport ) + { + var anchorableToImport = new LayoutAnchorable() + { + Content = anchorableContentToImport + }; - /// - /// Coerces the DocumentPaneMenuItemHeaderTemplate value. - /// - private static object CoerceDocumentPaneMenuItemHeaderTemplateValue( DependencyObject d, object value ) - { - if( value != null && - d.GetValue( DocumentPaneMenuItemHeaderTemplateSelectorProperty ) != null ) - return null; - if( value == null ) - return d.GetValue( DocumentHeaderTemplateProperty ); + bool added = false; + if( LayoutUpdateStrategy != null ) + { + added = LayoutUpdateStrategy.BeforeInsertAnchorable( layout, anchorableToImport, anchorablePane ); + } - return value; - } + if( !added ) + { + if( anchorablePane == null ) + { + var mainLayoutPanel = new LayoutPanel() { Orientation = Orientation.Horizontal }; + if( layout.RootPanel != null ) + { + mainLayoutPanel.Children.Add( layout.RootPanel ); + } - #endregion + layout.RootPanel = mainLayoutPanel; + anchorablePane = new LayoutAnchorablePane() { DockWidth = new GridLength( 200.0, GridUnitType.Pixel ) }; + mainLayoutPanel.Children.Add( anchorablePane ); + } - #region DocumentPaneMenuItemHeaderTemplateSelector + anchorablePane.Children.Add( anchorableToImport ); + added = true; + } - /// - /// DocumentPaneMenuItemHeaderTemplateSelector Dependency Property - /// - public static readonly DependencyProperty DocumentPaneMenuItemHeaderTemplateSelectorProperty = - DependencyProperty.Register( "DocumentPaneMenuItemHeaderTemplateSelector", typeof( DataTemplateSelector ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( DataTemplateSelector )null, - new PropertyChangedCallback( OnDocumentPaneMenuItemHeaderTemplateSelectorChanged ), - new CoerceValueCallback( CoerceDocumentPaneMenuItemHeaderTemplateSelectorValue ) ) ); + if( LayoutUpdateStrategy != null ) + LayoutUpdateStrategy.AfterInsertAnchorable( layout, anchorableToImport ); - /// - /// Gets or sets the DocumentPaneMenuItemHeaderTemplateSelector property. This dependency property - /// indicates the data template selector to use for the menu items show when user select the DocumentPane document switch context menu. - /// - public DataTemplateSelector DocumentPaneMenuItemHeaderTemplateSelector + + CreateAnchorableLayoutItem( anchorableToImport ); + + } + + _suspendLayoutItemCreation = false; + + var anchorablesSourceAsNotifier = anchorablesSource as INotifyCollectionChanged; + if( anchorablesSourceAsNotifier != null ) + anchorablesSourceAsNotifier.CollectionChanged += new NotifyCollectionChangedEventHandler( anchorablesSourceElementsChanged ); + } + + private void anchorablesSourceElementsChanged( object sender, NotifyCollectionChangedEventArgs e ) { - get + if( Layout == null ) + return; + + //When deserializing documents are created automatically by the deserializer + if( SuspendAnchorablesSourceBinding ) + return; + + //handle remove + if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) { - return ( DataTemplateSelector )GetValue( DocumentPaneMenuItemHeaderTemplateSelectorProperty ); + if( e.OldItems != null ) + { + var anchorablesToRemove = Layout.Descendents().OfType().Where( d => e.OldItems.Contains( d.Content ) ).ToArray(); + foreach( var anchorableToRemove in anchorablesToRemove ) + { + anchorableToRemove.Content = null; + ( anchorableToRemove.Parent as ILayoutContainer ).RemoveChild( + anchorableToRemove ); + this.RemoveViewFromLogicalChild( anchorableToRemove ); + } + } } - set + + //handle add + if( e.NewItems != null && + ( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) ) { - SetValue( DocumentPaneMenuItemHeaderTemplateSelectorProperty, value ); - } - } + if( e.NewItems != null ) + { + LayoutAnchorablePane anchorablePane = null; - /// - /// Handles changes to the DocumentPaneMenuItemHeaderTemplateSelector property. - /// - private static void OnDocumentPaneMenuItemHeaderTemplateSelectorChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) - { - ( ( DockingManager )d ).OnDocumentPaneMenuItemHeaderTemplateSelectorChanged( e ); - } + if( Layout.ActiveContent != null ) + { + //look for active content parent pane + anchorablePane = Layout.ActiveContent.Parent as LayoutAnchorablePane; + } - /// - /// Provides derived classes an opportunity to handle changes to the DocumentPaneMenuItemHeaderTemplateSelector property. - /// - protected virtual void OnDocumentPaneMenuItemHeaderTemplateSelectorChanged( DependencyPropertyChangedEventArgs e ) - { - if( e.NewValue != null && - DocumentPaneMenuItemHeaderTemplate != null ) - DocumentPaneMenuItemHeaderTemplate = null; + if( anchorablePane == null ) + { + //look for a pane on the right side + anchorablePane = Layout.Descendents().OfType().Where( pane => !pane.IsHostedInFloatingWindow && pane.GetSide() == AnchorSide.Right ).FirstOrDefault(); + } - } + if( anchorablePane == null ) + { + //look for an available pane + anchorablePane = Layout.Descendents().OfType().FirstOrDefault(); + } - /// - /// Coerces the DocumentPaneMenuItemHeaderTemplateSelector value. - /// - private static object CoerceDocumentPaneMenuItemHeaderTemplateSelectorValue( DependencyObject d, object value ) - { - return value; - } + _suspendLayoutItemCreation = true; + foreach( var anchorableContentToImport in e.NewItems ) + { + var anchorableToImport = new LayoutAnchorable() + { + Content = anchorableContentToImport + }; - #endregion + bool added = false; + if( LayoutUpdateStrategy != null ) + { + added = LayoutUpdateStrategy.BeforeInsertAnchorable( Layout, anchorableToImport, anchorablePane ); + } - #region IconContentTemplate + if( !added ) + { + if( anchorablePane == null ) + { + var mainLayoutPanel = new LayoutPanel() { Orientation = Orientation.Horizontal }; + if( Layout.RootPanel != null ) + { + mainLayoutPanel.Children.Add( Layout.RootPanel ); + } - /// - /// IconContentTemplate Dependency Property - /// - public static readonly DependencyProperty IconContentTemplateProperty = - DependencyProperty.Register( "IconContentTemplate", typeof( DataTemplate ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( DataTemplate )null ) ); + Layout.RootPanel = mainLayoutPanel; + anchorablePane = new LayoutAnchorablePane() { DockWidth = new GridLength( 200.0, GridUnitType.Pixel ) }; + mainLayoutPanel.Children.Add( anchorablePane ); + } - /// - /// Gets or sets the IconContentTemplate property. This dependency property - /// indicates the data template to use while extracting the icon from model. - /// - public DataTemplate IconContentTemplate - { - get - { - return ( DataTemplate )GetValue( IconContentTemplateProperty ); + anchorablePane.Children.Add( anchorableToImport ); + added = true; + } + + if( LayoutUpdateStrategy != null ) + { + LayoutUpdateStrategy.AfterInsertAnchorable( Layout, anchorableToImport ); + } + + var root = anchorableToImport.Root; + + if( root != null && root.Manager == this ) + { + CreateAnchorableLayoutItem( anchorableToImport ); + } + + } + _suspendLayoutItemCreation = false; + } } - set + + if( e.Action == NotifyCollectionChangedAction.Reset ) { - SetValue( IconContentTemplateProperty, value ); + //NOTE: I'm going to clear every anchorable present in layout but + //some anchorable may have been added directly to the layout, for now I clear them too + var anchorablesToRemove = Layout.Descendents().OfType().ToArray(); + foreach( var anchorableToRemove in anchorablesToRemove ) + { + ( anchorableToRemove.Parent as ILayoutContainer ).RemoveChild( + anchorableToRemove ); + this.RemoveViewFromLogicalChild( anchorableToRemove ); + } } + + if( Layout != null ) + Layout.CollectGarbage(); } - #endregion + private void DetachAnchorablesSource( LayoutRoot layout, IEnumerable anchorablesSource ) + { + if( anchorablesSource == null ) + return; - #region IconContentTemplateSelector + if( layout == null ) + return; - /// - /// IconContentTemplateSelector Dependency Property - /// - public static readonly DependencyProperty IconContentTemplateSelectorProperty = - DependencyProperty.Register( "IconContentTemplateSelector", typeof( DataTemplateSelector ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( DataTemplateSelector )null ) ); + var anchorablesToRemove = layout.Descendents().OfType() + .Where( d => anchorablesSource.Contains( d.Content ) ).ToArray(); - /// - /// Gets or sets the IconContentTemplateSelector property. This dependency property - /// indicates data template selector to use while selecting the datatamplate for content icons. - /// - public DataTemplateSelector IconContentTemplateSelector - { - get - { - return ( DataTemplateSelector )GetValue( IconContentTemplateSelectorProperty ); - } - set + foreach( var anchorableToRemove in anchorablesToRemove ) { - SetValue( IconContentTemplateSelectorProperty, value ); + ( anchorableToRemove.Parent as ILayoutContainer ).RemoveChild( + anchorableToRemove ); + this.RemoveViewFromLogicalChild( anchorableToRemove ); } - } - #endregion + var anchorablesSourceAsNotifier = anchorablesSource as INotifyCollectionChanged; + if( anchorablesSourceAsNotifier != null ) + anchorablesSourceAsNotifier.CollectionChanged -= new NotifyCollectionChangedEventHandler( anchorablesSourceElementsChanged ); + } - #region LayoutItems + private void RemoveViewFromLogicalChild( LayoutContent layoutContent ) + { + if( layoutContent == null ) + return; - List _layoutItems = new List(); + var layoutItem = this.GetLayoutItemFromModel( layoutContent ); + if( layoutItem != null ) + { + if( layoutItem.IsViewExists() ) + { + this.InternalRemoveLogicalChild( layoutItem.View ); + } + } + } - bool _suspendLayoutItemCreation = false; + private void InternalSetActiveContent( object contentObject ) + { + var layoutContent = Layout.Descendents().OfType().FirstOrDefault( lc => lc == contentObject || lc.Content == contentObject ); + _insideInternalSetActiveContent = true; + Layout.ActiveContent = layoutContent; + _insideInternalSetActiveContent = false; + } - void DetachLayoutItems() + private void DetachLayoutItems() { if( Layout != null ) { @@ -3166,7 +3062,7 @@ namespace Xceed.Wpf.AvalonDock } } - void Layout_ElementRemoved( object sender, LayoutElementEventArgs e ) + private void Layout_ElementRemoved( object sender, LayoutElementEventArgs e ) { if( _suspendLayoutItemCreation ) return; @@ -3174,7 +3070,7 @@ namespace Xceed.Wpf.AvalonDock CollectLayoutItemsDeleted(); } - void Layout_ElementAdded( object sender, LayoutElementEventArgs e ) + private void Layout_ElementAdded( object sender, LayoutElementEventArgs e ) { if( _suspendLayoutItemCreation ) return; @@ -3190,34 +3086,31 @@ namespace Xceed.Wpf.AvalonDock CollectLayoutItemsDeleted(); } - - DispatcherOperation _collectLayoutItemsOperations = null; - void CollectLayoutItemsDeleted() + private void CollectLayoutItemsDeleted() { if( _collectLayoutItemsOperations != null ) return; _collectLayoutItemsOperations = Dispatcher.BeginInvoke( new Action( () => - { - _collectLayoutItemsOperations = null; - foreach( var itemToRemove in _layoutItems.Where( item => item.LayoutElement.Root != Layout ).ToArray() ) - { + { + _collectLayoutItemsOperations = null; + foreach( var itemToRemove in _layoutItems.Where( item => item.LayoutElement.Root != Layout ).ToArray() ) + { - if( itemToRemove != null && - itemToRemove.Model != null && - itemToRemove.Model is UIElement ) - { - //((ILogicalChildrenContainer)this).InternalRemoveLogicalChild(itemToRemove.Model as UIElement); - } + if( itemToRemove != null && + itemToRemove.Model != null && + itemToRemove.Model is UIElement ) + { + //((ILogicalChildrenContainer)this).InternalRemoveLogicalChild(itemToRemove.Model as UIElement); + } - itemToRemove.Detach(); - _layoutItems.Remove( itemToRemove ); + itemToRemove.Detach(); + _layoutItems.Remove( itemToRemove ); - } - } ) ); + } + } ) ); } - - void AttachLayoutItems() + private void AttachLayoutItems() { if( Layout != null ) { @@ -3243,7 +3136,7 @@ namespace Xceed.Wpf.AvalonDock } } - void ApplyStyleToLayoutItem( LayoutItem layoutItem ) + private void ApplyStyleToLayoutItem( LayoutItem layoutItem ) { layoutItem._ClearDefaultBindings(); if( LayoutItemContainerStyle != null ) @@ -3253,7 +3146,7 @@ namespace Xceed.Wpf.AvalonDock layoutItem._SetDefaultBindings(); } - void CreateAnchorableLayoutItem( LayoutAnchorable contentToAttach ) + private void CreateAnchorableLayoutItem( LayoutAnchorable contentToAttach ) { if( _layoutItems.Any( item => item.LayoutElement == contentToAttach ) ) { @@ -3278,7 +3171,7 @@ namespace Xceed.Wpf.AvalonDock } - void CreateDocumentLayoutItem( LayoutDocument contentToAttach ) + private void CreateDocumentLayoutItem( LayoutDocument contentToAttach ) { if( _layoutItems.Any( item => item.LayoutElement == contentToAttach ) ) { @@ -3303,205 +3196,129 @@ namespace Xceed.Wpf.AvalonDock } - #region LayoutItemContainerStyle - - /// - /// LayoutItemContainerStyle Dependency Property - /// - public static readonly DependencyProperty LayoutItemContainerStyleProperty = - DependencyProperty.Register( "LayoutItemContainerStyle", typeof( Style ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( Style )null, - new PropertyChangedCallback( OnLayoutItemContainerStyleChanged ) ) ); - - /// - /// Gets or sets the LayoutItemContainerStyle property. This dependency property - /// indicates the style to apply to LayoutDocumentItem objects. A LayoutDocumentItem object is created when a new LayoutDocument is created inside the current Layout. - /// - public Style LayoutItemContainerStyle + private void ShowNavigatorWindow() { - get - { - return ( Style )GetValue( LayoutItemContainerStyleProperty ); - } - set + if( _navigatorWindow == null ) { - SetValue( LayoutItemContainerStyleProperty, value ); + _navigatorWindow = new NavigatorWindow( this ) + { + Owner = Window.GetWindow( this ), + WindowStartupLocation = WindowStartupLocation.CenterOwner + }; } - } - - /// - /// Handles changes to the LayoutItemContainerStyle property. - /// - private static void OnLayoutItemContainerStyleChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) - { - ( ( DockingManager )d ).OnLayoutItemContainerStyleChanged( e ); - } - /// - /// Provides derived classes an opportunity to handle changes to the LayoutItemContainerStyle property. - /// - protected virtual void OnLayoutItemContainerStyleChanged( DependencyPropertyChangedEventArgs e ) - { - AttachLayoutItems(); + _navigatorWindow.ShowDialog(); + _navigatorWindow = null; } #endregion - #region LayoutItemContainerStyleSelector + #region Events /// - /// LayoutItemContainerStyleSelector Dependency Property + /// Event fired when property changes /// - public static readonly DependencyProperty LayoutItemContainerStyleSelectorProperty = - DependencyProperty.Register( "LayoutItemContainerStyleSelector", typeof( StyleSelector ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( StyleSelector )null, - new PropertyChangedCallback( OnLayoutItemContainerStyleSelectorChanged ) ) ); + public event EventHandler LayoutChanged; /// - /// Gets or sets the LayoutItemContainerStyleSelector property. This dependency property - /// indicates style selector of the LayoutDocumentItemStyle. + /// Event fired when property is about to be changed /// - public StyleSelector LayoutItemContainerStyleSelector - { - get - { - return ( StyleSelector )GetValue( LayoutItemContainerStyleSelectorProperty ); - } - set - { - SetValue( LayoutItemContainerStyleSelectorProperty, value ); - } - } + public event EventHandler LayoutChanging; /// - /// Handles changes to the LayoutItemContainerStyleSelector property. + /// Event fired when a document is about to be closed /// - private static void OnLayoutItemContainerStyleSelectorChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) - { - ( ( DockingManager )d ).OnLayoutItemContainerStyleSelectorChanged( e ); - } + /// Subscribers have the opportuniy to cancel the operation. + public event EventHandler DocumentClosing; /// - /// Provides derived classes an opportunity to handle changes to the LayoutItemContainerStyleSelector property. + /// Event fired after a document is closed /// - protected virtual void OnLayoutItemContainerStyleSelectorChanged( DependencyPropertyChangedEventArgs e ) - { - AttachLayoutItems(); - } + public event EventHandler DocumentClosed; - #endregion + public event EventHandler ActiveContentChanged; - /// - /// Return the LayoutItem wrapper for the content passed as argument - /// - /// LayoutContent to search - /// Either a LayoutAnchorableItem or LayoutDocumentItem which contains the LayoutContent passed as argument - public LayoutItem GetLayoutItemFromModel( LayoutContent content ) - { - return _layoutItems.FirstOrDefault( item => item.LayoutElement == content ); - } #endregion - #region NavigatorWindow - NavigatorWindow _navigatorWindow = null; + #region IOverlayWindowHost Interface - void ShowNavigatorWindow() + bool IOverlayWindowHost.HitTest( Point dragPoint ) { - if( _navigatorWindow == null ) - { - _navigatorWindow = new NavigatorWindow( this ) - { - Owner = Window.GetWindow( this ), - WindowStartupLocation = WindowStartupLocation.CenterOwner - }; - } - - _navigatorWindow.ShowDialog(); - _navigatorWindow = null; + Rect detectionRect = new Rect( this.PointToScreenDPIWithoutFlowDirection( new Point() ), this.TransformActualSizeToAncestor() ); + return detectionRect.Contains( dragPoint ); } - bool IsNavigatorWindowActive + DockingManager IOverlayWindowHost.Manager { get { - return _navigatorWindow != null; + return this; } } - - protected override void OnPreviewKeyDown( KeyEventArgs e ) + IOverlayWindow IOverlayWindowHost.ShowOverlayWindow( LayoutFloatingWindowControl draggingWindow ) { - if( Keyboard.IsKeyDown( Key.LeftCtrl ) || Keyboard.IsKeyDown( Key.RightCtrl ) ) - { - if( e.IsDown && e.Key == Key.Tab ) - { - if( !IsNavigatorWindowActive ) - { - ShowNavigatorWindow(); - e.Handled = true; - } - } - } + CreateOverlayWindow(); + _overlayWindow.Owner = draggingWindow; + _overlayWindow.EnableDropTargets(); + _overlayWindow.Show(); + return _overlayWindow; + } - base.OnPreviewKeyDown( e ); + void IOverlayWindowHost.HideOverlayWindow() + { + _areas = null; + _overlayWindow.Owner = null; + _overlayWindow.HideDropTargets(); } - #endregion + IEnumerable IOverlayWindowHost.GetDropAreas( LayoutFloatingWindowControl draggingWindow ) + { + if( _areas != null ) + return _areas; - #region ShowSystemMenu + bool isDraggingDocuments = draggingWindow.Model is LayoutDocumentFloatingWindow; - /// - /// ShowSystemMenu Dependency Property - /// - public static readonly DependencyProperty ShowSystemMenuProperty = - DependencyProperty.Register( "ShowSystemMenu", typeof( bool ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( bool )true ) ); + _areas = new List(); - /// - /// Gets or sets the ShowSystemMenu property. This dependency property - /// indicates if floating windows should show the system menu when a custom context menu is not defined. - /// - public bool ShowSystemMenu - { - get - { - return ( bool )GetValue( ShowSystemMenuProperty ); - } - set + if( !isDraggingDocuments ) { - SetValue( ShowSystemMenuProperty, value ); - } - } - - #endregion - - #region AllowMixedOrientation + _areas.Add( new DropArea( + this, + DropAreaType.DockingManager ) ); - /// - /// AllowMixedOrientation Dependency Property - /// - public static readonly DependencyProperty AllowMixedOrientationProperty = - DependencyProperty.Register( "AllowMixedOrientation", typeof( bool ), typeof( DockingManager ), - new FrameworkPropertyMetadata( ( bool )false ) ); + foreach( var areaHost in this.FindVisualChildren() ) + { + if( areaHost.Model.Descendents().Any() ) + { + _areas.Add( new DropArea( + areaHost, + DropAreaType.AnchorablePane ) ); + } + } + } - /// - /// Gets or sets the AllowMixedOrientation property. This dependency property - /// indicates if the manager should allow mixed orientation for document panes. - /// - public bool AllowMixedOrientation - { - get + foreach( var areaHost in this.FindVisualChildren() ) { - return ( bool )GetValue( AllowMixedOrientationProperty ); + _areas.Add( new DropArea( + areaHost, + DropAreaType.DocumentPane ) ); } - set + + foreach( var areaHost in this.FindVisualChildren() ) { - SetValue( AllowMixedOrientationProperty, value ); + var documentGroupModel = areaHost.Model as LayoutDocumentPaneGroup; + if( documentGroupModel.Children.Where( c => c.IsVisible ).Count() == 0 ) + { + _areas.Add( new DropArea( + areaHost, + DropAreaType.DocumentPaneGroup ) ); + } } + + return _areas; } #endregion - - } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DocumentClosedEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DocumentClosedEventArgs.cs index 980bb0be..42b645e4 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DocumentClosedEventArgs.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DocumentClosedEventArgs.cs @@ -15,24 +15,21 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock { - public class DocumentClosedEventArgs : EventArgs + public class DocumentClosedEventArgs : EventArgs + { + public DocumentClosedEventArgs( LayoutDocument document ) { - public DocumentClosedEventArgs(LayoutDocument document) - { - Document = document; - } - - public LayoutDocument Document - { - get; - private set; - } + Document = document; } + + public LayoutDocument Document + { + get; + private set; + } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DocumentClosingEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DocumentClosingEventArgs.cs index 5c87d960..f7201e9b 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DocumentClosingEventArgs.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DocumentClosingEventArgs.cs @@ -14,26 +14,22 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.ComponentModel; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock { - public class DocumentClosingEventArgs : CancelEventArgs + public class DocumentClosingEventArgs : CancelEventArgs + { + public DocumentClosingEventArgs( LayoutDocument document ) { - public DocumentClosingEventArgs(LayoutDocument document) - { - Document = document; - } - - public LayoutDocument Document - { - get; - private set; - } + Document = document; } + + public LayoutDocument Document + { + get; + private set; + } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Extentions.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Extentions.cs index 5f998ee0..d31c0e33 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Extentions.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Extentions.cs @@ -16,45 +16,43 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Collections; namespace Xceed.Wpf.AvalonDock { - internal static class Extensions + internal static class Extensions + { + public static bool Contains( this IEnumerable collection, object item ) { - public static bool Contains(this IEnumerable collection, object item) - { - foreach (var o in collection) - if (o == item) - return true; - - return false; - } - - - public static void ForEach(this IEnumerable collection, Action action) - { - foreach (T v in collection) - action(v); - } - - - public static int IndexOf(this T[] array, T value) where T : class - { - for (int i = 0; i < array.Length; i++) - if (array[i] == value) - return i; - - return -1; - } - - public static V GetValueOrDefault(this WeakReference wr) - { - if (wr == null || !wr.IsAlive) - return default(V); - return (V)wr.Target; - } + foreach( var o in collection ) + if( o == item ) + return true; + + return false; + } + + + public static void ForEach( this IEnumerable collection, Action action ) + { + foreach( T v in collection ) + action( v ); + } + + + public static int IndexOf( this T[] array, T value ) where T : class + { + for( int i = 0; i < array.Length; i++ ) + if( array[ i ] == value ) + return i; + + return -1; + } + + public static V GetValueOrDefault( this WeakReference wr ) + { + if( wr == null || !wr.IsAlive ) + return default( V ); + return ( V )wr.Target; } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/AnchorSide.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/AnchorSide.cs index d024cb2c..c56c5572 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/AnchorSide.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/AnchorSide.cs @@ -14,21 +14,13 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - namespace Xceed.Wpf.AvalonDock.Layout { - public enum AnchorSide - { - Left, - - Top, - - Right, - - Bottom - } + public enum AnchorSide + { + Left, + Top, + Right, + Bottom + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/AnchorableShowStrategy.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/AnchorableShowStrategy.cs index 5b758db8..e3531984 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/AnchorableShowStrategy.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/AnchorableShowStrategy.cs @@ -15,19 +15,16 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Xceed.Wpf.AvalonDock.Layout { - [Flags] - public enum AnchorableShowStrategy : byte - { - Most = 0x0001, - Left = 0x0002, - Right = 0x0004, - Top = 0x0010, - Bottom= 0x0020, - } + [Flags] + public enum AnchorableShowStrategy : byte + { + Most = 0x0001, + Left = 0x0002, + Right = 0x0004, + Top = 0x0010, + Bottom = 0x0020, + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ChildrenTreeChangedEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ChildrenTreeChangedEventArgs.cs index d36b9c51..f71fd05d 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ChildrenTreeChangedEventArgs.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ChildrenTreeChangedEventArgs.cs @@ -15,32 +15,32 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Xceed.Wpf.AvalonDock.Layout { - public enum ChildrenTreeChange + public enum ChildrenTreeChange + { + /// + /// Direct insert/remove operation has been perfomed to the group + /// + DirectChildrenChanged, + + /// + /// An element below in the hierarchy as been added/removed + /// + TreeChanged + } + + public class ChildrenTreeChangedEventArgs : EventArgs + { + public ChildrenTreeChangedEventArgs( ChildrenTreeChange change ) { - /// - /// Direct insert/remove operation has been perfomed to the group - /// - DirectChildrenChanged, - - /// - /// An element below in the hierarchy as been added/removed - /// - TreeChanged + Change = change; } - public class ChildrenTreeChangedEventArgs : EventArgs + public ChildrenTreeChange Change { - public ChildrenTreeChangedEventArgs(ChildrenTreeChange change) - { - Change = change; - } - - public ChildrenTreeChange Change { get; private set; } + get; private set; } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Extentions.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Extentions.cs index 8cb5ac3e..ce491425 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Extentions.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Extentions.cs @@ -14,156 +14,149 @@ ***********************************************************************************/ -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Windows.Media; -using System.Windows.Media.Media3D; using System.Diagnostics; using System.Runtime.InteropServices; namespace Xceed.Wpf.AvalonDock.Layout { - public static class Extensions + public static class Extensions + { + #region Public Methods + + public static IEnumerable Descendents( this ILayoutElement element ) { - public static IEnumerable Descendents(this ILayoutElement element) + var container = element as ILayoutContainer; + if( container != null ) + { + foreach( var childElement in container.Children ) { - var container = element as ILayoutContainer; - if (container != null) - { - foreach (var childElement in container.Children) - { - yield return childElement; - foreach (var childChildElement in childElement.Descendents()) - yield return childChildElement; - } - } + yield return childElement; + foreach( var childChildElement in childElement.Descendents() ) + yield return childChildElement; } + } + } - public static T FindParent(this ILayoutElement element) //where T : ILayoutContainer - { - var parent = element.Parent; - while (parent != null && - !(parent is T)) - parent = parent.Parent; + public static T FindParent( this ILayoutElement element ) //where T : ILayoutContainer + { + var parent = element.Parent; + while( parent != null && + !( parent is T ) ) + parent = parent.Parent; - return (T)parent; - } + return ( T )parent; + } - public static ILayoutRoot GetRoot(this ILayoutElement element) //where T : ILayoutContainer - { - if (element is ILayoutRoot) - return element as ILayoutRoot; + public static ILayoutRoot GetRoot( this ILayoutElement element ) //where T : ILayoutContainer + { + if( element is ILayoutRoot ) + return element as ILayoutRoot; - var parent = element.Parent; - while (parent != null && - !(parent is ILayoutRoot)) - parent = parent.Parent; + var parent = element.Parent; + while( parent != null && + !( parent is ILayoutRoot ) ) + parent = parent.Parent; - return (ILayoutRoot)parent; - } + return ( ILayoutRoot )parent; + } - public static bool ContainsChildOfType(this ILayoutContainer element) - { - foreach (var childElement in element.Descendents()) - if (childElement is T) - return true; + public static bool ContainsChildOfType( this ILayoutContainer element ) + { + foreach( var childElement in element.Descendents() ) + if( childElement is T ) + return true; - return false; - } + return false; + } - public static bool ContainsChildOfType(this ILayoutContainer container) - { - foreach (var childElement in container.Descendents()) - if (childElement is T || childElement is S) - return true; + public static bool ContainsChildOfType( this ILayoutContainer container ) + { + foreach( var childElement in container.Descendents() ) + if( childElement is T || childElement is S ) + return true; - return false; - } + return false; + } - public static bool IsOfType(this ILayoutContainer container) + public static bool IsOfType( this ILayoutContainer container ) + { + return container is T || container is S; + } + + public static AnchorSide GetSide( this ILayoutElement element ) + { + var parentContainer = element.Parent as ILayoutOrientableGroup; + if( parentContainer != null ) + { + var layoutPanel = parentContainer as LayoutPanel; + if( layoutPanel == null ) { - return container is T || container is S; + layoutPanel = parentContainer.FindParent(); } - public static AnchorSide GetSide(this ILayoutElement element) + if( (layoutPanel != null) && ( layoutPanel.Children.Count > 0 ) ) { - var parentContainer = element.Parent as ILayoutOrientableGroup; - if (parentContainer != null) - { - if (!parentContainer.ContainsChildOfType()) - return GetSide(parentContainer); - - foreach (var childElement in parentContainer.Children) - { - if (childElement == element || - childElement.Descendents().Contains(element)) - return parentContainer.Orientation == System.Windows.Controls.Orientation.Horizontal ? - AnchorSide.Left : AnchorSide.Top; - - var childElementAsContainer = childElement as ILayoutContainer; - if (childElementAsContainer != null && - (childElementAsContainer.IsOfType() || - childElementAsContainer.ContainsChildOfType())) - { - return parentContainer.Orientation == System.Windows.Controls.Orientation.Horizontal ? - AnchorSide.Right : AnchorSide.Bottom; - } - } - } - - Debug.Fail("Unable to find the side for an element, possible layout problem!"); - return AnchorSide.Right; + if( layoutPanel.Orientation == System.Windows.Controls.Orientation.Horizontal ) + return layoutPanel.Children[ 0 ].Descendents().Contains( element ) ? AnchorSide.Left : AnchorSide.Right; + return layoutPanel.Children[ 0 ].Descendents().Contains( element ) ? AnchorSide.Top : AnchorSide.Bottom; } + } + Debug.Fail( "Unable to find the side for an element, possible layout problem!" ); + return AnchorSide.Right; + } - internal static void KeepInsideNearestMonitor(this ILayoutElementForFloatingWindow paneInsideFloatingWindow) - { - Win32Helper.RECT r = new Win32Helper.RECT(); - r.Left = (int)paneInsideFloatingWindow.FloatingLeft; - r.Top = (int)paneInsideFloatingWindow.FloatingTop; - r.Bottom = r.Top + (int)paneInsideFloatingWindow.FloatingHeight; - r.Right = r.Left + (int)paneInsideFloatingWindow.FloatingWidth; - - uint MONITOR_DEFAULTTONEAREST = 0x00000002; - uint MONITOR_DEFAULTTONULL = 0x00000000; - - System.IntPtr monitor = Win32Helper.MonitorFromRect(ref r, MONITOR_DEFAULTTONULL); - if (monitor == System.IntPtr.Zero) - { - System.IntPtr nearestmonitor = Win32Helper.MonitorFromRect(ref r, MONITOR_DEFAULTTONEAREST); - if (nearestmonitor != System.IntPtr.Zero) - { - Win32Helper.MonitorInfo monitorInfo = new Win32Helper.MonitorInfo(); - monitorInfo.Size = Marshal.SizeOf(monitorInfo); - Win32Helper.GetMonitorInfo(nearestmonitor, monitorInfo); - - if (paneInsideFloatingWindow.FloatingLeft < monitorInfo.Work.Left) - { - paneInsideFloatingWindow.FloatingLeft = monitorInfo.Work.Left + 10; - } - - if (paneInsideFloatingWindow.FloatingLeft + paneInsideFloatingWindow.FloatingWidth > monitorInfo.Work.Right) - { - paneInsideFloatingWindow.FloatingLeft = monitorInfo.Work.Right - (paneInsideFloatingWindow.FloatingWidth + 10); - } - - if (paneInsideFloatingWindow.FloatingTop < monitorInfo.Work.Top) - { - paneInsideFloatingWindow.FloatingTop = monitorInfo.Work.Top + 10; - } - - if (paneInsideFloatingWindow.FloatingTop + paneInsideFloatingWindow.FloatingHeight > monitorInfo.Work.Bottom) - { - paneInsideFloatingWindow.FloatingTop = monitorInfo.Work.Bottom - (paneInsideFloatingWindow.FloatingHeight + 10); - } - } - } + #endregion + + #region Internal Methods + internal static void KeepInsideNearestMonitor( this ILayoutElementForFloatingWindow paneInsideFloatingWindow ) + { + Win32Helper.RECT r = new Win32Helper.RECT(); + r.Left = ( int )paneInsideFloatingWindow.FloatingLeft; + r.Top = ( int )paneInsideFloatingWindow.FloatingTop; + r.Bottom = r.Top + ( int )paneInsideFloatingWindow.FloatingHeight; + r.Right = r.Left + ( int )paneInsideFloatingWindow.FloatingWidth; + + uint MONITOR_DEFAULTTONEAREST = 0x00000002; + uint MONITOR_DEFAULTTONULL = 0x00000000; + + System.IntPtr monitor = Win32Helper.MonitorFromRect( ref r, MONITOR_DEFAULTTONULL ); + if( monitor == System.IntPtr.Zero ) + { + System.IntPtr nearestmonitor = Win32Helper.MonitorFromRect( ref r, MONITOR_DEFAULTTONEAREST ); + if( nearestmonitor != System.IntPtr.Zero ) + { + Win32Helper.MonitorInfo monitorInfo = new Win32Helper.MonitorInfo(); + monitorInfo.Size = Marshal.SizeOf( monitorInfo ); + Win32Helper.GetMonitorInfo( nearestmonitor, monitorInfo ); + + if( paneInsideFloatingWindow.FloatingLeft < monitorInfo.Work.Left ) + { + paneInsideFloatingWindow.FloatingLeft = monitorInfo.Work.Left + 10; + } + + if( paneInsideFloatingWindow.FloatingLeft + paneInsideFloatingWindow.FloatingWidth > monitorInfo.Work.Right ) + { + paneInsideFloatingWindow.FloatingLeft = monitorInfo.Work.Right - ( paneInsideFloatingWindow.FloatingWidth + 10 ); + } + + if( paneInsideFloatingWindow.FloatingTop < monitorInfo.Work.Top ) + { + paneInsideFloatingWindow.FloatingTop = monitorInfo.Work.Top + 10; + } + + if( paneInsideFloatingWindow.FloatingTop + paneInsideFloatingWindow.FloatingHeight > monitorInfo.Work.Bottom ) + { + paneInsideFloatingWindow.FloatingTop = monitorInfo.Work.Bottom - ( paneInsideFloatingWindow.FloatingHeight + 10 ); + } } + } } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutAnchorablePane.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutAnchorablePane.cs index feacc288..f720726f 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutAnchorablePane.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutAnchorablePane.cs @@ -14,14 +14,10 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Xceed.Wpf.AvalonDock.Layout { - public interface ILayoutAnchorablePane : ILayoutPanelElement, ILayoutPane - { - } + public interface ILayoutAnchorablePane : ILayoutPanelElement, ILayoutPane + { + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutContainer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutContainer.cs index 78d765d8..542122aa 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutContainer.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutContainer.cs @@ -14,18 +14,32 @@ ***********************************************************************************/ -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Xceed.Wpf.AvalonDock.Layout { - public interface ILayoutContainer : ILayoutElement + public interface ILayoutContainer : ILayoutElement + { + #region Properties + + IEnumerable Children { - IEnumerable Children { get; } - void RemoveChild(ILayoutElement element); - void ReplaceChild(ILayoutElement oldElement, ILayoutElement newElement); - int ChildrenCount { get; } + get; } + + int ChildrenCount + { + get; + } + + #endregion + + #region Methods + + void RemoveChild( ILayoutElement element ); + + void ReplaceChild( ILayoutElement oldElement, ILayoutElement newElement ); + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutContentSelector.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutContentSelector.cs index ea01b9d5..da71a637 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutContentSelector.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutContentSelector.cs @@ -14,19 +14,28 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - namespace Xceed.Wpf.AvalonDock.Layout { - public interface ILayoutContentSelector - { - int SelectedContentIndex { get; set; } + public interface ILayoutContentSelector + { + #region Properties - int IndexOf(LayoutContent content); + int SelectedContentIndex + { + get; set; + } - LayoutContent SelectedContent { get; } + LayoutContent SelectedContent + { + get; } + + #endregion + + #region Methods + + int IndexOf( LayoutContent content ); + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutControl.cs index b6555122..8d6d120a 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutControl.cs @@ -14,15 +14,13 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - namespace Xceed.Wpf.AvalonDock.Layout { - public interface ILayoutControl + public interface ILayoutControl + { + ILayoutElement Model { - ILayoutElement Model { get; } + get; } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutDocumentPane.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutDocumentPane.cs index 239f9361..af7a89c7 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutDocumentPane.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutDocumentPane.cs @@ -14,14 +14,9 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - namespace Xceed.Wpf.AvalonDock.Layout { - public interface ILayoutDocumentPane : ILayoutPanelElement, ILayoutPane - { - } + public interface ILayoutDocumentPane : ILayoutPanelElement, ILayoutPane + { + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutElement.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutElement.cs index 605144d0..4bbf399d 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutElement.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutElement.cs @@ -14,17 +14,19 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.ComponentModel; namespace Xceed.Wpf.AvalonDock.Layout { - public interface ILayoutElement : INotifyPropertyChanged, INotifyPropertyChanging + public interface ILayoutElement : INotifyPropertyChanged, INotifyPropertyChanging + { + ILayoutContainer Parent { - ILayoutContainer Parent { get; } - ILayoutRoot Root { get; } + get; } + ILayoutRoot Root + { + get; + } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutElementWithVisibility.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutElementWithVisibility.cs index c65178b7..26227a40 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutElementWithVisibility.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutElementWithVisibility.cs @@ -14,15 +14,10 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - namespace Xceed.Wpf.AvalonDock.Layout { - public interface ILayoutElementWithVisibility - { - void ComputeVisibility(); - } + public interface ILayoutElementWithVisibility + { + void ComputeVisibility(); + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutGroup.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutGroup.cs index eab626a8..ea933786 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutGroup.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutGroup.cs @@ -15,18 +15,16 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Xceed.Wpf.AvalonDock.Layout { - public interface ILayoutGroup : ILayoutContainer - { - int IndexOfChild(ILayoutElement element); - void InsertChildAt(int index, ILayoutElement element); - void RemoveChildAt(int index); - void ReplaceChildAt(int index, ILayoutElement element); - event EventHandler ChildrenCollectionChanged; - } + public interface ILayoutGroup : ILayoutContainer + { + int IndexOfChild( ILayoutElement element ); + void InsertChildAt( int index, ILayoutElement element ); + void RemoveChildAt( int index ); + void ReplaceChildAt( int index, ILayoutElement element ); + + event EventHandler ChildrenCollectionChanged; + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutOrientableElement.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutOrientableElement.cs index 88e36611..80088c02 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutOrientableElement.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutOrientableElement.cs @@ -14,16 +14,15 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Controls; namespace Xceed.Wpf.AvalonDock.Layout { - public interface ILayoutOrientableGroup : ILayoutGroup + public interface ILayoutOrientableGroup : ILayoutGroup + { + Orientation Orientation { - Orientation Orientation { get; set; } + get; set; } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPane.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPane.cs index a65de4ba..36de7a57 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPane.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPane.cs @@ -14,17 +14,12 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - namespace Xceed.Wpf.AvalonDock.Layout { - public interface ILayoutPane : ILayoutContainer, ILayoutElementWithVisibility - { - void MoveChild(int oldIndex, int newIndex); + public interface ILayoutPane : ILayoutContainer, ILayoutElementWithVisibility + { + void MoveChild( int oldIndex, int newIndex ); - void RemoveChildAt(int childIndex); - } + void RemoveChildAt( int childIndex ); + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPaneSerializable.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPaneSerializable.cs index eba7e08e..0f76e247 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPaneSerializable.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPaneSerializable.cs @@ -14,15 +14,14 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Xceed.Wpf.AvalonDock.Layout { - interface ILayoutPaneSerializable + interface ILayoutPaneSerializable + { + string Id { - string Id { get; set; } + get; set; } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPanelElement.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPanelElement.cs index 7da961af..234a813a 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPanelElement.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPanelElement.cs @@ -14,16 +14,14 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; namespace Xceed.Wpf.AvalonDock.Layout { - public interface ILayoutPanelElement : ILayoutElement + public interface ILayoutPanelElement : ILayoutElement + { + bool IsVisible { - bool IsVisible { get; } + get; } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPositionableElement.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPositionableElement.cs index 34027fe9..34ef183c 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPositionableElement.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPositionableElement.cs @@ -14,49 +14,78 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; namespace Xceed.Wpf.AvalonDock.Layout { - internal interface ILayoutPositionableElement : ILayoutElement, ILayoutElementForFloatingWindow + internal interface ILayoutPositionableElement : ILayoutElement, ILayoutElementForFloatingWindow + { + GridLength DockWidth { - GridLength DockWidth - { - get; - set; - } + get; + set; + } - GridLength DockHeight - { - get; - set; - } + GridLength DockHeight + { + get; + set; + } - double DockMinWidth { get; set; } - double DockMinHeight { get; set; } + double DockMinWidth + { + get; set; + } + double DockMinHeight + { + get; set; + } - bool AllowDuplicateContent { get; set; } + bool AllowDuplicateContent + { + get; set; + } - bool IsVisible { get; } + bool IsVisible + { + get; } + } - internal interface ILayoutPositionableElementWithActualSize + internal interface ILayoutPositionableElementWithActualSize + { + double ActualWidth { - double ActualWidth { get; set; } - double ActualHeight { get; set; } + get; set; } + double ActualHeight + { + get; set; + } + } - internal interface ILayoutElementForFloatingWindow + internal interface ILayoutElementForFloatingWindow + { + double FloatingWidth + { + get; set; + } + double FloatingHeight + { + get; set; + } + double FloatingLeft + { + get; set; + } + double FloatingTop + { + get; set; + } + bool IsMaximized { - double FloatingWidth { get; set; } - double FloatingHeight { get; set; } - double FloatingLeft { get; set; } - double FloatingTop { get; set; } - bool IsMaximized { get; set; } + get; set; } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPreviousContainer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPreviousContainer.cs index 76a56212..805d254b 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPreviousContainer.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutPreviousContainer.cs @@ -14,17 +14,18 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - namespace Xceed.Wpf.AvalonDock.Layout { - interface ILayoutPreviousContainer + interface ILayoutPreviousContainer + { + ILayoutContainer PreviousContainer { - ILayoutContainer PreviousContainer { get; set; } + get; set; + } - string PreviousContainerId { get; set; } + string PreviousContainerId + { + get; set; } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutRoot.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutRoot.cs index 0eeb48b7..4408366c 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutRoot.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutRoot.cs @@ -14,30 +14,53 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Collections.ObjectModel; namespace Xceed.Wpf.AvalonDock.Layout { - public interface ILayoutRoot + public interface ILayoutRoot + { + DockingManager Manager { - DockingManager Manager { get; } - - LayoutPanel RootPanel { get; } + get; + } - LayoutAnchorSide TopSide { get; } - LayoutAnchorSide LeftSide { get; } - LayoutAnchorSide RightSide { get; } - LayoutAnchorSide BottomSide { get; } + LayoutPanel RootPanel + { + get; + } - LayoutContent ActiveContent { get; set; } + LayoutAnchorSide TopSide + { + get; + } + LayoutAnchorSide LeftSide + { + get; + } + LayoutAnchorSide RightSide + { + get; + } + LayoutAnchorSide BottomSide + { + get; + } - void CollectGarbage(); + LayoutContent ActiveContent + { + get; set; + } - ObservableCollection FloatingWindows { get; } - ObservableCollection Hidden { get; } + ObservableCollection FloatingWindows + { + get; + } + ObservableCollection Hidden + { + get; } + + void CollectGarbage(); + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutUpdateStrategy.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutUpdateStrategy.cs index 409fe509..eb31dceb 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutUpdateStrategy.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/ILayoutUpdateStrategy.cs @@ -14,32 +14,27 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - namespace Xceed.Wpf.AvalonDock.Layout { - public interface ILayoutUpdateStrategy - { - bool BeforeInsertAnchorable( - LayoutRoot layout, - LayoutAnchorable anchorableToShow, - ILayoutContainer destinationContainer); - - void AfterInsertAnchorable( - LayoutRoot layout, - LayoutAnchorable anchorableShown); - - - bool BeforeInsertDocument( - LayoutRoot layout, - LayoutDocument anchorableToShow, - ILayoutContainer destinationContainer); - - void AfterInsertDocument( - LayoutRoot layout, - LayoutDocument anchorableShown); - } + public interface ILayoutUpdateStrategy + { + bool BeforeInsertAnchorable( + LayoutRoot layout, + LayoutAnchorable anchorableToShow, + ILayoutContainer destinationContainer ); + + void AfterInsertAnchorable( + LayoutRoot layout, + LayoutAnchorable anchorableShown ); + + + bool BeforeInsertDocument( + LayoutRoot layout, + LayoutDocument anchorableToShow, + ILayoutContainer destinationContainer ); + + void AfterInsertDocument( + LayoutRoot layout, + LayoutDocument anchorableShown ); + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorGroup.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorGroup.cs index 6af4f25b..00b0412e 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorGroup.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorGroup.cs @@ -15,97 +15,111 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections.ObjectModel; using System.Windows.Markup; using System.Xml.Serialization; namespace Xceed.Wpf.AvalonDock.Layout { - [ContentProperty("Children")] - [Serializable] - public class LayoutAnchorGroup : LayoutGroup, ILayoutPreviousContainer, ILayoutPaneSerializable + [ContentProperty( "Children" )] + [Serializable] + public class LayoutAnchorGroup : LayoutGroup, ILayoutPreviousContainer, ILayoutPaneSerializable + { + #region Constructors + + public LayoutAnchorGroup() { - public LayoutAnchorGroup() - { - } + } - protected override bool GetVisibility() - { - return Children.Count > 0; - } + #endregion + #region Overrides - #region PreviousContainer + protected override bool GetVisibility() + { + return Children.Count > 0; + } - [field:NonSerialized] - private ILayoutContainer _previousContainer = null; - [XmlIgnore] - ILayoutContainer ILayoutPreviousContainer.PreviousContainer + public override void WriteXml( System.Xml.XmlWriter writer ) + { + if( _id != null ) + writer.WriteAttributeString( "Id", _id ); + if( _previousContainer != null ) + { + var paneSerializable = _previousContainer as ILayoutPaneSerializable; + if( paneSerializable != null ) { - get { return _previousContainer; } - set - { - if (_previousContainer != value) - { - _previousContainer = value; - RaisePropertyChanged("PreviousContainer"); - var paneSerializable = _previousContainer as ILayoutPaneSerializable; - if (paneSerializable != null && - paneSerializable.Id == null) - paneSerializable.Id = Guid.NewGuid().ToString(); - } - } + writer.WriteAttributeString( "PreviousContainerId", paneSerializable.Id ); } + } - #endregion + base.WriteXml( writer ); + } - string _id; - string ILayoutPaneSerializable.Id - { - get - { - return _id; - } - set - { - _id = value; - } - } + public override void ReadXml( System.Xml.XmlReader reader ) + { + if( reader.MoveToAttribute( "Id" ) ) + _id = reader.Value; + if( reader.MoveToAttribute( "PreviousContainerId" ) ) + ( ( ILayoutPreviousContainer )this ).PreviousContainerId = reader.Value; - string ILayoutPreviousContainer.PreviousContainerId - { - get; - set; - } - public override void WriteXml(System.Xml.XmlWriter writer) + base.ReadXml( reader ); + } + + #endregion + + #region ILayoutPreviousContainer Interface + + #region PreviousContainer + + [field: NonSerialized] + private ILayoutContainer _previousContainer = null; + [XmlIgnore] + ILayoutContainer ILayoutPreviousContainer.PreviousContainer + { + get + { + return _previousContainer; + } + set + { + if( _previousContainer != value ) { - if (_id != null) - writer.WriteAttributeString("Id", _id); - if (_previousContainer != null) - { - var paneSerializable = _previousContainer as ILayoutPaneSerializable; - if (paneSerializable != null) - { - writer.WriteAttributeString("PreviousContainerId", paneSerializable.Id); - } - } - - base.WriteXml(writer); + _previousContainer = value; + RaisePropertyChanged( "PreviousContainer" ); + var paneSerializable = _previousContainer as ILayoutPaneSerializable; + if( paneSerializable != null && + paneSerializable.Id == null ) + paneSerializable.Id = Guid.NewGuid().ToString(); } + } + } - public override void ReadXml(System.Xml.XmlReader reader) - { - if (reader.MoveToAttribute("Id")) - _id = reader.Value; - if (reader.MoveToAttribute("PreviousContainerId")) - ((ILayoutPreviousContainer)this).PreviousContainerId = reader.Value; + #endregion + string ILayoutPreviousContainer.PreviousContainerId + { + get; + set; + } - base.ReadXml(reader); - } + #endregion + + #region ILayoutPaneSerializable Interface + + string _id; + string ILayoutPaneSerializable.Id + { + get + { + return _id; + } + set + { + _id = value; + } } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorSide.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorSide.cs index 60908226..1f995b80 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorSide.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorSide.cs @@ -15,69 +15,79 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections.ObjectModel; using System.Windows.Markup; -using Xceed.Wpf.AvalonDock.Controls; namespace Xceed.Wpf.AvalonDock.Layout { - [ContentProperty("Children")] - [Serializable] - public class LayoutAnchorSide : LayoutGroup - { - public LayoutAnchorSide() - { - } + [ContentProperty( "Children" )] + [Serializable] + public class LayoutAnchorSide : LayoutGroup + { + #region Constructors - protected override bool GetVisibility() - { - return Children.Count > 0; - } + public LayoutAnchorSide() + { + } + #endregion - protected override void OnParentChanged(ILayoutContainer oldValue, ILayoutContainer newValue) - { - base.OnParentChanged(oldValue, newValue); + #region Properties - UpdateSide(); - } + #region Side - private void UpdateSide() + private AnchorSide _side; + public AnchorSide Side + { + get + { + return _side; + } + private set + { + if( _side != value ) { - if (Root.LeftSide == this) - Side = AnchorSide.Left; - else if (Root.TopSide == this) - Side = AnchorSide.Top; - else if (Root.RightSide == this) - Side = AnchorSide.Right; - else if (Root.BottomSide == this) - Side = AnchorSide.Bottom; + RaisePropertyChanging( "Side" ); + _side = value; + RaisePropertyChanged( "Side" ); } + } + } + #endregion - #region Side + #endregion - private AnchorSide _side; - public AnchorSide Side - { - get { return _side; } - private set - { - if (_side != value) - { - RaisePropertyChanging("Side"); - _side = value; - RaisePropertyChanged("Side"); - } - } - } + #region Overrides - #endregion + protected override bool GetVisibility() + { + return Children.Count > 0; + } + protected override void OnParentChanged( ILayoutContainer oldValue, ILayoutContainer newValue ) + { + base.OnParentChanged( oldValue, newValue ); + UpdateSide(); } + + #endregion + + #region Private Methods + + private void UpdateSide() + { + if( Root.LeftSide == this ) + Side = AnchorSide.Left; + else if( Root.TopSide == this ) + Side = AnchorSide.Top; + else if( Root.RightSide == this ) + Side = AnchorSide.Right; + else if( Root.BottomSide == this ) + Side = AnchorSide.Bottom; + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorable.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorable.cs index f298300f..4502e764 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorable.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorable.cs @@ -15,9 +15,7 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows; using System.Xml.Serialization; using System.Windows.Controls; @@ -29,72 +27,32 @@ namespace Xceed.Wpf.AvalonDock.Layout [Serializable] public class LayoutAnchorable : LayoutContent { - public LayoutAnchorable() - { - // LayoutAnchorable will hide by default, not close. - _canClose = false; - } + #region Members - #region IsVisible - [XmlIgnore] - public bool IsVisible - { - get - { - return Parent != null && !( Parent is LayoutRoot ); - } - set - { - if( value ) - { - Show(); - } - else - { - Hide(); - } - } - } - - public event EventHandler IsVisibleChanged; - - void NotifyIsVisibleChanged() - { - if( IsVisibleChanged != null ) - IsVisibleChanged( this, EventArgs.Empty ); - } + private double _autohideWidth = 0.0; + private double _autohideMinWidth = 100.0; + private double _autohideHeight = 0.0; + private double _autohideMinHeight = 100.0; + private bool _canHide = true; + private bool _canAutoHide = true; + private bool _canCloseValueBeforeInternalSet; - [XmlIgnore] - public bool IsHidden - { - get - { - return ( Parent is LayoutRoot ); - } - } + #endregion - protected override void OnParentChanged( ILayoutContainer oldValue, ILayoutContainer newValue ) - { - UpdateParentVisibility(); - RaisePropertyChanged( "IsVisible" ); - NotifyIsVisibleChanged(); - RaisePropertyChanged( "IsHidden" ); - RaisePropertyChanged( "IsAutoHidden" ); - base.OnParentChanged( oldValue, newValue ); - } + #region Constructors - void UpdateParentVisibility() + public LayoutAnchorable() { - var parentPane = Parent as ILayoutElementWithVisibility; - if( parentPane != null ) - parentPane.ComputeVisibility(); + // LayoutAnchorable will hide by default, not close. + _canClose = false; } #endregion + #region Properties + #region AutoHideWidth - private double _autohideWidth = 0.0; public double AutoHideWidth { get @@ -117,7 +75,6 @@ namespace Xceed.Wpf.AvalonDock.Layout #region AutoHideMinWidth - private double _autohideMinWidth = 100.0; public double AutoHideMinWidth { get @@ -141,7 +98,6 @@ namespace Xceed.Wpf.AvalonDock.Layout #region AutoHideHeight - private double _autohideHeight = 0.0; public double AutoHideHeight { get @@ -164,7 +120,6 @@ namespace Xceed.Wpf.AvalonDock.Layout #region AutoHideMinHeight - private double _autohideMinHeight = 100.0; public double AutoHideMinHeight { get @@ -186,98 +141,117 @@ namespace Xceed.Wpf.AvalonDock.Layout #endregion - /// - /// Hide this contents - /// - /// Add this content to collection of parent root. - public void Hide( bool cancelable = true ) - { - if( !IsVisible ) - { - IsSelected = true; - IsActive = true; - return; - } + #region CanHide - if( cancelable ) + public bool CanHide + { + get { - CancelEventArgs args = new CancelEventArgs(); - OnHiding( args ); - if( args.Cancel ) - return; + return _canHide; } - - RaisePropertyChanging( "IsHidden" ); - RaisePropertyChanging( "IsVisible" ); - //if (Parent is ILayoutPane) + set { - var parentAsGroup = Parent as ILayoutGroup; - PreviousContainer = parentAsGroup; - PreviousContainerIndex = parentAsGroup.IndexOfChild( this ); + if( _canHide != value ) + { + _canHide = value; + RaisePropertyChanged( "CanHide" ); + } } - Root.Hidden.Add( this ); - RaisePropertyChanged( "IsVisible" ); - RaisePropertyChanged( "IsHidden" ); - NotifyIsVisibleChanged(); } - public event EventHandler Hiding; + #endregion - protected virtual void OnHiding( CancelEventArgs args ) + #region CanAutoHide + + public bool CanAutoHide { - if( Hiding != null ) - Hiding( this, args ); + get + { + return _canAutoHide; + } + set + { + if( _canAutoHide != value ) + { + _canAutoHide = value; + RaisePropertyChanged( "CanAutoHide" ); + } + } } + #endregion + + #region IsAutoHidden /// - /// Show the content + /// Get a value indicating if the anchorable is anchored to a border in an autohide status /// - /// Try to show the content where it was previously hidden. - public void Show() + public bool IsAutoHidden { - if( IsVisible ) - return; + get + { + return Parent != null && Parent is LayoutAnchorGroup; + } + } - if( !IsHidden ) - throw new InvalidOperationException(); + #endregion - RaisePropertyChanging( "IsHidden" ); - RaisePropertyChanging( "IsVisible" ); + #region IsHidden - bool added = false; - var root = Root; - if( root != null && root.Manager != null ) + [XmlIgnore] + public bool IsHidden + { + get { - if( root.Manager.LayoutUpdateStrategy != null ) - added = root.Manager.LayoutUpdateStrategy.BeforeInsertAnchorable( root as LayoutRoot, this, PreviousContainer ); + return ( Parent is LayoutRoot ); } + } - if( !added && PreviousContainer != null ) + #endregion + + #region IsVisible + + [XmlIgnore] + public bool IsVisible + { + get { - var previousContainerAsLayoutGroup = PreviousContainer as ILayoutGroup; - if( PreviousContainerIndex < previousContainerAsLayoutGroup.ChildrenCount ) - previousContainerAsLayoutGroup.InsertChildAt( PreviousContainerIndex, this ); - else - previousContainerAsLayoutGroup.InsertChildAt( previousContainerAsLayoutGroup.ChildrenCount, this ); - IsSelected = true; - IsActive = true; + return Parent != null && !( Parent is LayoutRoot ); } - - if( root != null && root.Manager != null ) + set { - if( root.Manager.LayoutUpdateStrategy != null ) + if( value ) { - root.Manager.LayoutUpdateStrategy.AfterInsertAnchorable( root as LayoutRoot, this ); + Show(); + } + else + { + Hide(); } } + } - PreviousContainer = null; - PreviousContainerIndex = -1; + #endregion + + #endregion + + #region Events + + public event EventHandler IsVisibleChanged; + public event EventHandler Hiding; + #endregion + + #region Overrides + + protected override void OnParentChanged( ILayoutContainer oldValue, ILayoutContainer newValue ) + { + UpdateParentVisibility(); RaisePropertyChanged( "IsVisible" ); - RaisePropertyChanged( "IsHidden" ); NotifyIsVisibleChanged(); + RaisePropertyChanged( "IsHidden" ); + RaisePropertyChanged( "IsAutoHidden" ); + base.OnParentChanged( oldValue, newValue ); } protected override void InternalDock() @@ -338,6 +312,147 @@ namespace Xceed.Wpf.AvalonDock.Layout base.InternalDock(); } + public override void ReadXml( System.Xml.XmlReader reader ) + { + if( reader.MoveToAttribute( "CanHide" ) ) + CanHide = bool.Parse( reader.Value ); + if( reader.MoveToAttribute( "CanAutoHide" ) ) + CanAutoHide = bool.Parse( reader.Value ); + if( reader.MoveToAttribute( "AutoHideWidth" ) ) + AutoHideWidth = double.Parse( reader.Value, CultureInfo.InvariantCulture ); + if( reader.MoveToAttribute( "AutoHideHeight" ) ) + AutoHideHeight = double.Parse( reader.Value, CultureInfo.InvariantCulture ); + if( reader.MoveToAttribute( "AutoHideMinWidth" ) ) + AutoHideMinWidth = double.Parse( reader.Value, CultureInfo.InvariantCulture ); + if( reader.MoveToAttribute( "AutoHideMinHeight" ) ) + AutoHideMinHeight = double.Parse( reader.Value, CultureInfo.InvariantCulture ); + + base.ReadXml( reader ); + } + + public override void WriteXml( System.Xml.XmlWriter writer ) + { + if( !CanHide ) + writer.WriteAttributeString( "CanHide", CanHide.ToString() ); + if( !CanAutoHide ) + writer.WriteAttributeString( "CanAutoHide", CanAutoHide.ToString( CultureInfo.InvariantCulture ) ); + if( AutoHideWidth > 0 ) + writer.WriteAttributeString( "AutoHideWidth", AutoHideWidth.ToString( CultureInfo.InvariantCulture ) ); + if( AutoHideHeight > 0 ) + writer.WriteAttributeString( "AutoHideHeight", AutoHideHeight.ToString( CultureInfo.InvariantCulture ) ); + if( AutoHideMinWidth != 25.0 ) + writer.WriteAttributeString( "AutoHideMinWidth", AutoHideMinWidth.ToString( CultureInfo.InvariantCulture ) ); + if( AutoHideMinHeight != 25.0 ) + writer.WriteAttributeString( "AutoHideMinHeight", AutoHideMinHeight.ToString( CultureInfo.InvariantCulture ) ); + + + base.WriteXml( writer ); + } + + public override void Close() + { + this.CloseAnchorable(); + } + +#if TRACE + public override void ConsoleDump(int tab) + { + System.Diagnostics.Trace.Write( new string( ' ', tab * 4 ) ); + System.Diagnostics.Trace.WriteLine( "Anchorable()" ); + } +#endif + + #endregion + + #region Public Methods + + /// + /// Hide this contents + /// + /// Add this content to collection of parent root. + public void Hide( bool cancelable = true ) + { + if( !IsVisible ) + { + IsSelected = true; + IsActive = true; + return; + } + + if( cancelable ) + { + CancelEventArgs args = new CancelEventArgs(); + OnHiding( args ); + if( args.Cancel ) + return; + } + + RaisePropertyChanging( "IsHidden" ); + RaisePropertyChanging( "IsVisible" ); + //if (Parent is ILayoutPane) + { + var parentAsGroup = Parent as ILayoutGroup; + PreviousContainer = parentAsGroup; + PreviousContainerIndex = parentAsGroup.IndexOfChild( this ); + } + Root.Hidden.Add( this ); + RaisePropertyChanged( "IsVisible" ); + RaisePropertyChanged( "IsHidden" ); + NotifyIsVisibleChanged(); + } + + + /// + /// Show the content + /// + /// Try to show the content where it was previously hidden. + public void Show() + { + if( IsVisible ) + return; + + if( !IsHidden ) + throw new InvalidOperationException(); + + RaisePropertyChanging( "IsHidden" ); + RaisePropertyChanging( "IsVisible" ); + + bool added = false; + var root = Root; + if( root != null && root.Manager != null ) + { + if( root.Manager.LayoutUpdateStrategy != null ) + added = root.Manager.LayoutUpdateStrategy.BeforeInsertAnchorable( root as LayoutRoot, this, PreviousContainer ); + } + + if( !added && PreviousContainer != null ) + { + var previousContainerAsLayoutGroup = PreviousContainer as ILayoutGroup; + if( PreviousContainerIndex < previousContainerAsLayoutGroup.ChildrenCount ) + previousContainerAsLayoutGroup.InsertChildAt( PreviousContainerIndex, this ); + else + previousContainerAsLayoutGroup.InsertChildAt( previousContainerAsLayoutGroup.ChildrenCount, this ); + IsSelected = true; + IsActive = true; + } + + if( root != null && root.Manager != null ) + { + if( root.Manager.LayoutUpdateStrategy != null ) + { + root.Manager.LayoutUpdateStrategy.AfterInsertAnchorable( root as LayoutRoot, this ); + } + } + + PreviousContainer = null; + PreviousContainerIndex = -1; + + RaisePropertyChanged( "IsVisible" ); + RaisePropertyChanged( "IsHidden" ); + NotifyIsVisibleChanged(); + } + + /// /// Add the anchorable to a DockingManager layout /// @@ -415,20 +530,6 @@ namespace Xceed.Wpf.AvalonDock.Layout } } - - /// - /// Get a value indicating if the anchorable is anchored to a border in an autohide status - /// - public bool IsAutoHidden - { - get - { - return Parent != null && Parent is LayoutAnchorGroup; - } - } - - - #region AutoHide public void ToggleAutoHide() { #region Anchorable is already auto hidden @@ -540,12 +641,13 @@ namespace Xceed.Wpf.AvalonDock.Layout { if( parent is LayoutGroup ) { - (( LayoutGroup )parent).ComputeVisibility(); + ( ( LayoutGroup )parent ).ComputeVisibility(); } parent = parent.Parent as LayoutGroupBase; } } #endregion + #region Anchorable is docked else if( Parent is LayoutAnchorablePane ) { @@ -595,109 +697,53 @@ namespace Xceed.Wpf.AvalonDock.Layout #endregion - #region CanHide + #region Internal Methods - private bool _canHide = true; - public bool CanHide + protected virtual void OnHiding( CancelEventArgs args ) { - get - { - return _canHide; - } - set - { - if( _canHide != value ) - { - _canHide = value; - RaisePropertyChanged( "CanHide" ); - } - } + if( Hiding != null ) + Hiding( this, args ); } - #endregion - - #region CanAutoHide - - private bool _canAutoHide = true; - public bool CanAutoHide + internal void CloseAnchorable() { - get - { - return _canAutoHide; - } - set + if( this.TestCanClose() ) { - if( _canAutoHide != value ) - { - _canAutoHide = value; - RaisePropertyChanged( "CanAutoHide" ); - } + if( this.IsAutoHidden ) + this.ToggleAutoHide(); + + this.CloseInternal(); } } - #endregion - - - public override void ReadXml( System.Xml.XmlReader reader ) + internal void SetCanCloseInternal( bool canClose ) { - if( reader.MoveToAttribute( "CanHide" ) ) - CanHide = bool.Parse( reader.Value ); - if( reader.MoveToAttribute( "CanAutoHide" ) ) - CanAutoHide = bool.Parse( reader.Value ); - if( reader.MoveToAttribute( "AutoHideWidth" ) ) - AutoHideWidth = double.Parse( reader.Value, CultureInfo.InvariantCulture ); - if( reader.MoveToAttribute( "AutoHideHeight" ) ) - AutoHideHeight = double.Parse( reader.Value, CultureInfo.InvariantCulture ); - if( reader.MoveToAttribute( "AutoHideMinWidth" ) ) - AutoHideMinWidth = double.Parse( reader.Value, CultureInfo.InvariantCulture ); - if( reader.MoveToAttribute( "AutoHideMinHeight" ) ) - AutoHideMinHeight = double.Parse( reader.Value, CultureInfo.InvariantCulture ); - - base.ReadXml( reader ); + _canCloseValueBeforeInternalSet = _canClose; + _canClose = canClose; } - public override void WriteXml( System.Xml.XmlWriter writer ) + internal void ResetCanCloseInternal() { - if( !CanHide ) - writer.WriteAttributeString( "CanHide", CanHide.ToString() ); - if( !CanAutoHide ) - writer.WriteAttributeString( "CanAutoHide", CanAutoHide.ToString( CultureInfo.InvariantCulture ) ); - if( AutoHideWidth > 0 ) - writer.WriteAttributeString( "AutoHideWidth", AutoHideWidth.ToString( CultureInfo.InvariantCulture ) ); - if( AutoHideHeight > 0 ) - writer.WriteAttributeString( "AutoHideHeight", AutoHideHeight.ToString( CultureInfo.InvariantCulture ) ); - if( AutoHideMinWidth != 25.0 ) - writer.WriteAttributeString( "AutoHideMinWidth", AutoHideMinWidth.ToString( CultureInfo.InvariantCulture ) ); - if( AutoHideMinHeight != 25.0 ) - writer.WriteAttributeString( "AutoHideMinHeight", AutoHideMinHeight.ToString( CultureInfo.InvariantCulture ) ); + _canClose = _canCloseValueBeforeInternalSet; + } + #endregion - base.WriteXml( writer ); - } + #region Private Methods - public override void Close() + private void NotifyIsVisibleChanged() { - this.CloseAnchorable(); + if( IsVisibleChanged != null ) + IsVisibleChanged( this, EventArgs.Empty ); } - internal void CloseAnchorable() + private void UpdateParentVisibility() { - if( this.TestCanClose() ) - { - if( this.IsAutoHidden ) - this.ToggleAutoHide(); - - this.CloseInternal(); - } + var parentPane = Parent as ILayoutElementWithVisibility; + if( parentPane != null ) + parentPane.ComputeVisibility(); } - -#if TRACE - public override void ConsoleDump(int tab) - { - System.Diagnostics.Trace.Write( new string( ' ', tab * 4 ) ); - System.Diagnostics.Trace.WriteLine( "Anchorable()" ); - } -#endif + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorableFloatingWindow.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorableFloatingWindow.cs index 0cbd88b3..2dc51092 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorableFloatingWindow.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorableFloatingWindow.cs @@ -17,7 +17,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows.Markup; using System.Diagnostics; using System.Xml.Serialization; @@ -25,200 +24,208 @@ using System.Xml; namespace Xceed.Wpf.AvalonDock.Layout { - [Serializable] - [ContentProperty("RootPanel")] - public class LayoutAnchorableFloatingWindow : LayoutFloatingWindow, ILayoutElementWithVisibility + [Serializable] + [ContentProperty( "RootPanel" )] + public class LayoutAnchorableFloatingWindow : LayoutFloatingWindow, ILayoutElementWithVisibility + { + #region Members + + private LayoutAnchorablePaneGroup _rootPanel = null; + [NonSerialized] + private bool _isVisible = true; + + #endregion + + #region Constructors + + public LayoutAnchorableFloatingWindow() { - public LayoutAnchorableFloatingWindow() - { + } - } + #endregion - #region RootPanel + #region Properties - private LayoutAnchorablePaneGroup _rootPanel = null; - public LayoutAnchorablePaneGroup RootPanel - { - get { return _rootPanel; } - set - { - if (_rootPanel != value) - { - RaisePropertyChanging("RootPanel"); - - if (_rootPanel != null) - _rootPanel.ChildrenTreeChanged -= new EventHandler(_rootPanel_ChildrenTreeChanged); - - _rootPanel = value; - if (_rootPanel != null) - _rootPanel.Parent = this; - - if (_rootPanel != null) - _rootPanel.ChildrenTreeChanged += new EventHandler(_rootPanel_ChildrenTreeChanged); - - RaisePropertyChanged("RootPanel"); - RaisePropertyChanged("IsSinglePane"); - RaisePropertyChanged("SinglePane"); - RaisePropertyChanged("Children"); - RaisePropertyChanged("ChildrenCount"); - ((ILayoutElementWithVisibility)this).ComputeVisibility(); - } - } - } + #region IsSinglePane - void _rootPanel_ChildrenTreeChanged(object sender, ChildrenTreeChangedEventArgs e) - { - RaisePropertyChanged("IsSinglePane"); - RaisePropertyChanged("SinglePane"); + public bool IsSinglePane + { + get + { + return RootPanel != null && RootPanel.Descendents().OfType().Where( p => p.IsVisible ).Count() == 1; + } + } - } + #endregion - public bool IsSinglePane - { - get - { - return RootPanel != null && RootPanel.Descendents().OfType().Where(p => p.IsVisible).Count() == 1; - } - } + #region IsVisible - public ILayoutAnchorablePane SinglePane + [XmlIgnore] + public bool IsVisible + { + get + { + return _isVisible; + } + private set + { + if( _isVisible != value ) { - get - { - if (!IsSinglePane) - return null; - - var singlePane = RootPanel.Descendents().OfType().Single(p => p.IsVisible); - singlePane.UpdateIsDirectlyHostedInFloatingWindow(); - return singlePane; - } + RaisePropertyChanging( "IsVisible" ); + _isVisible = value; + RaisePropertyChanged( "IsVisible" ); + if( IsVisibleChanged != null ) + IsVisibleChanged( this, EventArgs.Empty ); } + } + } + + #endregion - #endregion + #region RootPanel - public override IEnumerable Children + public LayoutAnchorablePaneGroup RootPanel + { + get + { + return _rootPanel; + } + set + { + if( _rootPanel != value ) { - get - { - if (ChildrenCount == 1) - yield return RootPanel; + RaisePropertyChanging( "RootPanel" ); - yield break; - } - } + if( _rootPanel != null ) + _rootPanel.ChildrenTreeChanged -= new EventHandler( _rootPanel_ChildrenTreeChanged ); - public override void RemoveChild(ILayoutElement element) - { - Debug.Assert(element == RootPanel && element != null); - RootPanel = null; - } + _rootPanel = value; + if( _rootPanel != null ) + _rootPanel.Parent = this; - public override void ReplaceChild(ILayoutElement oldElement, ILayoutElement newElement) - { - Debug.Assert(oldElement == RootPanel && oldElement != null); - RootPanel = newElement as LayoutAnchorablePaneGroup; - } + if( _rootPanel != null ) + _rootPanel.ChildrenTreeChanged += new EventHandler( _rootPanel_ChildrenTreeChanged ); - public override int ChildrenCount - { - get - { - if (RootPanel == null) - return 0; - return 1; - } + RaisePropertyChanged( "RootPanel" ); + RaisePropertyChanged( "IsSinglePane" ); + RaisePropertyChanged( "SinglePane" ); + RaisePropertyChanged( "Children" ); + RaisePropertyChanged( "ChildrenCount" ); + ( ( ILayoutElementWithVisibility )this ).ComputeVisibility(); } + } + } - #region IsVisible - [NonSerialized] - private bool _isVisible = true; + #endregion - [XmlIgnore] - public bool IsVisible - { - get { return _isVisible; } - private set - { - if (_isVisible != value) - { - RaisePropertyChanging("IsVisible"); - _isVisible = value; - RaisePropertyChanged("IsVisible"); - if (IsVisibleChanged != null) - IsVisibleChanged(this, EventArgs.Empty); - } - } - } + #region SinglePane - public event EventHandler IsVisibleChanged; + public ILayoutAnchorablePane SinglePane + { + get + { + if( !IsSinglePane ) + return null; + + var singlePane = RootPanel.Descendents().OfType().Single( p => p.IsVisible ); + singlePane.UpdateIsDirectlyHostedInFloatingWindow(); + return singlePane; + } + } - #endregion + #endregion + #endregion - void ILayoutElementWithVisibility.ComputeVisibility() + #region Overrides + + public override IEnumerable Children + { + get + { + if( ChildrenCount == 1 ) + yield return RootPanel; + + yield break; + } + } + + public override void RemoveChild( ILayoutElement element ) + { + Debug.Assert( element == RootPanel && element != null ); + RootPanel = null; + } + + public override void ReplaceChild( ILayoutElement oldElement, ILayoutElement newElement ) + { + Debug.Assert( oldElement == RootPanel && oldElement != null ); + RootPanel = newElement as LayoutAnchorablePaneGroup; + } + + public override int ChildrenCount + { + get + { + if( RootPanel == null ) + return 0; + return 1; + } + } + + public override bool IsValid + { + get + { + return RootPanel != null; + } + } + + public override void ReadXml( XmlReader reader ) + { + reader.MoveToContent(); + if( reader.IsEmptyElement ) + { + reader.Read(); + ComputeVisibility(); + return; + } + + var localName = reader.LocalName; + reader.Read(); + + while( true ) + { + if( reader.LocalName.Equals( localName ) && ( reader.NodeType == XmlNodeType.EndElement ) ) { - ComputeVisibility(); + break; } - private void ComputeVisibility() + if( reader.NodeType == XmlNodeType.Whitespace ) { - if( RootPanel != null ) - IsVisible = RootPanel.IsVisible; - else - IsVisible = false; + reader.Read(); + continue; } - public override bool IsValid + XmlSerializer serializer; + if( reader.LocalName.Equals( "LayoutAnchorablePaneGroup" ) ) { - get { return RootPanel != null; } + serializer = new XmlSerializer( typeof( LayoutAnchorablePaneGroup ) ); } - - public override void ReadXml( XmlReader reader ) + else { - reader.MoveToContent(); - if( reader.IsEmptyElement ) + var type = LayoutRoot.FindType( reader.LocalName ); + if( type == null ) { - reader.Read(); - ComputeVisibility(); - return; + throw new ArgumentException( "AvalonDock.LayoutAnchorableFloatingWindow doesn't know how to deserialize " + reader.LocalName ); } + serializer = new XmlSerializer( type ); + } - var localName = reader.LocalName; - reader.Read(); + RootPanel = ( LayoutAnchorablePaneGroup )serializer.Deserialize( reader ); + } - while( true ) - { - if( reader.LocalName.Equals( localName ) && (reader.NodeType == XmlNodeType.EndElement) ) - { - break; - } - - if( reader.NodeType == XmlNodeType.Whitespace ) - { - reader.Read(); - continue; - } - - XmlSerializer serializer; - if( reader.LocalName.Equals("LayoutAnchorablePaneGroup") ) - { - serializer = new XmlSerializer( typeof( LayoutAnchorablePaneGroup ) ); - } - else - { - var type = LayoutRoot.FindType( reader.LocalName ); - if( type == null ) - { - throw new ArgumentException( "AvalonDock.LayoutAnchorableFloatingWindow doesn't know how to deserialize " + reader.LocalName ); - } - serializer = new XmlSerializer( type ); - } - - RootPanel = ( LayoutAnchorablePaneGroup )serializer.Deserialize( reader ); - } - - reader.ReadEndElement(); - } + reader.ReadEndElement(); + } #if TRACE public override void ConsoleDump(int tab) @@ -229,5 +236,40 @@ namespace Xceed.Wpf.AvalonDock.Layout RootPanel.ConsoleDump(tab + 1); } #endif + + #endregion + + #region Private Methods + + private void _rootPanel_ChildrenTreeChanged( object sender, ChildrenTreeChangedEventArgs e ) + { + RaisePropertyChanged( "IsSinglePane" ); + RaisePropertyChanged( "SinglePane" ); + } + + private void ComputeVisibility() + { + if( RootPanel != null ) + IsVisible = RootPanel.IsVisible; + else + IsVisible = false; + } + + #endregion + + #region Events + + public event EventHandler IsVisibleChanged; + + #endregion + + #region ILayoutElementWithVisibility Interface + + void ILayoutElementWithVisibility.ComputeVisibility() + { + ComputeVisibility(); + } + + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorablePane.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorablePane.cs index 9a920ca1..abb9ef29 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorablePane.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorablePane.cs @@ -15,256 +15,221 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Collections.ObjectModel; using System.Windows.Markup; -using System.ComponentModel; using System.Xml.Serialization; namespace Xceed.Wpf.AvalonDock.Layout { - [ContentProperty("Children")] - [Serializable] - public class LayoutAnchorablePane : LayoutPositionableGroup, ILayoutAnchorablePane, ILayoutPositionableElement, ILayoutContentSelector, ILayoutPaneSerializable - { - public LayoutAnchorablePane() - { - } + [ContentProperty( "Children" )] + [Serializable] + public class LayoutAnchorablePane : LayoutPositionableGroup, ILayoutAnchorablePane, ILayoutPositionableElement, ILayoutContentSelector, ILayoutPaneSerializable + { + #region Members - public LayoutAnchorablePane(LayoutAnchorable anchorable) - { - Children.Add(anchorable); - } + private int _selectedIndex = -1; + [XmlIgnore] + private bool _autoFixSelectedContent = true; + private string _name = null; - protected override bool GetVisibility() - { - return Children.Count > 0 && Children.Any(c => c.IsVisible); - } + #endregion - #region SelectedContentIndex + #region Constructors - private int _selectedIndex = -1; - public int SelectedContentIndex - { - get { return _selectedIndex; } - set - { - if (value < 0 || - value >= Children.Count) - value = -1; - - if (_selectedIndex != value) - { - RaisePropertyChanging("SelectedContentIndex"); - RaisePropertyChanging("SelectedContent"); - if (_selectedIndex >= 0 && - _selectedIndex < Children.Count) - Children[_selectedIndex].IsSelected = false; - - _selectedIndex = value; - - if (_selectedIndex >= 0 && - _selectedIndex < Children.Count) - Children[_selectedIndex].IsSelected = true; - - RaisePropertyChanged("SelectedContentIndex"); - RaisePropertyChanged("SelectedContent"); - } - } - } + public LayoutAnchorablePane() + { + } - protected override void ChildMoved(int oldIndex, int newIndex) - { - if (_selectedIndex == oldIndex) - { - RaisePropertyChanging("SelectedContentIndex"); - _selectedIndex = newIndex; - RaisePropertyChanged("SelectedContentIndex"); - } + public LayoutAnchorablePane( LayoutAnchorable anchorable ) + { + Children.Add( anchorable ); + } + #endregion - base.ChildMoved(oldIndex, newIndex); - } + #region Properties - public LayoutContent SelectedContent - { - get - { - return _selectedIndex == -1 ? null : Children[_selectedIndex]; - } - } - #endregion + #region CanHide - protected override void OnChildrenCollectionChanged() - { - AutoFixSelectedContent(); - for (int i = 0; i < Children.Count; i++) - { - if (Children[i].IsSelected) - { - SelectedContentIndex = i; - break; - } - } - - RaisePropertyChanged("CanClose"); - RaisePropertyChanged("CanHide"); - RaisePropertyChanged("IsDirectlyHostedInFloatingWindow"); - base.OnChildrenCollectionChanged(); - } + public bool CanHide + { + get + { + return Children.All( a => a.CanHide ); + } + } - [XmlIgnore] - bool _autoFixSelectedContent = true; - void AutoFixSelectedContent() - { - if (_autoFixSelectedContent) - { - if (SelectedContentIndex >= ChildrenCount) - SelectedContentIndex = Children.Count - 1; - - if (SelectedContentIndex == -1 && ChildrenCount > 0) - SetNextSelectedIndex(); - } - } + #endregion - public int IndexOf(LayoutContent content) - { - var anchorableChild = content as LayoutAnchorable; - if (anchorableChild == null) - return -1; + #region CanClose - return Children.IndexOf(anchorableChild); - } + public bool CanClose + { + get + { + return Children.All( a => a.CanClose ); + } + } + #endregion - public bool IsDirectlyHostedInFloatingWindow - { - get - { - var parentFloatingWindow = this.FindParent(); - if (parentFloatingWindow != null) - return parentFloatingWindow.IsSinglePane; - - return false; - //return Parent != null && Parent.ChildrenCount == 1 && Parent.Parent is LayoutFloatingWindow; - } - } + #region IsHostedInFloatingWindow - internal void SetNextSelectedIndex() - { - SelectedContentIndex = -1; - for( int i = 0; i < this.Children.Count; ++i ) - { - if( Children[ i ].IsEnabled ) - { - SelectedContentIndex = i; - return; - } - } - } + public bool IsHostedInFloatingWindow + { + get + { + return this.FindParent() != null; + } + } - internal void UpdateIsDirectlyHostedInFloatingWindow() - { - RaisePropertyChanged("IsDirectlyHostedInFloatingWindow"); - } + #endregion + + #region Name - public bool IsHostedInFloatingWindow + public string Name + { + get + { + return _name; + } + set + { + if( _name != value ) { - get - { - return this.FindParent() != null; - } + _name = value; + RaisePropertyChanged( "Name" ); } + } + } + + #endregion + + #region SelectedContentIndex - protected override void OnParentChanged(ILayoutContainer oldValue, ILayoutContainer newValue) + public int SelectedContentIndex + { + get + { + return _selectedIndex; + } + set + { + if( value < 0 || + value >= Children.Count ) + value = -1; + + if( _selectedIndex != value ) { - var oldGroup = oldValue as ILayoutGroup; - if (oldGroup != null) - oldGroup.ChildrenCollectionChanged -= new EventHandler(OnParentChildrenCollectionChanged); + RaisePropertyChanging( "SelectedContentIndex" ); + RaisePropertyChanging( "SelectedContent" ); + if( _selectedIndex >= 0 && + _selectedIndex < Children.Count ) + Children[ _selectedIndex ].IsSelected = false; - RaisePropertyChanged("IsDirectlyHostedInFloatingWindow"); + _selectedIndex = value; - var newGroup = newValue as ILayoutGroup; - if (newGroup != null) - newGroup.ChildrenCollectionChanged += new EventHandler(OnParentChildrenCollectionChanged); + if( _selectedIndex >= 0 && + _selectedIndex < Children.Count ) + Children[ _selectedIndex ].IsSelected = true; - base.OnParentChanged(oldValue, newValue); + RaisePropertyChanged( "SelectedContentIndex" ); + RaisePropertyChanged( "SelectedContent" ); } + } + } - void OnParentChildrenCollectionChanged(object sender, EventArgs e) - { - RaisePropertyChanged("IsDirectlyHostedInFloatingWindow"); - } + #endregion - string _id; + #region SelectedContent - string ILayoutPaneSerializable.Id - { - get - { - return _id; - } - set - { - _id = value; - } - } + public LayoutContent SelectedContent + { + get + { + return _selectedIndex == -1 ? null : Children[ _selectedIndex ]; + } + } - #region Name + #endregion - private string _name = null; - public string Name - { - get { return _name; } - set - { - if (_name != value) - { - _name = value; - RaisePropertyChanged("Name"); - } - } - } + #endregion - #endregion + #region Overrides + protected override bool GetVisibility() + { + return Children.Count > 0 && Children.Any( c => c.IsVisible ); + } + protected override void ChildMoved( int oldIndex, int newIndex ) + { + if( _selectedIndex == oldIndex ) + { + RaisePropertyChanging( "SelectedContentIndex" ); + _selectedIndex = newIndex; + RaisePropertyChanged( "SelectedContentIndex" ); + } - public override void WriteXml(System.Xml.XmlWriter writer) - { - if (_id != null) - writer.WriteAttributeString("Id", _id); - if (_name != null) - writer.WriteAttributeString("Name", _name); - base.WriteXml(writer); - } + base.ChildMoved( oldIndex, newIndex ); + } - public override void ReadXml(System.Xml.XmlReader reader) + protected override void OnChildrenCollectionChanged() + { + AutoFixSelectedContent(); + for( int i = 0; i < Children.Count; i++ ) + { + if( Children[ i ].IsSelected ) { - if (reader.MoveToAttribute("Id")) - _id = reader.Value; - if (reader.MoveToAttribute("Name")) - _name = reader.Value; - - _autoFixSelectedContent = false; - base.ReadXml(reader); - _autoFixSelectedContent = true; - AutoFixSelectedContent(); + SelectedContentIndex = i; + break; } + } + RaisePropertyChanged( "CanClose" ); + RaisePropertyChanged( "CanHide" ); + RaisePropertyChanged( "IsDirectlyHostedInFloatingWindow" ); + base.OnChildrenCollectionChanged(); + } - public bool CanHide - { - get { return Children.All(a => a.CanHide); } - } + protected override void OnParentChanged( ILayoutContainer oldValue, ILayoutContainer newValue ) + { + var oldGroup = oldValue as ILayoutGroup; + if( oldGroup != null ) + oldGroup.ChildrenCollectionChanged -= new EventHandler( OnParentChildrenCollectionChanged ); - public bool CanClose - { - get { return Children.All(a => a.CanClose);} - } + RaisePropertyChanged( "IsDirectlyHostedInFloatingWindow" ); + + var newGroup = newValue as ILayoutGroup; + if( newGroup != null ) + newGroup.ChildrenCollectionChanged += new EventHandler( OnParentChildrenCollectionChanged ); + + base.OnParentChanged( oldValue, newValue ); + } + + public override void WriteXml( System.Xml.XmlWriter writer ) + { + if( _id != null ) + writer.WriteAttributeString( "Id", _id ); + if( _name != null ) + writer.WriteAttributeString( "Name", _name ); + + base.WriteXml( writer ); + } + + public override void ReadXml( System.Xml.XmlReader reader ) + { + if( reader.MoveToAttribute( "Id" ) ) + _id = reader.Value; + if( reader.MoveToAttribute( "Name" ) ) + _name = reader.Value; + + _autoFixSelectedContent = false; + base.ReadXml( reader ); + _autoFixSelectedContent = true; + AutoFixSelectedContent(); + } #if TRACE public override void ConsoleDump(int tab) @@ -276,5 +241,94 @@ namespace Xceed.Wpf.AvalonDock.Layout child.ConsoleDump(tab + 1); } #endif + + #endregion + + #region Public Methods + + public int IndexOf( LayoutContent content ) + { + var anchorableChild = content as LayoutAnchorable; + if( anchorableChild == null ) + return -1; + + return Children.IndexOf( anchorableChild ); } + + public bool IsDirectlyHostedInFloatingWindow + { + get + { + var parentFloatingWindow = this.FindParent(); + if( parentFloatingWindow != null ) + return parentFloatingWindow.IsSinglePane; + + return false; + //return Parent != null && Parent.ChildrenCount == 1 && Parent.Parent is LayoutFloatingWindow; + } + } + + #endregion + + #region Internal Methods + + internal void SetNextSelectedIndex() + { + SelectedContentIndex = -1; + for( int i = 0; i < this.Children.Count; ++i ) + { + if( Children[ i ].IsEnabled ) + { + SelectedContentIndex = i; + return; + } + } + } + + internal void UpdateIsDirectlyHostedInFloatingWindow() + { + RaisePropertyChanged( "IsDirectlyHostedInFloatingWindow" ); + } + + #endregion + + #region Private Methods + + private void AutoFixSelectedContent() + { + if( _autoFixSelectedContent ) + { + if( SelectedContentIndex >= ChildrenCount ) + SelectedContentIndex = Children.Count - 1; + + if( SelectedContentIndex == -1 && ChildrenCount > 0 ) + SetNextSelectedIndex(); + } + } + + private void OnParentChildrenCollectionChanged( object sender, EventArgs e ) + { + RaisePropertyChanged( "IsDirectlyHostedInFloatingWindow" ); + } + + #endregion + + #region ILayoutPaneSerializable Interface + + string _id; + + string ILayoutPaneSerializable.Id + { + get + { + return _id; + } + set + { + _id = value; + } + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorablePaneGroup.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorablePaneGroup.cs index fb4253d8..f00808f0 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorablePaneGroup.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorablePaneGroup.cs @@ -15,102 +15,104 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Collections.ObjectModel; -using System.Windows; using System.Windows.Controls; using System.Windows.Markup; namespace Xceed.Wpf.AvalonDock.Layout { - [ContentProperty("Children")] - [Serializable] - public class LayoutAnchorablePaneGroup : LayoutPositionableGroup, ILayoutAnchorablePane, ILayoutOrientableGroup + [ContentProperty( "Children" )] + [Serializable] + public class LayoutAnchorablePaneGroup : LayoutPositionableGroup, ILayoutAnchorablePane, ILayoutOrientableGroup + { + #region Constructors + + public LayoutAnchorablePaneGroup() { - public LayoutAnchorablePaneGroup() - { - } + } - public LayoutAnchorablePaneGroup(LayoutAnchorablePane firstChild) - { - Children.Add(firstChild); - } + public LayoutAnchorablePaneGroup( LayoutAnchorablePane firstChild ) + { + Children.Add( firstChild ); + } - #region Orientation + #endregion - private Orientation _orientation; - public Orientation Orientation - { - get { return _orientation; } - set - { - if (_orientation != value) - { - RaisePropertyChanging("Orientation"); - _orientation = value; - RaisePropertyChanged("Orientation"); - } - } - } + #region Properties - #endregion + #region Orientation - protected override bool GetVisibility() + private Orientation _orientation; + public Orientation Orientation + { + get + { + return _orientation; + } + set + { + if( _orientation != value ) { - return Children.Count > 0 && Children.Any(c => c.IsVisible); + RaisePropertyChanging( "Orientation" ); + _orientation = value; + RaisePropertyChanged( "Orientation" ); } + } + } - protected override void OnIsVisibleChanged() - { - UpdateParentVisibility(); - base.OnIsVisibleChanged(); - } + #endregion - void UpdateParentVisibility() - { - var parentPane = Parent as ILayoutElementWithVisibility; - if (parentPane != null) - parentPane.ComputeVisibility(); - } + #endregion - protected override void OnDockWidthChanged() - { - if (DockWidth.IsAbsolute && ChildrenCount == 1) - ((ILayoutPositionableElement)Children[0]).DockWidth = DockWidth; + #region Overrides - base.OnDockWidthChanged(); - } + protected override bool GetVisibility() + { + return Children.Count > 0 && Children.Any( c => c.IsVisible ); + } - protected override void OnDockHeightChanged() - { - if (DockHeight.IsAbsolute && ChildrenCount == 1) - ((ILayoutPositionableElement)Children[0]).DockHeight = DockHeight; - base.OnDockHeightChanged(); - } + protected override void OnIsVisibleChanged() + { + UpdateParentVisibility(); + base.OnIsVisibleChanged(); + } - protected override void OnChildrenCollectionChanged() - { - if (DockWidth.IsAbsolute && ChildrenCount == 1) - ((ILayoutPositionableElement)Children[0]).DockWidth = DockWidth; - if (DockHeight.IsAbsolute && ChildrenCount == 1) - ((ILayoutPositionableElement)Children[0]).DockHeight = DockHeight; - base.OnChildrenCollectionChanged(); - } + protected override void OnDockWidthChanged() + { + if( DockWidth.IsAbsolute && ChildrenCount == 1 ) + ( ( ILayoutPositionableElement )Children[ 0 ] ).DockWidth = DockWidth; - public override void WriteXml(System.Xml.XmlWriter writer) - { - writer.WriteAttributeString("Orientation", Orientation.ToString()); - base.WriteXml(writer); - } + base.OnDockWidthChanged(); + } - public override void ReadXml(System.Xml.XmlReader reader) - { - if (reader.MoveToAttribute("Orientation")) - Orientation = (Orientation)Enum.Parse(typeof(Orientation), reader.Value, true); - base.ReadXml(reader); - } + protected override void OnDockHeightChanged() + { + if( DockHeight.IsAbsolute && ChildrenCount == 1 ) + ( ( ILayoutPositionableElement )Children[ 0 ] ).DockHeight = DockHeight; + base.OnDockHeightChanged(); + } + + protected override void OnChildrenCollectionChanged() + { + if( DockWidth.IsAbsolute && ChildrenCount == 1 ) + ( ( ILayoutPositionableElement )Children[ 0 ] ).DockWidth = DockWidth; + if( DockHeight.IsAbsolute && ChildrenCount == 1 ) + ( ( ILayoutPositionableElement )Children[ 0 ] ).DockHeight = DockHeight; + base.OnChildrenCollectionChanged(); + } + + public override void WriteXml( System.Xml.XmlWriter writer ) + { + writer.WriteAttributeString( "Orientation", Orientation.ToString() ); + base.WriteXml( writer ); + } + + public override void ReadXml( System.Xml.XmlReader reader ) + { + if( reader.MoveToAttribute( "Orientation" ) ) + Orientation = ( Orientation )Enum.Parse( typeof( Orientation ), reader.Value, true ); + base.ReadXml( reader ); + } #if TRACE public override void ConsoleDump(int tab) @@ -123,7 +125,17 @@ namespace Xceed.Wpf.AvalonDock.Layout } #endif + #endregion + #region Private Methods + + private void UpdateParentVisibility() + { + var parentPane = Parent as ILayoutElementWithVisibility; + if( parentPane != null ) + parentPane.ComputeVisibility(); } + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutContent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutContent.cs index ec2ef161..ffa93dbc 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutContent.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutContent.cs @@ -15,9 +15,7 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows.Markup; using System.Xml.Serialization; using System.Windows; @@ -28,775 +26,880 @@ using Xceed.Wpf.AvalonDock.Controls; namespace Xceed.Wpf.AvalonDock.Layout { - [ContentProperty("Content")] - [Serializable] - public abstract class LayoutContent : LayoutElement, IXmlSerializable, ILayoutElementForFloatingWindow, IComparable, ILayoutPreviousContainer + [ContentProperty( "Content" )] + [Serializable] + public abstract class LayoutContent : LayoutElement, IXmlSerializable, ILayoutElementForFloatingWindow, IComparable, ILayoutPreviousContainer + { + #region Constructors + + internal LayoutContent() { - internal LayoutContent() - { } + } - #region Title + #endregion - public static readonly DependencyProperty TitleProperty = - DependencyProperty.Register( "Title", typeof( string ), typeof( LayoutContent ), new UIPropertyMetadata( null, OnTitlePropertyChanged, CoerceTitleValue ) ); + #region Properties - public string Title - { - get { return ( string )GetValue( TitleProperty ); } - set { SetValue( TitleProperty, value ); } - } + #region Title - private static object CoerceTitleValue( DependencyObject obj, object value ) - { - var lc = ( LayoutContent )obj; - if( ( ( string )value ) != lc.Title ) - { - lc.RaisePropertyChanging( LayoutContent.TitleProperty.Name ); - } - return value; - } + public static readonly DependencyProperty TitleProperty = DependencyProperty.Register( "Title", typeof( string ), typeof( LayoutContent ), new UIPropertyMetadata( null, OnTitlePropertyChanged, CoerceTitleValue ) ); - private static void OnTitlePropertyChanged( DependencyObject obj, DependencyPropertyChangedEventArgs args ) - { - ( ( LayoutContent )obj ).RaisePropertyChanged( LayoutContent.TitleProperty.Name ); - } - - #endregion //Title + public string Title + { + get + { + return ( string )GetValue( TitleProperty ); + } + set + { + SetValue( TitleProperty, value ); + } + } - #region Content - [NonSerialized] - private object _content = null; - [XmlIgnore] - public object Content - { - get { return _content; } - set - { - if (_content != value) - { - RaisePropertyChanging("Content"); - _content = value; - RaisePropertyChanged("Content"); - } - } - } + private static object CoerceTitleValue( DependencyObject obj, object value ) + { + var lc = ( LayoutContent )obj; + if( ( ( string )value ) != lc.Title ) + { + lc.RaisePropertyChanging( LayoutContent.TitleProperty.Name ); + } + return value; + } - #endregion + private static void OnTitlePropertyChanged( DependencyObject obj, DependencyPropertyChangedEventArgs args ) + { + ( ( LayoutContent )obj ).RaisePropertyChanged( LayoutContent.TitleProperty.Name ); + } - #region ContentId + #endregion //Title - private string _contentId = null; - public string ContentId - { - get - { - if (_contentId == null) - { - var contentAsControl = _content as FrameworkElement; - if (contentAsControl != null && !string.IsNullOrWhiteSpace(contentAsControl.Name)) - return contentAsControl.Name; - } - return _contentId; - } - set - { - if (_contentId != value) - { - _contentId = value; - RaisePropertyChanged("ContentId"); - } - } - } + #region Content + [NonSerialized] + private object _content = null; + [XmlIgnore] + public object Content + { + get + { + return _content; + } + set + { + if( _content != value ) + { + RaisePropertyChanging( "Content" ); + _content = value; + RaisePropertyChanged( "Content" ); + } + } + } - #endregion + #endregion - #region IsSelected + #region ContentId - private bool _isSelected = false; - public bool IsSelected + private string _contentId = null; + public string ContentId + { + get + { + if( _contentId == null ) { - get { return _isSelected; } - set - { - if (_isSelected != value) - { - bool oldValue = _isSelected; - RaisePropertyChanging("IsSelected"); - _isSelected = value; - var parentSelector = (Parent as ILayoutContentSelector); - if (parentSelector != null) - parentSelector.SelectedContentIndex = _isSelected ? parentSelector.IndexOf(this) : -1; - OnIsSelectedChanged(oldValue, value); - RaisePropertyChanged("IsSelected"); - LayoutAnchorableTabItem.CancelMouseLeave(); - } - } + var contentAsControl = _content as FrameworkElement; + if( contentAsControl != null && !string.IsNullOrWhiteSpace( contentAsControl.Name ) ) + return contentAsControl.Name; } - - /// - /// Provides derived classes an opportunity to handle changes to the IsSelected property. - /// - protected virtual void OnIsSelectedChanged(bool oldValue, bool newValue) + return _contentId; + } + set + { + if( _contentId != value ) { - if (IsSelectedChanged != null) - IsSelectedChanged(this, EventArgs.Empty); + _contentId = value; + RaisePropertyChanged( "ContentId" ); } + } + } - public event EventHandler IsSelectedChanged; + #endregion - #endregion + #region IsSelected - #region IsActive + private bool _isSelected = false; + public bool IsSelected + { + get + { + return _isSelected; + } + set + { + if( _isSelected != value ) + { + bool oldValue = _isSelected; + RaisePropertyChanging( "IsSelected" ); + _isSelected = value; + var parentSelector = ( Parent as ILayoutContentSelector ); + if( parentSelector != null ) + parentSelector.SelectedContentIndex = _isSelected ? parentSelector.IndexOf( this ) : -1; + OnIsSelectedChanged( oldValue, value ); + RaisePropertyChanged( "IsSelected" ); + LayoutAnchorableTabItem.CancelMouseLeave(); + } + } + } - [field: NonSerialized] - private bool _isActive = false; - [XmlIgnore] - public bool IsActive - { - get { return _isActive; } - set - { - if (_isActive != value) - { - RaisePropertyChanging("IsActive"); - bool oldValue = _isActive; - - _isActive = value; - - var root = Root; - if (root != null && _isActive) - root.ActiveContent = this; - - if (_isActive) - IsSelected = true; - - OnIsActiveChanged(oldValue, value); - RaisePropertyChanged("IsActive"); - } - } - } + /// + /// Provides derived classes an opportunity to handle changes to the IsSelected property. + /// + protected virtual void OnIsSelectedChanged( bool oldValue, bool newValue ) + { + if( IsSelectedChanged != null ) + IsSelectedChanged( this, EventArgs.Empty ); + } + + public event EventHandler IsSelectedChanged; + + #endregion + + #region IsActive - /// - /// Provides derived classes an opportunity to handle changes to the IsActive property. - /// - protected virtual void OnIsActiveChanged(bool oldValue, bool newValue) + [field: NonSerialized] + private bool _isActive = false; + [XmlIgnore] + public bool IsActive + { + get + { + return _isActive; + } + set + { + if( _isActive != value ) { - if (newValue) - LastActivationTimeStamp = DateTime.Now; + RaisePropertyChanging( "IsActive" ); + bool oldValue = _isActive; + + _isActive = value; + + var root = Root; + if( root != null && _isActive ) + root.ActiveContent = this; + + if( _isActive ) + IsSelected = true; - if (IsActiveChanged != null) - IsActiveChanged(this, EventArgs.Empty); + OnIsActiveChanged( oldValue, value ); + RaisePropertyChanged( "IsActive" ); } + } + } - public event EventHandler IsActiveChanged; + /// + /// Provides derived classes an opportunity to handle changes to the IsActive property. + /// + protected virtual void OnIsActiveChanged( bool oldValue, bool newValue ) + { + if( newValue ) + LastActivationTimeStamp = DateTime.Now; - #endregion + if( IsActiveChanged != null ) + IsActiveChanged( this, EventArgs.Empty ); + } - #region IsLastFocusedDocument + public event EventHandler IsActiveChanged; - private bool _isLastFocusedDocument = false; - public bool IsLastFocusedDocument - { - get { return _isLastFocusedDocument; } - internal set - { - if (_isLastFocusedDocument != value) - { - RaisePropertyChanging("IsLastFocusedDocument"); - _isLastFocusedDocument = value; - RaisePropertyChanged("IsLastFocusedDocument"); - } - } - } + #endregion - #endregion + #region IsLastFocusedDocument - #region PreviousContainer + private bool _isLastFocusedDocument = false; + public bool IsLastFocusedDocument + { + get + { + return _isLastFocusedDocument; + } + internal set + { + if( _isLastFocusedDocument != value ) + { + RaisePropertyChanging( "IsLastFocusedDocument" ); + _isLastFocusedDocument = value; + RaisePropertyChanged( "IsLastFocusedDocument" ); + } + } + } - [field: NonSerialized] - private ILayoutContainer _previousContainer = null; + #endregion - [XmlIgnore] - ILayoutContainer ILayoutPreviousContainer.PreviousContainer - { - get { return _previousContainer; } - set - { - if (_previousContainer != value) - { - _previousContainer = value; - RaisePropertyChanged("PreviousContainer"); - - var paneSerializable = _previousContainer as ILayoutPaneSerializable; - if (paneSerializable != null && - paneSerializable.Id == null) - paneSerializable.Id = Guid.NewGuid().ToString(); - } - } - } + #region PreviousContainer - protected ILayoutContainer PreviousContainer - { - get { return ((ILayoutPreviousContainer)this).PreviousContainer; } - set { ((ILayoutPreviousContainer)this).PreviousContainer = value; } - } + [field: NonSerialized] + private ILayoutContainer _previousContainer = null; - [XmlIgnore] - string ILayoutPreviousContainer.PreviousContainerId - { - get; - set; - } + [XmlIgnore] + ILayoutContainer ILayoutPreviousContainer.PreviousContainer + { + get + { + return _previousContainer; + } + set + { + if( _previousContainer != value ) + { + _previousContainer = value; + RaisePropertyChanged( "PreviousContainer" ); + + var paneSerializable = _previousContainer as ILayoutPaneSerializable; + if( paneSerializable != null && + paneSerializable.Id == null ) + paneSerializable.Id = Guid.NewGuid().ToString(); + } + } + } - protected string PreviousContainerId - { - get { return ((ILayoutPreviousContainer)this).PreviousContainerId; } - set { ((ILayoutPreviousContainer)this).PreviousContainerId = value; } - } + protected ILayoutContainer PreviousContainer + { + get + { + return ( ( ILayoutPreviousContainer )this ).PreviousContainer; + } + set + { + ( ( ILayoutPreviousContainer )this ).PreviousContainer = value; + } + } - #endregion + [XmlIgnore] + string ILayoutPreviousContainer.PreviousContainerId + { + get; + set; + } - #region PreviousContainerIndex - [field: NonSerialized] - private int _previousContainerIndex = -1; - [XmlIgnore] - public int PreviousContainerIndex - { - get { return _previousContainerIndex; } - set - { - if (_previousContainerIndex != value) - { - _previousContainerIndex = value; - RaisePropertyChanged("PreviousContainerIndex"); - } - } - } + protected string PreviousContainerId + { + get + { + return ( ( ILayoutPreviousContainer )this ).PreviousContainerId; + } + set + { + ( ( ILayoutPreviousContainer )this ).PreviousContainerId = value; + } + } - #endregion + #endregion - #region LastActivationTimeStamp + #region PreviousContainerIndex + [field: NonSerialized] + private int _previousContainerIndex = -1; + [XmlIgnore] + public int PreviousContainerIndex + { + get + { + return _previousContainerIndex; + } + set + { + if( _previousContainerIndex != value ) + { + _previousContainerIndex = value; + RaisePropertyChanged( "PreviousContainerIndex" ); + } + } + } - private DateTime? _lastActivationTimeStamp = null; - public DateTime? LastActivationTimeStamp - { - get { return _lastActivationTimeStamp; } - set - { - if (_lastActivationTimeStamp != value) - { - _lastActivationTimeStamp = value; - RaisePropertyChanged("LastActivationTimeStamp"); - } - } - } + #endregion - #endregion + #region LastActivationTimeStamp - protected override void OnParentChanging(ILayoutContainer oldValue, ILayoutContainer newValue) - { - var root = Root; + private DateTime? _lastActivationTimeStamp = null; + public DateTime? LastActivationTimeStamp + { + get + { + return _lastActivationTimeStamp; + } + set + { + if( _lastActivationTimeStamp != value ) + { + _lastActivationTimeStamp = value; + RaisePropertyChanged( "LastActivationTimeStamp" ); + } + } + } - if (oldValue != null) - IsSelected = false; + #endregion - //if (root != null && _isActive && newValue == null) - // root.ActiveContent = null; + #region FloatingWidth - base.OnParentChanging(oldValue, newValue); - } + private double _floatingWidth = 0.0; + public double FloatingWidth + { + get + { + return _floatingWidth; + } + set + { + if( _floatingWidth != value ) + { + RaisePropertyChanging( "FloatingWidth" ); + _floatingWidth = value; + RaisePropertyChanged( "FloatingWidth" ); + } + } + } - protected override void OnParentChanged(ILayoutContainer oldValue, ILayoutContainer newValue) - { - if (IsSelected && Parent != null && Parent is ILayoutContentSelector) - { - var parentSelector = (Parent as ILayoutContentSelector); - parentSelector.SelectedContentIndex = parentSelector.IndexOf(this); - } + #endregion - //var root = Root; - //if (root != null && _isActive) - // root.ActiveContent = this; + #region FloatingHeight - base.OnParentChanged(oldValue, newValue); - } + private double _floatingHeight = 0.0; + public double FloatingHeight + { + get + { + return _floatingHeight; + } + set + { + if( _floatingHeight != value ) + { + RaisePropertyChanging( "FloatingHeight" ); + _floatingHeight = value; + RaisePropertyChanged( "FloatingHeight" ); + } + } + } - /// - /// Test if the content can be closed - /// - /// - internal bool TestCanClose() - { - CancelEventArgs args = new CancelEventArgs(); + #endregion - OnClosing(args); + #region FloatingLeft - if (args.Cancel) - return false; + private double _floatingLeft = 0.0; + public double FloatingLeft + { + get + { + return _floatingLeft; + } + set + { + if( _floatingLeft != value ) + { + RaisePropertyChanging( "FloatingLeft" ); + _floatingLeft = value; + RaisePropertyChanged( "FloatingLeft" ); + } + } + } - return true; - } + #endregion - internal void CloseInternal() - { - var root = Root; - var parentAsContainer = Parent as ILayoutContainer; - parentAsContainer.RemoveChild( this ); - if( root != null ) - root.CollectGarbage(); + #region FloatingTop - OnClosed(); - } + private double _floatingTop = 0.0; + public double FloatingTop + { + get + { + return _floatingTop; + } + set + { + if( _floatingTop != value ) + { + RaisePropertyChanging( "FloatingTop" ); + _floatingTop = value; + RaisePropertyChanged( "FloatingTop" ); + } + } + } - /// - /// Close the content - /// - /// Please note that usually the anchorable is only hidden (not closed). By default when user click the X button it only hides the content. - public abstract void Close(); + #endregion - /// - /// Event fired when the content is closed (i.e. removed definitely from the layout) - /// - public event EventHandler Closed; + #region IsMaximized - protected virtual void OnClosed() - { - if (Closed != null) - Closed(this, EventArgs.Empty); - } + private bool _isMaximized = false; + public bool IsMaximized + { + get + { + return _isMaximized; + } + set + { + if( _isMaximized != value ) + { + RaisePropertyChanging( "IsMaximized" ); + _isMaximized = value; + RaisePropertyChanged( "IsMaximized" ); + } + } + } - /// - /// Event fired when the content is about to be closed (i.e. removed definitely from the layout) - /// - /// Please note that LayoutAnchorable also can be hidden. Usually user hide anchorables when click the 'X' button. To completely close - /// an anchorable the user should click the 'Close' menu item from the context menu. When an LayoutAnchorable is hidden its visibility changes to false and - /// IsHidden property is set to true. - /// Hanlde the Hiding event for the LayoutAnchorable to cancel the hide operation. - public event EventHandler Closing; + #endregion - protected virtual void OnClosing(CancelEventArgs args) - { - if (Closing != null) - Closing(this, args); - } + #region ToolTip - public System.Xml.Schema.XmlSchema GetSchema() - { - return null; - } + private object _toolTip = null; + public object ToolTip + { + get + { + return _toolTip; + } + set + { + if( _toolTip != value ) + { + _toolTip = value; + RaisePropertyChanged( "ToolTip" ); + } + } + } - public virtual void ReadXml(System.Xml.XmlReader reader) - { - if (reader.MoveToAttribute("Title")) - Title = reader.Value; - //if (reader.MoveToAttribute("IconSource")) - // IconSource = new Uri(reader.Value, UriKind.RelativeOrAbsolute); - - if (reader.MoveToAttribute("IsSelected")) - IsSelected = bool.Parse(reader.Value); - if (reader.MoveToAttribute("ContentId")) - ContentId = reader.Value; - if (reader.MoveToAttribute("IsLastFocusedDocument")) - IsLastFocusedDocument = bool.Parse(reader.Value); - if (reader.MoveToAttribute("PreviousContainerId")) - PreviousContainerId = reader.Value; - if (reader.MoveToAttribute("PreviousContainerIndex")) - PreviousContainerIndex = int.Parse(reader.Value); - - if (reader.MoveToAttribute("FloatingLeft")) - FloatingLeft = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("FloatingTop")) - FloatingTop = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("FloatingWidth")) - FloatingWidth = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("FloatingHeight")) - FloatingHeight = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("IsMaximized")) - IsMaximized = bool.Parse(reader.Value); - if (reader.MoveToAttribute("CanClose")) - CanClose = bool.Parse(reader.Value); - if (reader.MoveToAttribute("CanFloat")) - CanFloat = bool.Parse(reader.Value); - if (reader.MoveToAttribute("LastActivationTimeStamp")) - LastActivationTimeStamp = DateTime.Parse(reader.Value, CultureInfo.InvariantCulture); - - reader.Read(); - } + #endregion - public virtual void WriteXml(System.Xml.XmlWriter writer) - { - if (!string.IsNullOrWhiteSpace(Title)) - writer.WriteAttributeString("Title", Title); - - //if (IconSource != null) - // writer.WriteAttributeString("IconSource", IconSource.ToString()); - - if (IsSelected) - writer.WriteAttributeString("IsSelected", IsSelected.ToString()); - - if (IsLastFocusedDocument) - writer.WriteAttributeString("IsLastFocusedDocument", IsLastFocusedDocument.ToString()); - - if (!string.IsNullOrWhiteSpace(ContentId)) - writer.WriteAttributeString("ContentId", ContentId); - - - if (ToolTip != null && ToolTip is string) - if (!string.IsNullOrWhiteSpace((string)ToolTip)) - writer.WriteAttributeString("ToolTip", (string)ToolTip); - - if (FloatingLeft != 0.0) - writer.WriteAttributeString("FloatingLeft", FloatingLeft.ToString(CultureInfo.InvariantCulture)); - if (FloatingTop != 0.0) - writer.WriteAttributeString("FloatingTop", FloatingTop.ToString(CultureInfo.InvariantCulture)); - if (FloatingWidth != 0.0) - writer.WriteAttributeString("FloatingWidth", FloatingWidth.ToString(CultureInfo.InvariantCulture)); - if (FloatingHeight != 0.0) - writer.WriteAttributeString("FloatingHeight", FloatingHeight.ToString(CultureInfo.InvariantCulture)); - - if (IsMaximized) - writer.WriteAttributeString("IsMaximized", IsMaximized.ToString()); - if (!CanClose) - writer.WriteAttributeString("CanClose", CanClose.ToString()); - if (!CanFloat) - writer.WriteAttributeString("CanFloat", CanFloat.ToString()); - - if (LastActivationTimeStamp != null) - writer.WriteAttributeString("LastActivationTimeStamp", LastActivationTimeStamp.Value.ToString(CultureInfo.InvariantCulture)); - - if (_previousContainer != null) - { - var paneSerializable = _previousContainer as ILayoutPaneSerializable; - if (paneSerializable != null) - { - writer.WriteAttributeString("PreviousContainerId", paneSerializable.Id); - writer.WriteAttributeString("PreviousContainerIndex", _previousContainerIndex.ToString()); - } - } + #region IsFloating + public bool IsFloating + { + get + { + return this.FindParent() != null; + } + } - } + #endregion - #region FloatingWidth + #region IconSource - private double _floatingWidth = 0.0; - public double FloatingWidth - { - get { return _floatingWidth; } - set - { - if (_floatingWidth != value) - { - RaisePropertyChanging("FloatingWidth"); - _floatingWidth = value; - RaisePropertyChanged("FloatingWidth"); - } - } - } + private ImageSource _iconSource = null; + public ImageSource IconSource + { + get + { + return _iconSource; + } + set + { + if( _iconSource != value ) + { + _iconSource = value; + RaisePropertyChanged( "IconSource" ); + } + } + } - #endregion + #endregion - #region FloatingHeight + #region CanClose - private double _floatingHeight = 0.0; - public double FloatingHeight - { - get { return _floatingHeight; } - set - { - if (_floatingHeight != value) - { - RaisePropertyChanging("FloatingHeight"); - _floatingHeight = value; - RaisePropertyChanged("FloatingHeight"); - } - } - } + internal bool _canClose = true; + public bool CanClose + { + get + { + return _canClose; + } + set + { + if( _canClose != value ) + { + _canClose = value; + RaisePropertyChanged( "CanClose" ); + } + } + } - #endregion + #endregion - #region FloatingLeft + #region CanFloat - private double _floatingLeft = 0.0; - public double FloatingLeft - { - get { return _floatingLeft; } - set - { - if (_floatingLeft != value) - { - RaisePropertyChanging("FloatingLeft"); - _floatingLeft = value; - RaisePropertyChanged("FloatingLeft"); - } - } - } + private bool _canFloat = true; + public bool CanFloat + { + get + { + return _canFloat; + } + set + { + if( _canFloat != value ) + { + _canFloat = value; + RaisePropertyChanged( "CanFloat" ); + } + } + } - #endregion + #endregion - #region FloatingTop + #region IsEnabled - private double _floatingTop = 0.0; - public double FloatingTop - { - get { return _floatingTop; } - set - { - if (_floatingTop != value) - { - RaisePropertyChanging("FloatingTop"); - _floatingTop = value; - RaisePropertyChanged("FloatingTop"); - } - } - } + private bool _isEnabled = true; + public bool IsEnabled + { + get + { + return _isEnabled; + } + set + { + if( _isEnabled != value ) + { + _isEnabled = value; + RaisePropertyChanged( "IsEnabled" ); + } + } + } - #endregion + #endregion - #region IsMaximized - private bool _isMaximized = false; - public bool IsMaximized - { - get { return _isMaximized; } - set - { - if (_isMaximized != value) - { - RaisePropertyChanging("IsMaximized"); - _isMaximized = value; - RaisePropertyChanged("IsMaximized"); - } - } - } - #endregion - #region ToolTip - private object _toolTip = null; - public object ToolTip - { - get { return _toolTip; } - set - { - if (_toolTip != value) - { - _toolTip = value; - RaisePropertyChanged("ToolTip"); - } - } - } - #endregion - public bool IsFloating - { - get { return this.FindParent() != null; } - } + #endregion - #region IconSource + #region Overrides - private ImageSource _iconSource = null; - public ImageSource IconSource - { - get { return _iconSource; } - set - { - if (_iconSource != value) - { - _iconSource = value; - RaisePropertyChanged("IconSource"); - } - } - } + protected override void OnParentChanging( ILayoutContainer oldValue, ILayoutContainer newValue ) + { + var root = Root; - #endregion + if( oldValue != null ) + IsSelected = false; - public int CompareTo(LayoutContent other) - { - var contentAsComparable = Content as IComparable; - if (contentAsComparable != null) - { - return contentAsComparable.CompareTo(other.Content); - } + //if (root != null && _isActive && newValue == null) + // root.ActiveContent = null; - return string.Compare(Title, other.Title); - } + base.OnParentChanging( oldValue, newValue ); + } - /// - /// Float the content in a popup window - /// - public void Float() - { - if (PreviousContainer != null && - PreviousContainer.FindParent() != null) - { + protected override void OnParentChanged( ILayoutContainer oldValue, ILayoutContainer newValue ) + { + if( IsSelected && Parent != null && Parent is ILayoutContentSelector ) + { + var parentSelector = ( Parent as ILayoutContentSelector ); + parentSelector.SelectedContentIndex = parentSelector.IndexOf( this ); + } - var currentContainer = Parent as ILayoutPane; - var currentContainerIndex = (currentContainer as ILayoutGroup).IndexOfChild(this); - var previousContainerAsLayoutGroup = PreviousContainer as ILayoutGroup; + //var root = Root; + //if (root != null && _isActive) + // root.ActiveContent = this; - if (PreviousContainerIndex < previousContainerAsLayoutGroup.ChildrenCount) - previousContainerAsLayoutGroup.InsertChildAt(PreviousContainerIndex, this); - else - previousContainerAsLayoutGroup.InsertChildAt(previousContainerAsLayoutGroup.ChildrenCount, this); + base.OnParentChanged( oldValue, newValue ); + } - PreviousContainer = currentContainer; - PreviousContainerIndex = currentContainerIndex; + #endregion - IsSelected = true; - IsActive = true; + #region Public Methods - Root.CollectGarbage(); - } - else - { - Root.Manager.StartDraggingFloatingWindowForContent(this, false); + /// + /// Close the content + /// + /// Please note that usually the anchorable is only hidden (not closed). By default when user click the X button it only hides the content. + public abstract void Close(); - IsSelected = true; - IsActive = true; - } + public System.Xml.Schema.XmlSchema GetSchema() + { + return null; + } - } + public virtual void ReadXml( System.Xml.XmlReader reader ) + { + if( reader.MoveToAttribute( "Title" ) ) + Title = reader.Value; + //if (reader.MoveToAttribute("IconSource")) + // IconSource = new Uri(reader.Value, UriKind.RelativeOrAbsolute); + + if( reader.MoveToAttribute( "IsSelected" ) ) + IsSelected = bool.Parse( reader.Value ); + if( reader.MoveToAttribute( "ContentId" ) ) + ContentId = reader.Value; + if( reader.MoveToAttribute( "IsLastFocusedDocument" ) ) + IsLastFocusedDocument = bool.Parse( reader.Value ); + if( reader.MoveToAttribute( "PreviousContainerId" ) ) + PreviousContainerId = reader.Value; + if( reader.MoveToAttribute( "PreviousContainerIndex" ) ) + PreviousContainerIndex = int.Parse( reader.Value ); + + if( reader.MoveToAttribute( "FloatingLeft" ) ) + FloatingLeft = double.Parse( reader.Value, CultureInfo.InvariantCulture ); + if( reader.MoveToAttribute( "FloatingTop" ) ) + FloatingTop = double.Parse( reader.Value, CultureInfo.InvariantCulture ); + if( reader.MoveToAttribute( "FloatingWidth" ) ) + FloatingWidth = double.Parse( reader.Value, CultureInfo.InvariantCulture ); + if( reader.MoveToAttribute( "FloatingHeight" ) ) + FloatingHeight = double.Parse( reader.Value, CultureInfo.InvariantCulture ); + if( reader.MoveToAttribute( "IsMaximized" ) ) + IsMaximized = bool.Parse( reader.Value ); + if( reader.MoveToAttribute( "CanClose" ) ) + CanClose = bool.Parse( reader.Value ); + if( reader.MoveToAttribute( "CanFloat" ) ) + CanFloat = bool.Parse( reader.Value ); + if( reader.MoveToAttribute( "LastActivationTimeStamp" ) ) + LastActivationTimeStamp = DateTime.Parse( reader.Value, CultureInfo.InvariantCulture ); + + reader.Read(); + } - /// - /// Dock the content as document - /// - public void DockAsDocument() - { - var root = Root as LayoutRoot; - if (root == null) - throw new InvalidOperationException(); - if (Parent is LayoutDocumentPane) - return; - - if (PreviousContainer is LayoutDocumentPane) - { - Dock(); - return; - } - - LayoutDocumentPane newParentPane; - if (root.LastFocusedDocument != null) - { - newParentPane = root.LastFocusedDocument.Parent as LayoutDocumentPane; - } - else - { - newParentPane = root.Descendents().OfType().FirstOrDefault(); - } - - if (newParentPane != null) - { - newParentPane.Children.Add(this); - root.CollectGarbage(); - } + public virtual void WriteXml( System.Xml.XmlWriter writer ) + { + if( !string.IsNullOrWhiteSpace( Title ) ) + writer.WriteAttributeString( "Title", Title ); - IsSelected = true; - IsActive = true; - } + //if (IconSource != null) + // writer.WriteAttributeString("IconSource", IconSource.ToString()); - /// - /// Re-dock the content to its previous container - /// - public void Dock() - { - if (PreviousContainer != null) - { - var currentContainer = Parent as ILayoutContainer; - var currentContainerIndex = (currentContainer is ILayoutGroup) ? (currentContainer as ILayoutGroup).IndexOfChild(this) : -1; - var previousContainerAsLayoutGroup = PreviousContainer as ILayoutGroup; - - if (PreviousContainerIndex < previousContainerAsLayoutGroup.ChildrenCount) - previousContainerAsLayoutGroup.InsertChildAt(PreviousContainerIndex, this); - else - previousContainerAsLayoutGroup.InsertChildAt(previousContainerAsLayoutGroup.ChildrenCount, this); - - if (currentContainerIndex > -1) - { - PreviousContainer = currentContainer; - PreviousContainerIndex = currentContainerIndex; - } - else - { - PreviousContainer = null; - PreviousContainerIndex = 0; - } - - IsSelected = true; - IsActive = true; - } - else - { - InternalDock(); - } - - - Root.CollectGarbage(); + if( IsSelected ) + writer.WriteAttributeString( "IsSelected", IsSelected.ToString() ); - } + if( IsLastFocusedDocument ) + writer.WriteAttributeString( "IsLastFocusedDocument", IsLastFocusedDocument.ToString() ); - protected virtual void InternalDock() - { + if( !string.IsNullOrWhiteSpace( ContentId ) ) + writer.WriteAttributeString( "ContentId", ContentId ); - } + if( ToolTip != null && ToolTip is string ) + if( !string.IsNullOrWhiteSpace( ( string )ToolTip ) ) + writer.WriteAttributeString( "ToolTip", ( string )ToolTip ); - #region CanClose + if( FloatingLeft != 0.0 ) + writer.WriteAttributeString( "FloatingLeft", FloatingLeft.ToString( CultureInfo.InvariantCulture ) ); + if( FloatingTop != 0.0 ) + writer.WriteAttributeString( "FloatingTop", FloatingTop.ToString( CultureInfo.InvariantCulture ) ); + if( FloatingWidth != 0.0 ) + writer.WriteAttributeString( "FloatingWidth", FloatingWidth.ToString( CultureInfo.InvariantCulture ) ); + if( FloatingHeight != 0.0 ) + writer.WriteAttributeString( "FloatingHeight", FloatingHeight.ToString( CultureInfo.InvariantCulture ) ); - internal bool _canClose = true; - public bool CanClose - { - get { return _canClose; } - set - { - if (_canClose != value) - { - _canClose = value; - RaisePropertyChanged("CanClose"); - } - } - } + if( IsMaximized ) + writer.WriteAttributeString( "IsMaximized", IsMaximized.ToString() ); + if( !CanClose ) + writer.WriteAttributeString( "CanClose", CanClose.ToString() ); + if( !CanFloat ) + writer.WriteAttributeString( "CanFloat", CanFloat.ToString() ); - #endregion - #region CanFloat + if( LastActivationTimeStamp != null ) + writer.WriteAttributeString( "LastActivationTimeStamp", LastActivationTimeStamp.Value.ToString( CultureInfo.InvariantCulture ) ); - private bool _canFloat = true; - public bool CanFloat + if( _previousContainer != null ) + { + var paneSerializable = _previousContainer as ILayoutPaneSerializable; + if( paneSerializable != null ) { - get { return _canFloat; } - set - { - if (_canFloat != value) - { - _canFloat = value; - RaisePropertyChanged("CanFloat"); - } - } + writer.WriteAttributeString( "PreviousContainerId", paneSerializable.Id ); + writer.WriteAttributeString( "PreviousContainerIndex", _previousContainerIndex.ToString() ); } + } + + } - #endregion + public int CompareTo( LayoutContent other ) + { + var contentAsComparable = Content as IComparable; + if( contentAsComparable != null ) + { + return contentAsComparable.CompareTo( other.Content ); + } - #region IsEnabled + return string.Compare( Title, other.Title ); + } - private bool _isEnabled = true; - public bool IsEnabled + /// + /// Float the content in a popup window + /// + public void Float() + { + if( PreviousContainer != null && + PreviousContainer.FindParent() != null ) + { + + var currentContainer = Parent as ILayoutPane; + var currentContainerIndex = ( currentContainer as ILayoutGroup ).IndexOfChild( this ); + var previousContainerAsLayoutGroup = PreviousContainer as ILayoutGroup; + + if( PreviousContainerIndex < previousContainerAsLayoutGroup.ChildrenCount ) + previousContainerAsLayoutGroup.InsertChildAt( PreviousContainerIndex, this ); + else + previousContainerAsLayoutGroup.InsertChildAt( previousContainerAsLayoutGroup.ChildrenCount, this ); + + PreviousContainer = currentContainer; + PreviousContainerIndex = currentContainerIndex; + + IsSelected = true; + IsActive = true; + + Root.CollectGarbage(); + } + else + { + Root.Manager.StartDraggingFloatingWindowForContent( this, false ); + + IsSelected = true; + IsActive = true; + } + + } + + /// + /// Dock the content as document + /// + public void DockAsDocument() + { + var root = Root as LayoutRoot; + if( root == null ) + throw new InvalidOperationException(); + if( Parent is LayoutDocumentPane ) + return; + + if( PreviousContainer is LayoutDocumentPane ) + { + Dock(); + return; + } + + LayoutDocumentPane newParentPane; + if( root.LastFocusedDocument != null ) + { + newParentPane = root.LastFocusedDocument.Parent as LayoutDocumentPane; + } + else + { + newParentPane = root.Descendents().OfType().FirstOrDefault(); + } + + if( newParentPane != null ) + { + newParentPane.Children.Add( this ); + root.CollectGarbage(); + } + + IsSelected = true; + IsActive = true; + } + + /// + /// Re-dock the content to its previous container + /// + public void Dock() + { + if( PreviousContainer != null ) + { + var currentContainer = Parent as ILayoutContainer; + var currentContainerIndex = ( currentContainer is ILayoutGroup ) ? ( currentContainer as ILayoutGroup ).IndexOfChild( this ) : -1; + var previousContainerAsLayoutGroup = PreviousContainer as ILayoutGroup; + + if( PreviousContainerIndex < previousContainerAsLayoutGroup.ChildrenCount ) + previousContainerAsLayoutGroup.InsertChildAt( PreviousContainerIndex, this ); + else + previousContainerAsLayoutGroup.InsertChildAt( previousContainerAsLayoutGroup.ChildrenCount, this ); + + if( currentContainerIndex > -1 ) + { + PreviousContainer = currentContainer; + PreviousContainerIndex = currentContainerIndex; + } + else { - get - { - return _isEnabled; - } - set - { - if( _isEnabled != value ) - { - _isEnabled = value; - RaisePropertyChanged( "IsEnabled" ); - } - } + PreviousContainer = null; + PreviousContainerIndex = 0; } - #endregion + IsSelected = true; + IsActive = true; + } + else + { + InternalDock(); + } + + + Root.CollectGarbage(); + + } + + + + + + #endregion + + #region Internal Methods + + /// + /// Test if the content can be closed + /// + /// + internal bool TestCanClose() + { + CancelEventArgs args = new CancelEventArgs(); + + OnClosing( args ); + + if( args.Cancel ) + return false; + + return true; } + + internal void CloseInternal() + { + var root = Root; + var parentAsContainer = Parent as ILayoutContainer; + parentAsContainer.RemoveChild( this ); + if( root != null ) + root.CollectGarbage(); + + OnClosed(); + } + + protected virtual void OnClosed() + { + if( Closed != null ) + Closed( this, EventArgs.Empty ); + } + + protected virtual void OnClosing( CancelEventArgs args ) + { + if( Closing != null ) + Closing( this, args ); + } + + protected virtual void InternalDock() + { + } + + #endregion + + #region Events + + /// + /// Event fired when the content is closed (i.e. removed definitely from the layout) + /// + public event EventHandler Closed; + + /// + /// Event fired when the content is about to be closed (i.e. removed definitely from the layout) + /// + /// Please note that LayoutAnchorable also can be hidden. Usually user hide anchorables when click the 'X' button. To completely close + /// an anchorable the user should click the 'Close' menu item from the context menu. When an LayoutAnchorable is hidden its visibility changes to false and + /// IsHidden property is set to true. + /// Hanlde the Hiding event for the LayoutAnchorable to cancel the hide operation. + public event EventHandler Closing; + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocument.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocument.cs index 050b5cfd..07d4b075 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocument.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocument.cs @@ -15,79 +15,87 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Globalization; +using System.Linq; namespace Xceed.Wpf.AvalonDock.Layout { - [Serializable] - public class LayoutDocument : LayoutContent + [Serializable] + public class LayoutDocument : LayoutContent + { + #region Properties + + #region IsVisible + + public bool IsVisible { - public bool IsVisible - { - get { return true; } - } + get + { + return _isVisible; + } + internal set + { + _isVisible = value; + } + } - #region Description + private bool _isVisible = true; - private string _description = null; - public string Description - { - get { return _description; } - set - { - if (_description != value) - { - _description = value; - RaisePropertyChanged("Description"); - } - } - } + #endregion - #endregion + #region Description - public override void WriteXml(System.Xml.XmlWriter writer) + private string _description = null; + public string Description + { + get + { + return _description; + } + set + { + if( _description != value ) { - base.WriteXml(writer); + _description = value; + RaisePropertyChanged( "Description" ); + } + } + } - if (!string.IsNullOrWhiteSpace(Description)) - writer.WriteAttributeString("Description", Description); + #endregion - } + #endregion - public override void ReadXml(System.Xml.XmlReader reader) - { - if (reader.MoveToAttribute("Description")) - Description = reader.Value; + #region Overrides - base.ReadXml(reader); - } + public override void WriteXml( System.Xml.XmlWriter writer ) + { + base.WriteXml( writer ); - public override void Close() - { - if( ( this.Root != null ) && ( this.Root.Manager != null ) ) - { - var dockingManager = this.Root.Manager; - dockingManager._ExecuteCloseCommand( this ); - } - else - { - this.CloseDocument(); - } - } + if( !string.IsNullOrWhiteSpace( this.Description ) ) + writer.WriteAttributeString( "Description", this.Description ); + } - internal bool CloseDocument() - { - if( this.TestCanClose() ) - { - this.CloseInternal(); - return true; - } + public override void ReadXml( System.Xml.XmlReader reader ) + { + if( reader.MoveToAttribute( "Description" ) ) + this.Description = reader.Value; - return false; - } + base.ReadXml( reader ); + } + + public override void Close() + { + if( ( this.Root != null ) && ( this.Root.Manager != null ) ) + { + var dockingManager = this.Root.Manager; + dockingManager._ExecuteCloseCommand( this ); + } + else + { + this.CloseDocument(); + } + } #if TRACE public override void ConsoleDump(int tab) @@ -97,45 +105,61 @@ namespace Xceed.Wpf.AvalonDock.Layout } #endif + protected override void InternalDock() + { + var root = Root as LayoutRoot; + LayoutDocumentPane documentPane = null; + if( root.LastFocusedDocument != null && + root.LastFocusedDocument != this ) + { + documentPane = root.LastFocusedDocument.Parent as LayoutDocumentPane; + } + + if( documentPane == null ) + { + documentPane = root.Descendents().OfType().FirstOrDefault(); + } + + + bool added = false; + if( root.Manager.LayoutUpdateStrategy != null ) + { + added = root.Manager.LayoutUpdateStrategy.BeforeInsertDocument( root, this, documentPane ); + } + + if( !added ) + { + if( documentPane == null ) + throw new InvalidOperationException( "Layout must contains at least one LayoutDocumentPane in order to host documents" ); + + documentPane.Children.Add( this ); + added = true; + } + + if( root.Manager.LayoutUpdateStrategy != null ) + { + root.Manager.LayoutUpdateStrategy.AfterInsertDocument( root, this ); + } + + + base.InternalDock(); + } - protected override void InternalDock() - { - var root = Root as LayoutRoot; - LayoutDocumentPane documentPane = null; - if (root.LastFocusedDocument != null && - root.LastFocusedDocument != this) - { - documentPane = root.LastFocusedDocument.Parent as LayoutDocumentPane; - } - - if (documentPane == null) - { - documentPane = root.Descendents().OfType().FirstOrDefault(); - } - - - bool added = false; - if (root.Manager.LayoutUpdateStrategy != null) - { - added = root.Manager.LayoutUpdateStrategy.BeforeInsertDocument(root, this, documentPane); - } - - if (!added) - { - if (documentPane == null) - throw new InvalidOperationException("Layout must contains at least one LayoutDocumentPane in order to host documents"); - - documentPane.Children.Add(this); - added = true; - } - - if (root.Manager.LayoutUpdateStrategy != null) - { - root.Manager.LayoutUpdateStrategy.AfterInsertDocument(root, this); - } - - - base.InternalDock(); - } + #endregion + + #region Internal Methods + + internal bool CloseDocument() + { + if( this.TestCanClose() ) + { + this.CloseInternal(); + return true; + } + + return false; } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocumentFloatingWindow.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocumentFloatingWindow.cs index 6e4018f3..aa71ef3a 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocumentFloatingWindow.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocumentFloatingWindow.cs @@ -16,8 +16,6 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Markup; using System.Diagnostics; using System.Xml.Serialization; @@ -25,120 +23,135 @@ using System.Xml; namespace Xceed.Wpf.AvalonDock.Layout { - [ContentProperty("RootDocument")] - [Serializable] - public class LayoutDocumentFloatingWindow : LayoutFloatingWindow + [ContentProperty( "RootDocument" )] + [Serializable] + public class LayoutDocumentFloatingWindow : LayoutFloatingWindow + { + #region Constructors + + public LayoutDocumentFloatingWindow() { - public LayoutDocumentFloatingWindow() - { + } - } + #endregion + + #region Properties - #region RootDocument + #region RootDocument - private LayoutDocument _rootDocument = null; - public LayoutDocument RootDocument + private LayoutDocument _rootDocument = null; + public LayoutDocument RootDocument + { + get + { + return _rootDocument; + } + set + { + if( _rootDocument != value ) { - get { return _rootDocument; } - set - { - if (_rootDocument != value) - { - RaisePropertyChanging("RootDocument"); - _rootDocument = value; - if (_rootDocument != null) - _rootDocument.Parent = this; - RaisePropertyChanged("RootDocument"); - - if (RootDocumentChanged != null) - RootDocumentChanged(this, EventArgs.Empty); - } - } + RaisePropertyChanging( "RootDocument" ); + _rootDocument = value; + if( _rootDocument != null ) + _rootDocument.Parent = this; + RaisePropertyChanged( "RootDocument" ); + + if( RootDocumentChanged != null ) + RootDocumentChanged( this, EventArgs.Empty ); } + } + } + #endregion - public event EventHandler RootDocumentChanged; + #endregion - #endregion + #region Overrides - public override IEnumerable Children - { - get - { - if (RootDocument == null) - yield break; + public override IEnumerable Children + { + get + { + if( RootDocument == null ) + yield break; - yield return RootDocument; - } - } + yield return RootDocument; + } + } - public override void RemoveChild(ILayoutElement element) - { - Debug.Assert(element == RootDocument && element != null); - RootDocument = null; - } + public override void RemoveChild( ILayoutElement element ) + { + Debug.Assert( element == RootDocument && element != null ); + RootDocument = null; + } + + public override void ReplaceChild( ILayoutElement oldElement, ILayoutElement newElement ) + { + Debug.Assert( oldElement == RootDocument && oldElement != null ); + RootDocument = newElement as LayoutDocument; + } + + public override int ChildrenCount + { + get + { + return RootDocument != null ? 1 : 0; + } + } - public override void ReplaceChild(ILayoutElement oldElement, ILayoutElement newElement) + public override bool IsValid + { + get + { + return RootDocument != null; + } + } + + public override void ReadXml( XmlReader reader ) + { + reader.MoveToContent(); + if( reader.IsEmptyElement ) + { + reader.Read(); + return; + } + + var localName = reader.LocalName; + reader.Read(); + + while( true ) + { + if( reader.LocalName.Equals( localName ) && ( reader.NodeType == XmlNodeType.EndElement ) ) { - Debug.Assert(oldElement == RootDocument && oldElement != null); - RootDocument = newElement as LayoutDocument; + break; } - public override int ChildrenCount + if( reader.NodeType == XmlNodeType.Whitespace ) { - get { return RootDocument != null ? 1 : 0; } + reader.Read(); + continue; } - public override bool IsValid + XmlSerializer serializer; + if( reader.LocalName.Equals( "LayoutDocument" ) ) { - get { return RootDocument != null; } + serializer = new XmlSerializer( typeof( LayoutDocument ) ); } - - public override void ReadXml( XmlReader reader ) + else { - reader.MoveToContent(); - if( reader.IsEmptyElement ) + var type = LayoutRoot.FindType( reader.LocalName ); + if( type == null ) { - reader.Read(); - return; + throw new ArgumentException( "AvalonDock.LayoutDocumentFloatingWindow doesn't know how to deserialize " + reader.LocalName ); } + serializer = new XmlSerializer( type ); + } - var localName = reader.LocalName; - reader.Read(); + RootDocument = ( LayoutDocument )serializer.Deserialize( reader ); + } - while( true ) - { - if( reader.LocalName.Equals(localName) && (reader.NodeType == XmlNodeType.EndElement) ) - { - break; - } - - if( reader.NodeType == XmlNodeType.Whitespace ) - { - reader.Read(); - continue; - } - - XmlSerializer serializer; - if( reader.LocalName.Equals( "LayoutDocument" ) ) - { - serializer = new XmlSerializer( typeof( LayoutDocument ) ); - } - else - { - var type = LayoutRoot.FindType( reader.LocalName ); - if( type == null ) - { - throw new ArgumentException( "AvalonDock.LayoutDocumentFloatingWindow doesn't know how to deserialize " + reader.LocalName ); - } - serializer = new XmlSerializer( type ); - } - - RootDocument = ( LayoutDocument )serializer.Deserialize( reader ); - } - - reader.ReadEndElement(); - } + reader.ReadEndElement(); + } #if TRACE public override void ConsoleDump(int tab) @@ -149,6 +162,13 @@ namespace Xceed.Wpf.AvalonDock.Layout RootDocument.ConsoleDump(tab + 1); } #endif - } + #endregion + + #region Events + + public event EventHandler RootDocumentChanged; + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocumentPane.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocumentPane.cs index 3ed6a022..35589ba8 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocumentPane.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocumentPane.cs @@ -17,8 +17,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Collections.ObjectModel; using System.Windows.Markup; namespace Xceed.Wpf.AvalonDock.Layout @@ -27,21 +25,19 @@ namespace Xceed.Wpf.AvalonDock.Layout [Serializable] public class LayoutDocumentPane : LayoutPositionableGroup, ILayoutDocumentPane, ILayoutPositionableElement, ILayoutContentSelector, ILayoutPaneSerializable { + #region Constructors + public LayoutDocumentPane() { } public LayoutDocumentPane( LayoutContent firstChild ) { - Children.Add( firstChild ); + this.Children.Add( firstChild ); } - protected override bool GetVisibility() - { - if( Parent is LayoutDocumentPaneGroup ) - return ChildrenCount > 0; + #endregion - return true; - } + #region Properties #region ShowHeader @@ -99,18 +95,9 @@ namespace Xceed.Wpf.AvalonDock.Layout } } - protected override void ChildMoved( int oldIndex, int newIndex ) - { - if( _selectedIndex == oldIndex ) - { - RaisePropertyChanging( "SelectedContentIndex" ); - _selectedIndex = newIndex; - RaisePropertyChanged( "SelectedContentIndex" ); - } - + #endregion - base.ChildMoved( oldIndex, newIndex ); - } + #region SelectedContent public LayoutContent SelectedContent { @@ -119,83 +106,75 @@ namespace Xceed.Wpf.AvalonDock.Layout return _selectedIndex == -1 ? null : Children[ _selectedIndex ]; } } + #endregion - protected override void OnChildrenCollectionChanged() + #region ChildrenSorted + + public IEnumerable ChildrenSorted { - if( SelectedContentIndex >= ChildrenCount ) - SelectedContentIndex = Children.Count - 1; - if( SelectedContentIndex == -1 && ChildrenCount > 0 ) + get { - if( Root == null ) - { - SetNextSelectedIndex(); - } - else - { - var childrenToSelect = Children.OrderByDescending( c => c.LastActivationTimeStamp.GetValueOrDefault() ).First(); - SelectedContentIndex = Children.IndexOf( childrenToSelect ); - childrenToSelect.IsActive = true; - } + var listSorted = this.Children.ToList(); + listSorted.Sort(); + return listSorted; } + } - base.OnChildrenCollectionChanged(); + #endregion - RaisePropertyChanged( "ChildrenSorted" ); - } + #endregion - public int IndexOf( LayoutContent content ) - { - return Children.IndexOf( content ); - } + #region Overrides - protected override void OnIsVisibleChanged() + protected override bool GetVisibility() { - UpdateParentVisibility(); - base.OnIsVisibleChanged(); + if( this.Parent is LayoutDocumentPaneGroup ) + return ( this.ChildrenCount > 0 ) && this.Children.Any( c => ( c is LayoutDocument && ( ( LayoutDocument )c ).IsVisible ) || ( c is LayoutAnchorable ) ); + + return true; } - internal void SetNextSelectedIndex() + protected override void ChildMoved( int oldIndex, int newIndex ) { - SelectedContentIndex = -1; - for( int i = 0; i < this.Children.Count; ++i ) + if( _selectedIndex == oldIndex ) { - if( Children[ i ].IsEnabled ) - { - SelectedContentIndex = i; - return; - } + RaisePropertyChanging( "SelectedContentIndex" ); + _selectedIndex = newIndex; + RaisePropertyChanged( "SelectedContentIndex" ); } - } - void UpdateParentVisibility() - { - var parentPane = Parent as ILayoutElementWithVisibility; - if( parentPane != null ) - parentPane.ComputeVisibility(); + + base.ChildMoved( oldIndex, newIndex ); } - public IEnumerable ChildrenSorted + protected override void OnChildrenCollectionChanged() { - get + if( this.SelectedContentIndex >= this.ChildrenCount ) + this.SelectedContentIndex = this.Children.Count - 1; + if( this.SelectedContentIndex == -1 && this.ChildrenCount > 0 ) { - var listSorted = Children.ToList(); - listSorted.Sort(); - return listSorted; + if( this.Root == null ) + { + this.SetNextSelectedIndex(); + } + else + { + var childrenToSelect = this.Children.OrderByDescending( c => c.LastActivationTimeStamp.GetValueOrDefault() ).First(); + this.SelectedContentIndex = this.Children.IndexOf( childrenToSelect ); + childrenToSelect.IsActive = true; + } } + + base.OnChildrenCollectionChanged(); + + RaisePropertyChanged( "ChildrenSorted" ); } - string _id; - string ILayoutPaneSerializable.Id + protected override void OnIsVisibleChanged() { - get - { - return _id; - } - set - { - _id = value; - } + this.UpdateParentVisibility(); + base.OnIsVisibleChanged(); } public override void WriteXml( System.Xml.XmlWriter writer ) @@ -231,5 +210,60 @@ namespace Xceed.Wpf.AvalonDock.Layout } #endif + #endregion + + #region Public Methods + + public int IndexOf( LayoutContent content ) + { + return Children.IndexOf( content ); + } + + #endregion + + #region Internal Methods + + internal void SetNextSelectedIndex() + { + this.SelectedContentIndex = -1; + for( int i = 0; i < this.Children.Count; ++i ) + { + if( this.Children[ i ].IsEnabled ) + { + this.SelectedContentIndex = i; + return; + } + } + } + + #endregion + + #region Private Methods + + private void UpdateParentVisibility() + { + var parentPane = this.Parent as ILayoutElementWithVisibility; + if( parentPane != null ) + parentPane.ComputeVisibility(); + } + + #endregion + + #region ILayoutPaneSerializable Interface + + string _id; + string ILayoutPaneSerializable.Id + { + get + { + return _id; + } + set + { + _id = value; + } + } + + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocumentPaneGroup.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocumentPaneGroup.cs index c751e2d1..495c7a96 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocumentPaneGroup.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutDocumentPaneGroup.cs @@ -15,65 +15,73 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections.ObjectModel; -using System.Windows; using System.Windows.Controls; using System.Windows.Markup; namespace Xceed.Wpf.AvalonDock.Layout { - [ContentProperty("Children")] - [Serializable] - public class LayoutDocumentPaneGroup : LayoutPositionableGroup, ILayoutDocumentPane, ILayoutOrientableGroup + [ContentProperty( "Children" )] + [Serializable] + public class LayoutDocumentPaneGroup : LayoutPositionableGroup, ILayoutDocumentPane, ILayoutOrientableGroup + { + #region Constructors + + public LayoutDocumentPaneGroup() { - public LayoutDocumentPaneGroup() - { - } + } - public LayoutDocumentPaneGroup(LayoutDocumentPane documentPane) - { - Children.Add(documentPane); - } + public LayoutDocumentPaneGroup( LayoutDocumentPane documentPane ) + { + Children.Add( documentPane ); + } - #region Orientation + #endregion - private Orientation _orientation; - public Orientation Orientation - { - get { return _orientation; } - set - { - if (_orientation != value) - { - RaisePropertyChanging("Orientation"); - _orientation = value; - RaisePropertyChanged("Orientation"); - } - } - } + #region Properties - #endregion + #region Orientation - protected override bool GetVisibility() + private Orientation _orientation; + public Orientation Orientation + { + get + { + return _orientation; + } + set + { + if( _orientation != value ) { - return true; + RaisePropertyChanging( "Orientation" ); + _orientation = value; + RaisePropertyChanged( "Orientation" ); } + } + } - public override void WriteXml(System.Xml.XmlWriter writer) - { - writer.WriteAttributeString("Orientation", Orientation.ToString()); - base.WriteXml(writer); - } + #endregion - public override void ReadXml(System.Xml.XmlReader reader) - { - if (reader.MoveToAttribute("Orientation")) - Orientation = (Orientation)Enum.Parse(typeof(Orientation), reader.Value, true); - base.ReadXml(reader); - } + #endregion + + #region Overrides + + protected override bool GetVisibility() + { + return true; + } + + public override void WriteXml( System.Xml.XmlWriter writer ) + { + writer.WriteAttributeString( "Orientation", Orientation.ToString() ); + base.WriteXml( writer ); + } + + public override void ReadXml( System.Xml.XmlReader reader ) + { + if( reader.MoveToAttribute( "Orientation" ) ) + Orientation = ( Orientation )Enum.Parse( typeof( Orientation ), reader.Value, true ); + base.ReadXml( reader ); + } #if TRACE public override void ConsoleDump(int tab) @@ -85,5 +93,7 @@ namespace Xceed.Wpf.AvalonDock.Layout child.ConsoleDump(tab + 1); } #endif - } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutElement.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutElement.cs index 8cda2f83..e3965f1b 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutElement.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutElement.cs @@ -15,117 +15,91 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; using System.ComponentModel; using System.Xml.Serialization; namespace Xceed.Wpf.AvalonDock.Layout { - [Serializable] - public abstract class LayoutElement : DependencyObject, ILayoutElement - { - internal LayoutElement() - { } + [Serializable] + public abstract class LayoutElement : DependencyObject, ILayoutElement + { + #region Members - #region Parent + [NonSerialized] + private ILayoutContainer _parent = null; + [NonSerialized] + private ILayoutRoot _root = null; - [NonSerialized] - private ILayoutContainer _parent = null; - [NonSerialized] - private ILayoutRoot _root = null; - [XmlIgnore] - public ILayoutContainer Parent - { - get { return _parent; } - set - { - if (_parent != value) - { - ILayoutContainer oldValue = _parent; - ILayoutRoot oldRoot = _root; - RaisePropertyChanging("Parent"); - OnParentChanging(oldValue, value); - _parent = value; - OnParentChanged(oldValue, value); - - _root = Root; - if (oldRoot != _root) - OnRootChanged(oldRoot, _root); - - RaisePropertyChanged("Parent"); - - var root = Root as LayoutRoot; - if (root != null) - root.FireLayoutUpdated(); - } - } - } + #endregion - /// - /// Provides derived classes an opportunity to handle execute code before to the Parent property changes. - /// - protected virtual void OnParentChanging(ILayoutContainer oldValue, ILayoutContainer newValue) - { - } + #region Constructors - /// - /// Provides derived classes an opportunity to handle changes to the Parent property. - /// - protected virtual void OnParentChanged(ILayoutContainer oldValue, ILayoutContainer newValue) - { + internal LayoutElement() + { + } - } + #endregion + #region Properties - protected virtual void OnRootChanged(ILayoutRoot oldRoot, ILayoutRoot newRoot) + #region Parent + + [XmlIgnore] + public ILayoutContainer Parent + { + get + { + return _parent; + } + set + { + if( _parent != value ) { - if (oldRoot != null) - ((LayoutRoot)oldRoot).OnLayoutElementRemoved(this); - if (newRoot != null) - ((LayoutRoot)newRoot).OnLayoutElementAdded(this); + ILayoutContainer oldValue = _parent; + ILayoutRoot oldRoot = _root; + RaisePropertyChanging( "Parent" ); + OnParentChanging( oldValue, value ); + _parent = value; + OnParentChanged( oldValue, value ); + + _root = Root; + if( oldRoot != _root ) + OnRootChanged( oldRoot, _root ); + + RaisePropertyChanged( "Parent" ); + + var root = Root as LayoutRoot; + if( root != null ) + root.FireLayoutUpdated(); } + } + } + #endregion - #endregion - - [field: NonSerialized] - [field: XmlIgnore] - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void RaisePropertyChanged(string propertyName) - { - if (PropertyChanged != null) - PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); - } + #region Root - [field: NonSerialized] - [field: XmlIgnore] - public event PropertyChangingEventHandler PropertyChanging; + public ILayoutRoot Root + { + get + { + var parent = Parent; - protected virtual void RaisePropertyChanging(string propertyName) + while( parent != null && ( !( parent is ILayoutRoot ) ) ) { - if (PropertyChanging != null) - PropertyChanging(this, new System.ComponentModel.PropertyChangingEventArgs(propertyName)); + parent = parent.Parent; } - public ILayoutRoot Root - { - get - { - var parent = Parent; + return parent as ILayoutRoot; + } + } - while (parent != null && (!(parent is ILayoutRoot))) - { - parent = parent.Parent; - } + #endregion - return parent as ILayoutRoot; - } - } + #endregion + #region Public Methods #if TRACE public virtual void ConsoleDump(int tab) @@ -134,5 +108,58 @@ namespace Xceed.Wpf.AvalonDock.Layout System.Diagnostics.Trace.WriteLine( this.ToString() ); } #endif + + #endregion + + #region Internal Methods + + /// + /// Provides derived classes an opportunity to handle execute code before to the Parent property changes. + /// + protected virtual void OnParentChanging( ILayoutContainer oldValue, ILayoutContainer newValue ) + { + } + + /// + /// Provides derived classes an opportunity to handle changes to the Parent property. + /// + protected virtual void OnParentChanged( ILayoutContainer oldValue, ILayoutContainer newValue ) + { } + + + protected virtual void OnRootChanged( ILayoutRoot oldRoot, ILayoutRoot newRoot ) + { + if( oldRoot != null ) + ( ( LayoutRoot )oldRoot ).OnLayoutElementRemoved( this ); + if( newRoot != null ) + ( ( LayoutRoot )newRoot ).OnLayoutElementAdded( this ); + } + + protected virtual void RaisePropertyChanged( string propertyName ) + { + if( PropertyChanged != null ) + PropertyChanged( this, new System.ComponentModel.PropertyChangedEventArgs( propertyName ) ); + } + + protected virtual void RaisePropertyChanging( string propertyName ) + { + if( PropertyChanging != null ) + PropertyChanging( this, new System.ComponentModel.PropertyChangingEventArgs( propertyName ) ); + } + + #endregion + + #region Events + + [field: NonSerialized] + [field: XmlIgnore] + public event PropertyChangedEventHandler PropertyChanged; + + [field: NonSerialized] + [field: XmlIgnore] + public event PropertyChangingEventHandler PropertyChanging; + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutElementEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutElementEventArgs.cs index 44c336d8..d5189321 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutElementEventArgs.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutElementEventArgs.cs @@ -15,24 +15,28 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Xceed.Wpf.AvalonDock.Layout { - public class LayoutElementEventArgs : EventArgs + public class LayoutElementEventArgs : EventArgs + { + #region Constructors + + public LayoutElementEventArgs( LayoutElement element ) { - public LayoutElementEventArgs(LayoutElement element) - { - Element = element; - } + Element = element; + } + + #endregion + #region Properties - public LayoutElement Element - { - get; - private set; - } + public LayoutElement Element + { + get; + private set; } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutFloatingWindow.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutFloatingWindow.cs index 64fd83fd..f41e479d 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutFloatingWindow.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutFloatingWindow.cs @@ -16,51 +16,77 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Markup; -using System.Windows; using System.Xml.Serialization; using System.Xml.Schema; using System.Xml; namespace Xceed.Wpf.AvalonDock.Layout { - [Serializable] - public abstract class LayoutFloatingWindow : LayoutElement, ILayoutContainer, IXmlSerializable + [Serializable] + public abstract class LayoutFloatingWindow : LayoutElement, ILayoutContainer, IXmlSerializable { - public LayoutFloatingWindow() - { + #region Constructors - } + public LayoutFloatingWindow() + { + } + #endregion - public abstract IEnumerable Children { get; } + #region Properties - public abstract void RemoveChild(ILayoutElement element); + #region Children - public abstract void ReplaceChild(ILayoutElement oldElement, ILayoutElement newElement); + public abstract IEnumerable Children + { + get; + } - public abstract int ChildrenCount { get; } + #endregion - public abstract bool IsValid { get; } + #region ChildrenCount - public XmlSchema GetSchema() - { - return null; - } + public abstract int ChildrenCount + { + get; + } - public abstract void ReadXml( XmlReader reader ); + #endregion - public virtual void WriteXml( XmlWriter writer ) - { - foreach( var child in Children ) - { - var type = child.GetType(); - var serializer = new XmlSerializer( type ); - serializer.Serialize( writer, child ); - } - } + #region IsValid + public abstract bool IsValid + { + get; + } + + #endregion + + #endregion + + #region Public Methods + + public abstract void RemoveChild( ILayoutElement element ); + + public abstract void ReplaceChild( ILayoutElement oldElement, ILayoutElement newElement ); + + public XmlSchema GetSchema() + { + return null; + } + + public abstract void ReadXml( XmlReader reader ); + + public virtual void WriteXml( XmlWriter writer ) + { + foreach( var child in Children ) + { + var type = child.GetType(); + var serializer = new XmlSerializer( type ); + serializer.Serialize( writer, child ); + } + } + + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutGroup.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutGroup.cs index 9af005bc..179a373f 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutGroup.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutGroup.cs @@ -17,253 +17,301 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Collections.ObjectModel; using System.Xml.Serialization; namespace Xceed.Wpf.AvalonDock.Layout { - [Serializable] - public abstract class LayoutGroup : LayoutGroupBase, ILayoutContainer, ILayoutGroup, IXmlSerializable where T : class, ILayoutElement + [Serializable] + public abstract class LayoutGroup : LayoutGroupBase, ILayoutContainer, ILayoutGroup, IXmlSerializable where T : class, ILayoutElement + { + #region Members + + ObservableCollection _children = new ObservableCollection(); + + #endregion + + #region Constructors + + internal LayoutGroup() { - internal LayoutGroup() - { - _children.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(_children_CollectionChanged); - } + _children.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler( _children_CollectionChanged ); + } - void _children_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) - { - if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace) - { - if (e.OldItems != null) - { - foreach (LayoutElement element in e.OldItems) - { - if (element.Parent == this) - element.Parent = null; - } - } - } + #endregion - if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace) - { - if (e.NewItems != null) - { - foreach (LayoutElement element in e.NewItems) - { - if (element.Parent != this) - { - if (element.Parent != null) - element.Parent.RemoveChild(element); - element.Parent = this; - } - - } - } - } + #region Properties - ComputeVisibility(); - OnChildrenCollectionChanged(); - NotifyChildrenTreeChanged(ChildrenTreeChange.DirectChildrenChanged); - RaisePropertyChanged("ChildrenCount"); - } + #region Children + + public ObservableCollection Children + { + get + { + return _children; + } + } - ObservableCollection _children = new ObservableCollection(); + #endregion - public ObservableCollection Children - { - get { return _children; } - } + #region IsVisible - IEnumerable ILayoutContainer.Children + private bool _isVisible = true; + public bool IsVisible + { + get + { + return _isVisible; + } + protected set + { + if( _isVisible != value ) { - get { return _children.Cast(); } + RaisePropertyChanging( "IsVisible" ); + _isVisible = value; + OnIsVisibleChanged(); + RaisePropertyChanged( "IsVisible" ); } + } + } + #endregion - #region IsVisible + #region ChildrenCount - private bool _isVisible = true; - public bool IsVisible - { - get { return _isVisible; } - protected set - { - if (_isVisible != value) - { - RaisePropertyChanging("IsVisible"); - _isVisible = value; - OnIsVisibleChanged(); - RaisePropertyChanged("IsVisible"); - } - } - } + public int ChildrenCount + { + get + { + return _children.Count; + } + } - protected virtual void OnIsVisibleChanged() - { - UpdateParentVisibility(); - } + #endregion - void UpdateParentVisibility() - { - var parentPane = Parent as ILayoutElementWithVisibility; - if (parentPane != null) - parentPane.ComputeVisibility(); - } + #endregion + #region Overrides - public void ComputeVisibility() - { - IsVisible = GetVisibility(); - } + protected override void OnParentChanged( ILayoutContainer oldValue, ILayoutContainer newValue ) + { + base.OnParentChanged( oldValue, newValue ); - protected abstract bool GetVisibility(); + ComputeVisibility(); + } - protected override void OnParentChanged(ILayoutContainer oldValue, ILayoutContainer newValue) - { - base.OnParentChanged(oldValue, newValue); + #endregion - ComputeVisibility(); - } + #region Public Methods - #endregion + public void ComputeVisibility() + { + IsVisible = GetVisibility(); + } + public void MoveChild( int oldIndex, int newIndex ) + { + if( oldIndex == newIndex ) + return; + _children.Move( oldIndex, newIndex ); + ChildMoved( oldIndex, newIndex ); + } - public void MoveChild(int oldIndex, int newIndex) - { - if (oldIndex == newIndex) - return; - _children.Move(oldIndex, newIndex); - ChildMoved(oldIndex, newIndex); - } + public void RemoveChildAt( int childIndex ) + { + _children.RemoveAt( childIndex ); + } - protected virtual void ChildMoved(int oldIndex, int newIndex) - { + public int IndexOfChild( ILayoutElement element ) + { + return _children.Cast().ToList().IndexOf( element ); + } - } + public void InsertChildAt( int index, ILayoutElement element ) + { + _children.Insert( index, ( T )element ); + } - public void RemoveChildAt(int childIndex) - { - _children.RemoveAt(childIndex); - } + public void RemoveChild( ILayoutElement element ) + { + _children.Remove( ( T )element ); + } - public int IndexOfChild(ILayoutElement element) - { - return _children.Cast().ToList().IndexOf(element); - } + public void ReplaceChild( ILayoutElement oldElement, ILayoutElement newElement ) + { + int index = _children.IndexOf( ( T )oldElement ); + _children.Insert( index, ( T )newElement ); + _children.RemoveAt( index + 1 ); + } - public void InsertChildAt(int index, ILayoutElement element) - { - _children.Insert(index, (T)element); - } + public void ReplaceChildAt( int index, ILayoutElement element ) + { + _children[ index ] = ( T )element; + } - public void RemoveChild(ILayoutElement element) - { - _children.Remove((T)element); - } - public void ReplaceChild(ILayoutElement oldElement, ILayoutElement newElement) + public System.Xml.Schema.XmlSchema GetSchema() + { + return null; + } + + public virtual void ReadXml( System.Xml.XmlReader reader ) + { + reader.MoveToContent(); + if( reader.IsEmptyElement ) + { + reader.Read(); + ComputeVisibility(); + return; + } + string localName = reader.LocalName; + reader.Read(); + while( true ) + { + if( ( reader.LocalName == localName ) && + ( reader.NodeType == System.Xml.XmlNodeType.EndElement ) ) { - int index = _children.IndexOf((T)oldElement); - _children.Insert(index, (T)newElement); - _children.RemoveAt(index + 1); + break; } - - public int ChildrenCount + if( reader.NodeType == System.Xml.XmlNodeType.Whitespace ) { - get { return _children.Count; } + reader.Read(); + continue; } - public void ReplaceChildAt(int index, ILayoutElement element) + XmlSerializer serializer = null; + if( reader.LocalName == "LayoutAnchorablePaneGroup" ) + serializer = new XmlSerializer( typeof( LayoutAnchorablePaneGroup ) ); + else if( reader.LocalName == "LayoutAnchorablePane" ) + serializer = new XmlSerializer( typeof( LayoutAnchorablePane ) ); + else if( reader.LocalName == "LayoutAnchorable" ) + serializer = new XmlSerializer( typeof( LayoutAnchorable ) ); + else if( reader.LocalName == "LayoutDocumentPaneGroup" ) + serializer = new XmlSerializer( typeof( LayoutDocumentPaneGroup ) ); + else if( reader.LocalName == "LayoutDocumentPane" ) + serializer = new XmlSerializer( typeof( LayoutDocumentPane ) ); + else if( reader.LocalName == "LayoutDocument" ) + serializer = new XmlSerializer( typeof( LayoutDocument ) ); + else if( reader.LocalName == "LayoutAnchorGroup" ) + serializer = new XmlSerializer( typeof( LayoutAnchorGroup ) ); + else if( reader.LocalName == "LayoutPanel" ) + serializer = new XmlSerializer( typeof( LayoutPanel ) ); + else { - _children[index] = (T)element; + Type type = this.FindType( reader.LocalName ); + if( type == null ) + throw new ArgumentException( "AvalonDock.LayoutGroup doesn't know how to deserialize " + reader.LocalName ); + serializer = new XmlSerializer( type ); } + Children.Add( ( T )serializer.Deserialize( reader ) ); + } + + reader.ReadEndElement(); + } + + public virtual void WriteXml( System.Xml.XmlWriter writer ) + { + foreach( var child in Children ) + { + var type = child.GetType(); + XmlSerializer serializer = new XmlSerializer( type ); + serializer.Serialize( writer, child ); + } + + } + + #endregion + + #region Internal Methods + + protected virtual void OnIsVisibleChanged() + { + UpdateParentVisibility(); + } + + protected abstract bool GetVisibility(); + + protected virtual void ChildMoved( int oldIndex, int newIndex ) + { + } + + #endregion - public System.Xml.Schema.XmlSchema GetSchema() + #region Private Methods + + private void _children_CollectionChanged( object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e ) + { + if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) + { + if( e.OldItems != null ) { - return null; + foreach( LayoutElement element in e.OldItems ) + { + if( element.Parent == this ) + element.Parent = null; + } } + } - public virtual void ReadXml(System.Xml.XmlReader reader) + if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) + { + if( e.NewItems != null ) { - reader.MoveToContent(); - if (reader.IsEmptyElement) - { - reader.Read(); - ComputeVisibility(); - return; - } - string localName = reader.LocalName; - reader.Read(); - while (true) + foreach( LayoutElement element in e.NewItems ) + { + if( element.Parent != this ) { - if ( (reader.LocalName == localName ) && - ( reader.NodeType == System.Xml.XmlNodeType.EndElement) ) - { - break; - } - if( reader.NodeType == System.Xml.XmlNodeType.Whitespace ) - { - reader.Read(); - continue; - } - - XmlSerializer serializer = null; - if (reader.LocalName == "LayoutAnchorablePaneGroup") - serializer = new XmlSerializer(typeof(LayoutAnchorablePaneGroup)); - else if (reader.LocalName == "LayoutAnchorablePane") - serializer = new XmlSerializer(typeof(LayoutAnchorablePane)); - else if (reader.LocalName == "LayoutAnchorable") - serializer = new XmlSerializer(typeof(LayoutAnchorable)); - else if (reader.LocalName == "LayoutDocumentPaneGroup") - serializer = new XmlSerializer(typeof(LayoutDocumentPaneGroup)); - else if (reader.LocalName == "LayoutDocumentPane") - serializer = new XmlSerializer(typeof(LayoutDocumentPane)); - else if (reader.LocalName == "LayoutDocument") - serializer = new XmlSerializer(typeof(LayoutDocument)); - else if (reader.LocalName == "LayoutAnchorGroup") - serializer = new XmlSerializer(typeof(LayoutAnchorGroup)); - else if (reader.LocalName == "LayoutPanel") - serializer = new XmlSerializer(typeof(LayoutPanel)); - else - { - Type type = this.FindType( reader.LocalName ); - if( type == null ) - throw new ArgumentException( "AvalonDock.LayoutGroup doesn't know how to deserialize " + reader.LocalName ); - serializer = new XmlSerializer( type ); - } - - Children.Add((T)serializer.Deserialize(reader)); + if( element.Parent != null ) + element.Parent.RemoveChild( element ); + element.Parent = this; } - reader.ReadEndElement(); + } } + } - public virtual void WriteXml(System.Xml.XmlWriter writer) - { - foreach (var child in Children) - { - var type = child.GetType(); - XmlSerializer serializer = new XmlSerializer(type); - serializer.Serialize(writer, child); - } + ComputeVisibility(); + OnChildrenCollectionChanged(); + NotifyChildrenTreeChanged( ChildrenTreeChange.DirectChildrenChanged ); + RaisePropertyChanged( "ChildrenCount" ); + } - } + private void UpdateParentVisibility() + { + var parentPane = Parent as ILayoutElementWithVisibility; + if( parentPane != null ) + parentPane.ComputeVisibility(); + } - private Type FindType( string name ) + private Type FindType( string name ) + { + foreach( var a in AppDomain.CurrentDomain.GetAssemblies() ) + { + foreach( var t in a.GetTypes() ) { - foreach( var a in AppDomain.CurrentDomain.GetAssemblies() ) - { - foreach( var t in a.GetTypes() ) - { - if( t.Name.Equals( name ) ) - return t; - } - } - return null; + if( t.Name.Equals( name ) ) + return t; } + } + return null; } + + #endregion + + #region ILayoutContainer Interface + + IEnumerable ILayoutContainer.Children + { + get + { + return _children.Cast(); + } + } + + #endregion + + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutGroupBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutGroupBase.cs index 9e7e93ce..f0e0bb51 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutGroupBase.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutGroupBase.cs @@ -15,44 +15,47 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Xml.Serialization; namespace Xceed.Wpf.AvalonDock.Layout { - [Serializable] - public abstract class LayoutGroupBase : LayoutElement + [Serializable] + public abstract class LayoutGroupBase : LayoutElement + { + #region Internal Methods + + protected virtual void OnChildrenCollectionChanged() { - [field: NonSerialized] - [field: XmlIgnore] - public event EventHandler ChildrenCollectionChanged; - - protected virtual void OnChildrenCollectionChanged() - { - if (ChildrenCollectionChanged != null) - ChildrenCollectionChanged(this, EventArgs.Empty); - } - - protected void NotifyChildrenTreeChanged(ChildrenTreeChange change) - { - OnChildrenTreeChanged(change); - var parentGroup = Parent as LayoutGroupBase; - if (parentGroup != null) - parentGroup.NotifyChildrenTreeChanged(ChildrenTreeChange.TreeChanged); - } - - [field: NonSerialized] - [field: XmlIgnore] - public event EventHandler ChildrenTreeChanged; - - protected virtual void OnChildrenTreeChanged(ChildrenTreeChange change) - { - if (ChildrenTreeChanged != null) - ChildrenTreeChanged(this, new ChildrenTreeChangedEventArgs(change)); - } + if( ChildrenCollectionChanged != null ) + ChildrenCollectionChanged( this, EventArgs.Empty ); + } + protected void NotifyChildrenTreeChanged( ChildrenTreeChange change ) + { + OnChildrenTreeChanged( change ); + var parentGroup = Parent as LayoutGroupBase; + if( parentGroup != null ) + parentGroup.NotifyChildrenTreeChanged( ChildrenTreeChange.TreeChanged ); + } + protected virtual void OnChildrenTreeChanged( ChildrenTreeChange change ) + { + if( ChildrenTreeChanged != null ) + ChildrenTreeChanged( this, new ChildrenTreeChangedEventArgs( change ) ); } + + #endregion + + #region Events + + [field: NonSerialized] + [field: XmlIgnore] + public event EventHandler ChildrenCollectionChanged; + + [field: NonSerialized] + [field: XmlIgnore] + public event EventHandler ChildrenTreeChanged; + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutPanel.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutPanel.cs index 6cde4784..5d9c36b1 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutPanel.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutPanel.cs @@ -15,68 +15,74 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows.Markup; -using System.Collections.ObjectModel; -using System.Windows; using System.Windows.Controls; namespace Xceed.Wpf.AvalonDock.Layout { - [ContentProperty("Children")] - [Serializable] - public class LayoutPanel : LayoutPositionableGroup, ILayoutPanelElement, ILayoutOrientableGroup + [ContentProperty( "Children" )] + [Serializable] + public class LayoutPanel : LayoutPositionableGroup, ILayoutPanelElement, ILayoutOrientableGroup + { + #region Constructors + + public LayoutPanel() { - public LayoutPanel() - { + } - } + public LayoutPanel( ILayoutPanelElement firstChild ) + { + Children.Add( firstChild ); + } - public LayoutPanel(ILayoutPanelElement firstChild) - { - Children.Add(firstChild); - } + #endregion + #region Properties - #region Orientation + #region Orientation - private Orientation _orientation; - public Orientation Orientation + private Orientation _orientation; + public Orientation Orientation + { + get + { + return _orientation; + } + set + { + if( _orientation != value ) { - get { return _orientation; } - set - { - if (_orientation != value) - { - RaisePropertyChanging("Orientation"); - _orientation = value; - RaisePropertyChanged("Orientation"); - } - } + RaisePropertyChanging( "Orientation" ); + _orientation = value; + RaisePropertyChanged( "Orientation" ); } + } + } - #endregion + #endregion + #endregion - protected override bool GetVisibility() - { - return Children.Any(c => c.IsVisible); - } + #region Overrides - public override void WriteXml(System.Xml.XmlWriter writer) - { - writer.WriteAttributeString("Orientation", Orientation.ToString()); - base.WriteXml(writer); - } + protected override bool GetVisibility() + { + return Children.Any( c => c.IsVisible ); + } - public override void ReadXml(System.Xml.XmlReader reader) - { - if (reader.MoveToAttribute("Orientation")) - Orientation = (Orientation)Enum.Parse(typeof(Orientation), reader.Value, true); - base.ReadXml(reader); - } + public override void WriteXml( System.Xml.XmlWriter writer ) + { + writer.WriteAttributeString( "Orientation", Orientation.ToString() ); + base.WriteXml( writer ); + } + + public override void ReadXml( System.Xml.XmlReader reader ) + { + if( reader.MoveToAttribute( "Orientation" ) ) + Orientation = ( Orientation )Enum.Parse( typeof( Orientation ), reader.Value, true ); + base.ReadXml( reader ); + } #if TRACE public override void ConsoleDump(int tab) @@ -88,5 +94,7 @@ namespace Xceed.Wpf.AvalonDock.Layout child.ConsoleDump(tab + 1); } #endif - } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutPositionableGroup.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutPositionableGroup.cs index 8257d7f3..9818face 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutPositionableGroup.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutPositionableGroup.cs @@ -15,335 +15,388 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; using System.Globalization; namespace Xceed.Wpf.AvalonDock.Layout { - [Serializable] - public abstract class LayoutPositionableGroup : LayoutGroup, ILayoutPositionableElement, ILayoutPositionableElementWithActualSize where T : class, ILayoutElement + [Serializable] + public abstract class LayoutPositionableGroup : LayoutGroup, ILayoutPositionableElement, ILayoutPositionableElementWithActualSize where T : class, ILayoutElement + { + #region Members + + private static GridLengthConverter _gridLengthConverter = new GridLengthConverter(); + + #endregion + + #region Constructors + + public LayoutPositionableGroup() { - public LayoutPositionableGroup() - { } + } - GridLength _dockWidth = new GridLength(1.0, GridUnitType.Star); - public GridLength DockWidth - { - get - { - return _dockWidth; - } - set - { - if (DockWidth != value) - { - RaisePropertyChanging("DockWidth"); - _dockWidth = value; - RaisePropertyChanged("DockWidth"); - - OnDockWidthChanged(); - } - } - } + #endregion + #region Properties - protected virtual void OnDockWidthChanged() + #region DockWidth + + GridLength _dockWidth = new GridLength( 1.0, GridUnitType.Star ); + public GridLength DockWidth + { + get + { + return _dockWidth; + } + set + { + if( DockWidth != value ) { + RaisePropertyChanging( "DockWidth" ); + _dockWidth = value; + RaisePropertyChanged( "DockWidth" ); + OnDockWidthChanged(); } + } + } - GridLength _dockHeight = new GridLength(1.0, GridUnitType.Star); - public GridLength DockHeight - { - get - { - return _dockHeight; - } - set - { - if (DockHeight != value) - { - RaisePropertyChanging("DockHeight"); - _dockHeight = value; - RaisePropertyChanged("DockHeight"); - - OnDockHeightChanged(); - } - } - } + #endregion + + #region DockHeight - protected virtual void OnDockHeightChanged() - { + GridLength _dockHeight = new GridLength( 1.0, GridUnitType.Star ); + public GridLength DockHeight + { + get + { + return _dockHeight; + } + set + { + if( DockHeight != value ) + { + RaisePropertyChanging( "DockHeight" ); + _dockHeight = value; + RaisePropertyChanged( "DockHeight" ); + OnDockHeightChanged(); } + } + } + + #endregion - #region AllowDuplicateContent + #region AllowDuplicateContent - private bool _allowDuplicateContent = true; - /// - /// Gets or sets the AllowDuplicateContent property. - /// When this property is true, then the LayoutDocumentPane or LayoutAnchorablePane allows dropping - /// duplicate content (according to its Title and ContentId). When this dependency property is false, - /// then the LayoutDocumentPane or LayoutAnchorablePane hides the OverlayWindow.DropInto button to prevent dropping of duplicate content. - /// - public bool AllowDuplicateContent + private bool _allowDuplicateContent = true; + /// + /// Gets or sets the AllowDuplicateContent property. + /// When this property is true, then the LayoutDocumentPane or LayoutAnchorablePane allows dropping + /// duplicate content (according to its Title and ContentId). When this dependency property is false, + /// then the LayoutDocumentPane or LayoutAnchorablePane hides the OverlayWindow.DropInto button to prevent dropping of duplicate content. + /// + public bool AllowDuplicateContent + { + get + { + return _allowDuplicateContent; + } + set + { + if( _allowDuplicateContent != value ) { - get - { - return _allowDuplicateContent; - } - set - { - if( _allowDuplicateContent != value ) - { - RaisePropertyChanging( "AllowDuplicateContent" ); - _allowDuplicateContent = value; - RaisePropertyChanged( "AllowDuplicateContent" ); - } - } + RaisePropertyChanging( "AllowDuplicateContent" ); + _allowDuplicateContent = value; + RaisePropertyChanged( "AllowDuplicateContent" ); } + } + } - #endregion + #endregion - #region CanRepositionItems + #region CanRepositionItems - private bool _canRepositionItems = true; - public bool CanRepositionItems + private bool _canRepositionItems = true; + public bool CanRepositionItems + { + get + { + return _canRepositionItems; + } + set + { + if( _canRepositionItems != value ) { - get - { - return _canRepositionItems; - } - set - { - if( _canRepositionItems != value ) - { - RaisePropertyChanging( "CanRepositionItems" ); - _canRepositionItems = value; - RaisePropertyChanged( "CanRepositionItems" ); - } - } + RaisePropertyChanging( "CanRepositionItems" ); + _canRepositionItems = value; + RaisePropertyChanged( "CanRepositionItems" ); } + } + } - #endregion + #endregion - #region DockMinWidth + #region DockMinWidth - private double _dockMinWidth = 25.0; - public double DockMinWidth + private double _dockMinWidth = 25.0; + public double DockMinWidth + { + get + { + return _dockMinWidth; + } + set + { + if( _dockMinWidth != value ) { - get { return _dockMinWidth; } - set - { - if (_dockMinWidth != value) - { - MathHelper.AssertIsPositiveOrZero(value); - RaisePropertyChanging("DockMinWidth"); - _dockMinWidth = value; - RaisePropertyChanged("DockMinWidth"); - } - } + MathHelper.AssertIsPositiveOrZero( value ); + RaisePropertyChanging( "DockMinWidth" ); + _dockMinWidth = value; + RaisePropertyChanged( "DockMinWidth" ); } + } + } - #endregion + #endregion - #region DockMinHeight + #region DockMinHeight - private double _dockMinHeight = 25.0; - public double DockMinHeight + private double _dockMinHeight = 25.0; + public double DockMinHeight + { + get + { + return _dockMinHeight; + } + set + { + if( _dockMinHeight != value ) { - get { return _dockMinHeight; } - set - { - if (_dockMinHeight != value) - { - MathHelper.AssertIsPositiveOrZero(value); - RaisePropertyChanging("DockMinHeight"); - _dockMinHeight = value; - RaisePropertyChanged("DockMinHeight"); - } - } + MathHelper.AssertIsPositiveOrZero( value ); + RaisePropertyChanging( "DockMinHeight" ); + _dockMinHeight = value; + RaisePropertyChanged( "DockMinHeight" ); } + } + } - #endregion + #endregion - #region FloatingWidth + #region FloatingWidth - private double _floatingWidth = 0.0; - public double FloatingWidth + private double _floatingWidth = 0.0; + public double FloatingWidth + { + get + { + return _floatingWidth; + } + set + { + if( _floatingWidth != value ) { - get { return _floatingWidth; } - set - { - if (_floatingWidth != value) - { - RaisePropertyChanging("FloatingWidth"); - _floatingWidth = value; - RaisePropertyChanged("FloatingWidth"); - } - } + RaisePropertyChanging( "FloatingWidth" ); + _floatingWidth = value; + RaisePropertyChanged( "FloatingWidth" ); } + } + } - #endregion + #endregion - #region FloatingHeight + #region FloatingHeight - private double _floatingHeight = 0.0; - public double FloatingHeight + private double _floatingHeight = 0.0; + public double FloatingHeight + { + get + { + return _floatingHeight; + } + set + { + if( _floatingHeight != value ) { - get { return _floatingHeight; } - set - { - if (_floatingHeight != value) - { - RaisePropertyChanging("FloatingHeight"); - _floatingHeight = value; - RaisePropertyChanged("FloatingHeight"); - } - } + RaisePropertyChanging( "FloatingHeight" ); + _floatingHeight = value; + RaisePropertyChanged( "FloatingHeight" ); } + } + } - #endregion + #endregion - #region FloatingLeft + #region FloatingLeft - private double _floatingLeft = 0.0; - public double FloatingLeft + private double _floatingLeft = 0.0; + public double FloatingLeft + { + get + { + return _floatingLeft; + } + set + { + if( _floatingLeft != value ) { - get { return _floatingLeft; } - set - { - if (_floatingLeft != value) - { - RaisePropertyChanging("FloatingLeft"); - _floatingLeft = value; - RaisePropertyChanged("FloatingLeft"); - } - } + RaisePropertyChanging( "FloatingLeft" ); + _floatingLeft = value; + RaisePropertyChanged( "FloatingLeft" ); } + } + } - #endregion + #endregion - #region FloatingTop + #region FloatingTop - private double _floatingTop = 0.0; - public double FloatingTop + private double _floatingTop = 0.0; + public double FloatingTop + { + get + { + return _floatingTop; + } + set + { + if( _floatingTop != value ) { - get { return _floatingTop; } - set - { - if (_floatingTop != value) - { - RaisePropertyChanging("FloatingTop"); - _floatingTop = value; - RaisePropertyChanged("FloatingTop"); - } - } + RaisePropertyChanging( "FloatingTop" ); + _floatingTop = value; + RaisePropertyChanged( "FloatingTop" ); } + } + } - #endregion + #endregion - #region IsMaximized + #region IsMaximized - private bool _isMaximized = false; - public bool IsMaximized + private bool _isMaximized = false; + public bool IsMaximized + { + get + { + return _isMaximized; + } + set + { + if( _isMaximized != value ) { - get { return _isMaximized; } - set - { - if (_isMaximized != value) - { - _isMaximized = value; - RaisePropertyChanged("IsMaximized"); - } - } + _isMaximized = value; + RaisePropertyChanged( "IsMaximized" ); } + } + } - #endregion + #endregion + #region ActualWidth - [NonSerialized] - double _actualWidth; - double ILayoutPositionableElementWithActualSize.ActualWidth - { - get - { - return _actualWidth; - } - set - { - _actualWidth = value; - } - } + [NonSerialized] + double _actualWidth; + double ILayoutPositionableElementWithActualSize.ActualWidth + { + get + { + return _actualWidth; + } + set + { + _actualWidth = value; + } + } - [NonSerialized] - double _actualHeight; - double ILayoutPositionableElementWithActualSize.ActualHeight - { - get - { - return _actualHeight; - } - set - { - _actualHeight = value; - } - } + #endregion - public override void WriteXml(System.Xml.XmlWriter writer) - { - if (DockWidth.Value != 1.0 || !DockWidth.IsStar) - writer.WriteAttributeString("DockWidth", _gridLengthConverter.ConvertToInvariantString(DockWidth)); - if (DockHeight.Value != 1.0 || !DockHeight.IsStar) - writer.WriteAttributeString("DockHeight", _gridLengthConverter.ConvertToInvariantString(DockHeight)); - - if (DockMinWidth != 25.0) - writer.WriteAttributeString("DocMinWidth", DockMinWidth.ToString(CultureInfo.InvariantCulture)); - if (DockMinHeight != 25.0) - writer.WriteAttributeString("DockMinHeight", DockMinHeight.ToString(CultureInfo.InvariantCulture)); - - if (FloatingWidth != 0.0) - writer.WriteAttributeString("FloatingWidth", FloatingWidth.ToString(CultureInfo.InvariantCulture)); - if (FloatingHeight != 0.0) - writer.WriteAttributeString("FloatingHeight", FloatingHeight.ToString(CultureInfo.InvariantCulture)); - if (FloatingLeft != 0.0) - writer.WriteAttributeString("FloatingLeft", FloatingLeft.ToString(CultureInfo.InvariantCulture)); - if (FloatingTop != 0.0) - writer.WriteAttributeString("FloatingTop", FloatingTop.ToString(CultureInfo.InvariantCulture)); - if( IsMaximized ) - writer.WriteAttributeString( "IsMaximized", IsMaximized.ToString() ); - - base.WriteXml(writer); - } + #region ActualHeight - static GridLengthConverter _gridLengthConverter = new GridLengthConverter(); - public override void ReadXml(System.Xml.XmlReader reader) - { - if (reader.MoveToAttribute("DockWidth")) - _dockWidth = (GridLength)_gridLengthConverter.ConvertFromInvariantString(reader.Value); - if (reader.MoveToAttribute("DockHeight")) - _dockHeight = (GridLength)_gridLengthConverter.ConvertFromInvariantString(reader.Value); - - if (reader.MoveToAttribute("DocMinWidth")) - _dockMinWidth = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("DocMinHeight")) - _dockMinHeight = double.Parse(reader.Value, CultureInfo.InvariantCulture); - - if (reader.MoveToAttribute("FloatingWidth")) - _floatingWidth = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("FloatingHeight")) - _floatingHeight = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("FloatingLeft")) - _floatingLeft = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("FloatingTop")) - _floatingTop = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if( reader.MoveToAttribute( "IsMaximized" ) ) - _isMaximized = bool.Parse( reader.Value ); - - base.ReadXml(reader); - } + [NonSerialized] + double _actualHeight; + double ILayoutPositionableElementWithActualSize.ActualHeight + { + get + { + return _actualHeight; + } + set + { + _actualHeight = value; + } + } + + #endregion + + #endregion + + #region Overrides + + public override void WriteXml( System.Xml.XmlWriter writer ) + { + if( DockWidth.Value != 1.0 || !DockWidth.IsStar ) + writer.WriteAttributeString( "DockWidth", _gridLengthConverter.ConvertToInvariantString( DockWidth ) ); + if( DockHeight.Value != 1.0 || !DockHeight.IsStar ) + writer.WriteAttributeString( "DockHeight", _gridLengthConverter.ConvertToInvariantString( DockHeight ) ); + + if( DockMinWidth != 25.0 ) + writer.WriteAttributeString( "DocMinWidth", DockMinWidth.ToString( CultureInfo.InvariantCulture ) ); + if( DockMinHeight != 25.0 ) + writer.WriteAttributeString( "DockMinHeight", DockMinHeight.ToString( CultureInfo.InvariantCulture ) ); + + if( FloatingWidth != 0.0 ) + writer.WriteAttributeString( "FloatingWidth", FloatingWidth.ToString( CultureInfo.InvariantCulture ) ); + if( FloatingHeight != 0.0 ) + writer.WriteAttributeString( "FloatingHeight", FloatingHeight.ToString( CultureInfo.InvariantCulture ) ); + if( FloatingLeft != 0.0 ) + writer.WriteAttributeString( "FloatingLeft", FloatingLeft.ToString( CultureInfo.InvariantCulture ) ); + if( FloatingTop != 0.0 ) + writer.WriteAttributeString( "FloatingTop", FloatingTop.ToString( CultureInfo.InvariantCulture ) ); + if( IsMaximized ) + writer.WriteAttributeString( "IsMaximized", IsMaximized.ToString() ); + + base.WriteXml( writer ); + } + + + public override void ReadXml( System.Xml.XmlReader reader ) + { + if( reader.MoveToAttribute( "DockWidth" ) ) + _dockWidth = ( GridLength )_gridLengthConverter.ConvertFromInvariantString( reader.Value ); + if( reader.MoveToAttribute( "DockHeight" ) ) + _dockHeight = ( GridLength )_gridLengthConverter.ConvertFromInvariantString( reader.Value ); + + if( reader.MoveToAttribute( "DocMinWidth" ) ) + _dockMinWidth = double.Parse( reader.Value, CultureInfo.InvariantCulture ); + if( reader.MoveToAttribute( "DocMinHeight" ) ) + _dockMinHeight = double.Parse( reader.Value, CultureInfo.InvariantCulture ); + + if( reader.MoveToAttribute( "FloatingWidth" ) ) + _floatingWidth = double.Parse( reader.Value, CultureInfo.InvariantCulture ); + if( reader.MoveToAttribute( "FloatingHeight" ) ) + _floatingHeight = double.Parse( reader.Value, CultureInfo.InvariantCulture ); + if( reader.MoveToAttribute( "FloatingLeft" ) ) + _floatingLeft = double.Parse( reader.Value, CultureInfo.InvariantCulture ); + if( reader.MoveToAttribute( "FloatingTop" ) ) + _floatingTop = double.Parse( reader.Value, CultureInfo.InvariantCulture ); + if( reader.MoveToAttribute( "IsMaximized" ) ) + _isMaximized = bool.Parse( reader.Value ); + + base.ReadXml( reader ); + } + + #endregion + + #region Internal Methods + + protected virtual void OnDockWidthChanged() + { } + + protected virtual void OnDockHeightChanged() + { + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutRoot.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutRoot.cs index 1170e3bc..f2fa1de9 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutRoot.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutRoot.cs @@ -25,6 +25,7 @@ using System.Xml.Serialization; using Standard; using System.Xml; using System.Xml.Schema; +using System.Windows.Controls; namespace Xceed.Wpf.AvalonDock.Layout { @@ -32,6 +33,8 @@ namespace Xceed.Wpf.AvalonDock.Layout [Serializable] public class LayoutRoot : LayoutElement, ILayoutContainer, ILayoutRoot, IXmlSerializable { + #region Constructors + public LayoutRoot() { RightSide = new LayoutAnchorSide(); @@ -41,6 +44,9 @@ namespace Xceed.Wpf.AvalonDock.Layout RootPanel = new LayoutPanel( new LayoutDocumentPane() ); } + #endregion + + #region Properties #region RootPanel @@ -170,6 +176,7 @@ namespace Xceed.Wpf.AvalonDock.Layout #endregion #region FloatingWindows + ObservableCollection _floatingWindows = null; public ObservableCollection FloatingWindows @@ -186,25 +193,6 @@ namespace Xceed.Wpf.AvalonDock.Layout } } - void _floatingWindows_CollectionChanged( object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e ) - { - if( e.OldItems != null && ( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) ) - { - foreach( LayoutFloatingWindow element in e.OldItems ) - { - if( element.Parent == this ) - element.Parent = null; - } - } - - if( e.NewItems != null && ( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) ) - { - foreach( LayoutFloatingWindow element in e.NewItems ) - element.Parent = this; - } - } #endregion #region HiddenAnchorables @@ -225,46 +213,10 @@ namespace Xceed.Wpf.AvalonDock.Layout } } - void _hiddenAnchorables_CollectionChanged( object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e ) - { - if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) - { - if( e.OldItems != null ) - { - foreach( LayoutAnchorable element in e.OldItems ) - { - if( element.Parent == this ) - element.Parent = null; - } - } - } - - if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) - { - if( e.NewItems != null ) - { - foreach( LayoutAnchorable element in e.NewItems ) - { - if( element.Parent != this ) - { - if( element.Parent != null ) - element.Parent.RemoveChild( element ); - element.Parent = this; - } - - } - } - } - - - - } - #endregion #region Children + public IEnumerable Children { get @@ -291,50 +243,10 @@ namespace Xceed.Wpf.AvalonDock.Layout } } } - public void RemoveChild( ILayoutElement element ) - { - if( element == RootPanel ) - RootPanel = null; - else if( _floatingWindows != null && _floatingWindows.Contains( element ) ) - _floatingWindows.Remove( element as LayoutFloatingWindow ); - else if( _hiddenAnchorables != null && _hiddenAnchorables.Contains( element ) ) - _hiddenAnchorables.Remove( element as LayoutAnchorable ); - else if( element == TopSide ) - TopSide = null; - else if( element == RightSide ) - RightSide = null; - else if( element == BottomSide ) - BottomSide = null; - else if( element == LeftSide ) - LeftSide = null; - } + #endregion - public void ReplaceChild( ILayoutElement oldElement, ILayoutElement newElement ) - { - if( oldElement == RootPanel ) - RootPanel = ( LayoutPanel )newElement; - else if( _floatingWindows != null && _floatingWindows.Contains( oldElement ) ) - { - int index = _floatingWindows.IndexOf( oldElement as LayoutFloatingWindow ); - _floatingWindows.Remove( oldElement as LayoutFloatingWindow ); - _floatingWindows.Insert( index, newElement as LayoutFloatingWindow ); - } - else if( _hiddenAnchorables != null && _hiddenAnchorables.Contains( oldElement ) ) - { - int index = _hiddenAnchorables.IndexOf( oldElement as LayoutAnchorable ); - _hiddenAnchorables.Remove( oldElement as LayoutAnchorable ); - _hiddenAnchorables.Insert( index, newElement as LayoutAnchorable ); - } - else if( oldElement == TopSide ) - TopSide = ( LayoutAnchorSide )newElement; - else if( oldElement == RightSide ) - RightSide = ( LayoutAnchorSide )newElement; - else if( oldElement == BottomSide ) - BottomSide = ( LayoutAnchorSide )newElement; - else if( oldElement == LeftSide ) - LeftSide = ( LayoutAnchorSide )newElement; - } + #region ChildrenCount public int ChildrenCount { @@ -345,6 +257,7 @@ namespace Xceed.Wpf.AvalonDock.Layout ( _hiddenAnchorables != null ? _hiddenAnchorables.Count : 0 ); } } + #endregion #region ActiveContent @@ -370,35 +283,7 @@ namespace Xceed.Wpf.AvalonDock.Layout } } - void InternalSetActiveContent( LayoutContent currentValue, LayoutContent newActiveContent ) - { - RaisePropertyChanging( "ActiveContent" ); - if( currentValue != null ) - currentValue.IsActive = false; - _activeContent = new WeakReference( newActiveContent ); - currentValue = ActiveContent; - if( currentValue != null ) - currentValue.IsActive = true; - RaisePropertyChanged( "ActiveContent" ); - _activeContentSet = currentValue != null; - if( currentValue != null ) - { - if( currentValue.Parent is LayoutDocumentPane || currentValue is LayoutDocument ) - LastFocusedDocument = currentValue; - } - else - LastFocusedDocument = null; - } - void UpdateActiveContentProperty() - { - var activeContent = ActiveContent; - if( _activeContentSet && ( activeContent == null || activeContent.Root != this ) ) - { - _activeContentSet = false; - InternalSetActiveContent( activeContent, null ); - } - } #endregion #region LastFocusedDocument @@ -461,7 +346,80 @@ namespace Xceed.Wpf.AvalonDock.Layout #endregion - #region CollectGarbage + #endregion + + #region Overrides + +#if TRACE + public override void ConsoleDump(int tab) + { + System.Diagnostics.Trace.Write( new string( ' ', tab * 4 ) ); + System.Diagnostics.Trace.WriteLine( "RootPanel()" ); + + RootPanel.ConsoleDump(tab + 1); + + System.Diagnostics.Trace.Write( new string( ' ', tab * 4 ) ); + System.Diagnostics.Trace.WriteLine( "FloatingWindows()" ); + + foreach (LayoutFloatingWindow fw in FloatingWindows) + fw.ConsoleDump(tab + 1); + + System.Diagnostics.Trace.Write( new string( ' ', tab * 4 ) ); + System.Diagnostics.Trace.WriteLine( "Hidden()" ); + + foreach (LayoutAnchorable hidden in Hidden) + hidden.ConsoleDump(tab + 1); + } +#endif + + #endregion + + #region Public Methods + + public void RemoveChild( ILayoutElement element ) + { + if( element == RootPanel ) + RootPanel = null; + else if( _floatingWindows != null && _floatingWindows.Contains( element ) ) + _floatingWindows.Remove( element as LayoutFloatingWindow ); + else if( _hiddenAnchorables != null && _hiddenAnchorables.Contains( element ) ) + _hiddenAnchorables.Remove( element as LayoutAnchorable ); + else if( element == TopSide ) + TopSide = null; + else if( element == RightSide ) + RightSide = null; + else if( element == BottomSide ) + BottomSide = null; + else if( element == LeftSide ) + LeftSide = null; + + } + + public void ReplaceChild( ILayoutElement oldElement, ILayoutElement newElement ) + { + if( oldElement == RootPanel ) + RootPanel = ( LayoutPanel )newElement; + else if( _floatingWindows != null && _floatingWindows.Contains( oldElement ) ) + { + int index = _floatingWindows.IndexOf( oldElement as LayoutFloatingWindow ); + _floatingWindows.Remove( oldElement as LayoutFloatingWindow ); + _floatingWindows.Insert( index, newElement as LayoutFloatingWindow ); + } + else if( _hiddenAnchorables != null && _hiddenAnchorables.Contains( oldElement ) ) + { + int index = _hiddenAnchorables.IndexOf( oldElement as LayoutAnchorable ); + _hiddenAnchorables.Remove( oldElement as LayoutAnchorable ); + _hiddenAnchorables.Insert( index, newElement as LayoutAnchorable ); + } + else if( oldElement == TopSide ) + TopSide = ( LayoutAnchorSide )newElement; + else if( oldElement == RightSide ) + RightSide = ( LayoutAnchorSide )newElement; + else if( oldElement == BottomSide ) + BottomSide = ( LayoutAnchorSide )newElement; + else if( oldElement == LeftSide ) + LeftSide = ( LayoutAnchorSide )newElement; + } /// /// Removes any empty container not directly referenced by other layout items @@ -654,9 +612,142 @@ namespace Xceed.Wpf.AvalonDock.Layout #endif } + public XmlSchema GetSchema() + { + return null; + } + + public void ReadXml( XmlReader reader ) + { + reader.MoveToContent(); + if( reader.IsEmptyElement ) + { + reader.Read(); + return; + } + + Orientation orientation; + var layoutPanelElements = this.ReadRootPanel( reader, out orientation ); + if( layoutPanelElements != null ) + { + this.RootPanel = new LayoutPanel() { Orientation = orientation }; + //Add all children to RootPanel + for( int i = 0; i < layoutPanelElements.Count; ++i ) + { + this.RootPanel.Children.Add( layoutPanelElements[ i ] ); + } + } + + this.TopSide = new LayoutAnchorSide(); + if( this.ReadElement( reader ) != null ) + { + this.FillLayoutAnchorSide( reader, TopSide ); + } + this.RightSide = new LayoutAnchorSide(); + if( this.ReadElement( reader ) != null ) + { + this.FillLayoutAnchorSide( reader, RightSide ); + } + this.LeftSide = new LayoutAnchorSide(); + if( this.ReadElement( reader ) != null ) + { + this.FillLayoutAnchorSide( reader, LeftSide ); + } + this.BottomSide = new LayoutAnchorSide(); + if( this.ReadElement( reader ) != null ) + { + this.FillLayoutAnchorSide( reader, BottomSide ); + } + + this.FloatingWindows.Clear(); + var floatingWindows = this.ReadElementList( reader, true ); + foreach( var floatingWindow in floatingWindows ) + { + this.FloatingWindows.Add( ( LayoutFloatingWindow )floatingWindow ); + } + + this.Hidden.Clear(); + var hidden = this.ReadElementList( reader, false ); + foreach( var hiddenObject in hidden ) + { + this.Hidden.Add( ( LayoutAnchorable )hiddenObject ); + } + } + + public void WriteXml( XmlWriter writer ) + { + writer.WriteStartElement( "RootPanel" ); + if( this.RootPanel != null ) + { + this.RootPanel.WriteXml( writer ); + } + writer.WriteEndElement(); + + writer.WriteStartElement( "TopSide" ); + if( this.TopSide != null ) + { + this.TopSide.WriteXml( writer ); + } + writer.WriteEndElement(); + + writer.WriteStartElement( "RightSide" ); + if( this.RightSide != null ) + { + this.RightSide.WriteXml( writer ); + } + writer.WriteEndElement(); + + writer.WriteStartElement( "LeftSide" ); + if( this.LeftSide != null ) + { + this.LeftSide.WriteXml( writer ); + } + writer.WriteEndElement(); + + writer.WriteStartElement( "BottomSide" ); + if( this.BottomSide != null ) + { + this.BottomSide.WriteXml( writer ); + } + writer.WriteEndElement(); + + // Write all floating windows (can be LayoutDocumentFloatingWindow or LayoutAnchorableFloatingWindow). + // To prevent "can not create instance of abstract type", the type is retrieved with GetType().Name + writer.WriteStartElement( "FloatingWindows" ); + foreach( var layoutFloatingWindow in FloatingWindows ) + { + writer.WriteStartElement( layoutFloatingWindow.GetType().Name ); + layoutFloatingWindow.WriteXml( writer ); + writer.WriteEndElement(); + } + writer.WriteEndElement(); + + writer.WriteStartElement( "Hidden" ); + foreach( var layoutAnchorable in Hidden ) + { + writer.WriteStartElement( layoutAnchorable.GetType().Name ); + layoutAnchorable.WriteXml( writer ); + writer.WriteEndElement(); + } + writer.WriteEndElement(); + } + #endregion - public event EventHandler Updated; + #region Internal Methods + + internal static Type FindType( string name ) + { + foreach( var assembly in AppDomain.CurrentDomain.GetAssemblies() ) + { + foreach( var type in assembly.GetTypes() ) + { + if( type.Name.Equals( name ) ) + return type; + } + } + return null; + } internal void FireLayoutUpdated() { @@ -664,16 +755,12 @@ namespace Xceed.Wpf.AvalonDock.Layout Updated( this, EventArgs.Empty ); } - #region LayoutElement Added/Removed events - internal void OnLayoutElementAdded( LayoutElement element ) { if( ElementAdded != null ) ElementAdded( this, new LayoutElementEventArgs( element ) ); } - public event EventHandler ElementAdded; - internal void OnLayoutElementRemoved( LayoutElement element ) { if( element.Descendents().OfType().Any( c => c == LastFocusedDocument ) ) @@ -684,68 +771,94 @@ namespace Xceed.Wpf.AvalonDock.Layout ElementRemoved( this, new LayoutElementEventArgs( element ) ); } - public event EventHandler ElementRemoved; - #endregion - public XmlSchema GetSchema() - { - return null; - } + #region Private Methods - public void ReadXml( XmlReader reader ) + private void _floatingWindows_CollectionChanged( object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e ) { - reader.MoveToContent(); - if( reader.IsEmptyElement ) - { - reader.Read(); - return; - } - - var layoutPanelElements = ReadRootPanel( reader ); - if( layoutPanelElements != null ) + if( e.OldItems != null && ( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) ) { - RootPanel = new LayoutPanel(); - //Add all children to RootPanel - for( int i = 0; i < layoutPanelElements.Count; ++i ) + foreach( LayoutFloatingWindow element in e.OldItems ) { - RootPanel.Children.Add( layoutPanelElements[ i ] ); + if( element.Parent == this ) + element.Parent = null; } } - TopSide = new LayoutAnchorSide(); - if( ReadElement( reader ) != null ) - { - FillLayoutAnchorSide( reader, TopSide ); - } - RightSide = new LayoutAnchorSide(); - if( ReadElement( reader ) != null ) + if( e.NewItems != null && ( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) ) { - FillLayoutAnchorSide( reader, RightSide ); + foreach( LayoutFloatingWindow element in e.NewItems ) + element.Parent = this; } - LeftSide = new LayoutAnchorSide(); - if( ReadElement( reader ) != null ) + } + + private void _hiddenAnchorables_CollectionChanged( object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e ) + { + if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) { - FillLayoutAnchorSide( reader, LeftSide ); + if( e.OldItems != null ) + { + foreach( LayoutAnchorable element in e.OldItems ) + { + if( element.Parent == this ) + element.Parent = null; + } + } } - BottomSide = new LayoutAnchorSide(); - if( ReadElement( reader ) != null ) + + if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ) { - FillLayoutAnchorSide( reader, BottomSide ); + if( e.NewItems != null ) + { + foreach( LayoutAnchorable element in e.NewItems ) + { + if( element.Parent != this ) + { + if( element.Parent != null ) + element.Parent.RemoveChild( element ); + element.Parent = this; + } + + } + } } - FloatingWindows.Clear(); - var floatingWindows = ReadElementList( reader ); - foreach( var floatingWindow in floatingWindows ) + + + } + + private void InternalSetActiveContent( LayoutContent currentValue, LayoutContent newActiveContent ) + { + RaisePropertyChanging( "ActiveContent" ); + if( currentValue != null ) + currentValue.IsActive = false; + _activeContent = new WeakReference( newActiveContent ); + currentValue = ActiveContent; + if( currentValue != null ) + currentValue.IsActive = true; + RaisePropertyChanged( "ActiveContent" ); + _activeContentSet = currentValue != null; + if( currentValue != null ) { - FloatingWindows.Add( ( LayoutFloatingWindow )floatingWindow ); + if( currentValue.Parent is LayoutDocumentPane || currentValue is LayoutDocument ) + LastFocusedDocument = currentValue; } + else + LastFocusedDocument = null; + } - Hidden.Clear(); - var hidden = ReadElementList( reader ); - foreach( var hiddenObject in hidden ) + private void UpdateActiveContentProperty() + { + var activeContent = ActiveContent; + if( _activeContentSet && ( activeContent == null || activeContent.Root != this ) ) { - Hidden.Add( ( LayoutAnchorable )hiddenObject ); + _activeContentSet = false; + InternalSetActiveContent( activeContent, null ); } } @@ -774,8 +887,9 @@ namespace Xceed.Wpf.AvalonDock.Layout } } - private List ReadRootPanel( XmlReader reader ) + private List ReadRootPanel( XmlReader reader, out Orientation orientation ) { + orientation = Orientation.Horizontal; var result = new List(); var startElementName = reader.LocalName; @@ -792,6 +906,7 @@ namespace Xceed.Wpf.AvalonDock.Layout if( reader.LocalName.Equals( "RootPanel" ) ) { + orientation = (reader.GetAttribute( "Orientation" ) == "Vertical") ? Orientation.Vertical : Orientation.Horizontal; reader.Read(); while( true ) @@ -814,10 +929,15 @@ namespace Xceed.Wpf.AvalonDock.Layout return result; } - private List ReadElementList( XmlReader reader ) + private List ReadElementList( XmlReader reader, bool isFloatingWindow ) { var resultList = new List(); + while( reader.NodeType == XmlNodeType.Whitespace ) + { + reader.Read(); + } + if( reader.IsEmptyElement ) { reader.Read(); @@ -838,13 +958,24 @@ namespace Xceed.Wpf.AvalonDock.Layout while( true ) { - var result = ReadElement( reader ) as LayoutFloatingWindow; - if( result == null ) + if( isFloatingWindow ) { - break; + var result = this.ReadElement( reader ) as LayoutFloatingWindow; + if( result == null ) + { + break; + } + resultList.Add( result ); + } + else + { + var result = this.ReadElement( reader ) as LayoutAnchorable; + if( result == null ) + { + break; + } + resultList.Add( result ); } - - resultList.Add( result ); } reader.ReadEndElement(); @@ -854,14 +985,14 @@ namespace Xceed.Wpf.AvalonDock.Layout private object ReadElement( XmlReader reader ) { - if( reader.NodeType == XmlNodeType.EndElement ) + while( reader.NodeType == XmlNodeType.Whitespace ) { - return null; + reader.Read(); } - while( reader.NodeType == XmlNodeType.Whitespace ) + if( reader.NodeType == XmlNodeType.EndElement ) { - reader.Read(); + return null; } XmlSerializer serializer; @@ -920,97 +1051,14 @@ namespace Xceed.Wpf.AvalonDock.Layout return serializer.Deserialize( reader ); } - public void WriteXml( XmlWriter writer ) - { - writer.WriteStartElement( "RootPanel" ); - if( RootPanel != null ) - { - RootPanel.WriteXml( writer ); - } - writer.WriteEndElement(); - - writer.WriteStartElement( "TopSide" ); - if( TopSide != null ) - { - TopSide.WriteXml( writer ); - } - writer.WriteEndElement(); - - writer.WriteStartElement( "RightSide" ); - if( RightSide != null ) - { - RightSide.WriteXml( writer ); - } - writer.WriteEndElement(); - - writer.WriteStartElement( "LeftSide" ); - if( LeftSide != null ) - { - LeftSide.WriteXml( writer ); - } - writer.WriteEndElement(); - - writer.WriteStartElement( "BottomSide" ); - if( BottomSide != null ) - { - BottomSide.WriteXml( writer ); - } - writer.WriteEndElement(); - - // Write all floating windows (can be LayoutDocumentFloatingWindow or LayoutAnchorableFloatingWindow). - // To prevent "can not create instance of abstract type", the type is retrieved with GetType().Name - writer.WriteStartElement( "FloatingWindows" ); - foreach( var layoutFloatingWindow in FloatingWindows ) - { - writer.WriteStartElement( layoutFloatingWindow.GetType().Name ); - layoutFloatingWindow.WriteXml( writer ); - writer.WriteEndElement(); - } - writer.WriteEndElement(); - - writer.WriteStartElement( "Hidden" ); - foreach( var layoutAnchorable in Hidden ) - { - layoutAnchorable.WriteXml( writer ); - } - writer.WriteEndElement(); - } - - internal static Type FindType( string name ) - { - foreach( var assembly in AppDomain.CurrentDomain.GetAssemblies() ) - { - foreach( var type in assembly.GetTypes() ) - { - if( type.Name.Equals( name ) ) - return type; - } - } - return null; - } - -#if TRACE - public override void ConsoleDump(int tab) - { - System.Diagnostics.Trace.Write( new string( ' ', tab * 4 ) ); - System.Diagnostics.Trace.WriteLine( "RootPanel()" ); - - RootPanel.ConsoleDump(tab + 1); - - System.Diagnostics.Trace.Write( new string( ' ', tab * 4 ) ); - System.Diagnostics.Trace.WriteLine( "FloatingWindows()" ); - - foreach (LayoutFloatingWindow fw in FloatingWindows) - fw.ConsoleDump(tab + 1); + #endregion - System.Diagnostics.Trace.Write( new string( ' ', tab * 4 ) ); - System.Diagnostics.Trace.WriteLine( "Hidden()" ); - - foreach (LayoutAnchorable hidden in Hidden) - hidden.ConsoleDump(tab + 1); - } -#endif + #region Events + public event EventHandler Updated; + public event EventHandler ElementAdded; + public event EventHandler ElementRemoved; + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/LayoutSerializationCallbackEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/LayoutSerializationCallbackEventArgs.cs index 554e2964..24ceb24b 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/LayoutSerializationCallbackEventArgs.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/LayoutSerializationCallbackEventArgs.cs @@ -14,25 +14,35 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.ComponentModel; namespace Xceed.Wpf.AvalonDock.Layout.Serialization { - public class LayoutSerializationCallbackEventArgs : CancelEventArgs + public class LayoutSerializationCallbackEventArgs : CancelEventArgs + { + #region constructor + + public LayoutSerializationCallbackEventArgs( LayoutContent model, object previousContent ) { - public LayoutSerializationCallbackEventArgs(LayoutContent model, object previousContent) - { - Cancel = false; - Model = model; - Content = previousContent; - } + Cancel = false; + Model = model; + Content = previousContent; + } + + #endregion + + #region Properties - public LayoutContent Model { get; private set; } + public LayoutContent Model + { + get; private set; + } - public object Content { get; set; } + public object Content + { + get; set; } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/LayoutSerializer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/LayoutSerializer.cs index 32f37c5c..3ff45860 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/LayoutSerializer.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/LayoutSerializer.cs @@ -15,124 +15,143 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; -using System.IO; -using Xceed.Wpf.AvalonDock.Controls; -using System.Windows; namespace Xceed.Wpf.AvalonDock.Layout.Serialization { - public abstract class LayoutSerializer + public abstract class LayoutSerializer + { + #region Members + + private DockingManager _manager; + private LayoutAnchorable[] _previousAnchorables = null; + private LayoutDocument[] _previousDocuments = null; + + #endregion + + #region Constructors + + public LayoutSerializer( DockingManager manager ) { - DockingManager _manager; + if( manager == null ) + throw new ArgumentNullException( "manager" ); - public LayoutSerializer(DockingManager manager) - { - if (manager == null) - throw new ArgumentNullException("manager"); + _manager = manager; + _previousAnchorables = _manager.Layout.Descendents().OfType().ToArray(); + _previousDocuments = _manager.Layout.Descendents().OfType().ToArray(); + } - _manager = manager; - _previousAnchorables = _manager.Layout.Descendents().OfType().ToArray(); - _previousDocuments = _manager.Layout.Descendents().OfType().ToArray(); - } + #endregion + + #region Properties + + public DockingManager Manager + { + get + { + return _manager; + } + } + + #endregion + + #region Events + + public event EventHandler LayoutSerializationCallback; + + #endregion - LayoutAnchorable[] _previousAnchorables = null; - LayoutDocument[] _previousDocuments = null; + #region Methods - public DockingManager Manager + protected virtual void FixupLayout( LayoutRoot layout ) + { + //fix container panes + foreach( var lcToAttach in layout.Descendents().OfType().Where( lc => lc.PreviousContainerId != null ) ) + { + var paneContainerToAttach = layout.Descendents().OfType().FirstOrDefault( lps => lps.Id == lcToAttach.PreviousContainerId ); + if( paneContainerToAttach == null ) + throw new ArgumentException( string.Format( "Unable to find a pane with id ='{0}'", lcToAttach.PreviousContainerId ) ); + + lcToAttach.PreviousContainer = paneContainerToAttach as ILayoutContainer; + } + + + //now fix the content of the layoutcontents + foreach( var lcToFix in layout.Descendents().OfType().Where( lc => lc.Content == null ).ToArray() ) + { + LayoutAnchorable previousAchorable = null; + if( lcToFix.ContentId != null ) { - get { return _manager; } + //try find the content in replaced layout + previousAchorable = _previousAnchorables.FirstOrDefault( a => a.ContentId == lcToFix.ContentId ); } - public event EventHandler LayoutSerializationCallback; - - protected virtual void FixupLayout(LayoutRoot layout) + if( LayoutSerializationCallback != null ) + { + var args = new LayoutSerializationCallbackEventArgs( lcToFix, previousAchorable != null ? previousAchorable.Content : null ); + LayoutSerializationCallback( this, args ); + if( args.Cancel ) + lcToFix.Close(); + else if( args.Content != null ) + lcToFix.Content = args.Content; + else if( args.Model.Content != null ) + lcToFix.Hide( false ); + } + else if( previousAchorable == null ) + lcToFix.Hide( false ); + else { - //fix container panes - foreach (var lcToAttach in layout.Descendents().OfType().Where(lc => lc.PreviousContainerId != null)) - { - var paneContainerToAttach = layout.Descendents().OfType().FirstOrDefault(lps => lps.Id == lcToAttach.PreviousContainerId); - if (paneContainerToAttach == null) - throw new ArgumentException(string.Format("Unable to find a pane with id ='{0}'", lcToAttach.PreviousContainerId)); - - lcToAttach.PreviousContainer = paneContainerToAttach as ILayoutContainer; - } - - - //now fix the content of the layoutcontents - foreach (var lcToFix in layout.Descendents().OfType().Where(lc => lc.Content == null).ToArray()) - { - LayoutAnchorable previousAchorable = null; - if (lcToFix.ContentId != null) - { - //try find the content in replaced layout - previousAchorable = _previousAnchorables.FirstOrDefault(a => a.ContentId == lcToFix.ContentId); - } - - if (LayoutSerializationCallback != null) - { - var args = new LayoutSerializationCallbackEventArgs(lcToFix, previousAchorable != null ? previousAchorable.Content : null); - LayoutSerializationCallback(this, args); - if (args.Cancel) - lcToFix.Close(); - else if (args.Content != null) - lcToFix.Content = args.Content; - else if (args.Model.Content != null) - lcToFix.Hide(false); - } - else if (previousAchorable == null) - lcToFix.Hide(false); - else - { - lcToFix.Content = previousAchorable.Content; - lcToFix.IconSource = previousAchorable.IconSource; - } - } - - - foreach (var lcToFix in layout.Descendents().OfType().Where(lc => lc.Content == null).ToArray()) - { - LayoutDocument previousDocument = null; - if (lcToFix.ContentId != null) - { - //try find the content in replaced layout - previousDocument = _previousDocuments.FirstOrDefault(a => a.ContentId == lcToFix.ContentId); - } - - if (LayoutSerializationCallback != null) - { - var args = new LayoutSerializationCallbackEventArgs(lcToFix, previousDocument != null ? previousDocument.Content : null); - LayoutSerializationCallback(this, args); - - if (args.Cancel) - lcToFix.Close(); - else if (args.Content != null) - lcToFix.Content = args.Content; - else if (args.Model.Content != null) - lcToFix.Close(); - } - else if (previousDocument == null) - lcToFix.Close(); - else - lcToFix.Content = previousDocument.Content; - } - - - layout.CollectGarbage(); + lcToFix.Content = previousAchorable.Content; + lcToFix.IconSource = previousAchorable.IconSource; } + } - protected void StartDeserialization() + + foreach( var lcToFix in layout.Descendents().OfType().Where( lc => lc.Content == null ).ToArray() ) + { + LayoutDocument previousDocument = null; + if( lcToFix.ContentId != null ) { - Manager.SuspendDocumentsSourceBinding = true; - Manager.SuspendAnchorablesSourceBinding = true; + //try find the content in replaced layout + previousDocument = _previousDocuments.FirstOrDefault( a => a.ContentId == lcToFix.ContentId ); } - protected void EndDeserialization() + if( LayoutSerializationCallback != null ) + { + var args = new LayoutSerializationCallbackEventArgs( lcToFix, previousDocument != null ? previousDocument.Content : null ); + LayoutSerializationCallback( this, args ); + + if( args.Cancel ) + lcToFix.Close(); + else if( args.Content != null ) + lcToFix.Content = args.Content; + else if( args.Model.Content != null ) + lcToFix.Close(); + } + else if( previousDocument == null ) + lcToFix.Close(); + else { - Manager.SuspendDocumentsSourceBinding = false; - Manager.SuspendAnchorablesSourceBinding = false; + lcToFix.Content = previousDocument.Content; + lcToFix.IconSource = previousDocument.IconSource; } + } + + layout.CollectGarbage(); } + + protected void StartDeserialization() + { + Manager.SuspendDocumentsSourceBinding = true; + Manager.SuspendAnchorablesSourceBinding = true; + } + + protected void EndDeserialization() + { + Manager.SuspendDocumentsSourceBinding = false; + Manager.SuspendAnchorablesSourceBinding = false; + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/XmlLayoutSerializer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/XmlLayoutSerializer.cs index a97e3277..05d3321e 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/XmlLayoutSerializer.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/XmlLayoutSerializer.cs @@ -14,97 +14,102 @@ ***********************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Xml.Serialization; using System.IO; namespace Xceed.Wpf.AvalonDock.Layout.Serialization { - public class XmlLayoutSerializer : LayoutSerializer + public class XmlLayoutSerializer : LayoutSerializer + { + #region Constructors + + public XmlLayoutSerializer( DockingManager manager ) + : base( manager ) + { + } + + #endregion + + #region Public Methods + + public void Serialize( System.Xml.XmlWriter writer ) + { + var serializer = new XmlSerializer( typeof( LayoutRoot ) ); + serializer.Serialize( writer, Manager.Layout ); + } + + public void Serialize( System.IO.TextWriter writer ) + { + var serializer = new XmlSerializer( typeof( LayoutRoot ) ); + serializer.Serialize( writer, Manager.Layout ); + } + + public void Serialize( System.IO.Stream stream ) + { + var serializer = new XmlSerializer( typeof( LayoutRoot ) ); + serializer.Serialize( stream, Manager.Layout ); + } + + public void Serialize( string filepath ) + { + using( var stream = new StreamWriter( filepath ) ) + Serialize( stream ); + } + + public void Deserialize( System.IO.Stream stream ) + { + try + { + StartDeserialization(); + var serializer = new XmlSerializer( typeof( LayoutRoot ) ); + var layout = serializer.Deserialize( stream ) as LayoutRoot; + FixupLayout( layout ); + Manager.Layout = layout; + } + finally + { + EndDeserialization(); + } + } + + public void Deserialize( System.IO.TextReader reader ) { - public XmlLayoutSerializer(DockingManager manager) - : base(manager) - { - - } - - public void Serialize(System.Xml.XmlWriter writer) - { - var serializer = new XmlSerializer(typeof(LayoutRoot)); - serializer.Serialize(writer, Manager.Layout); - } - public void Serialize(System.IO.TextWriter writer) - { - var serializer = new XmlSerializer(typeof(LayoutRoot)); - serializer.Serialize(writer, Manager.Layout); - } - public void Serialize(System.IO.Stream stream) - { - var serializer = new XmlSerializer(typeof(LayoutRoot)); - serializer.Serialize(stream, Manager.Layout); - } - - public void Serialize(string filepath) - { - using (var stream = new StreamWriter(filepath)) - Serialize(stream); - } - - public void Deserialize(System.IO.Stream stream) - { - try - { - StartDeserialization(); - var serializer = new XmlSerializer(typeof(LayoutRoot)); - var layout = serializer.Deserialize(stream) as LayoutRoot; - FixupLayout(layout); - Manager.Layout = layout; - } - finally - { - EndDeserialization(); - } - } - - public void Deserialize(System.IO.TextReader reader) - { - try - { - StartDeserialization(); - var serializer = new XmlSerializer(typeof(LayoutRoot)); - var layout = serializer.Deserialize(reader) as LayoutRoot; - FixupLayout(layout); - Manager.Layout = layout; - } - finally - { - EndDeserialization(); - } - } - - public void Deserialize(System.Xml.XmlReader reader) - { - try - { - StartDeserialization(); - var serializer = new XmlSerializer(typeof(LayoutRoot)); - var layout = serializer.Deserialize(reader) as LayoutRoot; - FixupLayout(layout); - Manager.Layout = layout; - } - finally - { - EndDeserialization(); - } - } - - public void Deserialize(string filepath) - { - using (var stream = new StreamReader(filepath)) - Deserialize(stream); - } + try + { + StartDeserialization(); + var serializer = new XmlSerializer( typeof( LayoutRoot ) ); + var layout = serializer.Deserialize( reader ) as LayoutRoot; + FixupLayout( layout ); + Manager.Layout = layout; + } + finally + { + EndDeserialization(); + } } + + public void Deserialize( System.Xml.XmlReader reader ) + { + try + { + StartDeserialization(); + var serializer = new XmlSerializer( typeof( LayoutRoot ) ); + var layout = serializer.Deserialize( reader ) as LayoutRoot; + FixupLayout( layout ); + Manager.Layout = layout; + } + finally + { + EndDeserialization(); + } + } + + public void Deserialize( string filepath ) + { + using( var stream = new StreamReader( filepath ) ) + Deserialize( stream ); + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/LayoutEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/LayoutEventArgs.cs index 25a6aa5c..81201acb 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/LayoutEventArgs.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/LayoutEventArgs.cs @@ -15,24 +15,21 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using Xceed.Wpf.AvalonDock.Layout; namespace Xceed.Wpf.AvalonDock { - class LayoutEventArgs : EventArgs + class LayoutEventArgs : EventArgs + { + public LayoutEventArgs( LayoutRoot layoutRoot ) { - public LayoutEventArgs(LayoutRoot layoutRoot) - { - LayoutRoot = layoutRoot; - } - - public LayoutRoot LayoutRoot - { - get; - private set; - } + LayoutRoot = layoutRoot; } + + public LayoutRoot LayoutRoot + { + get; + private set; + } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/MathHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/MathHelper.cs index 261f37fb..d059d55d 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/MathHelper.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/MathHelper.cs @@ -15,32 +15,28 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Xceed.Wpf.AvalonDock { - internal static class MathHelper + internal static class MathHelper + { + public static double MinMax( double value, double min, double max ) { + if( min > max ) + throw new ArgumentException( "min>max" ); - public static double MinMax(double value, double min, double max) - { - if (min > max) - throw new ArgumentException("min>max"); + if( value < min ) + return min; + if( value > max ) + return max; - if (value < min) - return min; - if (value > max) - return max; - - return value; - } + return value; + } - public static void AssertIsPositiveOrZero(double value) - { - if (value < 0.0) - throw new ArgumentException("Invalid value, must be a positive number or equal to zero"); - } + public static void AssertIsPositiveOrZero( double value ) + { + if( value < 0.0 ) + throw new ArgumentException( "Invalid value, must be a positive number or equal to zero" ); } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.Designer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.Designer.cs index 860054d5..620c95db 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.Designer.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.Designer.cs @@ -17,7 +17,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34014 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -148,6 +148,15 @@ namespace Xceed.Wpf.AvalonDock.Properties { } } + /// + /// Looks up a localized string similar to Toggle Pin status. + /// + public static string Document_BtnPinned_Hint { + get { + return ResourceManager.GetString("Document_BtnPinned_Hint", resourceCulture); + } + } + /// /// Looks up a localized string similar to Close. /// diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.de.resx b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.de.resx index e421ea6a..b0800844 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.de.resx +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.de.resx @@ -141,6 +141,9 @@ Schließen + + Pin-Status umschalten + Schließen @@ -177,4 +180,4 @@ Wiederherstellen - + \ No newline at end of file diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.es.resx b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.es.resx index 5b8b5166..9b2cf65c 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.es.resx +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.es.resx @@ -141,6 +141,9 @@ Esconder + + Activar el estado del pin + Cerrar @@ -177,4 +180,4 @@ Restaurar - + \ No newline at end of file diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.fr.resx b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.fr.resx index 0c269e23..8acbf362 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.fr.resx +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.fr.resx @@ -141,6 +141,9 @@ Cacher + + Ancrer / désancrer + Fermer @@ -177,4 +180,4 @@ Restaurer - + \ No newline at end of file diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.hu.resx b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.hu.resx index c9976b7e..54d0bcae 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.hu.resx +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.hu.resx @@ -141,6 +141,9 @@ Elrejtés + + Toggle Pin állapot + Bezárás @@ -177,4 +180,4 @@ Visszaállítás - + \ No newline at end of file diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.it.resx b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.it.resx index 505ca9a8..d72bc67a 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.it.resx +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.it.resx @@ -141,6 +141,9 @@ Nascondi + + Stato Toggle Pin + Chiudi @@ -177,4 +180,4 @@ Ripristina - + \ No newline at end of file diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.resx b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.resx index e956f595..67b1d132 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.resx +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.resx @@ -141,6 +141,9 @@ Hide + + Toggle Pin status + Close @@ -177,4 +180,4 @@ Restore - + \ No newline at end of file diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.ro.resx b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.ro.resx index 09799b58..db258c18 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.ro.resx +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.ro.resx @@ -141,6 +141,9 @@ Ascunde + + Starea de comutare Pin + Închide @@ -177,4 +180,4 @@ Restaurează - + \ No newline at end of file diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.ru.resx b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.ru.resx index cc5f76a0..247500ec 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.ru.resx +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.ru.resx @@ -141,6 +141,9 @@ Скрыть + + Статус Переключение Pin + Закрыть @@ -177,4 +180,4 @@ Восстановить - + \ No newline at end of file diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.sv.resx b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.sv.resx index afc0fd58..cccac740 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.sv.resx +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.sv.resx @@ -141,6 +141,9 @@ Dölj + + Toggle Pin status + Stäng @@ -177,4 +180,4 @@ Återställ - + \ No newline at end of file diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.zh-Hans.resx b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.zh-Hans.resx index 352a2671..9cc57795 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.zh-Hans.resx +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Properties/Resources.zh-Hans.resx @@ -141,6 +141,9 @@ 隐藏 + + 切換引腳狀態 + 关闭 @@ -177,4 +180,4 @@ 恢复 - + \ No newline at end of file diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/DictionaryTheme.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/DictionaryTheme.cs index 4e14f82d..6857768b 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/DictionaryTheme.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/DictionaryTheme.cs @@ -15,15 +15,14 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; namespace Xceed.Wpf.AvalonDock.Themes { public abstract class DictionaryTheme : Theme { + #region Constructors + public DictionaryTheme() { } @@ -33,15 +32,25 @@ namespace Xceed.Wpf.AvalonDock.Themes this.ThemeResourceDictionary = themeResourceDictionary; } + #endregion + + #region Properties + public ResourceDictionary ThemeResourceDictionary { get; private set; } + #endregion + + #region Overrides + public override Uri GetResourceUri() { return null; } + + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/GenericTheme.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/GenericTheme.cs index cdcb007e..857cd20c 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/GenericTheme.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/GenericTheme.cs @@ -15,9 +15,6 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Xceed.Wpf.AvalonDock.Themes { @@ -25,9 +22,7 @@ namespace Xceed.Wpf.AvalonDock.Themes { public override Uri GetResourceUri() { - return new Uri( - "/Xceed.Wpf.AvalonDock;component/Themes/generic.xaml", - UriKind.Relative ); + return new Uri( "/Xceed.Wpf.AvalonDock;component/Themes/generic.xaml", UriKind.Relative ); } } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Theme.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Theme.cs index dabd93c2..88abbfc0 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Theme.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Theme.cs @@ -15,22 +15,16 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; namespace Xceed.Wpf.AvalonDock.Themes { - public abstract class Theme : DependencyObject + public abstract class Theme : DependencyObject + { + public Theme() { - public Theme() - { - - } - - public abstract Uri GetResourceUri(); - - } + + public abstract Uri GetResourceUri(); + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/generic.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/generic.xaml index 33b1c73e..89dab4dd 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/generic.xaml +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/generic.xaml @@ -856,17 +856,17 @@ + - - + @@ -1035,7 +1041,7 @@ CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}}" ToolTip="{x:Static avalonDockProperties:Resources.Window_Restore}" Grid.Column="2"> - + @@ -1046,7 +1052,7 @@ ToolTip="{x:Static avalonDockProperties:Resources.Document_Close}" Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" Grid.Column="3"> - + @@ -1131,7 +1137,7 @@ DropDownContextMenu="{Binding Model.Root.Manager.AnchorableContextMenu, RelativeSource={RelativeSource TemplatedParent}}" DropDownContextMenuDataContext="{Binding Path=SingleContentLayoutItem, RelativeSource={RelativeSource TemplatedParent}}" ToolTip="{x:Static avalonDockProperties:Resources.Anchorable_CxMenu_Hint}"> - + @@ -1143,7 +1149,7 @@ CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}}" ToolTip="{x:Static avalonDockProperties:Resources.Window_Maximize}" Grid.Column="2"> - + @@ -1155,7 +1161,7 @@ CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}}" ToolTip="{x:Static avalonDockProperties:Resources.Window_Restore}" Grid.Column="2"> - + @@ -1167,7 +1173,7 @@ ToolTip="{x:Static avalonDockProperties:Resources.Anchorable_BtnClose_Hint}" Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" Grid.Column="3"> - + @@ -1253,19 +1259,21 @@ + Stretch="None"> - + Margin="4,0,0,0"> - + VerticalAlignment="Center"> @@ -1281,9 +1289,10 @@ + Margin="0,3,0,4"> - - + + + + + + diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Win32Helper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Win32Helper.cs index cade16f9..2106dd9b 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Win32Helper.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Win32Helper.cs @@ -15,447 +15,479 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Runtime.InteropServices; using System.Windows; namespace Xceed.Wpf.AvalonDock { - internal static class Win32Helper + internal static class Win32Helper + { + [DllImport( "user32.dll", EntryPoint = "CreateWindowEx", CharSet = CharSet.Unicode )] + internal static extern IntPtr CreateWindowEx( int dwExStyle, + string lpszClassName, + string lpszWindowName, + int style, + int x, int y, + int width, int height, + IntPtr hwndParent, + IntPtr hMenu, + IntPtr hInst, + [MarshalAs( UnmanagedType.AsAny )] object pvParam ); + internal const int + WS_CHILD = 0x40000000, + WS_VISIBLE = 0x10000000, + WS_VSCROLL = 0x00200000, + WS_BORDER = 0x00800000, + WS_CLIPSIBLINGS = 0x04000000, + WS_CLIPCHILDREN = 0x02000000, + WS_TABSTOP = 0x00010000, + WS_GROUP = 0x00020000; + + + /// + /// SetWindowPos Flags + /// + [Flags()] + internal enum SetWindowPosFlags : uint { - [DllImport("user32.dll", EntryPoint = "CreateWindowEx", CharSet = CharSet.Unicode)] - internal static extern IntPtr CreateWindowEx(int dwExStyle, - string lpszClassName, - string lpszWindowName, - int style, - int x, int y, - int width, int height, - IntPtr hwndParent, - IntPtr hMenu, - IntPtr hInst, - [MarshalAs(UnmanagedType.AsAny)] object pvParam); - internal const int - WS_CHILD = 0x40000000, - WS_VISIBLE = 0x10000000, - WS_VSCROLL = 0x00200000, - WS_BORDER = 0x00800000, - WS_CLIPSIBLINGS = 0x04000000, - WS_CLIPCHILDREN = 0x02000000, - WS_TABSTOP = 0x00010000, - WS_GROUP = 0x00020000; - - - /// - /// SetWindowPos Flags - /// - [Flags()] - internal enum SetWindowPosFlags : uint - { - /// If the calling thread and the thread that owns the window are attached to different input queues, - /// the system posts the request to the thread that owns the window. This prevents the calling thread from - /// blocking its execution while other threads process the request. - /// SWP_ASYNCWINDOWPOS - SynchronousWindowPosition = 0x4000, - /// Prevents generation of the WM_SYNCPAINT message. - /// SWP_DEFERERASE - DeferErase = 0x2000, - /// Draws a frame (defined in the window's class description) around the window. - /// SWP_DRAWFRAME - DrawFrame = 0x0020, - /// Applies new frame styles set using the SetWindowLong function. Sends a WM_NCCALCSIZE message to - /// the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE - /// is sent only when the window's size is being changed. - /// SWP_FRAMECHANGED - FrameChanged = 0x0020, - /// Hides the window. - /// SWP_HIDEWINDOW - HideWindow = 0x0080, - /// Does not activate the window. If this flag is not set, the window is activated and moved to the - /// top of either the topmost or non-topmost group (depending on the setting of the hWndInsertAfter - /// parameter). - /// SWP_NOACTIVATE - DoNotActivate = 0x0010, - /// Discards the entire contents of the client area. If this flag is not specified, the valid - /// contents of the client area are saved and copied back into the client area after the window is sized or - /// repositioned. - /// SWP_NOCOPYBITS - DoNotCopyBits = 0x0100, - /// Retains the current position (ignores X and Y parameters). - /// SWP_NOMOVE - IgnoreMove = 0x0002, - /// Does not change the owner window's position in the Z order. - /// SWP_NOOWNERZORDER - DoNotChangeOwnerZOrder = 0x0200, - /// Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to - /// the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent - /// window uncovered as a result of the window being moved. When this flag is set, the application must - /// explicitly invalidate or redraw any parts of the window and parent window that need redrawing. - /// SWP_NOREDRAW - DoNotRedraw = 0x0008, - /// Same as the SWP_NOOWNERZORDER flag. - /// SWP_NOREPOSITION - DoNotReposition = 0x0200, - /// Prevents the window from receiving the WM_WINDOWPOSCHANGING message. - /// SWP_NOSENDCHANGING - DoNotSendChangingEvent = 0x0400, - /// Retains the current size (ignores the cx and cy parameters). - /// SWP_NOSIZE - IgnoreResize = 0x0001, - /// Retains the current Z order (ignores the hWndInsertAfter parameter). - /// SWP_NOZORDER - IgnoreZOrder = 0x0004, - /// Displays the window. - /// SWP_SHOWWINDOW - ShowWindow = 0x0040, - } + /// If the calling thread and the thread that owns the window are attached to different input queues, + /// the system posts the request to the thread that owns the window. This prevents the calling thread from + /// blocking its execution while other threads process the request. + /// SWP_ASYNCWINDOWPOS + SynchronousWindowPosition = 0x4000, + /// Prevents generation of the WM_SYNCPAINT message. + /// SWP_DEFERERASE + DeferErase = 0x2000, + /// Draws a frame (defined in the window's class description) around the window. + /// SWP_DRAWFRAME + DrawFrame = 0x0020, + /// Applies new frame styles set using the SetWindowLong function. Sends a WM_NCCALCSIZE message to + /// the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE + /// is sent only when the window's size is being changed. + /// SWP_FRAMECHANGED + FrameChanged = 0x0020, + /// Hides the window. + /// SWP_HIDEWINDOW + HideWindow = 0x0080, + /// Does not activate the window. If this flag is not set, the window is activated and moved to the + /// top of either the topmost or non-topmost group (depending on the setting of the hWndInsertAfter + /// parameter). + /// SWP_NOACTIVATE + DoNotActivate = 0x0010, + /// Discards the entire contents of the client area. If this flag is not specified, the valid + /// contents of the client area are saved and copied back into the client area after the window is sized or + /// repositioned. + /// SWP_NOCOPYBITS + DoNotCopyBits = 0x0100, + /// Retains the current position (ignores X and Y parameters). + /// SWP_NOMOVE + IgnoreMove = 0x0002, + /// Does not change the owner window's position in the Z order. + /// SWP_NOOWNERZORDER + DoNotChangeOwnerZOrder = 0x0200, + /// Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to + /// the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent + /// window uncovered as a result of the window being moved. When this flag is set, the application must + /// explicitly invalidate or redraw any parts of the window and parent window that need redrawing. + /// SWP_NOREDRAW + DoNotRedraw = 0x0008, + /// Same as the SWP_NOOWNERZORDER flag. + /// SWP_NOREPOSITION + DoNotReposition = 0x0200, + /// Prevents the window from receiving the WM_WINDOWPOSCHANGING message. + /// SWP_NOSENDCHANGING + DoNotSendChangingEvent = 0x0400, + /// Retains the current size (ignores the cx and cy parameters). + /// SWP_NOSIZE + IgnoreResize = 0x0001, + /// Retains the current Z order (ignores the hWndInsertAfter parameter). + /// SWP_NOZORDER + IgnoreZOrder = 0x0004, + /// Displays the window. + /// SWP_SHOWWINDOW + ShowWindow = 0x0040, + } - /// - /// Special window handles - /// - internal static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); - internal static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); - internal static readonly IntPtr HWND_TOP = new IntPtr(0); - internal static readonly IntPtr HWND_BOTTOM = new IntPtr(1); + /// + /// Special window handles + /// + internal static readonly IntPtr HWND_TOPMOST = new IntPtr( -1 ); + internal static readonly IntPtr HWND_NOTOPMOST = new IntPtr( -2 ); + internal static readonly IntPtr HWND_TOP = new IntPtr( 0 ); + internal static readonly IntPtr HWND_BOTTOM = new IntPtr( 1 ); - [StructLayout(LayoutKind.Sequential)] - internal class WINDOWPOS - { - public IntPtr hwnd; - public IntPtr hwndInsertAfter; - public int x; - public int y; - public int cx; - public int cy; - public int flags; - }; - - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags); - - [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] - internal static extern bool IsChild(IntPtr hWndParent, IntPtr hwnd); - - [DllImport("user32.dll")] - internal static extern IntPtr SetFocus(IntPtr hWnd); - - internal const int WM_WINDOWPOSCHANGED = 0x0047; - internal const int WM_WINDOWPOSCHANGING = 0x0046; - internal const int WM_NCMOUSEMOVE = 0xa0; - internal const int WM_NCLBUTTONDOWN = 0xA1; - internal const int WM_NCLBUTTONUP = 0xA2; - internal const int WM_NCLBUTTONDBLCLK = 0xA3; - internal const int WM_NCRBUTTONDOWN = 0xA4; - internal const int WM_NCRBUTTONUP = 0xA5; - internal const int WM_CAPTURECHANGED = 0x0215; - internal const int WM_EXITSIZEMOVE = 0x0232; - internal const int WM_ENTERSIZEMOVE = 0x0231; - internal const int WM_MOVE = 0x0003; - internal const int WM_MOVING = 0x0216; - internal const int WM_KILLFOCUS = 0x0008; - internal const int WM_SETFOCUS = 0x0007; - internal const int WM_ACTIVATE = 0x0006; - internal const int WM_NCHITTEST = 0x0084; - internal const int WM_INITMENUPOPUP = 0x0117; - internal const int WM_KEYDOWN = 0x0100; - internal const int WM_KEYUP = 0x0101; - - internal const int WA_INACTIVE = 0x0000; - - internal const int WM_SYSCOMMAND = 0x0112; - // These are the wParam of WM_SYSCOMMAND - internal const int SC_MAXIMIZE = 0xF030; - internal const int SC_RESTORE = 0xF120; - - internal const int - WM_CREATE = 0x0001; - - [DllImport("user32.dll", SetLastError = true)] - public static extern IntPtr SetActiveWindow(IntPtr hWnd); - - [DllImport("user32.dll", EntryPoint = "DestroyWindow", CharSet = CharSet.Unicode)] - internal static extern bool DestroyWindow(IntPtr hwnd); - - internal const int HT_CAPTION = 0x2; - - [DllImportAttribute("user32.dll")] - internal static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); - [DllImportAttribute("user32.dll")] - internal static extern int PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); - - - [DllImport("user32.dll")] - static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect); - [DllImport("user32.dll")] - internal static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); - - // Hook Types - public enum HookType : int - { - WH_JOURNALRECORD = 0, - WH_JOURNALPLAYBACK = 1, - WH_KEYBOARD = 2, - WH_GETMESSAGE = 3, - WH_CALLWNDPROC = 4, - WH_CBT = 5, - WH_SYSMSGFILTER = 6, - WH_MOUSE = 7, - WH_HARDWARE = 8, - WH_DEBUG = 9, - WH_SHELL = 10, - WH_FOREGROUNDIDLE = 11, - WH_CALLWNDPROCRET = 12, - WH_KEYBOARD_LL = 13, - WH_MOUSE_LL = 14 - } + [StructLayout( LayoutKind.Sequential )] + internal class WINDOWPOS + { + public IntPtr hwnd; + public IntPtr hwndInsertAfter; + public int x; + public int y; + public int cx; + public int cy; + public int flags; + }; + + [DllImport( "user32.dll" )] + [return: MarshalAs( UnmanagedType.Bool )] + internal static extern bool SetWindowPos( IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags ); + + [DllImport( "user32.dll", CharSet = CharSet.Auto, ExactSpelling = true )] + internal static extern bool IsChild( IntPtr hWndParent, IntPtr hwnd ); + + [DllImport( "user32.dll" )] + internal static extern IntPtr SetFocus( IntPtr hWnd ); + + internal const int WM_WINDOWPOSCHANGED = 0x0047; + internal const int WM_WINDOWPOSCHANGING = 0x0046; + internal const int WM_NCMOUSEMOVE = 0xa0; + internal const int WM_NCLBUTTONDOWN = 0xA1; + internal const int WM_NCLBUTTONUP = 0xA2; + internal const int WM_NCLBUTTONDBLCLK = 0xA3; + internal const int WM_NCRBUTTONDOWN = 0xA4; + internal const int WM_NCRBUTTONUP = 0xA5; + internal const int WM_CAPTURECHANGED = 0x0215; + internal const int WM_EXITSIZEMOVE = 0x0232; + internal const int WM_ENTERSIZEMOVE = 0x0231; + internal const int WM_MOVE = 0x0003; + internal const int WM_MOVING = 0x0216; + internal const int WM_KILLFOCUS = 0x0008; + internal const int WM_SETFOCUS = 0x0007; + internal const int WM_ACTIVATE = 0x0006; + internal const int WM_NCHITTEST = 0x0084; + internal const int WM_INITMENUPOPUP = 0x0117; + internal const int WM_KEYDOWN = 0x0100; + internal const int WM_KEYUP = 0x0101; + + internal const int WA_INACTIVE = 0x0000; + + internal const int WM_SYSCOMMAND = 0x0112; + // These are the wParam of WM_SYSCOMMAND + internal const int SC_MAXIMIZE = 0xF030; + internal const int SC_RESTORE = 0xF120; + + internal const int + WM_CREATE = 0x0001; + + [DllImport( "user32.dll", SetLastError = true )] + public static extern IntPtr SetActiveWindow( IntPtr hWnd ); + + [DllImport( "user32.dll", EntryPoint = "DestroyWindow", CharSet = CharSet.Unicode )] + internal static extern bool DestroyWindow( IntPtr hwnd ); + + internal const int HT_CAPTION = 0x2; + + [DllImportAttribute( "user32.dll" )] + internal static extern int SendMessage( IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam ); + [DllImportAttribute( "user32.dll" )] + internal static extern int PostMessage( IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam ); + + + [DllImport( "user32.dll" )] + static extern bool GetClientRect( IntPtr hWnd, out RECT lpRect ); + [DllImport( "user32.dll" )] + internal static extern bool GetWindowRect( IntPtr hWnd, out RECT lpRect ); + + // Hook Types + public enum HookType : int + { + WH_JOURNALRECORD = 0, + WH_JOURNALPLAYBACK = 1, + WH_KEYBOARD = 2, + WH_GETMESSAGE = 3, + WH_CALLWNDPROC = 4, + WH_CBT = 5, + WH_SYSMSGFILTER = 6, + WH_MOUSE = 7, + WH_HARDWARE = 8, + WH_DEBUG = 9, + WH_SHELL = 10, + WH_FOREGROUNDIDLE = 11, + WH_CALLWNDPROCRET = 12, + WH_KEYBOARD_LL = 13, + WH_MOUSE_LL = 14 + } - public const int HCBT_SETFOCUS = 9; - public const int HCBT_ACTIVATE = 5; + public const int HCBT_SETFOCUS = 9; + public const int HCBT_ACTIVATE = 5; - [DllImport("kernel32.dll")] - public static extern uint GetCurrentThreadId(); + [DllImport( "kernel32.dll" )] + public static extern uint GetCurrentThreadId(); - public delegate int HookProc(int code, IntPtr wParam, - IntPtr lParam); + public delegate int HookProc( int code, IntPtr wParam, + IntPtr lParam ); - [DllImport("user32.dll")] - public static extern IntPtr SetWindowsHookEx(HookType code, - HookProc func, - IntPtr hInstance, - int threadID); - [DllImport("user32.dll")] - public static extern int UnhookWindowsHookEx(IntPtr hhook); - [DllImport("user32.dll")] - public static extern int CallNextHookEx(IntPtr hhook, - int code, IntPtr wParam, IntPtr lParam); + [DllImport( "user32.dll" )] + public static extern IntPtr SetWindowsHookEx( HookType code, + HookProc func, + IntPtr hInstance, + int threadID ); + [DllImport( "user32.dll" )] + public static extern int UnhookWindowsHookEx( IntPtr hhook ); + [DllImport( "user32.dll" )] + public static extern int CallNextHookEx( IntPtr hhook, + int code, IntPtr wParam, IntPtr lParam ); - [Serializable, StructLayout(LayoutKind.Sequential)] - internal struct RECT + [Serializable, StructLayout( LayoutKind.Sequential )] + internal struct RECT + { + public int Left; + public int Top; + public int Right; + public int Bottom; + public RECT( int left_, int top_, int right_, int bottom_ ) + { + Left = left_; + Top = top_; + Right = right_; + Bottom = bottom_; + } + + public int Height + { + get { - public int Left; - public int Top; - public int Right; - public int Bottom; - public RECT(int left_, int top_, int right_, int bottom_) - { - Left = left_; Top = top_; Right = right_; Bottom = bottom_; - } - - public int Height - { - get { return Bottom - Top; } - } - - public int Width - { - get { return Right - Left; } - } - public Size Size { get { return new Size(Width, Height); } } - public Point Location { get { return new Point(Left, Top); } } - // Handy method for converting to a System.Drawing.Rectangle - public Rect ToRectangle() { return new Rect(Left, Top, Right, Bottom); } - public static RECT FromRectangle(Rect rectangle) - { return new Rect(rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom); } - public override int GetHashCode() - { return Left ^ ((Top << 13) | (Top >> 0x13)) ^ ((Width << 0x1a) | (Width >> 6)) ^ ((Height << 7) | (Height >> 0x19)); } - - #region Operator overloads - public static implicit operator Rect(RECT rect) { return rect.ToRectangle(); } public static implicit operator RECT(Rect rect) { return FromRectangle(rect); } - #endregion + return Bottom - Top; } + } - internal static RECT GetClientRect(IntPtr hWnd) + public int Width + { + get { - RECT result = new RECT(); - GetClientRect(hWnd, out result); - return result; + return Right - Left; } - internal static RECT GetWindowRect(IntPtr hWnd) + } + public Size Size + { + get { - RECT result = new RECT(); - GetWindowRect(hWnd, out result); - return result; + return new Size( Width, Height ); } + } + public Point Location + { + get + { + return new Point( Left, Top ); + } + } + // Handy method for converting to a System.Drawing.Rectangle + public Rect ToRectangle() + { + return new Rect( Left, Top, Right, Bottom ); + } + public static RECT FromRectangle( Rect rectangle ) + { + return new Rect( rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom ); + } + public override int GetHashCode() + { + return Left ^ ( ( Top << 13 ) | ( Top >> 0x13 ) ) ^ ( ( Width << 0x1a ) | ( Width >> 6 ) ) ^ ( ( Height << 7 ) | ( Height >> 0x19 ) ); + } + + #region Operator overloads + public static implicit operator Rect( RECT rect ) + { + return rect.ToRectangle(); + } + public static implicit operator RECT( Rect rect ) + { + return FromRectangle( rect ); + } + #endregion + } - [DllImport("user32.dll")] - internal static extern IntPtr GetTopWindow(IntPtr hWnd); + internal static RECT GetClientRect( IntPtr hWnd ) + { + RECT result = new RECT(); + GetClientRect( hWnd, out result ); + return result; + } + internal static RECT GetWindowRect( IntPtr hWnd ) + { + RECT result = new RECT(); + GetWindowRect( hWnd, out result ); + return result; + } - internal const uint GW_HWNDNEXT = 2; - internal const uint GW_HWNDPREV = 3; + [DllImport( "user32.dll" )] + internal static extern IntPtr GetTopWindow( IntPtr hWnd ); + internal const uint GW_HWNDNEXT = 2; + internal const uint GW_HWNDPREV = 3; - [DllImport("user32.dll", SetLastError = true)] - internal static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd); - internal enum GetWindow_Cmd : uint - { - GW_HWNDFIRST = 0, - GW_HWNDLAST = 1, - GW_HWNDNEXT = 2, - GW_HWNDPREV = 3, - GW_OWNER = 4, - GW_CHILD = 5, - GW_ENABLEDPOPUP = 6 - } - - internal static int MakeLParam(int LoWord, int HiWord) - { - return (int) ((HiWord << 16) | (LoWord & 0xffff)); - } + [DllImport( "user32.dll", SetLastError = true )] + internal static extern IntPtr GetWindow( IntPtr hWnd, uint uCmd ); + internal enum GetWindow_Cmd : uint + { + GW_HWNDFIRST = 0, + GW_HWNDLAST = 1, + GW_HWNDNEXT = 2, + GW_HWNDPREV = 3, + GW_OWNER = 4, + GW_CHILD = 5, + GW_ENABLEDPOPUP = 6 + } - internal const int WM_MOUSEMOVE = 0x200; - internal const int WM_LBUTTONDOWN = 0x201; - internal const int WM_LBUTTONUP = 0x202; - internal const int WM_LBUTTONDBLCLK = 0x203; - internal const int WM_RBUTTONDOWN = 0x204; - internal const int WM_RBUTTONUP = 0x205; - internal const int WM_RBUTTONDBLCLK = 0x206; - internal const int WM_MBUTTONDOWN = 0x207; - internal const int WM_MBUTTONUP = 0x208; - internal const int WM_MBUTTONDBLCLK = 0x209; - internal const int WM_MOUSEWHEEL = 0x20A; - internal const int WM_MOUSEHWHEEL = 0x20E; + internal static int MakeLParam( int LoWord, int HiWord ) + { + return ( int )( ( HiWord << 16 ) | ( LoWord & 0xffff ) ); + } - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool GetCursorPos(ref Win32Point pt); + internal const int WM_MOUSEMOVE = 0x200; + internal const int WM_LBUTTONDOWN = 0x201; + internal const int WM_LBUTTONUP = 0x202; + internal const int WM_LBUTTONDBLCLK = 0x203; + internal const int WM_RBUTTONDOWN = 0x204; + internal const int WM_RBUTTONUP = 0x205; + internal const int WM_RBUTTONDBLCLK = 0x206; + internal const int WM_MBUTTONDOWN = 0x207; + internal const int WM_MBUTTONUP = 0x208; + internal const int WM_MBUTTONDBLCLK = 0x209; + internal const int WM_MOUSEWHEEL = 0x20A; + internal const int WM_MOUSEHWHEEL = 0x20E; - [StructLayout(LayoutKind.Sequential)] - internal struct Win32Point - { - public Int32 X; - public Int32 Y; - }; - internal static Point GetMousePosition() - { - Win32Point w32Mouse = new Win32Point(); - GetCursorPos(ref w32Mouse); - return new Point(w32Mouse.X, w32Mouse.Y); - } + [DllImport( "user32.dll" )] + [return: MarshalAs( UnmanagedType.Bool )] + internal static extern bool GetCursorPos( ref Win32Point pt ); - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool IsWindowVisible(IntPtr hWnd); - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool IsWindowEnabled(IntPtr hWnd); + [StructLayout( LayoutKind.Sequential )] + internal struct Win32Point + { + public Int32 X; + public Int32 Y; + }; + internal static Point GetMousePosition() + { + Win32Point w32Mouse = new Win32Point(); + GetCursorPos( ref w32Mouse ); + return new Point( w32Mouse.X, w32Mouse.Y ); + } - [DllImport("user32.dll")] - internal static extern IntPtr GetFocus(); - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool BringWindowToTop(IntPtr hWnd); + [DllImport( "user32.dll" )] + [return: MarshalAs( UnmanagedType.Bool )] + internal static extern bool IsWindowVisible( IntPtr hWnd ); + [DllImport( "user32.dll" )] + [return: MarshalAs( UnmanagedType.Bool )] + internal static extern bool IsWindowEnabled( IntPtr hWnd ); - [DllImport("user32.dll", SetLastError = true)] - internal static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); + [DllImport( "user32.dll" )] + internal static extern IntPtr GetFocus(); - [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] - internal static extern IntPtr GetParent(IntPtr hWnd); + [DllImport( "user32.dll" )] + [return: MarshalAs( UnmanagedType.Bool )] + internal static extern bool BringWindowToTop( IntPtr hWnd ); - /// - /// Changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window memory. - /// - /// A handle to the window and, indirectly, the class to which the window belongs.. - /// The zero-based offset to the value to be set. Valid values are in the range zero through the number of bytes of extra window memory, minus the size of an integer. To set any other value, specify one of the following values: GWL_EXSTYLE, GWL_HINSTANCE, GWL_ID, GWL_STYLE, GWL_USERDATA, GWL_WNDPROC - /// The replacement value. - /// If the function succeeds, the return value is the previous value of the specified 32-bit integer. - /// If the function fails, the return value is zero. To get extended error information, call GetLastError. - [DllImport("user32.dll")] - static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); + [DllImport( "user32.dll", SetLastError = true )] + internal static extern IntPtr SetParent( IntPtr hWndChild, IntPtr hWndNewParent ); - [DllImport("user32.dll", SetLastError = true)] - static extern int GetWindowLong(IntPtr hWnd, int nIndex); + [DllImport( "user32.dll", ExactSpelling = true, CharSet = CharSet.Auto )] + internal static extern IntPtr GetParent( IntPtr hWnd ); - public static void SetOwner(IntPtr childHandle, IntPtr ownerHandle) - { - SetWindowLong( - childHandle, - -8, // GWL_HWNDPARENT - ownerHandle.ToInt32()); - } + /// + /// Changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window memory. + /// + /// A handle to the window and, indirectly, the class to which the window belongs.. + /// The zero-based offset to the value to be set. Valid values are in the range zero through the number of bytes of extra window memory, minus the size of an integer. To set any other value, specify one of the following values: GWL_EXSTYLE, GWL_HINSTANCE, GWL_ID, GWL_STYLE, GWL_USERDATA, GWL_WNDPROC + /// The replacement value. + /// If the function succeeds, the return value is the previous value of the specified 32-bit integer. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + [DllImport( "user32.dll" )] + static extern int SetWindowLong( IntPtr hWnd, int nIndex, int dwNewLong ); - public static IntPtr GetOwner(IntPtr childHandle) - { - return new IntPtr(GetWindowLong(childHandle, -8)); - } + [DllImport( "user32.dll", SetLastError = true )] + static extern int GetWindowLong( IntPtr hWnd, int nIndex ); + public static void SetOwner( IntPtr childHandle, IntPtr ownerHandle ) + { + SetWindowLong( + childHandle, + -8, // GWL_HWNDPARENT + ownerHandle.ToInt32() ); + } - //Monitor Patch #13440 - - /// - /// The MonitorFromRect function retrieves a handle to the display monitor that - /// has the largest area of intersection with a specified rectangle. - /// - /// Pointer to a RECT structure that specifies the rectangle of interest in - /// virtual-screen coordinates - /// Determines the function's return value if the rectangle does not intersect - /// any display monitor - /// - /// If the rectangle intersects one or more display monitor rectangles, the return value - /// is an HMONITOR handle to the display monitor that has the largest area of intersection with the rectangle. - /// If the rectangle does not intersect a display monitor, the return value depends on the value of dwFlags. - /// - [DllImport("user32.dll")] - public static extern IntPtr MonitorFromRect([In] ref RECT lprc, uint dwFlags); - - /// - /// The MonitorFromWindow function retrieves a handle to the display monitor that has the largest area of intersection with the bounding rectangle of a specified window. - /// - /// A handle to the window of interest. - /// Determines the function's return value if the window does not intersect any display monitor. - /// If the window intersects one or more display monitor rectangles, the return value is an HMONITOR handle to the display monitor that has the largest area of intersection with the window. - /// If the window does not intersect a display monitor, the return value depends on the value of dwFlags. - /// - [DllImport("user32.dll")] - public static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags); - - - /// - /// The MONITORINFO structure contains information about a display monitor. - /// - [StructLayout(LayoutKind.Sequential)] - public class MonitorInfo - { - /// - /// The size of the structure, in bytes. - /// - public int Size = Marshal.SizeOf(typeof(MonitorInfo)); - /// - /// A RECT structure that specifies the display monitor rectangle, expressed - /// in virtual-screen coordinates. - /// Note that if the monitor is not the primary display monitor, - /// some of the rectangle's coordinates may be negative values. - /// - public RECT Monitor; - /// - /// A RECT structure that specifies the work area rectangle of the display monitor, - /// expressed in virtual-screen coordinates. Note that if the monitor is not the primary - /// display monitor, some of the rectangle's coordinates may be negative values. - /// - public RECT Work; - /// - /// A set of flags that represent attributes of the display monitor. - /// - public uint Flags; - } + public static IntPtr GetOwner( IntPtr childHandle ) + { + return new IntPtr( GetWindowLong( childHandle, -8 ) ); + } - /// - /// The GetMonitorInfo function retrieves information about a display monitor. - /// - /// Handle to the display monitor of interest. - /// Pointer to a MONITORINFO or MONITORINFOEX structure that receives - /// information about the specified display monitor - /// If the function succeeds, the return value is nonzero. - /// If the function fails, the return value is zero. - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool GetMonitorInfo(IntPtr hMonitor, [In, Out] MonitorInfo lpmi); + //Monitor Patch #13440 + + /// + /// The MonitorFromRect function retrieves a handle to the display monitor that + /// has the largest area of intersection with a specified rectangle. + /// + /// Pointer to a RECT structure that specifies the rectangle of interest in + /// virtual-screen coordinates + /// Determines the function's return value if the rectangle does not intersect + /// any display monitor + /// + /// If the rectangle intersects one or more display monitor rectangles, the return value + /// is an HMONITOR handle to the display monitor that has the largest area of intersection with the rectangle. + /// If the rectangle does not intersect a display monitor, the return value depends on the value of dwFlags. + /// + [DllImport( "user32.dll" )] + public static extern IntPtr MonitorFromRect( [In] ref RECT lprc, uint dwFlags ); + + /// + /// The MonitorFromWindow function retrieves a handle to the display monitor that has the largest area of intersection with the bounding rectangle of a specified window. + /// + /// A handle to the window of interest. + /// Determines the function's return value if the window does not intersect any display monitor. + /// If the window intersects one or more display monitor rectangles, the return value is an HMONITOR handle to the display monitor that has the largest area of intersection with the window. + /// If the window does not intersect a display monitor, the return value depends on the value of dwFlags. + /// + [DllImport( "user32.dll" )] + public static extern IntPtr MonitorFromWindow( IntPtr hwnd, uint dwFlags ); + + + /// + /// The MONITORINFO structure contains information about a display monitor. + /// + [StructLayout( LayoutKind.Sequential )] + public class MonitorInfo + { + /// + /// The size of the structure, in bytes. + /// + public int Size = Marshal.SizeOf( typeof( MonitorInfo ) ); + /// + /// A RECT structure that specifies the display monitor rectangle, expressed + /// in virtual-screen coordinates. + /// Note that if the monitor is not the primary display monitor, + /// some of the rectangle's coordinates may be negative values. + /// + public RECT Monitor; + /// + /// A RECT structure that specifies the work area rectangle of the display monitor, + /// expressed in virtual-screen coordinates. Note that if the monitor is not the primary + /// display monitor, some of the rectangle's coordinates may be negative values. + /// + public RECT Work; + /// + /// A set of flags that represent attributes of the display monitor. + /// + public uint Flags; } + + /// + /// The GetMonitorInfo function retrieves information about a display monitor. + /// + /// Handle to the display monitor of interest. + /// Pointer to a MONITORINFO or MONITORINFOEX structure that receives + /// information about the specified display monitor + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. + [DllImport( "user32.dll" )] + [return: MarshalAs( UnmanagedType.Bool )] + public static extern bool GetMonitorInfo( IntPtr hMonitor, [In, Out] MonitorInfo lpmi ); + + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/WindowHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/WindowHelper.cs index 91bb2d74..efd95082 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/WindowHelper.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/WindowHelper.cs @@ -15,66 +15,63 @@ ***********************************************************************************/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Media; using System.Windows; using System.Windows.Interop; namespace Xceed.Wpf.AvalonDock { - static class WindowHelper + static class WindowHelper + { + public static bool IsAttachedToPresentationSource( this Visual element ) { - public static bool IsAttachedToPresentationSource(this Visual element) - { - return PresentationSource.FromVisual(element as Visual) != null; - } + return PresentationSource.FromVisual( element as Visual ) != null; + } - public static void SetParentToMainWindowOf(this Window window, Visual element) - { - var wndParent = Window.GetWindow(element); - if (wndParent != null) - window.Owner = wndParent; - else - { - IntPtr parentHwnd; - if (GetParentWindowHandle(element, out parentHwnd)) - Win32Helper.SetOwner(new WindowInteropHelper(window).Handle, parentHwnd); - } - } + public static void SetParentToMainWindowOf( this Window window, Visual element ) + { + var wndParent = Window.GetWindow( element ); + if( wndParent != null ) + window.Owner = wndParent; + else + { + IntPtr parentHwnd; + if( GetParentWindowHandle( element, out parentHwnd ) ) + Win32Helper.SetOwner( new WindowInteropHelper( window ).Handle, parentHwnd ); + } + } - public static IntPtr GetParentWindowHandle(this Window window) - { - if (window.Owner != null) - return new WindowInteropHelper(window.Owner).Handle; - else - return Win32Helper.GetOwner(new WindowInteropHelper(window).Handle); - } + public static IntPtr GetParentWindowHandle( this Window window ) + { + if( window.Owner != null ) + return new WindowInteropHelper( window.Owner ).Handle; + else + return Win32Helper.GetOwner( new WindowInteropHelper( window ).Handle ); + } - public static bool GetParentWindowHandle(this Visual element, out IntPtr hwnd) - { - hwnd = IntPtr.Zero; - HwndSource wpfHandle = PresentationSource.FromVisual(element) as HwndSource; + public static bool GetParentWindowHandle( this Visual element, out IntPtr hwnd ) + { + hwnd = IntPtr.Zero; + HwndSource wpfHandle = PresentationSource.FromVisual( element ) as HwndSource; - if (wpfHandle == null) - return false; + if( wpfHandle == null ) + return false; - hwnd = Win32Helper.GetParent(wpfHandle.Handle); - if (hwnd == IntPtr.Zero) - hwnd = wpfHandle.Handle; - return true; - } + hwnd = Win32Helper.GetParent( wpfHandle.Handle ); + if( hwnd == IntPtr.Zero ) + hwnd = wpfHandle.Handle; + return true; + } - public static void SetParentWindowToNull(this Window window) - { - if (window.Owner != null) - window.Owner = null; - else - { - Win32Helper.SetOwner(new WindowInteropHelper(window).Handle, IntPtr.Zero); - } - } + public static void SetParentWindowToNull( this Window window ) + { + if( window.Owner != null ) + window.Owner = null; + else + { + Win32Helper.SetOwner( new WindowInteropHelper( window ).Handle, IntPtr.Zero ); + } } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Xceed.Wpf.AvalonDock.csproj b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Xceed.Wpf.AvalonDock.csproj index 2f447660..3e1a745a 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Xceed.Wpf.AvalonDock.csproj +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Xceed.Wpf.AvalonDock.csproj @@ -351,7 +351,12 @@ MSBuild:Compile - + + + {72e591d6-8f83-4d8c-8f67-9c325e623234} + Xceed.Wpf.Toolkit + + + + + - + diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit.LiveExplorer/CodeFiles/AvalonDockView.xaml.cs.txt b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit.LiveExplorer/CodeFiles/AvalonDockView.xaml.cs.txt index 73380b92..1df33371 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit.LiveExplorer/CodeFiles/AvalonDockView.xaml.cs.txt +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit.LiveExplorer/CodeFiles/AvalonDockView.xaml.cs.txt @@ -14,11 +14,9 @@ ************************************************************************************/ -using System; -using System.Windows.Controls; -using Xceed.Wpf.Toolkit; -using System.Windows.Media; using System.Windows; +using Xceed.Wpf.AvalonDock.Layout.Serialization; +using System.IO; namespace Xceed.Wpf.Toolkit.LiveExplorer.Samples.AvalonDock.Views { @@ -31,5 +29,23 @@ namespace Xceed.Wpf.Toolkit.LiveExplorer.Samples.AvalonDock.Views { InitializeComponent(); } + + private void SaveButton_Click( object sender, RoutedEventArgs e ) + { + using( var writer = new StreamWriter( "AvalonDockSavedFile.txt" ) ) + { + var layoutSerializer = new XmlLayoutSerializer( _dockingManager ); + layoutSerializer.Serialize( writer ); + } + } + + private void LoadButton_Click( object sender, RoutedEventArgs e ) + { + using( var reader = new StreamReader( "AvalonDockSavedFile.txt" ) ) + { + var layoutSerializer = new XmlLayoutSerializer( _dockingManager ); + layoutSerializer.Deserialize( reader ); + } + } } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit.LiveExplorer/CodeFiles/AvalonDockView.xaml.txt b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit.LiveExplorer/CodeFiles/AvalonDockView.xaml.txt index 67420a70..f17aa84b 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit.LiveExplorer/CodeFiles/AvalonDockView.xaml.txt +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit.LiveExplorer/CodeFiles/AvalonDockView.xaml.txt @@ -39,116 +39,130 @@ Text="Usage:" Style="{StaticResource Header}" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -