@romserg
Программирование, велоспорт

Notepad++, Scintilla, SendMessages и Delphi — как вставить строку?

Здравствуйте, у меня проблемы с управлением Scintillой в n++ через сообщения. Использую delphi.

Получаю handle скинтиллы через FindWindow и FindWindowEx.
Пытаюсь передать строку для замены так:
str:='qwerty'#0;
sendmessage(hwndScintilla,2170,0, lparam(pchar(str)) );

2170 - это SCI_REPLACESEL. Я не подключаю заголовочные файлы, поэтому использую просто числа вместо констант.

Но вместо переданной строки встаёт вот это:
K6c8b5L3YLBpTIEwj8Q_AN1BfZTxZS5BG9vspHPN

Причём при каждом перезапуске n++ и моей программы "это" всегда разное.

А сообщения, возвращающие числа, работают нормально:
sendmessage(hwndScintilla,2143,0,0 )
2143 - это SCI_GETSELECTIONSTART.

Как мне передать строку для замены в Scintilla?

Документация отсюда: https://www.scintilla.org/ScintillaDoc.html#SCI_RE...
Константы тут: freesourcecode.net/cprojects/106750/sourcecode/Sci...
  • Вопрос задан
  • 203 просмотра
Пригласить эксперта
Ответы на вопрос 1
@zedxxx
Вы передаёте указатель на область памяти в адресном пространстве вашей программы, а у Notepad++ своё, изолированное адресное пространство. И по адресу, указанному в сообщении, естественно, будет мусор.

Для того, чтобы передавать буфер из приложения в приложение, в WinAPI предусмотрено сообщение WM_COPYDATA. И в этом случае, Windows "под капотом" заботится о том, чтобы перенести передаваемый буфер в адресное пространство приложения адресата, чтобы оно могло его считать.

Но Scintilla не ожидает, что ей будут управлять извне, поэтому напрямую не получится послать ей такое сообщение. Можно попробовать внедрить свою dll в адресное пространство Notepad++ и добавить там обработчик сообщений WM_COPYDATA с пересылкой в Scintilla уже изнутри.

Поскольку Notepad++ поддерживает плагины, то с внедрением dll проблем быть не должно. В демке для Delphi плагина даже есть пример, как управлять Scintilla:

procedure THelloWorldPlugin.FuncHelloWorld;
var
  s: string;
begin
  s := 'Hello World';
  SendMessage(self.NppData.ScintillaMainHandle, SCI_REPLACESEL, 0, LPARAM(PChar(s)));
end;
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы