![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Опять - DeсimalSeparator???
SKing © (2002-03-26 13:42:00)Мастера помогите - пожалуйста...
Как заставить кнопку "." на доп. клавиатуре выдавать DeсimalSeparator во всех формах приложения при любой языковой раскладке?
Только не надо советовать для каждого контрола в отдельности.
Alx2 (2002-03-28 09:38:00) [1]>Lord Warlock © (28.03.02 09:07)
Вопрос в другом: "Как заставить кнопку "." на доп. клавиатуре выдавать DeсimalSeparator во всех формах приложения при любой языковой раскладке?". Его уже решили. Остались некоторые, но скорее всего надуманные, детали.
Lord Warlock (2002-03-28 09:07:00) [2]Господа, все очень просто.
В дельфе есть глобальная системная переменная
GlobalDecmailSeparator (по моему так, но точно не помню, можно поискать в хелпе по слову DecmailSeparator)
На ОнКреат приложения запоминаешь старый и ставишь какой нужно,
на ОнДестрой - возвращаешь старый и все :)
Alx2 (2002-03-28 08:14:00) [3]>Юрий Зотов.
Опять исправляюсь:
Вот это я нагнал: :) Как раз в случае <...>.ClassParent is TForm проверка не может работать: ошибка компиляции.Лучше бы я это не писал. Стыдно :(
Alx2 (2002-03-28 08:05:00) [4]>Юрий Зотов
>ClassParent=TForm лучше проверять is TForm,
>иначе проверка может и не сработать.
:) Как раз в случае <...>.ClassParent is TForm проверка не может работать: ошибка компиляции.
>как отловить создание формы не из нее самой?
>Решить можно, но это лишняя головная боль и лишний код.
Теперь понял, о чем Вы. Согласен.
>Anatoly Podgoretsky © (27.03.02 20:04)
>Alx2 © (27.03.02 11:57)
>Затем, что необязательно . или ,
Анатолий, если я правильно понял, это ответ на мое
"if Key in [",",".", DecimalSeparator - зачем?!] then Key := DecimalSeparator".
То есть, получается (что мне странно), Вы настаиваете на таком коде:
if Key in [",",".", DecimalSeparator] then Key:=DecimalSeparator;
Но это ведь эквивалентноследующему:
if Key in [",","."] then Key:=DecimalSeparator;
Если такое утверждение Вас не убеждает, то попробую расписать (хотя, мне кажется, что я Вас неправильно понял, ибо то, что пойдет ниже - само собой разумеещееся)
Итак,
if Key in [",",".",DecimalSeparator] then Key:=DecimalSeparator;
можно записать в виде:
if Key = "." then Key := DecimalSpearator else
if Key = "," then Key := DecimalSpearator else
if Key = DecimalSeparator then Key := DecimalSpearator;
Вопрос: а последняя строчка нужна ли? Ненужна. Посему
эквивалентная запись для "if Key in [",",".", DecimalSeparator] then Key:=DecimalSeparator" будет
if Key = "." then Key := DecimalSpearator else
if Key = "," then Key := DecimalSpearator;
или
if Key in [",","."] then Key:=DecimalSeparator;
Примечание: конструкцию с "Else" использовал для минимизации количества сравнений. Так как, при отсутствии else и Key="." после положительного результата теста на Key="." выполнится тест на Key=",", что уже не имеет смысла.
>Alx2 © (27.03.02 12:30)
>Неверно, может и другое
Я писал: "А запятую туда вставил, потому что с клавиши "." может прийти либо "." либо ",""
Спасибо за поправку. Действительно, категорично сказал.
Конечно, может прийти нечто другое :)). А оно нам надо?
Юрий Зотов (2002-03-27 22:37:00) [5]Ну, вот и вечер...
> Fay © (27.03.02 17:52)
> ... повлияет на весь ввод
А разве я говорил, что не нужно делать никаких проверок? Конечно, в обработчике нужен хотя бы if. Кстати, точно такой же if нужен и при любом другом способе перехвата клавиатуры для всех форм проекта разом. Поэтому речь может идти только о том, как осуществить этот перехват проще, универсальнее и без переделки кучи уже готовых форм. А уж что именно делать в этом перехватчике, что именно проверять или не проверять - это от способа перехвата, по сути, не зависит.
> Alx2 © (27.03.02 17:15)
> Но работает же! И не ругается.
В классе TForm1 обработчик FormKeyPress компилятору известен, поэтому, естественно, работает (а чего бы ему не работать?). Правда, форма не обязана наследоваться от TForm напрямую, поэтому вместо проверки ClassParent=TForm лучше проверять is TForm, иначе проверка может и не сработать.
Но исходную проблему это не решает - если на момент прогона цикла хотя бы одна из 100 форм еще не создана (в чем можно быть практически уверенным), или ее владельцем будет не Application, то и в цикл она не попадет. Соответственно, никаких KeyPreview и никаких обработчиков ей назначено не будет - и мы приплыли! Более того, стоит в процессе работы программы уничтожить любую форму, а потом снова ее создать - и для нее снова придется делать все то же самое. А отсюда новая проблема - как отловить создание формы не из нее самой? Решить можно, но это лишняя головная боль и лишний код.
> Всем желающим
Вот простейший (работающий) пример - во все TEdit"ы проекта, где бы они ни находились разрешается ввод только плюса, минуса, цифр, буквы "E", запятой и точки. При этом запятая, точка и все соответствующие им клавиши (на любом регистре) автоматически преобразуются в корректный DecimalSeparator (при любых настройках системы), а все клавиши, соответствующие русской или латинской букве "E" (на любом регистре) - в латинскую "E". Еще отключен стандартный Beep при Enter. И при этом проект может содержать любое количество любых форм, которые можно создавать и уничтожать где угодно и когда угодно.
type
TForm1 = class(TForm)
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
private
procedure OnAppMessage(var Msg: TMsg; var Handled: Boolean);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := OnAppMessage
end;
procedure TForm1.OnAppMessage(var Msg: TMsg; var Handled: Boolean);
const
Separators = [".", ",", "<", ">", "б", "ю", "Б", "Ю", "?", "/" ];
Exponents = ["e", "у", "У", "е", "Е", "t", "T"];
ValidChars = [#8, #9, "+", "-", "E", "0".."9"];
begin
with Msg do
if (Message = WM_CHAR) and (Screen.ActiveControl is TEdit) then
if Char(WParam) in Separators
then WParam := Byte(DecimalSeparator)
else if Char(WParam) in Exponents
then WParam := Byte("E")
else Handled := not (Char(WParam) in ValidChars)
end;
Anatoly Podgoretsky (2002-03-27 20:04:00) [6]Alx2 © (27.03.02 11:57)
Затем, что необязательно . или ,
Alx2 © (27.03.02 12:30)
Неверно, может и другое
Anatoly Podgoretsky (2002-03-27 19:58:00) [7]Reindeer Moss Eater (27.03.02 18:35)
Я пытаюсь вспомнить хоть один проект где бы было иначе.
Reindeer Moss Eater (2002-03-27 18:35:00) [8]Люди, а скажите честно, у вас что, есть проекты, где все формы - прямо от TForm отнаследованы?
Alx2 (2002-03-27 17:53:00) [9]Блин, я уже ухожу. Но завтра утром, думаю, ветка еще будет жить...
Fay (2002-03-27 17:52:00) [10]2Юрий Зотов
>Но чтобы сделать общего предка тоже придется перелопатить 100
>pas и 100 dfm. Зачем, если можно сделать проще?
ошибки на стадии проектирования часто бывают связаны с подобными траблами :(
Применение Вашего простого метода, если я правильно его понял, повлияет на весь ввод - где надо и где не надо; и не на весь, если понял не правильно Ж8)
Юрий Зотов (2002-03-27 17:50:00) [11]ОК, но вечером.
Alx2 (2002-03-27 17:49:00) [12]>Юрий Зотов
Но в общем случае, конечно, Вы правы.
Alx2 (2002-03-27 17:15:00) [13]>Во-первых, OnKeyPress - не метод, а событие.
Юрий, ну я ж исправился :( :
------------------
Alx2 © (27.03.02 16:50)
>Зато там есть метод OnKeyPress.
>И ему спокойно присваивается FormKeyPress
Пардон, не метод, а event
---------------------
>наплевать - в классе TForm он не знает
>никаких FormKeyPress и будет ругаться.
Но работает же! И не ругается. Я пример, который запостил, проверил и убедился, что все тип-топ. Никто не ругается, где бы форма ни была создана.
Но я Вас не понял. Давайте разберемся.
Мне действительно интересно, что Вы имеете в виду?
>И не всегда владельцем формы становится именно Application.
И про это тоже уже отписал.
Юрий Зотов (2002-03-27 17:08:00) [14]> Reindeer Moss Eater (27.03.02 16:37)
Наследование, конечно, не отдыхает. Но чтобы сделать общего предка тоже придется перелопатить 100 pas и 100 dfm. Зачем, если можно сделать проще?
> Alx2 © (27.03.02 16:45)
1. ... работающий пример для всех форм...
Которые на момент прогона цикла УЖЕ созданы и имеют владельцем Application. Я не представляю себе проект, в котором 100 форм создаются статически. И не всегда владельцем формы становится именно Application.
2. ...Зато там есть метод OnKeyPress. И ему спокойно присваивается FormKeyPress.
Во-первых, OnKeyPress - не метод, а событие. Адресное поле, в общем-то. Во-вторых, компилятору на все на это совершенно наплевать - в классе TForm он не знает никаких FormKeyPress и будет ругаться.
Alx2 (2002-03-27 16:57:00) [15]>А вот для Form2 := TForm2.Create(Nil)) - не сработает.
>Там только Ваш вариант IMHO.
Да, а кто мешает создавать через <...>.Create(Application)?
Alx2 (2002-03-27 16:50:00) [16]>Зато там есть метод OnKeyPress.
>И ему спокойно присваивается FormKeyPress
Пардон, не метод, а event
Alx2 (2002-03-27 16:45:00) [17]>Юрий Зотов © (27.03.02 16:28)
> ... forms currently displayed on the screen".
Хм.. действительно.
Но вот работающий пример для всех форм, которые входят в состав Application (то есть созданы через Application.CreateForm(TForm, Form, либо через Form := TForm.Create(Application));
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if Key in [",","."] Then Key := DecimalSeparator;
end;
procedure TForm1.InitHandlerBtnClick(Sender: TObject); // Раздаем обработчик.
Var k : Integer;
begin
for k := 0 to Application.ComponentCount-1 do
if Application.Components[k].ClassParent = TForm then
with Application.Components[k] as TForm do
begin
KeyPreview := true;
OnKeyPress := FormKeyPress;
end;
end;
А вот для Form2 := TForm2.Create(Nil)) - не сработает. Там только Ваш вариант IMHO.
>что FormKeyPress он не знает - ведь в классе TForm такого нет.
Зато там есть метод OnKeyPress. И ему спокойно присваивается FormKeyPress
Reindeer Moss Eater (2002-03-27 16:37:00) [18]Наследование отдыхает?
Юрий Зотов (2002-03-27 16:28:00) [19]Это не пройдет по 2-причинам.
Во-первых, компилятор скажет, что FormKeyPress он не знает - ведь в классе TForm такого нет. Но даже если это обойти (например, через RTTI), то остается еще и "во-вторых".
Читаем хелп на TScreen.FormCount:
" Read FormCount to learn the number of forms currently displayed on the screen ".
То есть, Ваш метод сработает, если в момент выполнения цикла все 100 форм присутствуют на экране одновременно. Что нереально.
Alx2 (2002-03-27 15:54:00) [20]>Вы предлагаете править все 100 вручную?
Зачем вручную?
Screen.Forms[i].KeyPreview := true;
Screen.Forms[i].OnKeyPress := FormKeyPress;
:)