Skip to content

Remove WS_EX_CONTROLPARENT when the panel undocks #88

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CSVLintNppPlugin/CsvLintNppPlugin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@
<Compile Include="Forms\CsvLintWindow.Designer.cs">
<DependentUpon>CsvLintWindow.cs</DependentUpon>
</Compile>
<Compile Include="Forms\DockingFormBase.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\DockingFormBase.Designer.cs">
<DependentUpon>DockingFormBase.cs</DependentUpon>
</Compile>
<Compile Include="PluginInfrastructure\ScintillaStreams.cs" />
<Compile Include="PluginInfrastructure\Win32.cs" />
<Compile Include="Main.cs" />
Expand Down
2 changes: 1 addition & 1 deletion CSVLintNppPlugin/Forms/CsvLintWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace Kbg.NppPluginNET
{
public partial class CsvLintWindow : Form
public partial class CsvLintWindow : DockingFormBase
{
public CsvLintWindow()
{
Expand Down
37 changes: 37 additions & 0 deletions CSVLintNppPlugin/Forms/DockingFormBase.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 68 additions & 0 deletions CSVLintNppPlugin/Forms/DockingFormBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Kbg.NppPluginNET.PluginInfrastructure;

namespace CSVLintNppPlugin.Forms
{
public partial class DockingFormBase : Form
{
private static Win32.WindowLongGetter _wndLongGetter;
private static Win32.WindowLongSetter _wndLongSetter;

public DockingFormBase()
{
InitializeComponent();
if (Marshal.SizeOf(typeof(IntPtr)) == 8) // we are 64-bit
{
_wndLongGetter = Win32.GetWindowLongPtr;
_wndLongSetter = Win32.SetWindowLongPtr;
}
else // we are 32-bit
{
_wndLongGetter = Win32.GetWindowLong;
_wndLongSetter = Win32.SetWindowLong;
}
}

protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case Win32.WM_NOTIFY:
var nmdr = (Win32.TagNMHDR)Marshal.PtrToStructure(m.LParam, typeof(Win32.TagNMHDR));
if (nmdr.hwndFrom == PluginBase.nppData._nppHandle)
{
switch ((DockMgrMsg)(nmdr.code & 0xFFFFU))
{
case DockMgrMsg.DMN_DOCK: // we are being docked
break;
case DockMgrMsg.DMN_FLOAT: // we are being _un_docked
RemoveControlParent(this);
break;
case DockMgrMsg.DMN_CLOSE: // we are being closed
break;
}
}
break;
}
base.WndProc(ref m);
}

private void RemoveControlParent(Control parent)
{
if (parent.HasChildren)
{
long extAttrs = (long)_wndLongGetter(parent.Handle, Win32.GWL_EXSTYLE);
if (Win32.WS_EX_CONTROLPARENT == (extAttrs & Win32.WS_EX_CONTROLPARENT))
{
_wndLongSetter(parent.Handle, Win32.GWL_EXSTYLE, new IntPtr(extAttrs & ~Win32.WS_EX_CONTROLPARENT));
}
foreach (Control c in parent.Controls)
{
RemoveControlParent(c);
}
}
}
}
}
61 changes: 61 additions & 0 deletions CSVLintNppPlugin/PluginInfrastructure/Win32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ public struct ScrollInfo
public int nTrackPos;
}

/// <summary>
/// @see https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-nmhdr
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct TagNMHDR
{
public IntPtr hwndFrom;
public UIntPtr idFrom;
public uint code;
}

/// <summary>
/// Used for the ScrollInfo fMask
/// SIF_ALL => Combination of SIF_PAGE, SIF_POS, SIF_RANGE, and SIF_TRACKPOS.
Expand Down Expand Up @@ -302,6 +313,56 @@ public static IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, ref LangType
public static extern int CheckMenuItem(IntPtr hmenu, int uIDCheckItem, int uCheck);

public const int WM_CREATE = 1;
public const int WM_NOTIFY = 0x004e;
public const int GWL_EXSTYLE = -20;
public const int GWLP_HINSTANCE = -6;
public const int GWLP_HWNDPARENT = -8;
public const int GWLP_ID = -12;
public const int GWL_STYLE = -16;
public const int GWLP_USERDATA = -21;
public const int GWLP_WNDPROC = -4;
public const long WS_EX_ACCEPTFILES = 0x00000010L;
public const long WS_EX_APPWINDOW = 0x00040000L;
public const long WS_EX_CLIENTEDGE = 0x00000200L;
public const long WS_EX_COMPOSITED = 0x02000000L;
public const long WS_EX_CONTEXTHELP = 0x00000400L;
public const long WS_EX_CONTROLPARENT = 0x00010000L;
public const long WS_EX_DLGMODALFRAME = 0x00000001L;
public const long WS_EX_LAYERED = 0x00080000L;
public const long WS_EX_LAYOUTRTL = 0x00400000L;
public const long WS_EX_LEFT = 0x00000000L;
public const long WS_EX_LEFTSCROLLBAR = 0x00004000L;
public const long WS_EX_LTRREADING = 0x00000000L;
public const long WS_EX_MDICHILD = 0x00000040L;
public const long WS_EX_NOACTIVATE = 0x08000000L;
public const long WS_EX_NOINHERITLAYOUT = 0x00100000L;
public const long WS_EX_NOPARENTNOTIFY = 0x00000004L;
public const long WS_EX_NOREDIRECTIONBITMAP = 0x00200000L;
public const long WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE);
public const long WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST);
public const long WS_EX_RIGHT = 0x00001000L;
public const long WS_EX_RIGHTSCROLLBAR = 0x00000000L;
public const long WS_EX_RTLREADING = 0x00002000L;
public const long WS_EX_STATICEDGE = 0x00020000L;
public const long WS_EX_TOOLWINDOW = 0x00000080L;
public const long WS_EX_TOPMOST = 0x00000008L;
public const long WS_EX_TRANSPARENT = 0x00000020L;
public const long WS_EX_WINDOWEDGE = 0x00000100L;

public delegate IntPtr WindowLongGetter(IntPtr hWnd, int nIndex);
public delegate IntPtr WindowLongSetter(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

[DllImport("user32")]
public static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);

[DllImport("user32")]
public static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32")]
public static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

[DllImport("user32")]
public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

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