Community
    • Login

    Plugin; irregularities with inplace editors closure

    Scheduled Pinned Locked Moved Notepad++ & Plugin Development
    13 Posts 5 Posters 162 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • K
      klaus101
      last edited by

      Just trying to activate rename capabilities in my plugin (written in Lazarus/FreePascal) using inplace editors for treeview and listview, i did run again into a strange phaenomen that i’d never encountered in regular stand-alone apps before.

      That is, once the item editor is opened, it will close only within too few cases. It’s only closed by: click on anther node; or: via Cancel key; or via value change and press <Enter>.
      It does NOT close if i click onto another control, for instance, or when clicking into another window, eg. the NPP editor area. It appears the message flow is somehow disturbed.

      I’d have three questions:

      1. Can someone imagine what might be the possible reason?
      2. Is such behaviour already known for other plugins?
      3. Could maybe someone replicate if this does occur also with Delphi?

      Steps:
      Take some demo app having a treeview, and set the treeview to not be readonly.
      Open an inplace editor on a tree node by any means, eg. a lazy doubleclick.
      Click onto any other control with the docking form, or onto NPP’s editing area.
      What does happen?

      CoisesC rdipardoR 2 Replies Last reply Reply Quote 0
      • CoisesC
        Coises @klaus101
        last edited by Coises

        @klaus101 said in Plugin; irregularities with inplace editors closure:

        Can someone imagine what might be the possible reason?

        Well, my guess would be that it’s a result of having a Lazarus window embedded in a plugin that is necessarily relying on a standard Win32 API message loop. Just as has been seen with C# and WinForms, I’m guessing Lazarus/Pascal probably implements a message loop that’s customized for how its components work. Maybe — unlike C# — they’ve managed to document that somewhere so you can figure out how those forms behave when used within a standard Win32 API program?

        Try intercepting NM_KILLFOCUS for list view and for tree view in your dialog procedure.

        K 1 Reply Last reply Reply Quote 0
        • K
          klaus101 @Coises
          last edited by klaus101

          @Coises thank you again for your response!
          Is it in it’s fundamentals “relying on a standard Win32 API message loop”? I’ve not yet enough info to know this exactly, but surely it’s not based on a pure WinMain loop using TranslateMessage, DispatchMessage etc. or it’s C++ equivalents, at least i’d suspect so, but more probably it “implements a message loop that’s customized for how its components” (and forms, for both forms and components heavily used). For to be precise here i’d need to ask architectural experts within their forum. Maybe i’ll do so, but anyhow i would have no means to operate and interact here if somewhere in a higher level of the hierachy something should have gone wrong.
          So i was also very interested in to hear if does occur with Delphi too, or in other language systems.

          And so i began also very early to search for workarounds, and the first candidate indeed was WM_KILLFOCUS from the message loop (would you differentiate between WM_KILLFOCUS and NM_KILLFOCUS regarding their potential here?). What i can say definitely (regarding WM_KILLFOCUS):
          no, that’s not usable for this purpose. Because: the one and only information it transports (in wParam), directly in the beginning and only once, is the handle of the item editor control.
          But this is self-evident from the beginning that the focus was transferred to the inplace editor, and not enough information though to decide about any other controls or windows which might have got the focus.

          Then i experimented with the “MouseLeave” event callback -> idea: if the mouse leaved the treeview, and leaved to a control which is not the item editor, then call the reponsible closure procedure. My initial problem had been that this crashed in Notepad++ -> Control “” has no parent window.
          And i had experimented here too long using the demo program only. Until i noticed i could use this in my own plugin quite well (i suspect the reason is that in my plugin, i expose a direct access to the inplace editor (so potenitally to it’s own proprties), wheras in the demo i simply called an LCL “EndEdit(true)” procedure - true means: cancel mode.
          Anyhow. For the treeview that appears to work. For the listview not quite. I couldn’t find here yet a “cancel” mode - but this is surely on the Lazarus side.

          But why the initial approach failed and a message might have gone lost, no idea, so an info about behaviour in other languages would be quite interesting.
          I think the best i can do is to work out the “MouseLeave” workaround approach for the listview too, if this should succeed. Would this make sense?

          CoisesC 1 Reply Last reply Reply Quote 0
          • CoisesC
            Coises @klaus101
            last edited by Coises

            @klaus101 said in Plugin; irregularities with inplace editors closure:

            would you differentiate between WM_KILLFOCUS and NM_KILLFOCUS regarding their potential here?

            Yes.

            WM_KILLFOCUS is sent to the window that is losing focus with the window handle of the window that will gain focus.

            NM_KILLFOCUS is sent to the parent window of a control that has lost focus, and it identifies the control that lost focus.

            To use WM_KILLFOCUS you would need to subclass the control in question (the tree view or list view) and react to that message in your custom window procedure. To use NM_KILLFOCUS you would recognize it within the WM_NOTIFY case in your dialog procedure.

            I don’t have enough experience with tree view or list view controls to know which, if either, might solve your problem. But they are very different.

            K 1 Reply Last reply Reply Quote 0
            • rdipardoR
              rdipardo @klaus101
              last edited by rdipardo

              @klaus101 said in Plugin; irregularities with inplace editors closure:

              1. Could maybe someone replicate if this does occur also with Delphi?

              No, I can’t, assuming I understand what you’re referring to.

              First, I downloaded a current snapshot of the latest template sources from https://bitbucket.org/rdipardo/delphiplugintemplate/downloads

              • I changed the TreeView’s ReadOnly property to make it editable:
              --- a/Source/Forms/helloworlddockingforms.lfm
              +++ b/Source/Forms/helloworlddockingforms.lfm
                   Height = 146
                   Top = 8
                   Width = 238
              -    ReadOnly = True
              +    ReadOnly = False
                   ScrollBars = ssVertical
                   TabOrder = 2
                   Items.Data = {
              
              
              • I built the plugin and placed it in the load path of a compatible N++ version.

              • I clicked the toolbar button to show the docking form.

              • I double-clicked a list item and typed into it.

              • With focus still on the item, I moved the mouse pointer into the buffer window, then clicked.

              • Focus moved into the buffer window:

              npp.8.8.1.ttreeview.item.edit.gif

              I did however notice a different issue, namely, when editing a TreeView item while the form is “floating” (i.e., dragged into the buffer window area).

              In that scenario, the list item’s edit control cannot be unfocused at all; it hangs up the message loop until the “Not responding” system dialog appears and you request a hard shutdown.

              The solution probably involves some variation of Damjan Cvetko’s famous hack of toggling the WS_EX_CONTROLPARENT attribute flag in the form’s WM_NOTIFY procedure. It’s just a matter of finding out whether WS_EX_CONTROLPARENT needs to be set or cleared, and in response to which DMN_* message.


              Moderator Note

              A better place to open this topic would have been the plugin template’s bug tracker.

              After some investigation, however, it seems the underlying issue is the N++ Docking Manager’s overbearing behavior in relation to docking forms that it sees as “child” dialogs, which can break dialogs that have their own complicated hierarchy of child components, as discussed in more detail here.

              For that reason I would not penalize the OP for straying off-topic. But only this time.

              K 1 Reply Last reply Reply Quote 0
              • K
                klaus101
                last edited by klaus101

                To the moderator: Which topic exactly to you mean? The latter about the floating window?.

                For myself i intentionally did not post in the plugin’s template bugtracker, because i never assumed i’d have a problem with this template’s demo program here.
                I had not been sure, is it a general issue with the NPP interface, or do i have a problem with the Lazarus code in this special case (therefore interest in comparison with Delphi or other languages).

                So, would it be possible for me to send one answer to Coises as well as to rdipardo tomorrow? I think most had been clarified. Thank your!

                1 Reply Last reply Reply Quote 0
                • ryangray01R
                  ryangray01
                  last edited by

                  Re: Plugin; irregularities with inplace editors closure
                  That’s a really interesting observation. I’ve faced similar quirks with inplace editor behavior in plugin environments, especially when dealing with embedded controls inside docking panels. It almost feels like the message loop or focus chain behaves differently compared to standalone apps — possibly because the parent window (like NPP) handles focus in a non-standard way. I haven’t tested this exact case in Delphi yet, but it sounds replicable. I’d guess it might have to do with how modal input or focus loss is propagated — or not — when nested within another host application. Have you tried subclassing the editor’s parent to monitor focus loss explicitly?

                  PeterJonesP 1 Reply Last reply Reply Quote -1
                  • K
                    klaus101 @Coises
                    last edited by klaus101

                    @Coises

                    To use WM_KILLFOCUS you would need to subclass the control in question (the tree view or list view) and react to that message in your custom window procedure

                    Yes, that’s already the case (have a subclassed windows procedure for, eg., the treeview), and here the treeview itself actually is notified via WM_ messages. So one knows that the treeview had lost the focus … to it’s overlaying child window “edit control”, and this is no surprise …

                    NM_KILLFOCUS is sent to the parent window of a control that has lost focus. … To use NM_KILLFOCUS you would recognize it within the WM_NOTIFY case in your dialog procedure

                    Well … understood. NM_KILLFOCUS would be one possible notification via/beyond WM_NOTIFY. One might intercept it here, and by that it can be known that one of the treeview’s children lost it’s focus too (and to which hwndFrom), and this is the essential part to know.

                    But … (and this surprised me too now!): the LCL treeview (at least mine) doesn’t receive such WM_NOTIFY (and then herein nm_killfocus).
                    Different from other controls where it can be intercepted. Imo one needs to know here that in Lazarus the treeview is purely LCL-written, other than, e.g., the listview, which is based on the windows common controls, and this might be a reason.
                    Afaik, in Delphi (at least in Delphi7 as i know from earlier days) the treeview is based on the windows control too.

                    With other words: at least for the treeview i’d need to pursue the “MouseLeave” way, which delivers the same information needed (treeview lost focus onto a control even outside the node editor, and which one).

                    1 Reply Last reply Reply Quote 0
                    • K
                      klaus101 @rdipardo
                      last edited by

                      @rdipardo Thank you for having tested!
                      It’s a bit hard to identify in the gif screen cast when/where a click happens. So only for confirmation: (regarding a docking, not floating window here):
                      when you write/type into the npp editor buffer, the treeview’s node editor stays open, but when you click into it, it correctly closes?
                      The latter would tell me that i encountered a Lazarus flaw here, and i’d indeed need a LCL fix or such workaround as described.

                      1 Reply Last reply Reply Quote 0
                      • PeterJonesP
                        PeterJones @ryangray01
                        last edited by

                        @ryangray01 ,

                        Piecing together random snippets from previous posts makes you look like an out-of-date generative AI. You might try putting more original content in your posts that hasn’t been covered by existing discussion, or you will find yourself banned for posting AI nonsense (which isn’t allowed in this forum)

                        K 1 Reply Last reply Reply Quote 0
                        • K
                          klaus101 @PeterJones
                          last edited by

                          @PeterJones ???

                          PeterJonesP 1 Reply Last reply Reply Quote 0
                          • PeterJonesP
                            PeterJones @klaus101
                            last edited by

                            @klaus101 ,

                            Look up a few posts. You will see a post by the user I was replying to. (From your perspective, it got buried a few posts above the most recent post, because they posted during a time when there was no moderator available to approve posts in the queue. That sometimes happens, because while we have moderators spread across the globe, we have lives outside of this Community, and so sometimes posts go up to even 6-8 hours without being approved; when they do finally get approved, they go into the discussion at the timeslot in the conversation when they were submitted, not the time where they were finally approved.)

                            K 1 Reply Last reply Reply Quote 1
                            • K
                              klaus101 @PeterJones
                              last edited by

                              @PeterJones Peter, oh sorry - i hadn’t realized it this morning in the hurry, my bad!

                              1 Reply Last reply Reply Quote 0
                              • First post
                                Last post
                              The Community of users of the Notepad++ text editor.
                              Powered by NodeBB | Contributors