Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.18 c
15-1335609759
Тут иногда бываю
2012-04-28 14:42
2013.03.22
Как точно располагать Gui в редакторе?


2-1347122752
Тимофей
2012-09-08 20:45
2013.03.22
MS SQL2005 express


15-1336535282
Ega23
2012-05-09 07:48
2013.03.22
С Днём Победы!


15-1337666878
mefodiy
2012-05-22 10:07
2013.03.22
Копирование файлов в batch файлах


2-1335519491
leklerk
2012-04-27 13:38
2013.03.22
Как получить доступ к текущей записи в ADODataSet?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский