Community
    • Login

    How to get the scintilla view0/view1 HWNDs

    Scheduled Pinned Locked Moved Notepad++ & Plugin Development
    31 Posts 7 Posters 6.8k 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.
    • PeterJonesP
      PeterJones
      last edited by

      @Ekopalypse said:

      what I did

      For future readers, here’s a link to his post: https://perlmonks.org/?node_id=11103649

      1 Reply Last reply Reply Quote 0
      • Teespring TeesT
        Teespring Tees
        last edited by

        This post is deleted!
        1 Reply Last reply Reply Quote -1
        • PeterJonesP
          PeterJones
          last edited by PeterJones

          I see that @Ekopalypse is making progress on his embedding-perl-using-VS2017, per his posts on perlmonks. That’s great.

          Semi-OT, but related to my implementation of perl modules to talk with Notepad++: I’m finding problems, because the perl-wrapper-library around SendMessage that I’m using (Win32::GuiTest) is truncating the 64-bit return-value of some Notepad++ messages (like GET_CURENTBUFFERID, which when talking with 64bit Notepad++ can return ID’s > 0xFFFFFFFF)

          I’m hoping to file a bug report with the module author, but it would go better if I could give a concrete example of a message that will return >32bits, but doesn’t require the module author to install/download Notepad++. (I have made a dummy windows app which just listens for a message and returns a 64bit number; so if necessary, I can send that code in my bug report, so that there’s a known tool to give the example of the failing condition. But if there were a standard windows program that responded to a specific message with a 64-bit-filling number, that would be an easier example to show the module author.)

          So I’ll ask an OT question here: do any users here with more Win32-API experience than I have know of a standard application (that most or all windows users can be expected to have, like notepad.exe) that has a message that returns* a number that requires more than 32 bits? (I’d prefer one that returns something other than 0xFFFFFFFF_FFFFFFFF, because the failure mechanism extends the 32nd bit to the left to fill all 64bits.) *: by “return”, I mean the retval from retval = SendMessage(...); it can correctly return 64bit values through LPARAM and WPARAM as pointers.

          EkopalypseE 1 Reply Last reply Reply Quote 1
          • EkopalypseE
            Ekopalypse @PeterJones
            last edited by

            @PeterJones

            I don’t know a message which returns an 64bit integer but may I ask you whether your perl is a 64bit application? I mean, LRESULT is defined as LONG_PTR which itself is defined as

            #if defined(_WIN64)
             typedef __int64 LONG_PTR; 
            #else
             typedef long LONG_PTR;
            #endif
            

            So in case you are using a 32bit perl it might explain the behavior.

            1 Reply Last reply Reply Quote 1
            • PeterJonesP
              PeterJones
              last edited by

              @Ekopalypse said:

              So in case you are using a 32bit perl it might explain the behavior.

              I am using 64bit strawberry perl.

              I know exactly where the bug is: in the “XS” glue (which is a pseudo-c wrapper language that binds DLL function names into perl subroutine namespace), the module declares SendMessage as int SendMessage, where int is still 32bits, rather than using a 64bit type (due to the restrictions of XS, it cannot be LRESULT, but there is an XS equivalent, IV, which is the type of that perl’s integer value; in the 64bit perl, it’s an 8-byte type, as it needs to be to line up with LRESULT).

              I just want an easy way to show the author how the bug and the fix both work, to try to encourage a prompt release of the fix. (Though, given that it’s been a few years since that module was last updated, I don’t know how “prompt” it will be.)

              I can, and probably soon will, submit the bug report and pull request with my suggested fix, but it would be nice if I had a simple way to replicate the problem with the bug.

              Alan KilbornA EkopalypseE 3 Replies Last reply Reply Quote 1
              • Alan KilbornA
                Alan Kilborn @PeterJones
                last edited by

                @PeterJones said:

                in the “XS” glue (which is a pseudo-c wrapper language that binds DLL function names into perl subroutine namespace), the module declares SendMessage as int SendMessage, where int is still 32bits, rather than using a 64bit type (due to the restrictions of XS, it cannot be LRESULT, but there is an XS equivalent, IV, which is the type of that perl’s integer value; in the 64bit perl, it’s an 8-byte type, as it needs to be to line up with LRESULT).

                You nerdy (Perl) geeks have lost me (by roughly half of the discussion), but it is fascinating reading. Pray continue. :)

                1 Reply Last reply Reply Quote 1
                • EkopalypseE
                  Ekopalypse @PeterJones
                  last edited by

                  @PeterJones

                  I see, what about using something like this

                  use Win32::API;
                  use Encode;
                  
                  # HWND FindWindowExW(
                    # HWND    hWndParent,
                    # HWND    hWndChildAfter,
                    # LPCWSTR lpszClass,
                    # LPCWSTR lpszWindow
                  # );
                  
                  my $FindWindow = new Win32::API::More('User32', 'FindWindowExW', 'qqPP', 'q');
                  if(not defined $FindWindow) {
                      die "Can't import API FindWindowExW: $^E\n";
                  }
                  
                  # LRESULT SendMessageW(
                    # HWND   hWnd,
                    # UINT   Msg,
                    # WPARAM wParam,
                    # LPARAM lParam
                  # );
                  
                  my $SendMessage = new Win32::API::More('User32', 'SendMessageW', 'qIQq', 'q');
                  if(not defined $SendMessage) {
                      die "Can't import API SendMessageW: $^E\n";
                  }
                  
                  my $npp_hwnd = $FindWindow->Call(0, 0, encode('UTF-16le',"Notepad++\0"), 0);
                  print "hwnd: $npp_hwnd\n";
                  
                  my $NPPMSG = 2024;
                  my $NPPM_GETCURRENTBUFFERID = $NPPMSG + 60;
                  my $current_buffer_id = $SendMessage->Call($npp_hwnd, $NPPM_GETCURRENTBUFFERID, 0, 0);
                  print "current_buffer_id: $current_buffer_id\n";
                  

                  I’m not 100% certain about the datatypes but seems to work.

                  1 Reply Last reply Reply Quote 1
                  • EkopalypseE
                    Ekopalypse @PeterJones
                    last edited by

                    @PeterJones

                    just for fun

                    use strict;
                    use warnings;
                    use Win32::API;
                    use Win32::API::Callback;
                    use Encode;
                    
                    # HWND FindWindowExW(
                      # HWND    hWndParent,
                      # HWND    hWndChildAfter,
                      # LPCWSTR lpszClass,
                      # LPCWSTR lpszWindow
                    # );
                    
                    my $FindWindow = new Win32::API::More('User32', 'FindWindowExW', 'qqPP', 'q');
                    if(not defined $FindWindow) {
                        die "Can't import API FindWindowExW: $^E\n";
                    }
                    
                    # LRESULT SendMessageW(
                      # HWND   hWnd,
                      # UINT   Msg,
                      # WPARAM wParam,
                      # LPARAM lParam
                    # );
                    
                    my $SendMessage = new Win32::API::More('User32', 'SendMessageW', 'qIQq', 'q');
                    if(not defined $SendMessage) {
                        die "Can't import API SendMessageW: $^E\n";
                    }
                    
                    # BOOL EnumChildWindows(
                      # HWND        hWndParent,
                      # WNDENUMPROC lpEnumFunc,
                      # LPARAM      lParam
                    # );
                    my $EnumChildWindows = new Win32::API::More('User32', 'EnumChildWindows', 'qKq', 'I');
                    if(not defined $EnumChildWindows) {
                        die "Can't import API EnumChildWindows: $^E\n";
                    }
                    
                    # int GetClassNameW(
                      # HWND   hWnd,
                      # LPWSTR lpClassName,
                      # int    nMaxCount
                    # );
                    my $GetClassName = new Win32::API::More('User32', 'GetClassNameW', 'qPI', 'I');
                    if(not defined $GetClassName) {
                        die "Can't import API GetClassNameW: $^E\n";
                    }
                    
                    # HWND GetParent(
                      # HWND hWnd
                    # );
                    my $GetParent = new Win32::API::More('User32', 'GetParent', 'q', 'q');
                    if(not defined $GetParent) {
                        die "Can't import API GetParent: $^E\n";
                    }
                    
                    
                    my $npp_hwnd = $FindWindow->Call(0, 0, encode('UTF-16le',"Notepad++"), 0);
                    print "npp_hwnd: $npp_hwnd\n";
                    
                    # my $sci1_hwnd = $FindWindow->Call($npp_hwnd, 0, encode('UTF-16le',"Scintilla"), 0);
                    # print "sci1_hwnd: $sci1_hwnd\n";
                    my %scintilla_hwnd = (0, 0, 1, 0);
                    my $callback = Win32::API::Callback->new(
                    	sub {
                    		my($hwnd, $lParam) = @_;
                    		my $curr_class    = " " x 1024;
                    		my $result = $GetClassName->Call($hwnd, $curr_class, 1024);
                    
                    		if (substr(decode('UTF-16le',$curr_class), 0, $result) eq 'Scintilla') {
                                if ($GetParent->Call($hwnd) == $npp_hwnd) {
                                    if ($scintilla_hwnd{0} == 0) {
                                        $scintilla_hwnd{0} = $hwnd;
                    				} elsif ($scintilla_hwnd{1} == 0) {
                                        $scintilla_hwnd{1} = $hwnd;
                                        return 0;
                    				}
                    			}
                    		}
                            return 1;
                    	}, "qq", "I",
                    );
                    
                    $EnumChildWindows->Call($npp_hwnd, $callback, 0);
                    print "first scintilla hwnd $scintilla_hwnd{0}\n";
                    print "second scintilla hwnd $scintilla_hwnd{1}\n";
                    
                    1 Reply Last reply Reply Quote 1
                    • EkopalypseE
                      Ekopalypse
                      last edited by

                      Some news - not embedded as to disturbing :-)
                      Currently this function calls a, hardcoded, script from the disc. No interaction yet as
                      it seems win32::api is not part of the standard distribution and must be installed via
                      e.g. cpan but having difficulties making this work. :-(
                      But at least, an embedded perl interpreter as a npp plugin.
                      Btw. thx to @dail for his cookiecuter template which I used for this :-)

                      Alan KilbornA 1 Reply Last reply Reply Quote 3
                      • Alan KilbornA
                        Alan Kilborn @Ekopalypse
                        last edited by

                        @Ekopalypse said:

                        Btw. thx to @dail for his cookiecuter template

                        Maybe worth pointing to that template…

                        EkopalypseE 1 Reply Last reply Reply Quote 2
                        • EkopalypseE
                          Ekopalypse @Alan Kilborn
                          last edited by

                          @Alan-Kilborn said:

                          Maybe worth pointing to that template…

                          Thanks, yes of course it is worht ;-) - it is here.

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