views:

92

answers:

1

I'm trying to make a "blank" background to place an image on top of. It's not too difficult to create crosshatches by placing a TImage on a form and doing the following:

image1.Canvas.brush.Style := bsDiagCross;
image1.canvas.brush.color := clWhatever;
image1.canvas.FillRect(image1.clientrect);

This works, and I get a crosshatch pattern in clWhatever over a black background. But that's the problem. It's always black, and I can't find any way to specify a background color in case I want something other than black.

Does anyone know how to do this?

+6  A: 

The color of a hatched brush is the foreground color - the color of the hatch itself.

The background color is set separately when using hatched brushes and as far as I know isn't exposed as a property of the TCanvas and thus requires the use of the Windows GDI API SetBkColor() function.

e.g. to draw a red hatch on a white background, add a call to set the background color before drawing using the canvas brush:

image1.Canvas.brush.Style := bsDiagCross;
image1.canvas.brush.color := clRed;

SetBkColor(image1.Canvas.Handle, ColorToRGB(clWhite));
image1.canvas.FillRect(image1.clientrect);

[Update:] NOTE: It appears that in Delphi 2010 (and possibly some earlier version/s) you should call SetBKColor() AFTER setting brush properties. Internally when the canvas creates it's brush it calls SetBKColor() which tramples on any explicit calls to SetBKColor() made prior to referencing the Canvas.Brush. The timing of when the internal canvas brush is created, or the internal use of SetBkColor(), appears to have changed between Delphi 2006 (used when testing the original posting) and Delphi 2010. Whatever the reason it is clearly more reliable to call SetBKColor immediately prior to using it.

Deltics
Just tested this on D2010 under Windows 7, and it doesn't work. I still get a black background.
Mason Wheeler
Well that's interesting. If you do it once it doesn't work, but the second time, it does.
Mason Wheeler
On Delphi 2010 it seems you have to set the background color immediately before using the brush. It appears that modifying the brush affects the background color in 2010 (previously posted solution/tip was done in Delphi 2006). I shall edit the code accordingly.
Deltics
Delphi 2005 calls `SetBkColor(not Brush.Color)` and `SetBkMode(Transparent)` after selecting the brush into the DC. Changing the brush's properties invalidates it and the DC handle. With the brush invalidated, the `FillRect` call re-creates the brush and calls `SetBkColor`. You can trigger that in advance of `FillRect` by reading the `Canvas.Handle` property. Once you do that, you can make whatever manual changes to the DC you want, such as by calling `SetBkColor` yourself. Deltics, unless Delphi 2006 introduced a regression fixed later, I suspect your original test only worked by accident.
Rob Kennedy
Yeah, may have been "lucky". Funny that my luck wasn't the same with D2010 as it was with D2006 tho. Whatever the reason, calling SetBKColor() as LATE as possible before making a call to a Canvas that requires it is the best approach - possibly avoiding using Canvas methods and calling GDI direct is even more advisable (or using a GDI Canvas wrapper that exposes GDI more faithfully, if such exists, which I'm sure it must do, somewhere...).
Deltics