Home
What's New
Delphi 3.0 Tips
Questions
Development Tools
Links

Prevent Flickering in a RichEdit

If you're doing a series of operations with a RichEdit and you only want the user to be able to see the end results and not everything done to the RichEdit to get there, you need to stop the RichEdit from redrawing. You can use the Perform function with EM_SETREDRAW, but a problem occurs if a function that turns redraw off and then on calls another function that turns redraw off then on. The called function will turn redraw back on before the callee would have, and the callee probably doesn't want it turned back on until it turns it back on itself.

Here's the solution. You create a property called RedrawOn which you assign a boolean to turn on or off. The thing is, you have to assign it true as many times as you assign it false for redraw to be turned back on. For instance, if you assign RedrawOn to false 5 times, you must assign RedrawOn to true 5 times before it comes back on. Below is the code to implement this. I assume the programmer has a RichEdit called Edit on a Form called MainForm.

TMainForm = class(TForm)
...
private
  procedure SetRedraw(value : boolean);

  property RedrawOn : boolean
    write SetRedraw;
...
procedure TMainForm.SetRedraw(value : boolean);
const redrawCount : integer = 0;
begin
  if value then begin
    assert(redrawCount > 0);
    dec(redrawCount);
    //Don't want Edit to be redrawn if it's not visible
    if Edit.Visible and (redrawCount = 0) then
      Edit.Perform(WM_SETREDRAW, 1, 0);
  end else begin
    if redrawCount = 0 then Edit.Perform(WM_SETREDRAW, 0, 0);
    inc(redrawCount);
  end;
end;
Notes:
Invalidating Edit while redraw is off has no effect, so if you need to invalidate it, do it after you set redraw on.

If you want redraw on the have a read property, just make redrawCount a data member of MainForm and write a function that returns true when redrawCount = 0.