Форум Magic Team


 

Новости:

01.01.2017: Релиз испанской версии Naruto - Ninja Council (GBA)
02.12.2016: Добавлена документация по Kruptar 7
09.10.2015: Обновление перевода игры Battletoads (NES) [версия 1.3]
22.01.2015: Kruptar Open Source
18.10.2014: Релиз обновлённой русской версии Castlevania - Dawn of Sorrow (GBA) от Owls Group
01.05.2014: Релиз русской версии Taiyou no Yuusha Firebird (NES)
24.06.2012: Добавлена доработанная документация и инструкция
26.05.2012: Обновление ORITON [версия 2.050]
11.05.2012: Обновление ORITON [версия 2.048]
11.03.2012: Обновление Kruptar 7 [версия 7.1.1.17]
29.01.2012: Обновление LZ77Restructor 2 [версия 1.02]
01.01.2012: Релиз русской версии Drill Dozer (GBA)

Подробнее на страничке новостей.
Ознакомьтесь с правилами нашего форума.


  • Форум
  • Поиск
  • Вход
  • Регистрация

  • Форум Magic Team »
  • Разное »
  • Программирование »
  • Помощь по Delphi
« предыдущая тема следующая тема »
  • Печать
Страницы: [1] 2 3 4   Вниз

Автор Тема: Помощь по Delphi  (Прочитано 81722 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Помощь по Delphi
« : 27 Февраля 2009, 11:09:59 »
На старом форуме находилась очень полезная тема: http://magicteam.mybb.ru/viewtopic.php?id=4&p=6 . Думаю, её стоит продолжить. Тем более, что у меня появилось затруднение. Постараюсь сформулировать попонятнее.


Хочу наконец научиться создавать собственные компоненты. А конкретнее, собираюсь создать небольшой простенький компонент (HexEasy), который бы позволял работать с числом как в десятичном, так и в шестнадцатеричном представлениях. Не мудрствуя, в качестве базового взяла Edit. Сочла наиболее удобным создать отдельное поле (FValue: Integer), непосредственно содержащее число, десятичное или шестнадцатеричное изображение которого выведено на монитор. По моей задумке, когда фокус находится на данном компоненте, любое нажатие клавиши должно либо игнорироваться, либо приводить к изменению данной переменной. Т.е. обработка события KeyPress должна состоять как бы из трёх этапов:
1. Предварительный анализ введённого символа на его допустимость.
2. Изменение свойства Text элемента.
3. Анализ изменённого свойства Text: преобразование его в значение FValue и в случае необходимости дальнейшая корректировка.

Я пыталась это сделать примерно таким образом:

procedure THexEasy.KeyPress (var key: Char);
begin
 
  . . . . . . . . . . . .            //предварительная обработка символа key
 
  inherited KeyPress(key);
 
  If Text='' then begin
                      FValue := 0;
                      EXIT;
                      end;
  FValue := StrToInt(Text);
  If FValue>FValueMax then begin  //если число больше максимально допустимого...
                                      FValue := FValueMax;
                                      Text := IntToStr(FValue);
                                      end;  //всё это упрощённо, когда работа идёт с десятичным числом

end;


Но в результате вставки в программу примерно такого кода обнаружилось, что свойство Text компонента изменяется лишь после того, как данная процедура полностью закончит свою работу. Т.е. анализируемое в последней части свойство Text имеет содержание, которое было до того, как пользователь нажал клавишу, а мне нужно обработать именно последствия нажатия. Можно ли как-то форсировать изменение свойства Text?

Никогда не создавала компоненты и даже классы, не ругайтесь сильно, если где-то глуплю.
Надеюсь на возвращение, но сейчас меня нет.

Оффлайн Джинни

  • Администратор
  • Сообщений: 1339
  • Репутация: +666/-0
  • Metamorphosis
    • Просмотр профиля
    • Magic Team
Re: Помощь по Delphi
« Ответ #1 : 27 Февраля 2009, 14:59:06 »
{
 !!УБРАТЬ!!
. . . . . . . . . . . .            //предварительная обработка символа key
 
  inherited KeyPress(key);
  If Text='' then begin
                      FValue := 0;
                      EXIT;
                      end;
 !!УБРАТЬ!!
}


 if Key in ['$', 'x', #13] then Key := #0;
 if Key in ['0'..'9', 'A'..'F', 'a'..'f'] then
 begin
  FValue := StrToIntDef(Text + Key, FValueMax); //в случае ошибки будет возвращать FValueMax
  Key := #0;
  If FValue>FValueMax then begin  //если число больше максимально допустимого...
                                      FValue := FValueMax;
                                      end;  //всё это упрощённо, когда работа идёт с десятичным числом
  Text := IntToStr(FValue);
 end;

//всё это будет работать и с шестнадцатиричными числами в формате $123 или 0x123

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Re: Помощь по Delphi
« Ответ #2 : 27 Февраля 2009, 16:05:26 »
Прости, Джинни, но данный алгоритм кривоватенький, поскольку новый символ всегда добавляется в конец, вне зависимости от места расположения курсора. Да и сам курсор после каждого нажатия перемещается на первую позицию поля ввода, что сбивает с толку.

Насколько я знаю, есть свойство SelStart, которое находит/устанавливает позицию курсора. С его помощью данный алгоритм, наверное, получится довести до ума, хотя всё это и будет выглядеть громоздко. Не знаю..., здесь тоже есть подводные камни... Но неужели нет более простого способа непосредственно прочитать уже изменённое свойство Text?
Надеюсь на возвращение, но сейчас меня нет.

Оффлайн Джинни

  • Администратор
  • Сообщений: 1339
  • Репутация: +666/-0
  • Metamorphosis
    • Просмотр профиля
    • Magic Team
Re: Помощь по Delphi
« Ответ #3 : 27 Февраля 2009, 16:55:24 »
Это вообще не алгоритм, а спонтанная демонстрация возможностей. :)
SelStart есть, да. Но значение Text вообще лучше в KeyPress не обрабатывать. Есть событие OnChange - там текст уже изменённый после KeyPress.

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Re: Помощь по Delphi
« Ответ #4 : 27 Февраля 2009, 17:58:19 »
Спасибо, сейчас попробую. Мне в любом случае нужно было писать обработчик события onChange :), поскольку значения могут заноситься в поле ввода не только набором с клавиатуры, но и копированием. Мне нравится, когда всё учтено.  o:)
Надеюсь на возвращение, но сейчас меня нет.

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Re: Помощь по Delphi
« Ответ #5 : 27 Февраля 2009, 21:54:18 »
Упс... При простом вводе с клавиатуры похоже, что всё работает. Но совершенно неожиданно обнаружила, что ограничения, прописанные мною в обработчике события onKeyPress, не позволяют копировать значения в буфер и вставлять из буфера. Сажусь думать дальше.
Надеюсь на возвращение, но сейчас меня нет.

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Re: Помощь по Delphi
« Ответ #6 : 27 Февраля 2009, 23:54:27 »
Почти уверена, что можно добиться нужного мне эффекта, если ограничить нажатие некорректных клавиш с помощью процедуры KeyDown, а затем произвести более тонкую настройку вводимых символов процедурой KeyPress. Но у меня никак не получается заблокировать нажатие некорректных клавиш в процедуре KeyDown. Для простоты предположим, что необходимо заставить программу реагировать исключительно на нажатия цифровых клавиш основного блока клавиатуры. Их коды от 48 до 57. Соответственно, я пишу

procedure THexEasy.KeyDown(var key: Word; shift: TShiftState);
begin
  if not (key in [48..57]) then key:=0;
  inherited KeyDown(key, shift);
end;


Но несмотря на это, в поле всё равно вводятся любые буквы, блокируются всего несколько клавиш, таких как стрелки, Home, End, Delete. И только этими клавишами у меня получается здесь управлять. Скажите, что я делаю неправильно? Как можно с помощью обработчика события onKeyDown заставить программу не реагировать на нажатие любых клавиш кроме специально перечисленных?
Надеюсь на возвращение, но сейчас меня нет.

Оффлайн Джинни

  • Администратор
  • Сообщений: 1339
  • Репутация: +666/-0
  • Metamorphosis
    • Просмотр профиля
    • Magic Team
Re: Помощь по Delphi
« Ответ #7 : 28 Февраля 2009, 08:00:05 »
Не нужен тебе OnKeyDown. Только OnKeyPress и OnChange. В KeyPress только запрет символов, которые нельзя вводить:
if not (Key in ['0'..'9', 'A'..'F', 'a'..'f', '$', 'x']) then Key := #0;

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Re: Помощь по Delphi
« Ответ #8 : 28 Февраля 2009, 10:59:00 »
Цитата: Джинни от 28 Февраля 2009, 08:00:05
if not (Key in ['0'..'9', 'A'..'F', 'a'..'f', '$', 'x']) then Key := #0;

Но при таком запрете перестают работать управляющие комбинации клавиш, такие как <Ctrl+X>, <Ctrl+C>, <Ctrl+V>. В поле ничего нельзя вставить и ничего нельзя оттуда скопировать.

С выспавшейся головой села разбираться, как подобная проблема преодолена в компоненте SpinEdit. Там что-то замудрено, какие-то свои внутренние непонятные переменный, но до сути я докопалась.  8) В результате создала вот такой код:


procedure THexEasy.KeyPress(var key: Char);
begin
  If FSystemHex
    then begin                       //если число 16-ное
           case key of
                 'a','Ф','ф': key:='A';
                 'b','И','и': key:='B';
                 'c','С','с': key:='C';
                 'd','В','в': key:='D';
                 'e','У','у': key:='E';
                 'f','А','а': key:='F';
                 end;
           if not (key in ['0'..'9','A'..'F',#1..#31]) then key:=#0;
           end
    else                               //если число 10-ное
           if not (key in ['0'..'9',#1..#31]) then key:=#0;

  If key=#0
    then Beep
    else inherited KeyPress(key);
end;



Буду доделывать дальше. Спасибо за поддержку. Наверное, скоро появятся новые вопросы.  :-[
Надеюсь на возвращение, но сейчас меня нет.

Оффлайн Джинни

  • Администратор
  • Сообщений: 1339
  • Репутация: +666/-0
  • Metamorphosis
    • Просмотр профиля
    • Magic Team
Re: Помощь по Delphi
« Ответ #9 : 28 Февраля 2009, 12:47:39 »
Цитата: BlueHairLady от 28 Февраля 2009, 10:59:00
Цитата: Джинни от 28 Февраля 2009, 08:00:05
if not (Key in ['0'..'9', 'A'..'F', 'a'..'f', '$', 'x']) then Key := #0;

Но при таком запрете перестают работать управляющие комбинации клавиш, такие как <Ctrl+X>, <Ctrl+C>, <Ctrl+V>. В поле ничего нельзя вставить и ничего нельзя оттуда скопировать.
Ну добавить остальные исключения несложно.

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Re: Помощь по Delphi
« Ответ #10 : 28 Февраля 2009, 13:15:39 »
Ради интереса, а каким образом? Ведь клавиша <Ctrl> в данной процедуре не читается! Как раз именно из-за этого я вчера и застряла.

(Ну кроме того способа, который я применила. Хотя сама не понимаю, как это работает. :-[ Выставила значения #1..#31 просто по аналогии со SpinEdit.)
Надеюсь на возвращение, но сейчас меня нет.

Оффлайн Джинни

  • Администратор
  • Сообщений: 1339
  • Репутация: +666/-0
  • Metamorphosis
    • Просмотр профиля
    • Magic Team
Re: Помощь по Delphi
« Ответ #11 : 28 Февраля 2009, 16:06:01 »
Описать глобальную переменную:

var
 ShiftData: TShiftState;

в OnKeyDown прописать:

ShiftData := Shift;

В OnKeyPress:

if ShiftData = [] then
begin
 if not (Key in [#8, '0'..'9', 'A'..'F', 'a'..'f', '$', 'x']) then Key := #0;
end;

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Re: Помощь по Delphi
« Ответ #12 : 28 Февраля 2009, 16:58:40 »
Вынести значение переменной Shift из обработчика события onKeyDown посредством глобальной переменной... - любопытно. :)  Но мне больше нравится вариант, который был выстрадан мною. ;D


P.S. Проявлю-ка я свой вредный характер и испорчу такую замечательную карму! *MALVINA3*
Надеюсь на возвращение, но сейчас меня нет.

Оффлайн Джинни

  • Администратор
  • Сообщений: 1339
  • Репутация: +666/-0
  • Metamorphosis
    • Просмотр профиля
    • Magic Team
Re: Помощь по Delphi
« Ответ #13 : 01 Марта 2009, 06:39:33 »
Не хулигань. :)

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Re: Помощь по Delphi
« Ответ #14 : 01 Марта 2009, 09:58:06 »
Компонент почти создан! Но баги так просто никогда не сдаются. *F_DISAPPOINTED*

Когда после установки компонента в среду Delphi я помещаю его на форму, то выскакивает предупреждающее окно, которое по начальной задумке должно появляться при попытке пользователя скопировать в поле ввода нецифровую строку. Хотя элемент затем и создаётся, и работает. В какой-то мере такое поведение правильно, посколько текст базового элемента 'Edit1' изображением числа не является. Но как это исправить? Как сделать так, чтобы при создании компонента в поле ввода находился '0'? Я попыталась написать такой код:

constructor THexEasy.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FValueMax := 1000000;
  //Text := '0';
end;


Так вот, выражение "FValueMax := 1000000" Delphi воспринимает абсолютно адекватно. Но если раскомментировать выражение "Text := '0'" , то при компиляции программы выводится сообщение "Control '' has no parent window." и элемент не создаётся. А в SpinEdit было сделано именно так  *SCRATCH* - и никаких проблем. В чём дело?
Надеюсь на возвращение, но сейчас меня нет.

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Re: Помощь по Delphi
« Ответ #15 : 01 Марта 2009, 19:25:15 »
Кажется, до меня что-то начало доходить... Данный сбой происходит из-за того, что в обработчике onChange упоминается свойство SelStart. Но в этот момент элемент ещё вроде бы как не создан, обращение уходит в никуда, отсюда и ошибка. Но без использования данного свойства элемент будет работать криво. Возможно, специально ради этого стоит использовать конструкцию try...except. Буду думать.
Надеюсь на возвращение, но сейчас меня нет.

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Re: Помощь по Delphi
« Ответ #16 : 01 Марта 2009, 21:41:14 »
Ура! Ура! УРА!!! Компонент создан, все баги разбежались. А если вдруг какой покажется, запущу босоножкой! (Эх, побыстрее бы лето...) Теперь можно приниматься и за непосредственно программу.
Надеюсь на возвращение, но сейчас меня нет.

Оффлайн Джинни

  • Администратор
  • Сообщений: 1339
  • Репутация: +666/-0
  • Metamorphosis
    • Просмотр профиля
    • Magic Team
Re: Помощь по Delphi
« Ответ #17 : 02 Марта 2009, 07:01:57 »
Поздравляю :)

Оффлайн Guyver

  • Пользователь
  • Сообщений: 180
  • Репутация: +7/-0
  • Я НЕ ВОЛШЕБНИК - Я ТОЛЬКО УЧУСЬ...
    • Просмотр профиля
    • GUYVERperevod
Re: Помощь по Delphi
« Ответ #18 : 02 Марта 2009, 10:45:06 »
А что за прога будет?

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Re: Помощь по Delphi
« Ответ #19 : 02 Марта 2009, 17:18:40 »
Ничего нового не придумываю. Просто решила свою Поганку переделать на Delphi. Рано мне ещё Круптары писать.*MALVINA3*  Ну естественно, добавлю кое-какие новые возможности. А некоторые старые наоборот уберу.:) Постараюсь добиться максимального соотношения простоты и полезности. Это если успею закончить, у меня не так много времени.


Только что набросала интерфейс главного окна. Увидела, что моему компоненту явно не хватает свойства Enabled и парочки других. (Да, здесь должна пояснить, что я решила изменить базовый класс с TEdit на TCustomEdit. Ну зачем мне куча ненужных настроек?) Решила также сразу на основе первого компонента сделать ещё один, прикрутить к нему стрелочки, как в SpinEdit. Интересно, а получится оба компонента запихнуть в один модуль? Вроде бы всё вышеперечисленное сделать не сложно...*MALVINA2*  Пока не начала... ;D
Надеюсь на возвращение, но сейчас меня нет.

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Re: Помощь по Delphi
« Ответ #20 : 02 Марта 2009, 23:28:39 »
На базе старого элемента сОздала новый, со стрелочками. Аналог SpinEdit, но умеет обращаться с 16-ными числами. Глюков не наблюдается, распугала их портретом Билла Гейтса. Или они убежали созывать другие глюки... В общем, пока их нет. :D  Но у меня крайне большая просьба. Кто-нибудь, пожалуйста, очень прошу, объясните мне, КАК ЭТОТ КОМПОНЕНТ РАБОТАЕТ?!!!

Вставить стрелочки внутрь текстового поля не сложно. Но затем уже внутри элемента нужно как-то перераспределить какие-то рабочие области, чтобы цифры не забегали за стрелки, а сами стрелки не исчезали. Это уже не искусство, это наука! И этой науке я не обучена! Несколько часов копалась в элементе SpinEdit, но толком ничего не поняла. Куча каких-то то ли констант, то ли переменных, то ли функций, которые приходят вообще из других модулей... Ничего не понятно. *SCRATCH*  Просто тупо скопировала ключевые места.


P.S. Люблю сама с собой поболтать. ;D
Надеюсь на возвращение, но сейчас меня нет.

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Re: Помощь по Delphi
« Ответ #21 : 06 Марта 2009, 19:13:18 »
Никто случайно с такой проблемкой не сталкивался? :-[  В общем, как писала ранее, создала два собственных компонента, запихнула их в один модуль, установила, вроде бы всё работало нормально. Затем мне понадобились цветные кнопки. Нашла рецепт на http://delphiworld.narod.ru/base/change_button_color.html, скопировала, по началу тоже никаких проблем. Но вот незадача: когда перезапускаешь компьютер, тот "забывает", где находится файл с этой самой цветной кнопкой. Выводится сообщение "File not found: 'ColorButton.dcu'". Файл на месте, где и положено находиться, просто почему-то Delphi его не видит. %) Поэтому на протяжении последних нескольких дней компонент каждое утро приходится устанавливать в среду Delphi заново. После этого всё снова начинает работать, но только до следующей перезагрузки компьютера. *SCRATCH*


В принципе, мне не составит труда запихнуть текст этого компонента в свой модуль. Так наверное и сделаю, если никто не подскажет другой вариант. Но всё же мне бы хотелось, чтобы мои компоненты были в одной папке, а чужие - в другой.
Надеюсь на возвращение, но сейчас меня нет.

Оффлайн Джинни

  • Администратор
  • Сообщений: 1339
  • Репутация: +666/-0
  • Metamorphosis
    • Просмотр профиля
    • Magic Team
Re: Помощь по Delphi
« Ответ #22 : 07 Марта 2009, 09:09:25 »
Tools->Environment Options->Library->Library Path->Нажать "..."->выбрать папку где лежит твой модуль ColorButton.dcu->Нажать "OK"->Нажать "Add"->OK, OK

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Re: Помощь по Delphi
« Ответ #23 : 07 Марта 2009, 10:46:27 »
Надо же, сегодня всё запустилось без проблем! Вчера вместо того, чтобы просто нажать Component->Install Component, решила всё переделать с самого начала, с чистого листа (вернее, файла). Первым делом снова щёлкнула на Component->New Component, образовавшийся шаблон заменила скопированным текстом модуля, сохранила - и уже новый файл вмонтировала в среду Delphi. Хочется верить, что проблем с этим и дальше не будет.

Вот почему так получается? Сижу над проблемой, думаю, решения не вижу. Стоит описать ситуацию на форуме - и через пару часов к самой приходит озарение?!
Надеюсь на возвращение, но сейчас меня нет.

Оффлайн BlueHairLady

  • Пользователь
  • Сообщений: 41
  • Репутация: +8/-0
    • Просмотр профиля
    • http://bhlady.narod.ru/
Re: Помощь по Delphi
« Ответ #24 : 12 Марта 2009, 12:03:23 »
Не дадите совет? Наивное затруднение. :-[  У меня в программе несколько форм и мне бы хотелось, чтобы внутри каждой из них существовало несколько переменных, которые были бы видны во всех процедурах данной формы, но не были бы видны из других форм. Как это положено делать? Засунуть их в раздел private объявления типа формы или создать ещё один блок var в разделе реализации (т.е. ниже слов implementation   {$R *.dfm})?
Надеюсь на возвращение, но сейчас меня нет.

  • Печать
Страницы: [1] 2 3 4   Вверх
« предыдущая тема следующая тема »
  • Форум Magic Team »
  • Разное »
  • Программирование »
  • Помощь по Delphi
 

  • SMF 2.0.12 | SMF © 2011, Simple Machines
  • XHTML
  • RSS
  • Мобильная версия

  • GreenUP by Neekiinh0.

Размер занимаемой памяти: 2.25 мегабайта.
Страница сгенерирована за 0.096 секунд. Запросов: 73.