Форум: "Основная";
Текущий архив: 2002.04.08;
Скачать: [xml.tar.bz2];
ВнизОпять - DeсimalSeparator??? Найти похожие ветки
← →
SKing (2002-03-26 13:42) [0]Мастера помогите - пожалуйста...
Как заставить кнопку "." на доп. клавиатуре выдавать DeсimalSeparator во всех формах приложения при любой языковой раскладке?
Только не надо советовать для каждого контрола в отдельности.
← →
Вадим (2002-03-26 13:59) [1]А если для каждого контрола использовать одну процедуру
← →
Юрий Зотов (2002-03-26 14:03) [2]Например, написать обработчик Application.OnMessage, а там проверять, что нажато и подменять код клавиши, если нужно.
← →
Johnmen (2002-03-26 14:08) [3]Можно хирургически - заменить "," на "." в kbdru.kbd в нужном месте - тогда будет всегда "."
Можно прописать в приложении обработчик <Del> и делать, что надо...
← →
SKing (2002-03-27 11:05) [4]Вадиму-> Это для одной формы, а если форм в прилож. 100 ?
Юрию Зотову-> Если не трудно, можно поподробней...
← →
Reindeer Moss Eater (2002-03-27 11:10) [5]>SKing
А если все сто форм приложения сделать наследниками одной и обработку делать в ней?
← →
Alx2 (2002-03-27 11:29) [6]делаем) Form1.KeyPreview = true
И добавляем метод
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if Key in [",","."] Then Key := ".";
end;
← →
Alx2 (2002-03-27 11:30) [7]Пардон, вот так:
if Key in [",","."] Then Key := DecimalSeparator;
← →
Fay (2002-03-27 11:55) [8]2Alx2
if Key in [",",".", DecimalSeparator] then Key := DecimalSeparator
← →
Alx2 (2002-03-27 11:57) [9]if Key in [",",".", DecimalSeparator - зачем?!] then Key := DecimalSeparator
← →
Юрий Зотов (2002-03-27 12:10) [10]Можно. Но я придерживаюсь принципа "надо давать не рыбу, а удочку", поэтому расскажу как я сам это делаю.
Открываем хелп на странице TApplication, щелкаем по линку Events, читаем. В боковом окне щелкаем по линку OnMessage, снова читаем. Потом в основном окне щелкаем по линку Example, смотрим пример. Копируем его к себе в программу и подправляем код под свои нужды. Для этого в том же хелпе смотрим объявление типа TMsg, а в SDK - сообщения WM_KEYDOWN, WM_KEYUP, WM_CHAR и страницу Virtual-Key Codes.
Написанный нами обработчик, конечно, сразу правильно работать не будет и это вполне нормально. Ставим в нем BreakPoint, запускаем программу, нажимаем нужные клавиши, смотрим значения переменных, выясняем, что у нас не так и исправляем. В частности, выясняем, как нужно изменить в сообщении WParam и биты 16-23 в LParam, чтобы "подменить" клавишу.
Вот так я это делаю и (честное слово!) еще ни разу не было, чтобы решение не было найдено. Чего и Вам желаю.
← →
Fay (2002-03-27 12:16) [11]2Alx2
А "," зачем ?
← →
Alx2 (2002-03-27 12:30) [12]>Fay © (27.03.02 12:16)
Просто если key = DecimalSeparator, то ее не надо переприсваивать снова значению DecimalSeparator.
А запятую туда вставил, потому что с клавиши "." может прийти либо "." либо ","
← →
Fay (2002-03-27 12:37) [13]2Alx2
Угу
← →
Юрий Зотов (2002-03-27 15:46) [14]> Alx2
> Fay
Читаем вопрос. Там сказано: "... во всех формах приложения...".
Предположим, в проекте 100 форм. Вы предлагаете править все 100 вручную?
← →
Alx2 (2002-03-27 15:54) [15]>Вы предлагаете править все 100 вручную?
Зачем вручную?
Screen.Forms[i].KeyPreview := true;
Screen.Forms[i].OnKeyPress := FormKeyPress;
:)
← →
Юрий Зотов (2002-03-27 16:28) [16]Это не пройдет по 2-причинам.
Во-первых, компилятор скажет, что FormKeyPress он не знает - ведь в классе TForm такого нет. Но даже если это обойти (например, через RTTI), то остается еще и "во-вторых".
Читаем хелп на TScreen.FormCount:
" Read FormCount to learn the number of forms currently displayed on the screen ".
То есть, Ваш метод сработает, если в момент выполнения цикла все 100 форм присутствуют на экране одновременно. Что нереально.
← →
Reindeer Moss Eater (2002-03-27 16:37) [17]Наследование отдыхает?
← →
Alx2 (2002-03-27 16:45) [18]>Юрий Зотов © (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
← →
Alx2 (2002-03-27 16:50) [19]>Зато там есть метод OnKeyPress.
>И ему спокойно присваивается FormKeyPress
Пардон, не метод, а event
← →
Alx2 (2002-03-27 16:57) [20]>А вот для Form2 := TForm2.Create(Nil)) - не сработает.
>Там только Ваш вариант IMHO.
Да, а кто мешает создавать через <...>.Create(Application)?
← →
Юрий Зотов (2002-03-27 17:08) [21]> 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 17:15) [22]>Во-первых, OnKeyPress - не метод, а событие.
Юрий, ну я ж исправился :( :
------------------
Alx2 © (27.03.02 16:50)
>Зато там есть метод OnKeyPress.
>И ему спокойно присваивается FormKeyPress
Пардон, не метод, а event
---------------------
>наплевать - в классе TForm он не знает
>никаких FormKeyPress и будет ругаться.
Но работает же! И не ругается. Я пример, который запостил, проверил и убедился, что все тип-топ. Никто не ругается, где бы форма ни была создана.
Но я Вас не понял. Давайте разберемся.
Мне действительно интересно, что Вы имеете в виду?
>И не всегда владельцем формы становится именно Application.
И про это тоже уже отписал.
← →
Юрий Зотов (2002-03-27 17:50) [23]ОК, но вечером.
← →
Alx2 (2002-03-27 17:49) [24]>Юрий Зотов
Но в общем случае, конечно, Вы правы.
← →
Fay (2002-03-27 17:52) [25]2Юрий Зотов
>Но чтобы сделать общего предка тоже придется перелопатить 100
>pas и 100 dfm. Зачем, если можно сделать проще?
ошибки на стадии проектирования часто бывают связаны с подобными траблами :(
Применение Вашего простого метода, если я правильно его понял, повлияет на весь ввод - где надо и где не надо; и не на весь, если понял не правильно Ж8)
← →
Alx2 (2002-03-27 17:53) [26]Блин, я уже ухожу. Но завтра утром, думаю, ветка еще будет жить...
← →
Reindeer Moss Eater (2002-03-27 18:35) [27]Люди, а скажите честно, у вас что, есть проекты, где все формы - прямо от TForm отнаследованы?
← →
Anatoly Podgoretsky (2002-03-27 19:58) [28]Reindeer Moss Eater (27.03.02 18:35)
Я пытаюсь вспомнить хоть один проект где бы было иначе.
← →
Anatoly Podgoretsky (2002-03-27 20:04) [29]Alx2 © (27.03.02 11:57)
Затем, что необязательно . или ,
Alx2 © (27.03.02 12:30)
Неверно, может и другое
← →
Юрий Зотов (2002-03-27 22:37) [30]Ну, вот и вечер...
> 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;
← →
Alx2 (2002-03-28 08:05) [31]>Юрий Зотов
>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)
>Неверно, может и другое
Я писал: "А запятую туда вставил, потому что с клавиши "." может прийти либо "." либо ",""
Спасибо за поправку. Действительно, категорично сказал.
Конечно, может прийти нечто другое :)). А оно нам надо?
← →
Alx2 (2002-03-28 08:14) [32]>Юрий Зотов.
Опять исправляюсь:
Вот это я нагнал: :) Как раз в случае <...>.ClassParent is TForm проверка не может работать: ошибка компиляции. Лучше бы я это не писал. Стыдно :(
← →
Lord Warlock (2002-03-28 09:07) [33]Господа, все очень просто.
В дельфе есть глобальная системная переменная
GlobalDecmailSeparator (по моему так, но точно не помню, можно поискать в хелпе по слову DecmailSeparator)
На ОнКреат приложения запоминаешь старый и ставишь какой нужно,
на ОнДестрой - возвращаешь старый и все :)
← →
Alx2 (2002-03-28 09:38) [34]>Lord Warlock © (28.03.02 09:07)
Вопрос в другом: "Как заставить кнопку "." на доп. клавиатуре выдавать DeсimalSeparator во всех формах приложения при любой языковой раскладке?". Его уже решили. Остались некоторые, но скорее всего надуманные, детали.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.04.08;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.007 c