Skip to content

Commit 18d5a59

Browse files
committed
Improved support for themes in the main window
1 parent 691e8bc commit 18d5a59

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+995
-573
lines changed

LICENSE

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
2-
31
The MIT License (MIT)
42

5-
Copyright (c) <year> <copyright holders>
3+
Copyright (c) 2020 couchcoding
64

75
Permission is hereby granted, free of charge, to any person obtaining a copy
86
of this software and associated documentation files (the "Software"), to deal

src/Couchcoding.Logbert.Gui/Controls/DataGridViewEx.cs

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,22 @@
2828

2929
#endregion
3030

31+
using Couchcoding.Logbert.Gui.Helper;
32+
using Couchcoding.Logbert.Gui.Interop;
33+
using Couchcoding.Logbert.Theme.Helper;
34+
using Couchcoding.Logbert.Theme.Interfaces;
35+
using Couchcoding.Logbert.Theme.Themes;
36+
using System;
37+
using System.Drawing;
38+
using System.Runtime.InteropServices;
3139
using System.Windows.Forms;
3240

3341
namespace Couchcoding.Logbert.Gui.Controls
3442
{
3543
/// <summary>
3644
/// Implements a double buffered <see cref="DataGridView"/> <see cref="Control"/>.
3745
/// </summary>
38-
public class DataGridViewEx : DataGridView
46+
public class DataGridViewEx : DataGridView, IThemable
3947
{
4048
#region Constructor
4149

@@ -49,5 +57,59 @@ public DataGridViewEx()
4957
}
5058

5159
#endregion
60+
61+
/// <summary>
62+
/// Creates the window handle of the <see cref="TreeViewEx"/> <see cref="Control"/>.
63+
/// </summary>
64+
protected override void CreateHandle()
65+
{
66+
base.CreateHandle();
67+
68+
foreach (Control ctrl in Controls)
69+
{
70+
if (ctrl is ScrollBar)
71+
72+
Win32.SetWindowTheme(Handle, "Explorer", null);
73+
}
74+
}
75+
76+
protected override void OnPaint(PaintEventArgs e)
77+
{
78+
base.OnPaint(e);
79+
80+
if (ClientRectangle.Width > 0 && ClientRectangle.Height > 0)
81+
{
82+
var spaceLeft = VerticalScrollBar.Visible
83+
? SystemInformation.VerticalScrollBarWidth
84+
: 0;
85+
86+
var spaceBottom = HorizontalScrollBar.Visible
87+
? SystemInformation.HorizontalScrollBarHeight
88+
: 0;
89+
90+
e.Graphics.FillRectangle(GdiCache.GetBrushFromColor(Theme.ThemeManager.CurrentApplicationTheme.ColorPalette.ContentBackground), new Rectangle(
91+
ClientRectangle.Width - spaceLeft,
92+
ClientRectangle.Height - spaceBottom,
93+
SystemInformation.VerticalScrollBarWidth,
94+
SystemInformation.HorizontalScrollBarHeight));
95+
}
96+
}
97+
98+
/// <summary>
99+
/// Applies the current theme to the <see cref="Control"/>.
100+
/// </summary>
101+
/// <param name="theme">The <see cref="BaseTheme"/> instance to apply.</param>
102+
public void ApplyTheme(BaseTheme theme)
103+
{
104+
BackColor = theme.ColorPalette.ContentBackground;
105+
106+
foreach (Control ctrl in Controls)
107+
{
108+
if (ctrl is ScrollBar && OSHelper.IsWinVista && !string.IsNullOrEmpty(theme.WindowThemeName))
109+
{
110+
Win32.SetWindowTheme(ctrl.Handle, theme.WindowThemeName, null);
111+
}
112+
}
113+
}
52114
}
53115
}

src/Couchcoding.Logbert.Gui/Controls/ListViewEx.cs

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
#endregion
3030

31+
using Couchcoding.Logbert.Gui.Helper;
32+
using Couchcoding.Logbert.Gui.Interop;
3133
using System;
3234
using System.Runtime.InteropServices;
3335
using System.Windows.Forms;
@@ -48,48 +50,18 @@ public class ListViewEx : ListView
4850

4951
#endregion
5052

51-
#region Interop Methods
52-
53-
/// <summary>
54-
/// Causes a window to use a different set of visual style information than its class normally uses.
55-
/// </summary>
56-
/// <param name="hWnd">Handle to the window whose visual style information is to be changed.</param>
57-
/// <param name="pszSubAppName">Pointer to a string that contains the application name to use in place of the calling application's name.</param>
58-
/// <param name="pszSubIdList">Pointer to a string that contains a semicolon-separated list of CLSID names to use in place of the actual list passed by the window's class.</param>
59-
/// <returns>If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
60-
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
61-
private extern static int SetWindowTheme(IntPtr hWnd, string pszSubAppName, string pszSubIdList);
62-
63-
#endregion
64-
65-
#region Private Properties
66-
67-
/// <summary>
68-
/// Indicates whether we're running on window vista or higher, or not.
69-
/// </summary>
70-
public static bool IsWinVista
71-
{
72-
get
73-
{
74-
OperatingSystem os = Environment.OSVersion;
75-
return (os.Platform == PlatformID.Win32NT) && (os.Version.Major >= 6);
76-
}
77-
}
78-
79-
#endregion
80-
8153
#region Private Methods
8254

8355
/// <summary>
84-
/// Creates the window handle of the <see cref="TreeViewEx"/> <see cref="Control"/>.
56+
/// Creates the window handle of the <see cref="ListViewEx"/> <see cref="Control"/>.
8557
/// </summary>
8658
protected override void CreateHandle()
8759
{
8860
base.CreateHandle();
8961

90-
if (IsWinVista)
62+
if (OSHelper.IsWinVista)
9163
{
92-
SetWindowTheme(Handle, "explorer", null);
64+
Win32.SetWindowTheme(Handle, "Explorer", null);
9365
}
9466
}
9567

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#region Copyright © 2015 Couchcoding
2+
3+
// File: TableLayoutPanelEx.cs
4+
// Package: Logbert
5+
// Project: Logbert
6+
//
7+
// The MIT License (MIT)
8+
//
9+
// Copyright (c) 2020 Couchcoding
10+
//
11+
// Permission is hereby granted, free of charge, to any person obtaining a copy
12+
// of this software and associated documentation files (the "Software"), to deal
13+
// in the Software without restriction, including without limitation the rights
14+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15+
// copies of the Software, and to permit persons to whom the Software is
16+
// furnished to do so, subject to the following conditions:
17+
//
18+
// The above copyright notice and this permission notice shall be included in
19+
// all copies or substantial portions of the Software.
20+
//
21+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27+
// THE SOFTWARE.
28+
29+
#endregion
30+
31+
using Couchcoding.Logbert.Gui.Interop;
32+
using System;
33+
using System.Windows.Forms;
34+
35+
namespace Couchcoding.Logbert.Gui.Controls
36+
{
37+
public class TableLayoutPanelEx : TableLayoutPanel
38+
{
39+
#region Public Properties
40+
41+
/// <summary>
42+
/// Gets the required creation parameters when the control handle is created.
43+
/// </summary>
44+
protected override CreateParams CreateParams
45+
{
46+
get
47+
{
48+
CreateParams cp = base.CreateParams;
49+
cp.ExStyle |= Win32.WS_EX_COMPOSITED;
50+
return cp;
51+
}
52+
}
53+
54+
#endregion
55+
56+
#region Private Methods
57+
58+
/// <summary>
59+
/// Raises the CreateControl() method.
60+
/// </summary>
61+
protected override void OnCreateControl()
62+
{
63+
base.OnCreateControl();
64+
65+
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
66+
SetStyle(ControlStyles.CacheText, true);
67+
}
68+
69+
#endregion
70+
71+
#region Public Methods
72+
73+
/// <summary>
74+
/// Disables any redrawing of the <see cref="Control"/>.
75+
/// </summary>
76+
public void BeginUpdate()
77+
{
78+
if (IsHandleCreated)
79+
{
80+
Win32.SendMessage(Handle, Win32.WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero);
81+
}
82+
}
83+
84+
/// <summary>
85+
/// Enables any redrawing of the <see cref="Control"/>.
86+
/// </summary>
87+
public void EndUpdate()
88+
{
89+
if (IsHandleCreated)
90+
{
91+
Win32.SendMessage(Handle, Win32.WM_SETREDRAW, new IntPtr(1), IntPtr.Zero);
92+
93+
Parent?.Invalidate(true);
94+
}
95+
}
96+
97+
#endregion
98+
}
99+
}

src/Couchcoding.Logbert.Gui/Controls/TreeViewEx.cs

Lines changed: 8 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
#endregion
3030

31+
using Couchcoding.Logbert.Gui.Helper;
32+
using Couchcoding.Logbert.Gui.Interop;
3133
using System;
3234
using System.Drawing;
3335
using System.Runtime.InteropServices;
@@ -74,47 +76,6 @@ public class TreeViewEx : TreeView
7476

7577
#endregion
7678

