Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
14-22829
Лёша
2002-02-22 15:43
2002.04.08
Посоветуйте хостинг.


3-22548
Atrem
2002-03-13 20:00
2002.04.08
Сортировка НД


3-22553
knyaz17
2002-03-14 16:47
2002.04.08
Где поменять кодировку сообщений сервера Oracle?


1-22730
Gayrus
2002-03-27 03:22
2002.04.08
TComboBox


1-22625
Goblinus
2002-03-27 17:30
2002.04.08
Обработка OnClose





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский