Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.03.22;
Скачать: CL | DM;

Вниз

Перехвать изменений текста в ричЭдите   Найти похожие ветки 

 
TStas   (2012-05-18 22:54) [0]

Вообще-то сами изменения я уже благополучно перехватил. Но я ловил изменения положений выделения и размера текста, а ловил через SelectionChange и Change. Причем делал так, чтобы к свойству Text не обращаться, ибо текст может быть и огромным.
Потом пробовал подменять табулятор двумя пробелами. Пробовал по-всякому, в первую очередь путём перехвата WM_KEYDOWn WM_KEYUP. Всё ловится, а вот подмены не просисходит. Подменять пробовал путём посылки себе же сообщения в другим кодом клавиши. Даже не убирается табулятор. Однако как-то делал похожие вещи, только со свтавкой при определённом сочитании клавиш спецсимволов. Всё получалось, только делал через компонент ApplicationEvent. А почему так? В поле Result помещал ненулевые значения и inherited не вызывал.
Код выложить не могу, ибо стёр, потому как не работает.


 
TStas   (2012-05-18 22:56) [1]

PS: EM_SETSELTEXT почему-то вообще не ловится. :( То есть пишу обработчик с директивой message, но при изменениях текста, в. т. ч. вставки из буфера он вообще не вызывается.


 
Rouse_ ©   (2012-05-18 23:35) [2]


> EM_SETSELTEXT почему-то вообще не ловится.

А где ты это все делаешь-то? WndProc подменил или в наследнике?


 
TStas   (2012-05-18 23:49) [3]

В наследнике. А что, надо WndProc подменять?


 
Rouse_ ©   (2012-05-19 00:20) [4]


> TStas   (18.05.12 23:49) [3]
> В наследнике. А что, надо WndProc подменять?

В наследнике WndProc подменять уже поздно :) Давай демопроект, который кажет ошибку...


 
TStas   (2012-05-19 01:12) [5]

Так ошибки-то и нету. Просто не получается подменить табулятор двумя пробелами. А одним - легко! Перекрыть KeyPress и всё. Однако посылки сообщения из KetPress, чтобы второй пробел появился, тоже ничего не даёт. Один способ, притом верный, я знаю, это через ApplicationEvent. Но он мне не нравится тем, что потом могут быть косяки при взаимодействии с другими ApplicationEvent.


 
Rouse_ ©   (2012-05-19 01:38) [6]


> Так ошибки-то и нету.

Ну раз нет ошибки и демопроекта, то даже не знаю что и посоветовать, телепатор включать лениво...


 
Германн ©   (2012-05-19 01:39) [7]


> Stas   (19.05.12 01:12) [5]
>
> Так ошибки-то и нету.

Имхо Розыч говоря ошибка имел в виду "не получается подменить табулятор двумя пробелам".


 
Rouse_ ©   (2012-05-19 01:51) [8]


> Германн ©   (19.05.12 01:39) [7]
> Имхо Розыч говоря ошибка имел в виду

Серег, я ничего не имел ввиду.
По словам ТС, он сидит на наследнике, но зачем-то залез аж в ApplicationEvent.
Нет ошибки, нет проблемы.


 
Германн ©   (2012-05-19 02:26) [9]


>  Rouse_ ©   (19.05.12 01:51) [8]
>
>
> > Германн ©   (19.05.12 01:39) [7]
> > Имхо Розыч говоря ошибка имел в виду
>
> Серег, я ничего не имел ввиду.

Кроме демопроекта, который можно "пощупать".
А как он "сидит на наследнике" пока никому не известно.
Если я не прав, то ...


 
TStas   (2012-05-19 04:03) [10]

Розыч, проект повешу. Надо тогда написать, что именно не работает? А происходит вот что: пишу
Procedure WMKeyDown(var Message: TWMKey); message WM_KEYDown;
Begin
If Message.CharCode = 9 then
  Begin
  ShowMessage("Попался, табулятор!") //Не попадается
  end
else
  Inherited;
End;

У компонента в Style scReflector добавлял, лучше от этого не стало.
Точно такой же код в WMKeyUp с тем же результатом.
Пробовал и иначе:
Procedre KeyPress(var Key: Char); Override;
If Key = 9 then
Begin
Key := #32; //На один пробел спокойно заменяется
SendMessage(Handle, WM_KEYDOWN, 32, 0); //Нихрена не происходит
SendMessage(Handle, WM_KEYUP, 32, 0); //И второй пробел не хочет вставляться

end;


 
TStas   (2012-05-19 04:10) [11]

procedure KeyPress(var Key: Char);
var
 n: integer;
begin
 If Key = #9 then
   Begin
   Key := #32;
   n := Perform(WM_KEYDOWN, 32, 0);
   ShowMessage("n = "+IntToStr(n));
   n := Perform(WM_KEYUP, 32, 0);
   ShowMessage("n = "+IntToStr(n));
   End;

 inherited;
end;

n в обоих случаях 0, но второй не добавляется.

