Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.05.30;
Скачать: CL | DM;

Вниз

копмонент ValueListEditor - событие OnKeyPress   Найти похожие ветки 

 
Idiliya ©   (2004-05-10 23:02) [0]

При написании курсовой работы возникла такая проблема:
На отдельной форме у меня расположен компонент ValueListEditor (Name, допустим, ValueListEditor1), в котором пользователь может менять значение параметров (задача по мат.физике – там параметров очень много). Чтобы пользователь вводил туда только цифры и запятые, я сделала обработчик события OnKeyPress, но вот беда – это событие действует для всего ValueListEditor сразу, а не для каждой строки отдельно. Все вроде бы и ничего, но пользователь может поставить сколько угодно запятых. Это не есть правильно. Чтобы вставить счетчик запятых, надо знать, в какой строке произошло нажатие клавиши. В обычном Edit посчитать легко, но как отловить в момент нажатия пользователем клавиши, где введен символ, чтобы затем номер строки передать дальше в обработку? Та же проблема с компонентом StringGrid. Подскажите как быть, уж очень удобные эти компоненты для данной задачи.


 
KilkennyCat ©   (2004-05-11 01:33) [1]

что касается запрета на ввода чего-то:

есть такое понятие - маска.
установить можно в ValueListEditor1GetEditMask
счетчик запятых - излишне. достаточно булевскую переменную. Если в строке есть запятая - она принимает значение истина, и пока истина другую не поставить.

Как отлавливать строку ввода...

procedure TForm1.ValueListEditor1GetEditText(Sender: TObject; ACol,
 ARow: Integer; var Value: String); - это то, что Вам нужно.

Прчем, здесь АСол - столбец текущий, АРоу - строка, Value - тот самый текст, который вводится.

Для стриннгрида то же самое.


 
Idiliya ©   (2004-05-11 23:34) [2]

Уважаемый KilkennyCat! Огромное спасибо за ответ.
procedure TForm1.ValueListEditor1GetEditText обрабатывает каждую строку отдельно, это значит мне пришлось бы написать 18 процедур по обработке своих переменных. Это действительно выход, если бы я не наткнулась на свойство SelectCell, которое определяет выделенную ячейку, в нем я определяю, есть ли в строке запятая, и передаю сведения об этом во флажок g_vfComma описанный глобально (спасибо за идею – счетчик утяжелял процедуру на несколько лишних строк).
Дальше при работе с этой строкой каждое нажатие пользователя контролируется второй процедурой и отсекает лишние запятые и др. недозволенные символы.
Идея с маской тоже привлекательна, не подскажете, где можно подробнее прочитать про маски? Я как-то не сталкивалась раньше с ними.
С Вашего позволения приведу на радостях код своих двух процедур - работает:
Name ValueListEditor1 = VaLiEd
//====================================================
procedure TFormVar.VaLiEdSelectCell(Sender: TObject; ACol,
 ARow: Integer; var CanSelect: Boolean);
var icom : Integer;  //icom - номер позиции запятой в тексте
begin
   icom := pos(",", FormVar.SecVaLiEd.Cells[ACol,ARow]);
//если icom пуста - запятая не встретилась:
   if icom = 0 then g_vfComma := FALSE
//если icom не пуста - запятая есть:
     else g_vfComma := TRUE;
end; {VaLiEdSelectCell}
//====================================================
procedure TFormVar.VaLiEdKeyPress(Sender: TObject; var Key: Char);
begin
 case Key of
   "0".."9":                   ; // цифра
   "."        : Key := ","  ; //точка заменяется на запятую
   ","        :                 ;  //запятая
   #8       :                 ; // клавиша <Back Space>
   #13     :                 ; // клавиша <Enter>
   //остальные символы запрещены
   else Key := Chr(0); //символ не отображать
 end;
 if Key = "," then   //если символ - запятая
  begin
    //если запятая уже есть - не пропускаем этот символ
    if g_vfComma then Key := Chr(0)
     else g_vfComma := TRUE;  //теперь точно есть
  end;
end; {VaLiEdKeyPress}
//====================================================


 
Idiliya ©   (2004-05-12 00:41) [3]

Ах, да. Это не панацея - если стереть запятую в строке, назад ее не поставишь, пока не выделишь строку заново, чтобы вызвать SelectCell :^)
Надо подумать...


 
Idiliya ©   (2004-05-12 01:03) [4]

Ага! Если из процедуры SelectCell передавать не флаг о наличии запятой, а номер строки, то остальную начинку можно аккуратно перенести в KeyPress и все заработает!
Кажется, я пишу сама себе... Того и гляди в орех загремлю :)


 
KilkennyCat ©   (2004-05-12 03:06) [5]

Да нет, не загремите, я вижу :) Просто трезвел. Сейчас подумаю.


 
KilkennyCat ©   (2004-05-12 03:44) [6]

Все таки непонимаю насчет 18 процедур...
о маске можно прочитать, если набрать TEditMask ctrl+ F1, хотя, наверное, это не подойдет...


 
Petr V. Abramov ©   (2004-05-12 04:12) [7]

Если проблема в том, что "надо знать, в какой строке произошло нажатие клавиши", то Вам поможет св-во Row. Есть у всех потомков TCustomGrid, правда, оно protected.

type
 TFriendGrid = class(TCustomGrid);
-----
procedure ValueListEditor1.KeyPress( --
---
 if TFriendGrid(Sender).Row = 1 then
   ПередатьДальше


 
KilkennyCat ©   (2004-05-12 04:18) [8]

Мда... старею. Точно мне начнут LMD ставить...

Вообщем, думаю, Вы уже справились :)

но на всякий случай мой вариант:

 Row, col : integer; // глобальные

procedure TForm1.ValueListEditor1DrawCell(Sender: TObject; ACol,
 ARow: Integer; Rect: TRect; State: TGridDrawState);
begin
 Row := Arow;
 col := Acol + 1; // пришлось добавить, то ли я глючу, то ли делфи, то ли где-то скрылся столбец. Скорее - первое.
end;


Ваш код с моей переделкой, чтоб меньше было... :)

procedure TForm1.ValueListEditor1KeyPress(Sender: TObject; var Key: Char);
begin
 case Key of
  "0".."9", #8, #13  : ;
  ".", "," : if pos(",", ValueListEditor1.Cells[col, row]) <> 0 then Key := Chr(0) else if key = "." then key := ",";
  else Key := Chr(0);
end;
end;


 
Вованчик ©   (2004-05-12 08:09) [9]

можно без всяких переменных на OnKeyPress

if Pos(",", ValueListEditor.Values[ValueListEditor.Keys[ValueListEditor.Row]]) > 0 then
   begin
     if not (Key in ["0".."9", #8]) then
       Key := #27;
   end
 else
   if not (Key in ["0".."9", ",", #8]) then
     Key := #27;


 
idiliya ©   (2004-05-14 14:53) [10]

Аха, Вовчик.
Только ValueListEditor.Row не бывает, потому все равно глобальная переменная нужна для передачи этой самой ROW.
А в остальном, действительно чистенький код получается.
Спасибо :)
Вопрос закрыт.


 
Petr V. Abramov ©   (2004-05-14 17:25) [11]

> Только ValueListEditor.Row не бывает,
 Не путайте "не бывает" и "находится в protected"



Страницы: 1 вся ветка

Текущий архив: 2004.05.30;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.026 c
4-1081879825
AndersoNRules
2004-04-13 22:10
2004.05.30
Trouble s WM_ENDSESSION. ne vizivaezza prozzedura


14-1084540703
Mehriddin
2004-05-14 17:18
2004.05.30
Help me


14-1084111140
VID
2004-05-09 17:59
2004.05.30
Как выполнить макрос в Excel ?


14-1083921039
Den_AK20000
2004-05-07 13:10
2004.05.30
Компоненты в стиле Outlook 2003


3-1084053792
Shade_
2004-05-09 02:03
2004.05.30
Суммирование полей