Page 1 of 1
prevent that only the 1st character in a cell is a number
Posted: Sat Aug 01, 2015 9:45 am
by j&b
Hello,
at the input (memoKeyDown) of a text I want to prevent that only the 1st character in the cell is a number.
Example: 1. Es ... (wrong)
Es steht 1 Baum im Wald (correct)
procedure TForm1.memoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var r,c,cs,rs, v,ItemNo,Offs,StyleNo,ParaNo: integer;
posFlag: boolean;
Cell: TRVTableCellData;
Table: TRVTableItemInfo;
begin
//...
if memo.InplaceEditor<>nil then begin //rveTabelle hat den Focus
rveTable.GetEditedCell(r,c);
if (c=0) and (key>47) and (key<58) then begin //lfd. Nr.
s:= rveTable.Cells[r,0].GetRVData.GetItemTextA(0); //Zellinhalt - necessary ?
ShowMessage(s+#10#10+
'In der 1. Spalte darf als 1. Zeichen keine Zahl stehen !');
SendKeys('{BACKSPACE}',true);
exit;
end;
end; //of if memo.InplaceEditor<>nil
//...
end;
Posted: Sat Aug 01, 2015 12:49 pm
by Sergey Tkachenko
You can also process OnKeyPress and simply assign Key := #0, without sending Bakspace.
(The problem with your code is possibility to undo)
Posted: Sat Aug 01, 2015 2:55 pm
by j&b
[/img]
Posted: Sat Aug 01, 2015 3:15 pm
by j&b
... and (position>1) and ... is wrong.
It should say: ... and (position=1) and ...
if (rveTspalte1=0) and (position=1) and (key>47) and (key<58) then begin[/b]
Posted: Sat Aug 01, 2015 3:23 pm
by Sergey Tkachenko
Assigning Key := 0 in OnKeyDown does not prevent the character for insertion.
You need to use OnKeyPress instead.
Posted: Sat Aug 01, 2015 4:25 pm
by j&b
Thank you for your answere.
I understand the difference between memoKeyDown and memoKeyPress.
But that is not my problem.
I want that a number cannot stand as first character in a cell while I press 1 (a number).
1. Es ... (wrong).
but as x. character: Es waren 2 Versuche. (correct)
I think if I know where caret stands (caretPosition in cell) before I press a number
I can replace the number by #0.
procedure TForm1.memoKeyPress(Sender: TObject; var Key: Char);
begin
if memo.InplaceEditor<>nil then begin
rveTable.GetEditedCell(rveTzeile1,rveTspalte1);
if (rveTspalte1=0) and (carePosition=1) and (pos(key, '1234567890')>0) then begin
key:= #0;
ShowMessage('Zeilen ohne Beurteilungspalten oder weniger als x Spalten ...');
exit;
end;
end; //of if memo.InplaceEditor<>nil
end;
Posted: Sun Aug 02, 2015 10:22 am
by j&b
Because I found no help, I tried some ideas.
Only with procedure TForm1.memoKeyDown(...) I found a solution:
procedure TForm1.memoKeyDown(...)
var ...
begin
...
if memo.InplaceEditor<>nil then begin
rveTable.GetEditedCell(rveTzeile1,rveTspalte1);
if (rveTspalte1=0) and (key>47) and (key<58) then begin
Application.ProcessMessages; //<--------------------------------- !!
s:=rveTable.Cells[rveTzeile1,rveTspalte1].GetRVData.GetItemTextA(0);
if (s<>'') and (pos(s[1],'1234567890')>0) then begin
ShowMessage('Zeilen ohne Beurteilungspalten oder weniger als '+intToStr(cs)+
' Spalten dürfen in der'+#10+'(1. Zeile der) 1. Spalte keine Zahl (lfd. Nr.) haben !');
SendKeys('{BACKSPACE}',true); //works reliable - why not use ?
end;
exit;
end; //of if (rveTspalte1=0) and
end; //of if memo.InplaceEditor<>nil
...
end; //of .memoKeyDown
if someone has a better codierung please tell us
Posted: Sun Aug 02, 2015 11:29 am
by Sergey Tkachenko
This function returns True if the caret is at the beginning of rve.
Pass memo.TopLevelEditor as the parameter.
Code: Select all
function IsCaretAtTheBeginning(rve: TCustomRichViewEdit): Boolean;
var FirstItemIndex: Integer;
ItemNo1, Offs1, ItemNo2, Offs2: Integer;
begin
FirstItemIndex := 0;
if rve.GetItemStyle(0)=rvsListMarker then
inc(FirstItemIndex);
rve.GetSelectionBounds(ItemNo1, Offs1, ItemNo2, Offs2);
if ItemNo1<0 then begin
ItemNo1 := rve.CurItemNo;
Offs1 := rve.OffsetInCurItem;
end;
Result := (ItemNo1=FirstItemIndex) and (Offs1<=rve.GetOffsBeforeItem(ItemNo1));
end;
The function takes into account that:
- there may be a selection that will be removed on insertion
- there may be not only a single text item in this cell
Posted: Mon Aug 03, 2015 7:27 am
by j&b
Thank you for your answere.
Your function refers to the memo, not to a rveZell.
It would be nice if function can tell the position of caret (cursor) in a cell.
Posted: Mon Aug 03, 2015 8:02 am
by Sergey Tkachenko
I forgot to tell, call it for memo.TopLevelEditor. When a cell is being edited, this is the cell editor.