Micha Nelissen wroteCan you explain this a little more detailed? What is the cause of the
flickering exactly? The win32 interface also has this problem.
I am not sure its quite the same issue though it might be.. basically SynEdit calls ExtTextOut on each block of text, for instance on a line with
Procedure MyFunction(someclass : TBlah);
would call ExtTextOut something like 8 times. Now since SynEdit supports using a different background colour for each block of text, then this means ExtTextOut will get called with ETO_OPAQUE.
This means that most of the time a block of text calls ExtTextOut, that block of text will get filled with the current brush before drawing the text. This means the text essentially disapears from the screen and then reapears. Since there are so many blocks this results in constant flashing all over the place every time something is invalidated. So in this case there are 8 potential flashes any time invalidate/repaint etc. What I have done in the GTK interface, is if ETO_OPAQUE is passed, I create a buffer pixmap of the size of the passed rectangle, and perform actual filling and drawing of text on that offset, then draw pixmap, meaning the block is drawn in one step to the screen.
I don't know how easily this could be done in win32 since you would have to create a buffer hdc and hbitmap, calculate relative offsets, based on whether it was buffering or not, then draw to it, which also means possibly a fair bit more amount of memory needed etc.
And I don't think CreateCompatibleDC copies pen brush and font info does it? So you might have to get that and assign it to both.
Assuming I have a clue the appened is an example of what _might_ work. I probably made mistakes, I am not sure of the offset etc. I just threw it together in this e-mail without any double checking or even reading msdn docs so it may not even compile.... But feel free to try (and fix) at your own risk :)
Andrew
Function TWin32Object.ExtTextOut(DC: HDC; X, Y: Integer; Options:
Longint; Rect: PRect; Str: PChar; Count: Longint; Dx: PInteger):
Boolean;
var
Buffered : Boolean;
Buffer : HDC;
BufferBitmap : HBitmap;
bX, bY, bWidth, bHeight : Longint
BufferDrawRect : TRect;
DrawRect : LPRect;
OldBrsh, OldPen, OldFont : hObject;
Begin
Assert(False, Format('trace:> [TWin32Object.ExtTextOut] DC:0x%x, X:%d,
Y:%d, Options:%d, Str:''%s'', Count: %d', [DC, X, Y, Options, Str,
Count]));
//Check for opaque flag and buffer if there
if ((Options and ETO_OPAQUE) 0) and Assigned(Rect) then
begin
//get DC objects
OldBrush := SelectObject(DC, GetStockObject(NULL_BRUSH));
OldPen := SelectObject(DC, GetStockObject(NULL_PEN));
OldFont := SelectObject(DC, GetStockObject(DEFAULT_GUI_FONT));
//reset DC objects
SelectObject(DC, OldBrush);
SelectObject(DC, OldPen);
SelectObject(DC, OldFont);
//Calculate relative size/pos
bX := X - Rect^.Left;
bY := Y - Rect^.Top;
bWidth := Rect^.Right - Rect^.Left;
bHeight := Rect^.Bottom - Rect^.Top;
BufferDrawRect := Rect(0, 0, bWidth, bHeight);
DrawRect := LPRECT(@BufferDrawRect);
//Create buffer
Buffer := CreateCompatibleDC(0);
BufferBitmap := CreateCompatibleBitmap(0, bWidth, bHeight);
SelectObject(Buffer, BufferBitmap);
//get buffer objects and set DC objects
OldBrush := SelectObject(Buffer, OldBrush);
OldPen := SelectObject(Buffer, OldPen);
OldFont := SelectObject(Buffer, OldFont);
buffered := True;
end else begin
//Just use Defaults
Buffer := DC;
bX := X;
bY := Y;
If Asigned(Rect) then
DrawRect := LPRect(DrawRect)
else
DrawRect := nil;
buffered := False;
end;
//Perform Real ExtTextOut
Result := Windows.ExtTextOut(Buffer, bX, bY, Options, DrawRect, Str,
Count, Dx);
If Buffered then begin
//Blt Buffer to screen
Windows.BitBlt(DC, X, Y, bWidth, bHeight, Buffer, 0, 0, SRCCOPY);
//reset buffer objects
SelectObject(Buffer, OldBrush);
SelectObject(Buffer, OldPen);
SelectObject(Buffer, OldFont);
//free bitmap and dc
DeleteObject(BufferBitmap);
DeleteDC(Buffer);
end;
Assert(False, Format('trace:< [TWin32Object.ExtTextOut] DC:0x%x, X:%d,
Y:%d, Options:%d, Str:''%s'', Count: %d', [DC, X, Y, Options, Str,
Count]));
End;