Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблема с UpperCase и InputBox [D7, WinXP]


PRT ©   (2006-06-18 18:23:00) 

1. Почему UpperCase('строка') не работает если строка - русские символы ???
2. Можно ли в InputBox ограничить ввод символов ?? (например, чтоб можно было вводить только русские символы)


Leonid Troyanovsky   (2006-06-19 20:42:00) [1]


> begin...end ©   (19.06.06 20:38) [10]

> ли когда-нибудь будет по-другому, но мне почему-то полагаться
> на это не хочется.


Тогда ActiveForm и перебрать Controls.

--
Regards, LVT.


begin...end   (2006-06-19 20:38:00) [2]

> Leonid Troyanovsky ©   (19.06.06 20:20) [8]

> Хотя, конечно, Screen.ActiveControl для InputBox вполне,
> IMHO, хватит.

Ну, если положиться на то, что фокус после вызова InputBox обязательно будет у edit'а -- тогда да. Собственно, вряд ли когда-нибудь будет по-другому, но мне почему-то полагаться на это не хочется.

:-)


begin...end   (2006-06-19 20:25:00) [3]

> Leonid Troyanovsky ©   (19.06.06 20:20) [8]

И правда. Забыл.


Leonid Troyanovsky   (2006-06-19 20:20:00) [4]


> begin...end ©   (19.06.06 19:53) [7]

>    EditInstance := TEdit(SendMessage(EditHandle, GetObjectInstanceMessage,


Ну, есть, вообще-то, FindControl.
Хотя, конечно, Screen.ActiveControl для InputBox вполне, IMHO, хватит.

--
Regards, LVT.


begin...end   (2006-06-19 19:53:00) [5]

> PRT   (18.06.06 18:23) [0]

> 2. Можно ли в InputBox ограничить ввод символов ?? (например,
> чтоб можно было вводить только русские символы)

Можно.

Что происходит при вызове InputBox? Создаётся форма c edit'ом и двумя кнопками, которая показывается модально.

Можем ли мы выполнить какой-нибудь свой код сразу после того, как эта форма будет модально показана? Можем -- сразу после её показа заработает цикл выборки сообщений, заключённый в методе ShowModal. Если послать, скажем, нашей главной форме асинхронное сообщение перед вызовом InputBox, то оно будет выбрано из очереди в ходе работы этого цикла. А в обработчике этого сообщения как раз и можно разместить нужный код.

Допустим, дескриптор модальной формы мы определили.

Можем ли мы получить дескриптор дочернего edit'а? Можем -- см. FindWindowEx.

Можем ли мы получить указатель на экземпляр класса TEdit (Self), связанный с этим дескриптором? Можем -- см. Controls.pas, сообщение RM_GETOBJECTINSTANCE.

Безопасно ли использовать этот указатель? Да, безопасно, потому что контрол находится в том же процессе, в котором находимся мы -- а значит, указатель содержит адрес экземпляра в ВАП нашего процесса.

Можем ли мы, имея этот указатель, назначить edit'у свой обработчик события? Можем, причём совершенно стандартно -- установив значение соответствующего свойства.

А вот код, который всё это делает. Особо не тестировал, но, вроде бы,  работает.

const
 WM_MODALMESSAGE = WM_USER + 100;

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   procedure WMModalMessage(var Message: TMessage); message WM_MODALMESSAGE;
   procedure EditKeyPress(Sender: TObject; var Key: Char);
 end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 PostMessage(Handle, WM_MODALMESSAGE, 0, 0);
 InputBox('Изменённый InputBox', 'Сюда вводятся только русские буквы:', '')
end;

procedure TForm1.EditKeyPress(Sender: TObject; var Key: Char);
begin
 if not (Key in ['А'..'я', 'ё', 'Ё']) then
   Key := #0
end;

procedure TForm1.WMModalMessage(var Message: TMessage);
var
 EditHandle: Cardinal;
 EditInstance: TEdit;
 GetObjectInstanceMessage: Cardinal;
begin
 EditHandle := FindWindowEx(GetActiveWindow, 0, 'TEdit', nil);
 if EditHandle <> 0 then
 begin
   GetObjectInstanceMessage := RegisterWindowMessage(PChar(Format('ControlOfs%.8X%.8X', [HInstance, GetCurrentThreadID])));
   EditInstance := nil;
   EditInstance := TEdit(SendMessage(EditHandle, GetObjectInstanceMessage, 0, 0));
   if Assigned(EditInstance) then
   begin
     EditInstance.OnKeyPress := EditKeyPress
   end
 end
end;


Здесь edit'у назначается обработчик OnKeyPress, поэтому будет фильтроваться только текст, вводимый вручную, а проблему вставки текста с русскими буквами из буфера это не решает, но совершенно аналогично можно решить и эту проблему -- назначить нужный OnChange вместо OnKeyPress.


kaif   (2006-06-19 10:37:00) [6]

AnsiUpperCase


PZ   (2006-06-18 20:09:00) [7]

Используйте переключатель клавиатуры:
 LoadKeyboardLayout('00000419', KLF_ACTIVATE); // вкл. русский шрифт
 LoadKeyboardLayout('00000409', KLF_ACTIVATE); // вкл. латинский шрифт


Rial   (2006-06-18 20:03:00) [8]

function UpCase(C : Char): Char; assembler;
asm
    MOV    AL,C
    CMP    AL,'a'
    JB     @@3
    CMP    AL,'z'
    JBE    @@2
    CMP    AL,'ё'
    JZ     @@1
    CMP    AL,'а'
    JB     @@3
    CMP    AL,'я'
    JBE    @@2
    JMP    @@3
@@1: MOV    AL,'Ё'
    JMP    @@3
@@2: SUB    AL,$20
@@3:
end;


jack128   (2006-06-18 18:59:00) [9]

PRT   (18.06.06 18:56) [2]
Не спорю, но это еще одна форма, еще пару лишних кБ.

если форму динамически создавать, а не в дезин тайм, то не более 500 байт - 100 пудов.


PRT   (2006-06-18 18:56:00) [10]


> вряд ли, но что может быть проще, чем написать свою InputBoxEx
> ?

Не спорю, но это еще одна форма, еще пару лишних кБ.


Eraser   (2006-06-18 18:29:00) [11]

> [0] PRT   (18.06.06 18:23)


> 1. Почему UpperCase('строка') не работает если строка -
> русские символы ???

см. AnsiUpperCase

> 2.

вряд ли, но что может быть проще, чем написать свою InputBoxEx ?


Наверх

Титульная страница Поиск, карта сайта Написать письмо