Page 1 of 1
Can I to modify and clear cells content at run time?
Posted: Sun Jan 23, 2011 11:15 pm
by jhonalone
I'm trying to insert barcode and text into existing table cells.
So that, I designed a test procedure, before insert it to proyect.
I've an "EAccessViolation" error that I do not know how to solve.
Can you help me?
Code: Select all
...
table := TRVTableItemInfo.CreateEx(NumR,NumC, rve.RVData);
...
if rve.InsertItem('test', table) then begin end;
...
procedure TForm1.rveDblClick(Sender: TObject);
var
table:TRVTableItemInfo;
i : integer;
r,c : integer;
begin
for i := 0 to rve.ItemCount-1
do if (rve.GetItemStyle(i)=rvsTable) and
(rve.GetItemText(i)='test')
then begin
table := TRVTableItemInfo(EditorActivo.GetItem(i));
table.GetEditedCell(r,c);
table.Cells[r,c].Clear;
table.Cells[r,c].AddNL('Test test test',7,0);
rve.Format;
table.EditCell(r,c);
end;
end;
Posted: Mon Jan 24, 2011 5:18 pm
by Sergey Tkachenko
1) Are rve and EditorActivo the same
2) Your code expects that some table cell is being edited. You should check if table.GetEditedCell(r,c)<>nil
3) Do you want to implement this procedure as an editing operation (undoable?)
In this case:
Code: Select all
procedure TForm1.rveDblClick(Sender: TObject);
var
table:TRVTableItemInfo;
celledit: TCustomRichViewEdit;
i : integer;
r,c : integer;
begin
for i := 0 to rve.ItemCount-1 do
if (rve.GetItemStyle(i)=rvsTable) and
(rve.GetItemText(i)='test')
then begin
table := TRVTableItemInfo(rve.GetItem(i));
celledit := table.GetEditedCell(r,c);
if celledit<>nil then begin
celledit.SelectAll;
// celledit.DeleteSelection;
celledit.CurTextStyleNo := 7;
celledit.CurParaStyleNo := 0;
celledit.InsertText('Test test test');
end;
end;
Posted: Mon Jan 24, 2011 6:24 pm
by jhonalone
Yes, rve and EditorActivo are the same. This is a copy error.
Yes, code is undoable by the editor. I do not want the end user to modify anyware.
I'm trying to do an exact image of DIN-A4 8x3 labels matrix in a table of 8x3 rows/cols. Well, each cell is one barcode label. If the user double-click on one cell then barcode appears into cell, if double-clic again in the same cell, then the cell is cleared and codebar is also cleared.
Therefore, the end user can select and deselect which 8x3 label will be printed.
I have not implemented the labels drawing yet.
Is it possible to draw the codebar directly on the cells canvas? and how can I do it?
I thank you a lot, again.
Posted: Tue Jan 25, 2011 10:06 am
by Sergey Tkachenko
The code I posted above works as an editing operation, i.e. the user can undo it with Ctrl+Z.
If you do not want to allow editing document, it's better using TRichView instead of TRichViewEdit. And the code would be:
Code: Select all
uses CRVFData;
procedure TForm3.RichViewEdit1RVMouseDown(Sender: TCustomRichView;
Button: TMouseButton; Shift: TShiftState; ItemNo, X, Y: Integer);
var ClickedItemNo, ClickedOffs: Integer;
ClickedRVData: TCustomRVFormattedData;
pt: TPoint;
begin
if ssDouble in Shift then begin
pt := Sender.ClientToDocument(Point(X, Y));
Sender.GetItemAt(pt.X, pt.Y, ClickedRVData, ClickedItemNo, ClickedOffs, False);
if (ClickedRVData.GetSourceRVData is TRVTableCellData) and
(TRVTableCellData(ClickedRVData.GetSourceRVData).GetTable.ItemText='test') then begin
ClickedRVData.Clear;
ClickedRVData.AddNL('Test test test', 7, 0);
Sender.Format;
end;
end;
end;
As for drawing, you can try to use table.OnDrawBorder for drawing inside table cell, but I think it's better to insert metafiles in cells.
Posted: Sat Jan 29, 2011 2:22 pm
by jhonalone
Hello again, Sergey!
I just tried both procedures. But the latest procedure can be modified by user, also. Therefore, I decided to use the procedure below.
Code: Select all
...
EtiActiva:Array[0..7,0..2] of Boolean;
//All EtiActiva[r,c] begin at false
...
procedure TFormUnidad1.RichViewEdit1DblClick(Sender: TObject);
var
table : TRVTableItemInfo;
CellEdit : TCustomRichViewEdit;
i : integer;
r,c : integer;
Imagen : TBitmap;
begin
Imagen := TBitmap.Create;
Imagen.Height := 40;
Imagen.Width := 235;
PrinCb.SendToCell('Name Name Name',Imagen.Canvas);
for i := 0 to RVE.ItemCount-1 do
if (RVE.GetItemStyle(i)=rvsTable) and
(RVE.GetItemText(i)='Labels')
then begin
table := TRVTableItemInfo(RVE.GetItem(i));
CellEdit := table.GetEditedCell(r,c);
if CellEdit<>nil
then begin
CellEdit.SelectAll;
if EtiActiva[r,c]
then begin
CellEdit.DeleteSelection;
RVE.ClearUndo;
UpdateUndoMenu;
EtiActiva[r,c] := False;
end
else begin
CellEdit.AddPictureEx('', Imagen, 0, rvvaMiddle);
CellEdit.AddNL('Name Name Name',7,0);
RVE.ClearUndo;
UpdateUndoMenu;
EtiActiva[r,c] := True;
end;
end;
end;
end;
But there is a little problem with this code:
It runs fine if I double-click over the top side of the cells.
If I double-click on the lower half of the cell, nothing appears into cell until I click on another cell or on the upper part of this cell.
I'm very surprised by this.
Can you help me, please?
Many thanks, as always!
Posted: Sat Jan 29, 2011 7:51 pm
by Sergey Tkachenko
Call RVE.Format after using non-editing methods (like AddNL and AddPictureEx)
Posted: Sat Jan 29, 2011 10:59 pm
by jhonalone
Sergey, I tried this option before asking you. Then I got a EAccessViolation error. ( !? )
Well, I don't want to use this type of solution, but I'm thinking about using this code:
Code: Select all
if (r > 0) and (c > 0) // we can't go back from the first cell
then begin
// back to the previous cell
keybd_event(VK_SHIFT,0,0,0); // Down
keybd_event(VK_TAB,0,0,0); // Down
keybd_event(VK_TAB,0,2,0); // Up
keybd_event(VK_SHIFT,0,2,0); // Up
// to the following cell
keybd_event(VK_TAB,0,0,0); // Down
// thus, we go back to the clicked cell
end
else begin // if it is the first cell
// first we go to the next cell
keybd_event(VK_TAB,0,0,0); // Down
// now we go back to the clicked cell
keybd_event(VK_SHIFT,0,0,0); // Down
keybd_event(VK_TAB,0,0,0); // Down
keybd_event(VK_TAB,0,2,0); // Up
keybd_event(VK_SHIFT,0,2,0); // Up
end;
I've tried this code and it seems to run really well.
Thank you again for your efforts and quick answer.
Posted: Sun Jan 30, 2011 1:27 pm
by Sergey Tkachenko
Well, correct, RVE.Format cannot be called from OnDblClick (because it moves the caret outside the cell; it destroys the cell inplace editor, but it is not allowed inside this event).
So use InsertPicture and InsertText instead.