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
Image

Image[/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.