delphirichedittrichedit

Printing a richedit with background colour


I'm outputting text from a delphi TRichedit control to a printer. There is a background image, so I'm using the EM_FORMATRANGE with this logic ...

myrichedit.Perform(EM_FORMATRANGE, 1, Longint(@Range));

... and that works fine except that when the text is rendered it always has a white background regardless of the color of the richedit. Any idea why?

EDIT: From comment posted:

Range is a RANGEFORMAT, and is assigned values like this:

Range.hdc := aCanvas.Handle; 
Range.hdcTarget := aCanvas.Handle; 
LogX := GetDeviceCaps(Range.hdc, LOGPIXELSX); 
LogY := GetDeviceCaps(Range.hdc, LOGPIXELSY); 
Range.rc.Left := x * 1440 div LogX; 
Range.rc.Right := (x+re.ClientWidth) * 1440 div LogX; // (1440=twips/inch)
Range.rc.Top := y * 1440 div LogY; 
Range.rc.Bottom := 5000 * 1440 div LogY; // Some bigish number 
Range.rcPage := Range.rc; 
Range.chrg.cpMin := 0; 
Range.chrg.cpMax := -1;

Solution

  • What I've found is that a solution to this is that you can set the background of individual characters with the code (before adding the text to the richedit) ...

    var
      Format: CHARFORMAT2;
    begin
    ...
     myrichedit.SelStart:=myrichedit.GetTextLen;
     FillChar(Format, SizeOf(Format), 0);
     with Format do begin
         cbSize := SizeOf(Format);
         dwMask := CFM_BACKCOLOR;
         crBackColor := charbackgroundcolor;
         myrichedit.Perform(EM_SETCHARFORMAT, SCF_SELECTION, Longint(@Format));
     end;
     myrichedit.SetText:='Hello';
    

    ... but to get a background color for the whole block of text then do this to draw the text ...

    var
      size : Tsize;
      Range: TFormatRange;
      Rect: TRect;
      LogX, LogY : Integer;
      bm : tbitmap;
      aCanvas : TCanvas;
      ExStyle: DWord;
    begin
      aCanvas:=Printer.Canvas;
    
      Range.hdc := aCanvas.Handle;
      Range.hdcTarget := aCanvas.Handle;
    
      LogX := GetDeviceCaps(Range.hdc, LOGPIXELSX);
      LogY := GetDeviceCaps(Range.hdc, LOGPIXELSY);
    
      Range.rc.Left := x * 1440 div LogX;
      Range.rc.Right := (x+myrichedit.ClientWidth) * 1440 div LogX; // (1440=twips/inch)
      Range.rc.Top := y * 1440 div LogY;
      Range.rc.Bottom := 5000 * 1440 div LogY; // Some bigish number
      Range.rcPage := Range.rc;
      Range.chrg.cpMin := 0;
      Range.chrg.cpMax := -1;  
      myrichedit.Perform(EM_FORMATRANGE, 0, Longint(@Range)); // Measure the formatted text
      rect:=Range.rc;
      rect.Left:=Range.rc.Left * LogX div 1440;
      rect.Top:=Range.rc.Top * LogY div 1440;
      rect.Right:=Range.rc.Right * LogX div 1440;
      rect.Bottom:=Range.rc.Bottom * LogY div 1440;
      acanvas.Brush.Color:=myblockcolor;
      acanvas.FillRect(rect); // Fill the background rectangle
    
      ExStyle := GetWindowLong(re.Handle, GWL_EXSTYLE); // Draw richedit transparently over coloured area
      ExStyle := ExStyle or WS_EX_TRANSPARENT;
      SetWindowLong(re.Handle, GWL_EXSTYLE, ExStyle);
      myrichedit.Perform(EM_FORMATRANGE, 1, Longint(@Range));  
    end;