kbilsted / NotepadPlusPlusPluginPack.Net

.Net package to install into visual studio to make plugins for Notepad++
Apache License 2.0
164 stars 52 forks source link

Notepad++ freezes when working with undocked dialogs that use container-controls #17

Open dirk-runge opened 7 years ago

dirk-runge commented 7 years ago

An exact description can be found here: https://notepad-plus-plus.org/community/topic/12519/net-plugin-dockable-dialog-freezes-notepad

kbilsted commented 7 years ago

I cannot give you a good answer as to why this crashes. I'd be happy to receive a PR when you fixed the bug.

dail8859 commented 7 years ago

I did some digging around into this but could not track it down, even ran Notepad++ in a debugger and stepped through the code. The last thing Notepad++ appears to call is ShowWindow(). I can't say I completely understand fully what it expects from docked dialogs. I do use a docked dialog for one of my other plugins and have never ran into this kind of issue (though it doesn't use the combination of groupbox/button as described in the forum post.)

kbilsted commented 7 years ago

have you tried compiling the demo from the plugin pack and starting n++ ? there is an example of dockable windows

dail8859 commented 7 years ago

Yes I was able to replicate the bug with the demo plugin but wasn't able to track down the cause of the problem.

mahee96 commented 4 years ago

I too am facing some kind of issue with dock panel container, in which I was trying to host a WPF window inside the Win32 dock container provided by Npp. The problem was that whenever the hosted dock window is being re-sized or docked/undocked it goes blank or renders incorrectly.

If anyone has any ideas or pointers on what could be the issue will be much helpful(I am deugging native Npp's WndProc messaging loop in the meantime to check what causes the flicker with the dock panel on re-size/move(dock/undock)) https://stackoverflow.com/questions/32003868/blank-wpf-child-windows-on-windows-10

I will report back if I have any leads.

mahee96 commented 4 years ago

okay, I did some profiling and can clearly see some hotspot in the gripper function in notepad++ main process which handles the dragging for the dock panel container. Probably its getting locked up in the Kernel or some bug (looping?) in the message handling loop Gripper::staticWinProc() of notepad++ process.

Since Winforms are just a wrapper to WinAPI, probably there shouldn't be any issue using .NET.

Let's see if anything more comes up.

Attaching Profiled data: The yellow markings on the CPU utilization shows that CPU got busy(1:27.5 min - 25%) when the UI stopped responding

Profiling3 Profiling1 Profiling2

mahee96 commented 4 years ago

Found something on this:

https://forums.codeguru.com/showthread.php?412421-endless-messages-WM_GETDLGCODE-when-focus-is-lost

https://www.codeproject.com/Articles/470997/A-tale-of-two-flags-DS-CONTROL-and-WS-EX-CONTROLPA

http://www.guyswithtowels.com/blog/10-things-i-hate-about-win32.html (See Nested Dialogs section)

Looks like it's a InterOp issue(dialog manager doesn't find the target child/nested grid container and so it sends the message WM_GETDLGCODE infinitely to parent window message proc) when using managed .NET group containers inside unmanaged Win32 based window.

This issue as it doesn't occur when using plain unmanaged Win32 APIs for creating windows or child containers.

A work around suggested was to ...set the Extended style attribute of grid(group) control to WS_EX_CONTROLPARENT once the control is loaded or created.

mahee96 commented 4 years ago

About the profiling screenshots attached earlier(I stepped into Npp source code to look what's happening):

  1. Npp creates the dock container window internally and hosts the new control or window(registered by passing an handle + Npp data to Npp using message NPPM_DMMREGASDCKDLG). When register request is received the docking manager of Npp not only creates a docking window container but also displays the hosted window inside the container(if any else just shows blank/black). This window is now docked and shown in the NPP main window based on the Docking property (left/right/top/bottom/float(default)). Note: Since .Net controls are hosted inside Plain Win32 Window the control is not visible unless .Show() is called.(which creates the window/control completely in .Net world) so in order to show the control when the dock panel is registered and shown the child .Net window needs to call its own .Show() method.

  2. When the docking window is moved or resized, the parent Win32 dock container's message proc is invoked with WM_SIZE. Npp handles these by having a Gripper class dedicated to handle the movement or resize. On WM_DESTROY message is received as a result to destroy the old window in its previous location or before resizing, and in handling/processing this message the SetWindowPos() function is invoked to reset the window pos to "HWND_NOTTOPMOST" in the z-order .... But once this gets called control never returns to the next line of execution which is "focusClient()"

  3. This is when the CPU utilization spikes up(25%), and some research shows that this is a known bug which causes WM_GETDLGCODE message to be flooded infinitely into Hook proc for mouse movement. The reason it wasn't consuming 100% cpu is that only one logical core(out of my 4 logical core) was affected(targetted for this message pumping) and other cores are unused. As mentioned earlier, this was due to the inability of Docking Manager to find the target child/nested control(grid control here, in winforms)and hence flooding the parent Win32 docking Window hook procedure with WM_GETDLGCODE message 0x87.

There were lot of precautions and tips needed to deal with child controls and their message procs since lots of users have faced this issue and still weren't able to conclude the root cause of it.

A Google search on this topic should now give more info....

I tried to hack the GridControl's style attribute to have WS_EX_CONTROLPARENT flag....but didnt complete the testing whether it resolves our issue...(I had some personal and office work)..maybe someone could try and report it?

The content posted above is based on my quick research and understanding on Npp docking procedure so could be incorrect in some places for the NPP internal operations, I would suggest checking the original source code.

Denisf88 commented 2 years ago

Hi, was a solution found for the original issue ? I'm having the same issue using buttons inside a tab control. works fine when docked but freezes when the panel is undocked.

mahee96 commented 2 years ago

@Denisf88 A work around suggested was to ...set the Extended style attribute of grid(group) control to WS_EX_CONTROLPARENT once the control is loaded or created.

mahee96 commented 2 years ago

@Denisf88 can you check if that helps, I haven't been in touch with this codebase since sometime now...will check out when I get time.

Denisf88 commented 2 years ago

@mahee96 thanks for the info, I'm not quite sure how apply this workaround, will try figure it out.