External SendMessage to Notepad++ for NPPM_GETOPENFILENAMES and other TCHAR**
-
Addition: To solve the problem you need one of the following:
- A COM or ActiveX interface for Notepad++ that allows an external process to interact with it.
- A bridge plugin that you can control via
NPPM_MSGTOPLUGIN
messages sent to the Npp window. This plugin should forward messages from external processes to Npp and send back the results.
-
Good news, I got a solution at perlmonks (below).
But first, replying to a couple of things:
@Ekopalypse said in External SendMessage to Notepad++ for NPPM_GETOPENFILENAMES and other TCHAR**:
You need to get the process handle from OpenProcess etc… not the window handle.
The perl wrappers for
AllocateVirtualBuffer
->VirtualAllocEx
take care of the process handle. (Otherwise it wouldn’t have worked for the plain string)- Npp has to allocate memory in the address space of your process via VirtualAllocEx
Actually, no. The
my @strBufs = map { AllocateVirtualBuffer( $hwnd, 1024 ) } 1 .. $nFiles;
is a perl-idiom for loop that allocates n different buffers; thepack
a few lines later packs those virtual-buffer pointers into the main virtual-buffer (loading the TCHAR** with n TCHAR* memories). The pointer to the main virtual buffer is then what functions as the TCHAR**Solution
In perlmonks, vr pointed out that I when I called the SendMessage, I accidentally sent it the perl variable
$tcharpp
instead of the pointer thatAllocateVirtualBuffer
->VirtualAllocEx
created:$tcharpp->{ptr}
. And I forgot to pass it the number of files.Changing that one line to
print "SendMessage status: ", my $ret = SendMessage( $hwnd, NPPM_GETOPENFILENAMES, $tcharpp->{ptr}, $nFiles);
solved both problems, and I now can get the file names back.
I feel silly about missing the ->{ptr}, because I got that right in the normal string SendMessage, so I should have noticed that! And if I hadn’t been so distracted by that not working, I may have eventually noticed that I was asking for 0 filenames… then again, maybe not. :-)
-
@dinkumoil said in External SendMessage to Notepad++ for NPPM_GETOPENFILENAMES and other TCHAR**:
To solve the problem you need one of the following:
Fortunately, it ended up being simpler than that. :-)
-
Hmm, no more mark-as-question / mark-as-solved in the topic tools.
-
@PeterJones said in External SendMessage to Notepad++ for NPPM_GETOPENFILENAMES and other TCHAR**:
loop that allocates n different buffers;
In case I wasn’t clear (3min passed, so cannot edit): when passing it the TCHAR**, it is the calling process’s responsibility to create the memory, both for the n pointers, and what those n pointers point to. Npp expects the caller of GETOPENFILENAMES to have done the allocation.
-
But again, thank you for your thoughts and willingness to help.
-
@PeterJones said:
when passing it the TCHAR**, it is the calling process’s responsibility to create the memory, both for the n pointers, and what those n pointers point to. Npp expects the caller of GETOPENFILENAMES to have done the allocation.
Ahh, I forgot the
and what those n pointers point to
part, now it makes sense. Congratulations! I stay tuned to see an external Perl instance to interact with Npp. -
@dinkumoil said in External SendMessage to Notepad++ for NPPM_GETOPENFILENAMES and other TCHAR**:
I stay tuned to see an external Perl instance to interact with Npp.
I should start making forward progress much more quickly again. I hope to have the Notepad object by the end of the week, and maybe the scintilla object by next week.
Except callbacks. Without the intimacy of Npp->plugin, I don’t think callbacks will be able to be registered. But I’ll try that after I’m done with the rest of the NPP and SCINTILLA object code.
My long-term plan, after I get as much as I can done externally, is to have a very simple plugin interface, to give me visibility to the few things I cannot get externally, and allow either version for Perl users – if all they want is some simple remote control, then they can just download the module from CPAN. If they want full-fledged plugin, with callbacks and a menu-system for running the scripts inside Notepad++, then they will also need the plugin (though I still haven’t decided whether I’ll follow @Ekopalypse and compile my own matching perl, embedding it in the plugin, or whether the plugin will just ask for the path-to-perl.exe when being configured).
-
@PeterJones said in External SendMessage to Notepad++ for NPPM_GETOPENFILENAMES and other TCHAR**:
I hope to have the Notepad object by the end of the week, and maybe the scintilla object by next week
Three months later… Yeah. I was only a week or two late on the Notepad object, though I didn’t announce it. And I’ve made significant progress on the Scintilla object, but there’s still a lot to go: I think I’m about halfway. (I’m using some of Perl’s AUTOLOAD tricks to generate some of the wrapper functions at-request rather than having to manually define hundreds of wrappers for individual messages, so one piece of code can be re-used to wrap dozens or hundreds of messages automatically; if my assumptions about which groups of messages should use the same wrapping style, I think I’ve got about 300-400 messages that should work, with another 300-400 to go; but those assumptions could be wrong; I’m tracking my progress in https://github.com/pryrt/Win32-Mechanize-NotepadPlusPlus/blob/master/debug/sortSciMsgs.txt.)
But it is to the point where someone with a lot of Perl experience ( @Michael-Vincent : hint, hint) should be able to pick it up, look at my docs and the test suite (which gives some example idioms), and try running various functions, and giving me feedback. I believe the Notepad object is good enough for a production release; the Scintilla methods still have a way to go, but I’d like alpha-testers/feedback to see whether my bulk wrapper-generator is working (ie, if the other methods I’ve grouped together really work correctly; I’ve tested one or two functions from each “completed” group, but there is the possibility that the ones I’ve grouped aren’t quite as similar as I thought).
Anyway, for those who are interested, you can grab the source code from https://github.com/pryrt/Win32-Mechanize-NotepadPlusPlus (and then either install the Perl module, or just set your Perl library search path to include the lib directory from that repo)
Feedback can go here, or as issues if you think it’s something worth tracking
-
Wow, I made drastic progress today. It turned out most of those last hundreds of messages were just the simplest mapping from wrapper to Scintilla message.
There now remain a few messages that use various Scintilla structures (Sci_RangeToFormat, Sci_TextRange, cell), and a few more that will require manual coding for other reasons, to correctly map arguments from the method to the message.
And I probably need to audit things, because I found that for a few methods, my regex which had mapped the old PythonScript v1.4 docs (which I was starting with) to the Scintilla message didn’t quite get things right; so I need to make sure I don’t have methods mapped to the completely wrong message; and also need to check that I’m not missing important methods from newer releases.
But I think the bulk of the methods that can be handled by AUTOLOAD are done.
Except for the special structures, and anything regarding callbacks and the like (which aren’t going to be implemented in the first release), I think it should be reasonably usable at this point.
This morning, I was thinking this was more of an alpha-test situation. Now I’m thinking it’s really more of a beta test. Cool. :-)
-
@PeterJones,
from the github repo it seems that you do not use the iface file.
Any reason for that? -
@Ekopalypse said in External SendMessage to Notepad++ for NPPM_GETOPENFILENAMES and other TCHAR**:
Any reason for that?
Yes. Mostly, because I didn’t know it contained much the same information as Scintilla.h. And I already had my script to convert from
.h
to a Perl data structure, so even if I had known it was there, I probably would have preferred the.h
.