77-
#region Interop Methods
78-
79-
/// <summary>
80-
/// Causes a window to use a different set of visual style information than its class normally uses.
81-
/// </summary>
82-
/// <param name="hWnd">Handle to the window whose visual style information is to be changed.</param>
83-
/// <param name="pszSubAppName">Pointer to a string that contains the application name to use in place of the calling application's name.</param>
84-
/// <param name="pszSubIdList">Pointer to a string that contains a semicolon-separated list of CLSID names to use in place of the actual list passed by the window's class.</param>
85-
/// <returns>If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
86-
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
87-
private extern static int SetWindowTheme(IntPtr hWnd, string pszSubAppName, string pszSubIdList);
88-
89-
/// <summary>
90-
/// Sends the specified message to a window or windows.
91-
/// </summary>
92-
/// <param name="hWnd">A handle to the window whose window procedure will receive the message.</param>
93-
/// <param name="msg">The message to be sent.</param>
94-
/// <param name="wParam">Additional message-specific information.</param>
95-
/// <param name="lParam">Additional message-specific information.</param>
96-
/// <returns>The return value specifies the result of the message processing; it depends on the message sent.</returns>
97-
[DllImport("user32.dll")]
98-
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
99-
100-
#endregion
101-
102-
#region Private Properties
103-
104-
/// <summary>
105-
/// Indicates whether we're running on window vista or higher, or not.
106-
/// </summary>
107-
private static bool IsWinVista
108-
{
109-
get
110-
{
111-
OperatingSystem os = Environment.OSVersion;
112-
return (os.Platform == PlatformID.Win32NT) && (os.Version.Major >= 6);
113-
}
114-
}
115-
116-
#endregion
117-
11879
#region Private Fields
11980

12081
/// <summary>
@@ -128,7 +89,7 @@ private void UpdateExtendedStyles()
12889

12990
if (style != 0 && IsHandleCreated)
13091
{
131-
SendMessage(
92+
Win32.SendMessage(
13293
Handle
13394
, TVM_SETEXTENDEDSTYLE
13495
, (IntPtr)TVS_EX_DOUBLEBUFFER
@@ -150,9 +111,9 @@ protected override void OnHandleCreated(EventArgs e)
150111

151112
UpdateExtendedStyles();
152113

153-
if (!IsWinVista)
114+
if (!OSHelper.IsWinVista)
154115
{
155-
SendMessage(
116+
Win32.SendMessage(
156117
Handle
157118
, TVM_SETBKCOLOR
158119
, IntPtr.Zero
@@ -196,14 +157,14 @@ public void UseNativeSystemRendering(bool value)
196157
return;
197158
}
198159

199-
if (IsWinVista && value)
160+
if (OSHelper.IsWinVista && value)
200161
{
201162
if (!IsHandleCreated)
202163
{
203164
CreateHandle();
204165
}
205166

206-
SetWindowTheme(Handle, "explorer", null);
167+
//Win32.SetWindowTheme(Handle, "Explorer", null);
207168
}
208169
}
209170

@@ -221,7 +182,7 @@ public TreeViewEx()
221182
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
222183

223184
// Disable default CommCtrl painting on non-Vista systems
224-
if (!IsWinVista)
185+
if (!OSHelper.IsWinVista)
225186
{
226187
SetStyle(ControlStyles.UserPaint, true);
227188
}

src/Couchcoding.Logbert.Gui/Couchcoding.Logbert.Gui.csproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@
8888
<Compile Include="Controls\PictureBoxEx.cs">
8989
<SubType>Component</SubType>
9090
</Compile>
91+
<Compile Include="Controls\TableLayoutPanelEx.cs">
92+
<SubType>Component</SubType>
93+
</Compile>
9194
<Compile Include="Controls\TextBoxEx.cs">
9295
<SubType>Component</SubType>
9396
</Compile>
@@ -101,12 +104,19 @@
101104
<SubType>Form</SubType>
102105
</Compile>
103106
<Compile Include="Helper\DpiHelper.cs" />
107+
<Compile Include="Helper\OSHelper.cs" />
104108
<Compile Include="Interop\Win32.cs" />
105109
<Compile Include="Properties\AssemblyInfo.cs" />
106110
</ItemGroup>
107111
<ItemGroup>
108112
<None Include=".editorconfig" />
109113
</ItemGroup>
114+
<ItemGroup>
115+
<ProjectReference Include="..\Couchcoding.Logbert.Theme\Couchcoding.Logbert.Theme.csproj">
116+
<Project>{de30d0ed-e29f-4779-a057-c7c1f1ef4f59}</Project>
117+
<Name>Couchcoding.Logbert.Theme</Name>
118+
</ProjectReference>
119+
</ItemGroup>
110120
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
111121
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
112122
Other similar extension points exist, see Microsoft.Common.targets.

0 commit comments

Comments
 (0)