А как отловить SetSelText? Он в private объявлен. Уже все сообщения перебрал, но так момент вставки не нашел.


 
Anatoly Podgoretsky ©   (2012-05-19 08:40) [12]

> TStas  (19.05.2012 04:10:11)  [11]

Естественно,  EM_SETSEL


 
TStas   (2012-05-19 11:07) [13]

Вот EM_SETSEL я и начал первым пробовать. Вдумчиво прочитал всю родословную до TCustomEdita, нашел, где определены все EM_ и все прочитал, вереннее, подозревая, что мне SelText надо ловить, запустил на поиск SEL и сразу нашел. Только не дало это ничего. Сейчас еще раз попробую и повешу код.


 
TStas   (2012-05-19 11:18) [14]

procedure EMSetSel(var Message: TMessage);
begin
 ShowMessage("EMSetSel");
 Inherited;
end;

procedure CMTextChanged(var Message: TMessage);
begin
 ShowMessage("CMTextChanged");
 Inherited;
end;

При добавлении строк срабатывают, а при редактировании текста - нет! Пробовал, и не раз, в конструкторе писать
 Style := ControlStyle;
 Include(Style, csReflector);
 ControlStyle := Style;
Это почему-то ничего не дало. Однако Procedure EMSetReadOnly(var Message: TMessage); message EM_SETREADONLY; чудесно работает. Вот что это может быть?


 
TStas   (2012-05-19 11:48) [15]

Ага, кое-что заработало:
procedure TStCodeEditor.CNKeyUP(var Message: TMessage);
begin
 If Message.WParam = 9 then
   Begin
   If FTab then
     Begin
     FTab := False;
     Message.Result := 1;

     SelText := #32#32;
     //ShowMessage("Tab up")
     End
   else
     Inherited
   End
 else
   Inherited
end;

procedure TStCodeEditor.CNKeyDown(var Message: TMessage);
begin
 If Message.WParam = 9 then
   Begin
   FTab := True;
   Message.Result := 1 //ShowMessage("Tab down")
   End
 else
   Inherited
end;

А вот не простая замена, а посылка себе сообщений работать не хочет почему-то. Пробовал и
     PostMessage(Handle, CN_KEYDOWN, 32, Message.LParam);
     PostMessage(Handle, CN_KEYUP, 32, Message.LParam);
И WM_KEYDOWN и SEndMessage и Perform. Ничего не выходило.

Слава Богу, хоть так получается. Момент загрузки сток из потока ловится уже несколько дней как. Осталось последнее - поймать момент вставки из буфера. Больше табуляторы в тексте не могут ни откуда появиться. На буфере стоит наблюдатель, чтобы PasteAction делать недоступным, когда в буфере нет текста. А вот как поймать момент вставки? Хорошо бы, конечно, только в SelText проводить замену, ну, а если не удастся, то во всём тексте их искать.


 
TStas   (2012-05-19 13:00) [16]

Вставку из буфера тоже поймал:

procedure TStCodeEditor.WMPaste(var Message: TWMPaste);
var
 OldSelStart, NewSelStart: Integer;
 S, S1: String;
begin
 OldSelStart := SelStart;

 Inherited; //Вызвал уаследованный. Здесь всё и случилось

 NewSelStart := SelStart;

 Lines.BeginUpdate;
 SelStart := OldSelStart;
 SelLength := NewSelStart - OldSelStart;

 If ReplaceTab then //Заменять табуляторы?
   Begin // - Да, заменять
   S1 := SelText;
   If Pos(#9, S) > 0 then //Есть табуляторы с строке?
     Begin // - Да, есть
     S1 := LineWithNoTab(S);
     SelText := S1;
     SelLength := Length(S1);
     End; //Если есть табуляторы
   End; //Если заменять табуляторы

 Lines.EndUpdate;
end;

Осталось отловить присвоение св-ва Text. Наверно, тоже через сообщения буду ловить.


 
TStas   (2012-05-19 13:08) [17]

А Уставновку текста перехватить удалось сразу:
procedure TStCodeEditor.WMSetText(var Message: TWMSetText);
var
 S1, S2: String;
begin
 If ReplaceTab then
   Begin
   S1 := Message.Text; //Получил текст
   If Pos(#9, S1) > 0 then
     Begin
     S2 := LineWithNoTab(S1);
     Message.Text := PChar(S2);
     End;
   End;

 Inherited;
end;

Теперь хорошо бы поймать переключение раскладки, и всё :)



Страницы: 1 вся ветка

Текущий архив: 2013.03.22;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.049 c
2-1333344537
SvK.droNe
2012-04-02 09:28
2013.03.22
Рациональная интерполяция с помощью непрерывных дробей.


15-1348161804
ClawClaw
2012-09-20 21:23
2013.03.22
Глюк в Сапёре? (Windows 7)


2-1341996851
MTK
2012-07-11 12:54
2013.03.22
Отправка почты


15-1339412694
NieL
2012-06-11 15:04
2013.03.22
ошибка xml


15-1338322058
Bluejohn
2012-05-30 00:07
2013.03.22
Чем порезать видео?