JohnLM 14 Posted September 29, 2023 (edited) I have been searching via google but not turned up any answer to this. 1. Say I have multiple files of similar text and I save them. 2. Then, when I load (or open) any of those text files in TMemo, I want to maintain the last screen layout (line) within the dimensions. I am comparing structures of column (hex/ascii) data in these text files and if I am in the middle of the file in the tmemo and I decide to load another file to quickly compare back/forth with, I want the layout the remain the same but not start from the top of the text file. I know I have to save the last topmost line in a variable but I don't know how to go further in this. TIA. Fig A - this is the layout that opens by default for every load. But I want Fib B if I am scrolling down and stop and decide to load another file. Fig B - if I open at the last layout position this is what I want to see.., not Fig A. Edited September 29, 2023 by JohnLM added images Share this post Link to post
Kas Ob. 121 Posted September 30, 2023 If i understand your request, then you need to restore the position of first visible line In that case you can use this type TForm11 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private FMemo1Position: Integer; procedure Memo1SavePosition; procedure Memo1RestorePosition; public procedure LoadContent; end; var Form11: TForm11; implementation {$R *.dfm} procedure TForm11.Button1Click(Sender: TObject); begin LoadContent; end; procedure TForm11.LoadContent; begin Memo1SavePosition; Memo1.Lines.BeginUpdate; try Memo1.Lines.Clear; while Memo1.Lines.Count < 100 do Memo1.Lines.Add(IntToStr(Memo1.Lines.Count)); finally Memo1.Lines.EndUpdate; end; Memo1RestorePosition; end; procedure TForm11.Memo1RestorePosition; var Current: Integer; begin Current := Memo1.perform(EM_GETFIRSTVISIBLELINE, 0, 0); Memo1.perform(EM_LINESCROLL, 0, FMemo1Position - Current); // or //Memo1.perform(EM_LINESCROLL, 0, FMemo1Position - Memo1.perform(EM_GETFIRSTVISIBLELINE, 0, 0)); end; procedure TForm11.Memo1SavePosition; begin FMemo1Position := Memo1.perform(EM_GETFIRSTVISIBLELINE, 0, 0); end; Share this post Link to post
JohnLM 14 Posted September 30, 2023 Hi. I had found something that works (but does not account for the cursor at this time) but had not the time to post back how I did it. But I will read/consider your method as a possible option, thank you. The method that I have been testing is below. I have a [Load] button that loads streams that I save using the sfBinary format of TStream/TMemoryStream. var form1: TForm1; topline: integer=0; ... procedure TForm1.btnLoadClick(Sender: TObject); begin if mem1.Active then begin mem1.LoadFromFile(txtFilename.text,sfjson); // store the top line of memo into global var on load TopLine := memo1.Perform(EM_GETFIRSTVISIBLELINE, 0, 0); end; btnbufArray.Click; // process array into hex and ascii code and show in memo1 // now, if at any time I was in the memo and scrolling up/down and TopLine > 0 then I update the memo's viewing position. if TopLine > 0 then begin SendMessage(memo1.Handle, EM_LINESCROLL, 0, TopLine); end; Share this post Link to post
Pat Foley 51 Posted September 30, 2023 The trouble with memo need to set word wrap to false to track lines. Here's a way to simply output to image or Paintbox. Painting StringGrid is above my paygrade. To call it pass self and a canvas when the view or the data is changed. procedure DrawCanvasPat(Sender: Tobject; Canvas: TCanvas); begin with Canvas do begin Pen.Width := 3; for var C in [0 .. 9] do // := Low to High do FAD here begin var R := 0; var fields := ['First', '', '', '', 'Mid', '', '', 'H', '', 'Last', 'Ten']; // ShowMessage(fields[0]); TextOut(C * 45 + 45, R + 23, fields[C]); for R in [CSVHeaderTopLine .. 9] do begin var value := (Random(20) - 10); if value > 0 then Pen.Color := clGreen else Pen.Color := clRed; Rectangle(C * 45 + 60, R * 23 + 30, C * 45 + 64, R * 23 + 33); TextOut(C * 45 + 45, R * 23 + 23, value.ToString); // ColorDrawItem2(sgUI, sgUI.Canvas,cellValue.tostring,Lrect,TRue); end; end; end; end; Share this post Link to post