Handling notifications from a docked scintilla (in the same style as the standard Npp Finder)



  • I began writing a Npp plugin a few days ago in C# using https://github.com/kbilsted/NotepadPlusPlusPluginPack.Net as a basis.

    The component I am working on is intended to display some results lines (from analysing some files content) in the same way the standard Npp FindReplace command does, via a docked scintilla component that display the lines and can be interacted with, e.g. : to go the line in the original document by double-clicking one of the result lines.

    My first approach was to create a new Scintilla handle via NPPM_CREATESCINTILLAHANDLE then display it with NPPM_DMMREGASDCKDLG (see code extracts below).
    It kinda seem to work at first : the docked scintilla is opened and I can type text in it. But clicking on the close button does not do anything.

    // Extract from NotepadPPGateway.cs
    public IntPtr CreateScintillaHandle(IntPtr parentWindowHandle)
    {
    	return Win32.SendMessage(PluginBase.nppData._nppHandle, (uint) NppMsg.NPPM_CREATESCINTILLAHANDLE, 0, parentWindowHandle);
    }
    
    public void DMMRegAsDckDlg(IntPtr dockingData)
    {
    	Win32.SendMessage(PluginBase.nppData._nppHandle, (uint) NppMsg.NPPM_DMMREGASDCKDLG, 0, dockingData);
    }
    
    // Extract from the function that creates the docked scintilla
    
    // The bitmap creation was in the demo, I have not yet seen if it is really necessary
    using (Bitmap newBmp = new Bitmap(16, 16))
    {
        Graphics g = Graphics.FromImage(newBmp);
        ColorMap[] colorMap = new ColorMap[1];
        colorMap[0] = new ColorMap();
        colorMap[0].OldColor = Color.Fuchsia;
        colorMap[0].NewColor = Color.FromKnownColor(KnownColor.ButtonFace);
        ImageAttributes attr = new ImageAttributes();
        attr.SetRemapTable(colorMap);
        g.DrawImage(Kbg.NppPluginNET.Properties.Resources.star_bmp, new Rectangle(0, 0, 16, 16), 0, 0, 16, 16, GraphicsUnit.Pixel, attr);
        tbIcon = Icon.FromHandle(newBmp.GetHicon());
    }
                
    scintillaHandle = NotepadPPGateway.Instance.CreateScintillaHandle((IntPtr)null);
    scintillaGateway = new ScintillaGateway(scintillaHandle);
    
    NppTbData _nppTbData = new NppTbData();
    _nppTbData.hClient = (IntPtr)scintillaHandle;
    _nppTbData.pszName = "UFT Tests Analysis Result";
    _nppTbData.dlgID = 1;
    _nppTbData.uMask = NppTbMsg.DWS_DF_CONT_BOTTOM | NppTbMsg.DWS_ICONTAB | NppTbMsg.DWS_ICONBAR;
    _nppTbData.hIconTab = (uint)tbIcon.Handle;
    _nppTbData.pszModuleName = Main.PluginName;
    IntPtr _ptrNppTbData = Marshal.AllocHGlobal(Marshal.SizeOf(_nppTbData));
    Marshal.StructureToPtr(_nppTbData, _ptrNppTbData, false);
    
    NotepadPPGateway.Instance.DMMRegAsDckDlg(_ptrNppTbData);
    
    //Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_MODELESSDIALOG, (IntPtr)NppMsg.MODELESSDIALOGADD, scintillaHandle);
    
    // Tmp block for prototyping
    scintillaGateway.AddText("Test 1 (Analysed)\r\n".Length, "Test 1 (Analysed)\r\n");
    scintillaGateway.AddText("Test 2 (Analysed)\r\n".Length, "Test 2 (Analysed)\r\n");
    

    And when I tried catching notifications coming from the docked scintilla with the code below, it did not do anything either. (Works fine in the main scintilla as expected though.)

    if (notification.Header.Code == (uint)SciMsg.SCN_DOUBLECLICK)
    {
        MessageBox.Show("DOUBLE CLICK " + notification.Header.hwndFrom.ToString() + " " + notification.Header.IdFrom.ToString() + " " + notification.Header.Code.ToString());
    }
    

    I’m a bit stuck here. How do I set this up to properly get the notifications from the docked scintilla ?
    Is there a problem with directly docking a scintilla handle with NPPM_DMMREGASDCKDLG as I did ? Or is it a problem with the NPPM_CREATESCINTILLAHANDLE call ?
    I also tried registering the scintilla handle via the NPPM_MODELESSDIALOG message, but while it did seem to intercept keystrokes in the docked scintilla (not able to type or modify the content anymore), it did not improve the situation on the notification side.

    I am also looking in the Npp FindReplace code for inspiration (https://github.com/notepad-plus-plus/notepad-plus-plus/blob/master/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp, beginning with the ‘void FindReplaceDlg::findAllIn(InWhat op)’ function), but I have not found a solution as of yet. In there, the notifications seems to be handled directly as part of the ‘Finder class’ which implements ‘DockingDlgInterface’, in particular method ‘notify’.

    Does someone have any leads on this ?

    Thanks.



  • @Romain-BOUCHAUD-LEDUC

    I’m no expert but I can say from experience I have gotten a similar setup working in C++

    I have a docked dialog with 2 scintilla instances and have full control over them and receive notifications.

    My plugin is here if you are interested in digging through it to look at a working C++ example

    https://github.com/dail8859/LuaScript



  • @dail Thanks, I will take a look at it when I have the time.


Log in to reply