Skip to content

Commit e7046fe

Browse files
authored
Merge pull request #88 from rdipardo/fix/BdR76-issue-83
Remove `WS_EX_CONTROLPARENT` when the panel undocks
2 parents eb8c45c + 175a187 commit e7046fe

File tree

5 files changed

+173
-1
lines changed

5 files changed

+173
-1
lines changed

CSVLintNppPlugin/CsvLintNppPlugin.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@
140140
<Compile Include="Forms\CsvLintWindow.Designer.cs">
141141
<DependentUpon>CsvLintWindow.cs</DependentUpon>
142142
</Compile>
143+
<Compile Include="Forms\DockingFormBase.cs">
144+
<SubType>Form</SubType>
145+
</Compile>
146+
<Compile Include="Forms\DockingFormBase.Designer.cs">
147+
<DependentUpon>DockingFormBase.cs</DependentUpon>
148+
</Compile>
143149
<Compile Include="PluginInfrastructure\ScintillaStreams.cs" />
144150
<Compile Include="PluginInfrastructure\Win32.cs" />
145151
<Compile Include="Main.cs" />

CSVLintNppPlugin/Forms/CsvLintWindow.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace Kbg.NppPluginNET
1111
{
12-
public partial class CsvLintWindow : Form
12+
public partial class CsvLintWindow : DockingFormBase
1313
{
1414
public CsvLintWindow()
1515
{

CSVLintNppPlugin/Forms/DockingFormBase.Designer.cs

Lines changed: 37 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
using System.Windows.Forms;
4+
using Kbg.NppPluginNET.PluginInfrastructure;
5+
6+
namespace CSVLintNppPlugin.Forms
7+
{
8+
public partial class DockingFormBase : Form
9+
{
10+
private static Win32.WindowLongGetter _wndLongGetter;
11+
private static Win32.WindowLongSetter _wndLongSetter;
12+
13+
public DockingFormBase()
14+
{
15+
InitializeComponent();
16+
if (Marshal.SizeOf(typeof(IntPtr)) == 8) // we are 64-bit
17+
{
18+
_wndLongGetter = Win32.GetWindowLongPtr;
19+
_wndLongSetter = Win32.SetWindowLongPtr;
20+
}
21+
else // we are 32-bit
22+
{
23+
_wndLongGetter = Win32.GetWindowLong;
24+
_wndLongSetter = Win32.SetWindowLong;
25+
}
26+
}
27+
28+
protected override void WndProc(ref Message m)
29+
{
30+
switch (m.Msg)
31+
{
32+
case Win32.WM_NOTIFY:
33+
var nmdr = (Win32.TagNMHDR)Marshal.PtrToStructure(m.LParam, typeof(Win32.TagNMHDR));
34+
if (nmdr.hwndFrom == PluginBase.nppData._nppHandle)
35+
{
36+
switch ((DockMgrMsg)(nmdr.code & 0xFFFFU))
37+
{
38+
case DockMgrMsg.DMN_DOCK: // we are being docked
39+
break;
40+
case DockMgrMsg.DMN_FLOAT: // we are being _un_docked
41+
RemoveControlParent(this);
42+
break;
43+
case DockMgrMsg.DMN_CLOSE: // we are being closed
44+
break;
45+
}
46+
}
47+
break;
48+
}
49+
base.WndProc(ref m);
50+
}
51+
52+
private void RemoveControlParent(Control parent)
53+
{
54+
if (parent.HasChildren)
55+
{
56+
long extAttrs = (long)_wndLongGetter(parent.Handle, Win32.GWL_EXSTYLE);
57+
if (Win32.WS_EX_CONTROLPARENT == (extAttrs & Win32.WS_EX_CONTROLPARENT))
58+
{
59+
_wndLongSetter(parent.Handle, Win32.GWL_EXSTYLE, new IntPtr(extAttrs & ~Win32.WS_EX_CONTROLPARENT));
60+
}
61+
foreach (Control c in parent.Controls)
62+
{
63+
RemoveControlParent(c);
64+
}
65+
}
66+
}
67+
}
68+
}

CSVLintNppPlugin/PluginInfrastructure/Win32.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ public struct ScrollInfo
4848
public int nTrackPos;
4949
}
5050

51+
/// <summary>
52+
/// @see https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-nmhdr
53+
/// </summary>
54+
[StructLayout(LayoutKind.Sequential)]
55+
public struct TagNMHDR
56+
{
57+
public IntPtr hwndFrom;
58+
public UIntPtr idFrom;
59+
public uint code;
60+
}
61+
5162
/// <summary>
5263
/// Used for the ScrollInfo fMask
5364
/// SIF_ALL => Combination of SIF_PAGE, SIF_POS, SIF_RANGE, and SIF_TRACKPOS.
@@ -302,6 +313,56 @@ public static IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, ref LangType
302313
public static extern int CheckMenuItem(IntPtr hmenu, int uIDCheckItem, int uCheck);
303314

304315
public const int WM_CREATE = 1;
316+
public const int WM_NOTIFY = 0x004e;
317+
public const int GWL_EXSTYLE = -20;
318+
public const int GWLP_HINSTANCE = -6;
319+
public const int GWLP_HWNDPARENT = -8;
320+
public const int GWLP_ID = -12;
321+
public const int GWL_STYLE = -16;
322+
public const int GWLP_USERDATA = -21;
323+
public const int GWLP_WNDPROC = -4;
324+
public const long WS_EX_ACCEPTFILES = 0x00000010L;
325+
public const long WS_EX_APPWINDOW = 0x00040000L;
326+
public const long WS_EX_CLIENTEDGE = 0x00000200L;
327+
public const long WS_EX_COMPOSITED = 0x02000000L;
328+
public const long WS_EX_CONTEXTHELP = 0x00000400L;
329+
public const long WS_EX_CONTROLPARENT = 0x00010000L;
330+
public const long WS_EX_DLGMODALFRAME = 0x00000001L;
331+
public const long WS_EX_LAYERED = 0x00080000L;
332+
public const long WS_EX_LAYOUTRTL = 0x00400000L;
333+
public const long WS_EX_LEFT = 0x00000000L;
334+
public const long WS_EX_LEFTSCROLLBAR = 0x00004000L;
335+
public const long WS_EX_LTRREADING = 0x00000000L;
336+
public const long WS_EX_MDICHILD = 0x00000040L;
337+
public const long WS_EX_NOACTIVATE = 0x08000000L;
338+
public const long WS_EX_NOINHERITLAYOUT = 0x00100000L;
339+
public const long WS_EX_NOPARENTNOTIFY = 0x00000004L;
340+
public const long WS_EX_NOREDIRECTIONBITMAP = 0x00200000L;
341+
public const long WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE);
342+
public const long WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST);
343+
public const long WS_EX_RIGHT = 0x00001000L;
344+
public const long WS_EX_RIGHTSCROLLBAR = 0x00000000L;
345+
public const long WS_EX_RTLREADING = 0x00002000L;
346+
public const long WS_EX_STATICEDGE = 0x00020000L;
347+
public const long WS_EX_TOOLWINDOW = 0x00000080L;
348+
public const long WS_EX_TOPMOST = 0x00000008L;
349+
public const long WS_EX_TRANSPARENT = 0x00000020L;
350+
public const long WS_EX_WINDOWEDGE = 0x00000100L;
351+
352+
public delegate IntPtr WindowLongGetter(IntPtr hWnd, int nIndex);
353+
public delegate IntPtr WindowLongSetter(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
354+
355+
[DllImport("user32")]
356+
public static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
357+
358+
[DllImport("user32")]
359+
public static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);
360+
361+
[DllImport("user32")]
362+
public static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
363+
364+
[DllImport("user32")]
365+
public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
305366

306367
[DllImport("user32")]
307368
public static extern bool ClientToScreen(IntPtr hWnd, ref Point lpPoint);

0 commit comments

Comments
 (0)