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.