• Login
Community
  • Login

Notepad++, Scintilla, SendMessages and Delphi

Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
5 Posts 3 Posters 1.2k 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.
  • S
    Sun Bright
    last edited by Sep 20, 2019, 7:07 PM

    Hello, I am having problems managing Scintilla in n ++ via messages. I use delphi. And sorry for my English, I used Google Translate.!!

    I get handle skinntills through FindWindow and FindWindowEx.
    I am trying to pass the replacement string like this:
    str: = ‘qwerty’ # 0;
    sendmessage (hwndScintilla, 2170,0, lparam (pchar (str)));

    2170 is SCI_REPLACESEL. I do not include header files, so I just use numbers instead of constants.

    But instead of the passed string, this appears:

    https://yadi.sk/i/-Vp5G2gdTIngLA
    Moreover, each time you restart n ++ and my program, “this” is always different.

    And messages returning numbers work fine:
    sendmessage (hwndScintilla, 2143,0,0)
    2143 is SCI_GETSELECTIONSTART.

    How do I pass a replacement string in Scintilla?

    Documentation from here: https://www.scintilla.org/ScintillaDoc.html#SCI_REPLACESEL
    Constants here: http://freesourcecode.net/cprojects/106750/sourcecode/Scintilla.h

    E 1 Reply Last reply Sep 20, 2019, 7:25 PM Reply Quote 0
    • E
      Ekopalypse @Sun Bright
      last edited by Sep 20, 2019, 7:25 PM

      @Sun-Bright

      do you develop a plugin?
      If so you do get the window handles of notepad and scintilla editor1 and editor2 via the setInfo callback.
      Depending on how you use FindWindow api it might not return the handle you expect as npp itself is using
      already three scintilla windows. Plugins might use additional windows as well.

      I don’t know enough about delphi but scintilla expects to receive a byte string NOT a unicode string.
      Is this your case?

      1 Reply Last reply Reply Quote 1
      • S
        Sun Bright
        last edited by Sep 21, 2019, 4:19 PM

        No, I just want to send commands from my program to npp, without using dll. But it seems that this will be impossible, because from the address space of my program, the scintilla will not be able to get data in the address space of npp.
        From Delphi I transmit a string of bytes, not Unicode.
        Thank you for answer.

        E 1 Reply Last reply Sep 21, 2019, 7:29 PM Reply Quote 0
        • E
          Ekopalypse @Sun Bright
          last edited by Sep 21, 2019, 7:29 PM

          @Sun-Bright

          that is correct, if you want to access scintilla from another process you have to get access
          to the process memory of npp. See Read-/WriteProcessMemory functions and friends.

          1 Reply Last reply Reply Quote 1
          • P
            PeterJones
            last edited by Sep 22, 2019, 11:07 PM

            @Sun-Bright said in Notepad++, Scintilla, SendMessages and Delphi:

            But it seems that this will be impossible, because from the address space of my program, the scintilla will not be able to get data in the address space of npp.

            You can actually send strings back and forth, even from another process. I’m starting to do it in my developing perl-driving-npp module. I don’t know how to do it in delphi, but the commands involved are VirtualAllocEx , WriteProcessMemory , ReadProcessMemory , and VirtualFreeEx . (Oh, I misinterpreted @Ekopalypse’s response; he was saying the same thing. But now I’ve linked to the official win32 api for you. :-) )

            They may be called something else in Delphi. (For example, in the perl wrapper Win32::GuiTest I am using for issuing the SendMessage to NPP, they call those AllocateVirtualBuffer, WriteToVirtualBuffer, ReadFromVirtualBuffer, and FreeVirtualBuffer.

            For commands that want to get or send a single string, like NPPM_DOOPEN for sending a string via LPARAM, or NPPM_GETFULLPATHFROMBUFFERID for reading a string via LPARAM, I use the following sequences successfully.

            # $obj->SendMessage_getUcs2le( $message_id, $wparam ):
            #   issues a SendMessage, and grabs a string up to 1024 bytes, and
            #   converts them from UCS-2 LE into up to 512 perl characters
            #   (includes the memory allocation necessary for cross-application communication)
            #   RETURN: the Perl string
            sub SendMessage_getUcs2le {
                my $self = shift; croak "no object sent" unless defined $self;
                my $msgid = shift; croak "no message id sent" unless defined $msgid;
                my $wparam = shift || 0;
            
                my $buf_uc2le = Win32::GuiTest::AllocateVirtualBuffer( $self->hwnd, 1024 );   # 1024 byte string maximum
                Win32::GuiTest::WriteToVirtualBuffer( $buf_uc2le, "\0"x1024 );                # pre-populate
                my $rslt = $self->SendMessage( $msgid, $wparam, $buf_uc2le->{ptr});
                #diag "SendMessage_getStr(@{[$self->hwnd]}, $msgid, $wparam, @{[explain $buf_uc2le]} ) = $rslt";
                my $rbuf = Win32::GuiTest::ReadFromVirtualBuffer( $buf_uc2le, 1024 );
                Win32::GuiTest::FreeVirtualBuffer( $buf_uc2le );
                return substr Encode::decode('ucs2-le', $rbuf), 0, $rslt;   # return the valid characters from the raw string
            }
            
            # $obj->SendMessage_sendStrAsUcs2le( $message_id, $wparam , $lparam_string ):
            #   issues a SendMessage, sending a string (encoded as UCS-2 LE)
            sub SendMessage_sendStrAsUcs2le {
                my $self = shift; croak "no object sent" unless defined $self;
                my $msgid = shift; croak "no message id sent" unless defined $msgid;
                my $wparam = shift; croak "no wparam sent" unless defined $wparam;
                my $lparam_string = shift; croak "no lparam string sent" unless defined $lparam_string;
            
                # convert string to UCS-2 LE
                my $ucs2le = Encode::encode('ucs2-le', $lparam_string);
            
                # copy string into virtual buffer
                my $buf_str = Win32::GuiTest::AllocateVirtualBuffer( $self->hwnd, length($ucs2le) );
                Win32::GuiTest::WriteToVirtualBuffer( $buf_str, $ucs2le );
            
                # send the message with the string ptr as the lparam
                my $rslt = Win32::GuiTest::SendMessage($self->hwnd, $msgid, $wparam, $buf_str->{ptr});
            
                # clear virtual buffer
                Win32::GuiTest::FreeVirtualBuffer( $buf_str );
            
                # return
                return $rslt;
            
            }
            

            (And yes, I successfully use those same sequences for talking with the NPP hwnd and the Scintilla hwnds.)

            Similar sequences, but using Delphi syntax and function names, should work for those commands.

            I’m actually still working on getting the more complicated messages (which want WPARAM as a TCHAR** rather than just a TCHAR*), but the above wrappers work for all the single-string LPARAM messages.

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