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

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

нужна помощь с событием onkeydown [D7, XP]


serge ©   (2012-05-23 11:18:00) 

Есть компонент tmemo, в него можно вводить только числа и запятую, также надо отлавливать нажатия клавиш ctrl, shift и т.д.

процедура Memo1KeyDown имеет вид:
procedure TformSec9InputData.memoBedThicknessKeyDown(Sender: TObject;
 var Key: Word; Shift: TShiftState);
begin
   key:=OnlyNumerals(key, Shift);
   SymbolCheck(Memo1);
end;


где OnlyNumerals - функция запрета ввода символов, SymbolCheck - процедура удаления символа.

OnlyNumerals
function OnlyNumerals(key:word; Shift: TShiftState):word;
var ch: string;
begin
   ch:= GetCharFromVKey(key);
   if (Shift=[ssCtrl]) and (key=86) then
       begin
           result:=0;
       end
   else if ch='.' then
       begin
           result:=0;
           ShowMessage('Разделитель между целой и дробной частью - запятая');
       end
   else
       if not (ch='0') and not (ch='1') and not (ch='2') and not (ch='3') and not (ch='4')//
          and not (ch='5') and not (ch='6') and not (ch='7') and not (ch='8') and not (ch='9')//
          and not (ord(key)=VK_BACK) and not (ord(key)=VK_DELETE) and not (ord(key)=vk_LEFT)//
          and not (ord(key)=VK_TAB) and not (ord(key)=vk_Right) and not (ch='-')//
          and not (ch=',') and not (ord(key)=vk_CONTROL) and not (ord(key)=vk_SHIFT) //
          and not (ssAlt in Shift) and not (Shift=[ssCtrl]) and not (ord(key)=vk_RETURN) then
              begin
                  result:=0;
                  ShowMessage('Введите цифры или запятую');
              end
       else
           result:=key;
end;


SymbolCheck
procedure SymbolCheck(Memo: TMemo);
var i: integer;
   s: string;
begin
   s:='';
   for i:=1 to length(Memo.Text) do
       if Memo.Text[i]='.' then
               begin
                   Memo.Text:=s;
                   Memo.SelStart:=length(Memo.Text);
                   Exit;
               end
       else
           if (Memo.Text[i]<>'0') and (Memo.Text[i]<>'1') and (Memo.Text[i]<>'2') //
               and (Memo.Text[i]<>'3') and (Memo.Text[i]<>'4') and (Memo.Text[i]<>'5')//
               and (Memo.Text[i]<>'6') and (Memo.Text[i]<>'7') and (Memo.Text[i]<>'8')//
               and (Memo.Text[i]<>'9') and (Memo.Text[i]<>',') then
                   begin
                       Memo.Text:=s;
                       Memo.SelStart:=length(Memo.Text);
                       Exit;
                   end
           else
               s:=s+Memo.Text[i];
end;


Если вводить символы с клавиатуры, то все работает, неправильный символ удаляется. Если делать вставку, то ничего не работает. Заметил Такой момент: если в OnlyNumerals в условии "if (Shift=[ssCtrl]) and (key=86) then" после "result:=0;" добавить ShowMessage, то вставленный текст, если он будет содержать запрещенные символы, - удалится.

Вопрос собственно в том, почему при использовании ShowMessage в Memo1KeyDown выполняются процедуры, следующие за "key:=OnlyNumerals(key, Shift);"? Если же ShowMessage не использовать, то возникает мысль, что onkeydown игнорирует последующие команды


serge   (2012-05-23 11:49:00) [1]

Спасибо за помощь. Я изначально зацепился за onkeydown и функцию OnlyNumerals, остальное уже потом дописывал, и про onchange даже и не думал. Еще раз спасибо за помощь


Медвежонок Пятачок   (2012-05-23 11:43:00) [2]

Ходишь, ходишь в школу,
потом - бац! - вторая смена.
И прощай любимые учителя

что насчет вот такого ввода?

1,2,3,4,5,6,7,8,9


serge   (2012-05-23 11:39:00) [3]

З.Ы. memoBedThickness забыл поменять на Memo1


ProgRAMmer Dimonych   (2012-05-23 11:37:00) [4]

Во-первых,


> if (Memo.Text[i]<>'0') and (Memo.Text[i]<>'1') and (Memo.Text[i]<>'2')
> //
>               and (Memo.Text[i]<>'3') and (Memo.Text[i]<>'4')
> and (Memo.Text[i]<>'5')//
>               and (Memo.Text[i]<>'6') and (Memo.Text[i]<>'7')
> and (Memo.Text[i]<>'8')//
>               and (Memo.Text[i]<>'9') and (Memo.Text[i]<>',
> ') then


пишется как-то так:

if not(Memo.Text[i] in ['0'..'9', ',']) then

и множество ещё константой лучше сделать.

А во-вторых, вопрос: почему бы не сделать это в OnChange, если неправильный символ всё равно только выделяется?


Наверх

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