0

I have a memo field where instructions on how to use my GUI can be displayed. I have both horizontal and vertical scroll bars enabled for the memo. Both scroll bars show as the instructions are detailed and exceed the frame both vertically and horizontally. However, the vertical scroll bar is always at the bottom, and so unless the user scrolls up, he will miss the instructions at the beginning. The horizontal scroll bar is correctly at the left. Is there some property of the memo that I need to change in the Object Inspector to ensure that the vertical bar is on top so that the user can read the instructions from the beginning?

I have saved the instructions as a string called Instructions. I copy this string into the memo by means of the following code:

procedure TfrmHSR.mmuDispInstructionsClick(Sender: TObject); //display instructions in Memo field var DispText: string; begin Memo1.Clear; DispText := Wraptext(Instructions, 125); Memo1.Lines.Add(DispText); mmuDisplayClear.Enabled := True; mmuFileSave.Enabled := False; //if input file created and opened, allow display of input data if Assigned(InputFile) then //if TStringList has been created begin if (InputFile.Count > 0) then mmuDispData.Enabled := True else mmuDispData.Enabled := False; end else mmuDispData.Enabled := False; //if results available, allow display if Assigned(OutputFile) then //if TStringList has been created begin if (OutputFile.Count > 0) then mmuDispResults.Enabled := True else mmuDispResults.Enabled := False; end else mmuDispResults.Enabled := False; mmuDispInstructions.Enabled := False; end; 
17
  • How are you filling the memo? I can't replicate this in a quick test app. Commented Dec 9, 2013 at 1:09
  • If you're going to keep the caret on the upper left corner, then I don't think there's an explicit setting to do so. However, you can call this Memo.Perform(EM_SETSEL, 0, 0); Memo.Perform(EM_SCROLLCARET, 0, 0); after you add the lines. Commented Dec 9, 2013 at 1:09
  • I have saved the instructions as a long string (with plenty of line breaks) that is displayed when the user clicks on the "Display Instructions" sub-menu option, which is part of a "Display" menu (other things can be displayed in the menu field as well, such as the uploaded data). Commented Dec 9, 2013 at 1:16
  • 2
    @user1505202, here is the code where I've reproduced your problem and where I've been able to move the caret to top. (however, as Ken said, in that code using Clear and Add is useless; coincidentally I pointed this out today). Commented Dec 9, 2013 at 1:44
  • 2
    Thanks, @TLama. It worked. When I first tried it, I had put the lines before the `Line.Add' statement, assuming that I need to first set the scroll bar before I add anything. But I see that you added the two lines after. I did too, and it worked. Thanks much. And thanks to Ken too for the tips. Commented Dec 9, 2013 at 1:58

2 Answers 2

2

The simplest fix for the problem you're having is simply to not use TMemo.Clear and TMemo.Add, but to directly assign to the Text property as a whole. (You have all the text at once, so there's no need to use Add at all.)

I've taken the liberty of making some other minor changes to your code that you might also find helpful; IMO it's a little clearer to read, and somewhat shorter. :-)

//display instructions in Memo field procedure TfrmHSR.mmuDispInstructionsClick(Sender: TObject); var DispText: string; begin DispText := Wraptext(Instructions, 125); Memo1.Text := DispText; mmuDisplayClear.Enabled := True; mmuFileSave.Enabled := False; //if input file created and opened, allow display of input data //if TStringList has been created mnuDispData.Enabled := Assigned(InputFile) and (InputFile.Count > 0); //if results available, allow display //if TStringList has been created mnuDispResults.Enabled := Assigned(OutputFile) and (OutputCount > 0); mmuDispInstructions.Enabled := False; end; 
Sign up to request clarification or add additional context in comments.

3 Comments

thanks. Your code is certainly shorter. I also did not know that you could use assign in this manner: mnuDispData.Enabled := Assigned(InputFile) and (InputFile.Count > 0); mmuDispInstructions.Enabled := False; instead of the more cumbersome if statement: ` if Assigned(InputFile) then begin if (InputFile.Count > 0) then mmuDispData.Enabled := True else mmuDispData.Enabled := False; end else mmuDispData.Enabled := False;`. But what happens if the Input file has not been created and/or nothing has been added to the OutputFile? What does the assignment do?
By default, Delphi does short-circuit Boolean evaluations, which means if the first condition is false, the second never executes. So in the case of InputFile, for instance, if Assigned returns false, the InputFile.Count - 1 never executes. If Assigned is true, then the InputFile.Count is evaluated. If both are true, then the entire expression returns true (because of the and), and that is assigned to the Enabled property of the menu item. If either returns false, then the entire expression returns false (again, because of the and), and that is assigned to Enabled.
Nice. Thanks for the explanation. I hope to think like a programmer some day! :0( But this forum has been an immense help! Thanks again.
0
//if you need to add the lines using lines.add() you can use this... procedure TForm2.Button1Click(Sender: TObject); var I: Integer; begin for I := 0 to 1000 do begin memo1.Lines.add('line ' + intToStr(i)); end; SendMessage(Memo1.Handle, EM_SETSEL, 0, 0); SendMessage(Memo1.Handle, EM_SCROLLCARET, 0, 0); end; 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.