Xamarin Public Jenkins 6992685b86 Imported Upstream version 4.2.0.179
Former-commit-id: 0a113cb3a6feb7873f632839b1307cc6033cd595
2015-11-10 14:54:39 +00:00

452 lines
17 KiB
C#

//
// VisualStylesNative.cs: IVisualStyles that uses the Visual Styles feature of
// Windows XP and later.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (c) 2006 Novell, Inc.
//
// Authors:
// Jonathan Pobst (monkey@jpobst.com)
//
using System.Drawing;
using System.Diagnostics;
namespace System.Windows.Forms.VisualStyles
{
class VisualStylesNative : IVisualStyles
{
#region UxTheme
public int UxThemeCloseThemeData (IntPtr hTheme)
{
return UXTheme.CloseThemeData (hTheme);
}
public int UxThemeDrawThemeBackground (IntPtr hTheme, IDeviceContext dc, int iPartId, int iStateId, Rectangle bounds)
{
XplatUIWin32.RECT BoundsRect = XplatUIWin32.RECT.FromRectangle (bounds);
int result = UXTheme.DrawThemeBackground(hTheme, dc.GetHdc (), iPartId, iStateId, ref BoundsRect, IntPtr.Zero);
dc.ReleaseHdc ();
return result;
}
public int UxThemeDrawThemeBackground (IntPtr hTheme, IDeviceContext dc, int iPartId, int iStateId, Rectangle bounds, Rectangle clipRectangle)
{
XplatUIWin32.RECT BoundsRect = XplatUIWin32.RECT.FromRectangle (bounds);
XplatUIWin32.RECT ClipRect = XplatUIWin32.RECT.FromRectangle (clipRectangle);
int result = UXTheme.DrawThemeBackground (hTheme, dc.GetHdc (), iPartId, iStateId, ref BoundsRect, ref ClipRect);
dc.ReleaseHdc ();
return result;
}
public int UxThemeDrawThemeEdge (IntPtr hTheme, IDeviceContext dc, int iPartId, int iStateId, Rectangle bounds, Edges edges, EdgeStyle style, EdgeEffects effects, out Rectangle result)
{
XplatUIWin32.RECT BoundsRect = XplatUIWin32.RECT.FromRectangle (bounds);
XplatUIWin32.RECT retval;
int hresult = UXTheme.DrawThemeEdge (hTheme, dc.GetHdc (), iPartId, iStateId, ref BoundsRect, (uint)style, (uint)edges + (uint)effects, out retval);
dc.ReleaseHdc ();
result = retval.ToRectangle();
return hresult;
}
public int UxThemeDrawThemeParentBackground (IDeviceContext dc, Rectangle bounds, Control childControl)
{
int result;
XplatUIWin32.RECT BoundsRect = XplatUIWin32.RECT.FromRectangle (bounds);
using (Graphics g = Graphics.FromHwnd (childControl.Handle)) {
IntPtr hdc = g.GetHdc ();
result = UXTheme.DrawThemeParentBackground (childControl.Handle, hdc, ref BoundsRect);
g.ReleaseHdc (hdc);
}
return result;
}
public int UxThemeDrawThemeText (IntPtr hTheme, IDeviceContext dc, int iPartId, int iStateId, string text, TextFormatFlags textFlags, Rectangle bounds)
{
XplatUIWin32.RECT BoundsRect = XplatUIWin32.RECT.FromRectangle (bounds);
int result = UXTheme.DrawThemeText (hTheme, dc.GetHdc (), iPartId, iStateId, text, text.Length, (uint)textFlags, 0, ref BoundsRect);
dc.ReleaseHdc ();
return result;
}
public int UxThemeGetThemeBackgroundContentRect (IntPtr hTheme, IDeviceContext dc, int iPartId, int iStateId, Rectangle bounds, out Rectangle result)
{
XplatUIWin32.RECT BoundsRect = XplatUIWin32.RECT.FromRectangle (bounds);
XplatUIWin32.RECT retval;
int hresult = UXTheme.GetThemeBackgroundContentRect (hTheme, dc.GetHdc (), iPartId, iStateId, ref BoundsRect, out retval);
dc.ReleaseHdc ();
result = retval.ToRectangle ();
return hresult;
}
public int UxThemeGetThemeBackgroundExtent (IntPtr hTheme, IDeviceContext dc, int iPartId, int iStateId, Rectangle contentBounds, out Rectangle result)
{
XplatUIWin32.RECT BoundsRect = XplatUIWin32.RECT.FromRectangle (contentBounds);
XplatUIWin32.RECT retval = new XplatUIWin32.RECT ();
int hresult = UXTheme.GetThemeBackgroundExtent (hTheme, dc.GetHdc (), iPartId, iStateId, ref BoundsRect, ref retval);
dc.ReleaseHdc ();
result = retval.ToRectangle ();
return hresult;
}
public int UxThemeGetThemeBackgroundRegion (IntPtr hTheme, IDeviceContext dc, int iPartId, int iStateId, Rectangle bounds, out Region result)
{
XplatUIWin32.RECT BoundsRect = XplatUIWin32.RECT.FromRectangle (bounds);
IntPtr retval;
int hresult = UXTheme.GetThemeBackgroundRegion (hTheme, dc.GetHdc (), iPartId, iStateId, ref BoundsRect, out retval);
dc.ReleaseHdc ();
result = Region.FromHrgn (retval);
return hresult;
}
public int UxThemeGetThemeBool (IntPtr hTheme, int iPartId, int iStateId, BooleanProperty prop, out bool result)
{
int retval;
int hresult = UXTheme.GetThemeBool (hTheme, iPartId, iStateId, (int)prop, out retval);
result = retval == 0 ? false : true;
return hresult;
}
public int UxThemeGetThemeColor (IntPtr hTheme, int iPartId, int iStateId, ColorProperty prop, out Color result)
{
int retval;
int hresult = UXTheme.GetThemeColor (hTheme, iPartId, iStateId, (int)prop, out retval);
result = System.Drawing.Color.FromArgb ((int)(0x000000FFU & retval),
(int)(0x0000FF00U & retval) >> 8, (int)(0x00FF0000U & retval) >> 16);
return hresult;
}
public int UxThemeGetThemeEnumValue (IntPtr hTheme, int iPartId, int iStateId, EnumProperty prop, out int result)
{
int retval;
int hresult = UXTheme.GetThemeEnumValue (hTheme, iPartId, iStateId, (int)prop, out retval);
result = retval;
return hresult;
}
public int UxThemeGetThemeFilename (IntPtr hTheme, int iPartId, int iStateId, FilenameProperty prop, out string result)
{
Text.StringBuilder sb = new Text.StringBuilder (255);
int hresult = UXTheme.GetThemeFilename (hTheme, iPartId, iStateId, (int)prop, sb, sb.Capacity);
result = sb.ToString ();
return hresult;
}
public int UxThemeGetThemeInt (IntPtr hTheme, int iPartId, int iStateId, IntegerProperty prop, out int result)
{
int retval;
int hresult = UXTheme.GetThemeInt (hTheme, iPartId, iStateId, (int)prop, out retval);
result = retval;
return hresult;
}
public int UxThemeGetThemeMargins (IntPtr hTheme, IDeviceContext dc, int iPartId, int iStateId, MarginProperty prop, out Padding result)
{
UXTheme.MARGINS retval = new UXTheme.MARGINS ();
XplatUIWin32.RECT BoundsRect;
int hresult = UXTheme.GetThemeMargins (hTheme, dc.GetHdc (), iPartId, iStateId, (int)prop, out BoundsRect, out retval);
dc.ReleaseHdc ();
result = retval.ToPadding();
return hresult;
}
public int UxThemeGetThemePartSize (IntPtr hTheme, IDeviceContext dc, int iPartId, int iStateId, Rectangle bounds, ThemeSizeType type, out Size result)
{
XplatUIWin32.RECT BoundsRect = XplatUIWin32.RECT.FromRectangle (bounds);
UXTheme.SIZE retval;
int hresult = UXTheme.GetThemePartSize (hTheme, dc.GetHdc (), iPartId, iStateId, ref BoundsRect, (int)type, out retval);
dc.ReleaseHdc ();
result = retval.ToSize();
return hresult;
}
public int UxThemeGetThemePartSize (IntPtr hTheme, IDeviceContext dc, int iPartId, int iStateId, ThemeSizeType type, out Size result)
{
UXTheme.SIZE retval;
int hresult = UXTheme.GetThemePartSize (hTheme, dc.GetHdc (), iPartId, iStateId, IntPtr.Zero, (int)type, out retval);
dc.ReleaseHdc ();
result = retval.ToSize ();
return hresult;
}
public int UxThemeGetThemePosition (IntPtr hTheme, int iPartId, int iStateId, PointProperty prop, out Point result)
{
POINT retval;
int hresult = UXTheme.GetThemePosition (hTheme, iPartId, iStateId, (int)prop, out retval);
result = retval.ToPoint();
return hresult;
}
public int UxThemeGetThemeString (IntPtr hTheme, int iPartId, int iStateId, StringProperty prop, out string result)
{
Text.StringBuilder sb = new Text.StringBuilder (255);
int hresult = UXTheme.GetThemeString (hTheme, iPartId, iStateId, (int)prop, sb, sb.Capacity);
result = sb.ToString ();
return hresult;
}
public int UxThemeGetThemeTextExtent (IntPtr hTheme, IDeviceContext dc, int iPartId, int iStateId, string textToDraw, TextFormatFlags flags, Rectangle bounds, out Rectangle result)
{
XplatUIWin32.RECT BoundsRect = XplatUIWin32.RECT.FromRectangle (bounds);
XplatUIWin32.RECT retval;
int hresult = UXTheme.GetThemeTextExtent (hTheme, dc.GetHdc (), iPartId, iStateId, textToDraw, textToDraw.Length, (int)flags, ref BoundsRect, out retval);
dc.ReleaseHdc ();
result = retval.ToRectangle ();
return hresult;
}
public int UxThemeGetThemeTextExtent (IntPtr hTheme, IDeviceContext dc, int iPartId, int iStateId, string textToDraw, TextFormatFlags flags, out Rectangle result)
{
XplatUIWin32.RECT retval;
int hresult = UXTheme.GetThemeTextExtent (hTheme, dc.GetHdc (), iPartId, iStateId, textToDraw, textToDraw.Length, (int)flags, 0, out retval);
dc.ReleaseHdc ();
result = retval.ToRectangle ();
return hresult;
}
public int UxThemeGetThemeTextMetrics (IntPtr hTheme, IDeviceContext dc, int iPartId, int iStateId, out TextMetrics result)
{
XplatUIWin32.TEXTMETRIC metrics;
int hresult = UXTheme.GetThemeTextMetrics (hTheme, dc.GetHdc (), iPartId, iStateId, out metrics);
dc.ReleaseHdc ();
TextMetrics retval = new TextMetrics ();
retval.Ascent = metrics.tmAscent;
retval.AverageCharWidth = metrics.tmAveCharWidth;
retval.BreakChar =(char)metrics.tmBreakChar;
retval.CharSet = (TextMetricsCharacterSet)metrics.tmCharSet;
retval.DefaultChar = (char)metrics.tmDefaultChar;
retval.Descent = metrics.tmDescent;
retval.DigitizedAspectX = metrics.tmDigitizedAspectX;
retval.DigitizedAspectY = metrics.tmDigitizedAspectY;
retval.ExternalLeading = metrics.tmExternalLeading;
retval.FirstChar = (char)metrics.tmFirstChar;
retval.Height = metrics.tmHeight;
retval.InternalLeading = metrics.tmInternalLeading;
retval.Italic = metrics.tmItalic == 0 ? false : true;
retval.LastChar = (char)metrics.tmLastChar;
retval.MaxCharWidth = metrics.tmMaxCharWidth;
retval.Overhang = metrics.tmOverhang;
retval.PitchAndFamily = (TextMetricsPitchAndFamilyValues)metrics.tmPitchAndFamily;
retval.StruckOut = metrics.tmStruckOut == 0 ? false : true;
retval.Underlined = metrics.tmUnderlined == 0 ? false : true;
retval.Weight = metrics.tmWeight;
result = retval;
return hresult;
}
public int UxThemeHitTestThemeBackground (IntPtr hTheme, IDeviceContext dc, int iPartId, int iStateId, HitTestOptions options, Rectangle backgroundRectangle, IntPtr hrgn, Point pt, out HitTestCode result)
{
XplatUIWin32.RECT BoundsRect = XplatUIWin32.RECT.FromRectangle (backgroundRectangle);
int retval;
int hresult = UXTheme.HitTestThemeBackground (hTheme, dc.GetHdc (), iPartId, iStateId, (uint)options, ref BoundsRect, hrgn, new POINT(pt.X, pt.Y), out retval);
dc.ReleaseHdc ();
result = (HitTestCode)retval;
return hresult;
}
public bool UxThemeIsAppThemed ()
{
return UXTheme.IsAppThemed ();
}
public bool UxThemeIsThemeActive ()
{
return UXTheme.IsThemeActive ();
}
public bool UxThemeIsThemePartDefined (IntPtr hTheme, int iPartId)
{
return UXTheme.IsThemePartDefined (hTheme, iPartId, 0);
}
public bool UxThemeIsThemeBackgroundPartiallyTransparent (IntPtr hTheme, int iPartId, int iStateId)
{
int retval = UXTheme.IsThemeBackgroundPartiallyTransparent (hTheme, iPartId, iStateId);
return retval == 0 ? false : true;
}
public IntPtr UxThemeOpenThemeData (IntPtr hWnd, string classList)
{
return UXTheme.OpenThemeData (hWnd, classList);
}
#endregion
#region VisualStyleInformation
public string VisualStyleInformationAuthor {
get {
return GetData ("AUTHOR");
}
}
public string VisualStyleInformationColorScheme {
get {
Text.StringBuilder ThemeName = new Text.StringBuilder (260);
Text.StringBuilder ColorName = new Text.StringBuilder (260);
Text.StringBuilder SizeName = new Text.StringBuilder (260);
UXTheme.GetCurrentThemeName (ThemeName, ThemeName.Capacity, ColorName, ColorName.Capacity, SizeName, SizeName.Capacity);
return ColorName.ToString ();
}
}
public string VisualStyleInformationCompany {
get {
return GetData ("COMPANY");
}
}
public Color VisualStyleInformationControlHighlightHot {
get {
IntPtr theme = UXTheme.OpenThemeData (IntPtr.Zero, "BUTTON");
uint retval = UXTheme.GetThemeSysColor (theme, 1621);
UXTheme.CloseThemeData (theme);
return System.Drawing.Color.FromArgb ((int)(0x000000FFU & retval),
(int)(0x0000FF00U & retval) >> 8, (int)(0x00FF0000U & retval) >> 16);
}
}
public string VisualStyleInformationCopyright {
get {
return GetData ("COPYRIGHT");
}
}
public string VisualStyleInformationDescription {
get {
return GetData ("DESCRIPTION");
}
}
public string VisualStyleInformationDisplayName {
get {
return GetData ("DISPLAYNAME");
}
}
public string VisualStyleInformationFileName {
get {
Text.StringBuilder ThemeName = new Text.StringBuilder (260);
Text.StringBuilder ColorName = new Text.StringBuilder (260);
Text.StringBuilder SizeName = new Text.StringBuilder (260);
UXTheme.GetCurrentThemeName (ThemeName, ThemeName.Capacity, ColorName, ColorName.Capacity, SizeName, SizeName.Capacity);
return ThemeName.ToString ();
}
}
static string GetData (string propertyName)
{
Text.StringBuilder ThemeName = new Text.StringBuilder (260);
Text.StringBuilder ColorName = new Text.StringBuilder (260);
Text.StringBuilder SizeName = new Text.StringBuilder (260);
UXTheme.GetCurrentThemeName (ThemeName, ThemeName.Capacity, ColorName, ColorName.Capacity, SizeName, SizeName.Capacity);
Text.StringBuilder PropertyValue = new Text.StringBuilder (260);
UXTheme.GetThemeDocumentationProperty (ThemeName.ToString(), propertyName, PropertyValue, PropertyValue.Capacity);
return PropertyValue.ToString ();
}
public bool VisualStyleInformationIsSupportedByOS {
get {
return IsSupported ();
}
}
public int VisualStyleInformationMinimumColorDepth {
get {
IntPtr theme = UXTheme.OpenThemeData (IntPtr.Zero, "BUTTON");
int retval;
UXTheme.GetThemeSysInt (theme, 1301, out retval);
UXTheme.CloseThemeData (theme);
return retval;
}
}
public static bool IsSupported ()
{
// Supported OS's should be NT based and at least XP (XP, 2003, Vista)
if ((Environment.OSVersion.Platform == PlatformID.Win32NT) && (Environment.OSVersion.Version >= new Version (5, 1)))
return true;
return false;
}
public string VisualStyleInformationSize {
get {
Text.StringBuilder ThemeName = new Text.StringBuilder (260);
Text.StringBuilder ColorName = new Text.StringBuilder (260);
Text.StringBuilder SizeName = new Text.StringBuilder (260);
UXTheme.GetCurrentThemeName (ThemeName, ThemeName.Capacity, ColorName, ColorName.Capacity, SizeName, SizeName.Capacity);
return SizeName.ToString ();
}
}
public bool VisualStyleInformationSupportsFlatMenus {
get {
IntPtr theme = UXTheme.OpenThemeData (IntPtr.Zero, "BUTTON");
bool retval;
retval = UXTheme.GetThemeSysBool (theme, 1001) == 0 ? false : true;
UXTheme.CloseThemeData (theme);
return retval;
}
}
public Color VisualStyleInformationTextControlBorder {
get {
IntPtr theme = UXTheme.OpenThemeData (IntPtr.Zero, "EDIT");
uint retval = UXTheme.GetThemeSysColor (theme, 1611);
UXTheme.CloseThemeData (theme);
return System.Drawing.Color.FromArgb ((int)(0x000000FFU & retval),
(int)(0x0000FF00U & retval) >> 8, (int)(0x00FF0000U & retval) >> 16);
}
}
public string VisualStyleInformationUrl {
get {
return GetData ("URL");
}
}
public string VisualStyleInformationVersion {
get {
return GetData ("VERSION");
}
}
#endregion
#region VisualStyleRenderer
public void VisualStyleRendererDrawBackgroundExcludingArea (IntPtr theme, IDeviceContext dc, int part, int state, Rectangle bounds, Rectangle excludedArea)
{
XplatUIWin32.RECT bounds_rect = XplatUIWin32.RECT.FromRectangle (bounds);
IntPtr hdc = dc.GetHdc ();
XplatUIWin32.Win32ExcludeClipRect (hdc, excludedArea.Left, excludedArea.Top, excludedArea.Right, excludedArea.Bottom);
UXTheme.DrawThemeBackground (theme, hdc, part, state, ref bounds_rect, IntPtr.Zero);
IntPtr hrgn = XplatUIWin32.Win32CreateRectRgn (excludedArea.Left, excludedArea.Top, excludedArea.Right, excludedArea.Bottom);
XplatUIWin32.Win32ExtSelectClipRgn (hdc, hrgn, (int)ClipCombineMode.RGN_OR);
XplatUIWin32.Win32DeleteObject (hrgn);
dc.ReleaseHdc ();
}
#endregion
}
}