Get Backgroundcolor of themed TListView - delphi

Since XE2, there are several themes that can be used for your application. E.g. Carbon that changes the background color of the TListView to gray besides other things.
Is there any way to get this color?
TListView.Color returns white altough the background is some kind of gray.
I tried using StyleServices.GetElementDetails with a snippet like this:
var lColor: TColor;
lDetails: TThemedElementDetails;
if StyleServices.Enabled then
begin
lDetails := StyleServices.GetElementDetails(tlListviewRoot);
StyleServices.GetElementColor(lDetails, ecFillColor, lColor);
end;
But GetElementColorfails and returns false. Am I using the wrong parameter? Or is my approach just wrong.
The possible parameters can be found here:
TThemedListView
TElementColor
Thank you.
P.S.: I also read this post but the answer didn't help me so far.

To get the background color of the TListView that has a StyleHook implemented :
uses Vcl.Themes;
var Color : TColor;
Color := StyleServices.GetStyleColor(scListView);

Related

Delphi DrawThemeBackground on timage causing white background

I want to use Windows's native look and I am trying to learn how to do it.
I am trying to paint timage.canvas with Windows toolbutton background but the background of timage seems White and it doesnt seem same as Windows,
how can i fix that?
here is my code;
procedure TForm1.Button1Click(Sender: TObject);
var
theme: HTHEME;
begin
theme := OpenThemeData(Handle, 'TOOLBAR');
// error checking omitted for brevity
try
DrawThemeBackground(
theme,
Image1.Canvas.Handle,
TP_BUTTON,
TS_HOT,
Image1.ClientRect,
nil
);
finally
CloseThemeData(theme);
end;
end;
here is the picture of result when i applied theme on timage:
You should ask for a 'BUTTON' theme, not 'TOOLBAR' if you want a button.
theme := OpenThemeData(Handle, 'BUTTON');
Also this line should come before the try.
For a list of theme parts and states see this
From the above list you will see that the iPartId and iStateId you used are not the right ones (although worked). I would suggest BP_PUSHBUTTON and PBS_HOT instead.
procedure TForm3.Button2Click(Sender: TObject);
var
theme: HTHEME;
begin
theme := OpenThemeData(Handle, 'BUTTON');
try
DrawThemeBackground(theme,
Image1.Canvas.Handle,
BP_PUSHBUTTON,
PBS_HOT,
Image1.ClientRect,
nil);
finally
CloseThemeData(theme);
end;
end;
Edit Here's an image just for comparison of a TToolButton on a TToolBar in Windows 7:
As you see the TToolbutton (on TToolbar at the top) when 'hot', doesn't have the bluish appearance as a TButton. Beneath the toolbar are your code on the left and my suggestion on the right. Is it the difference in lightgray / white or lightgray / bluish you ask about?

Why does TDrawGrid.OnDrawCell draw black background when Brush.Style is bsFDiagonal?

I have the following code (assigned to DrawGrid1.OnDrawCell event):
procedure TForm1.DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
DrawGrid1.Canvas.Brush.Style:= bsFDiagonal;
DrawGrid1.Canvas.Brush.Color:= clSkyBlue;
DrawGrid1.Canvas.FillRect(Rect);
end;
It always draws black background even if the DrawGrid1.Color properties has been set to clRed. I also tried to change the Pen and Font properties, no luck.
What did I miss here?
ps: I have checked this code: Diagonal brush style gives me black area.
I have failed to see what is the difference between the question and the answer (apart from the commented line) and that code not working for me, as I mentioned, I already tried to change Pen properties without any result.
All I want is red background with sky blue diagonal lines.
Solved, have to add SetBKColor() before FillRect:
DrawGrid1.Canvas.Brush.Style:= bsFDiagonal;
DrawGrid1.Canvas.Brush.Color:= clSkyBlue;
SetBkColor(DrawGrid1.Canvas.Handle, ColorToRGB(clRed));
DrawGrid1.Canvas.FillRect(Rect);
I still don't know why, but it's working.

Set Disabled Background and Text Color in RichEdit Control in Delphi

I have developed a custom component derived from a richedit component.
I used the example in PBExEdit created by Peter Below to erase and repaint the background. This is successful in having a different color for the richedit background when disabled. However, the text that is in the richedit is not repainted. I have attempted to use the following lines to no success. The component does not even render on run.
procedure WMPaint...
var Format: TCharFormat2;
begin
//call to erase and paint bg using WMEraseBkGnd...
//Here are the lines that are not working.
try
FillChar(Format, SizeOf(Format), 0);
Format.cbSize := SizeOf(Format);
Format.dwMask := CFM_COLOR;
Format.crTextColor := ColorToRGB(Font.Color);
Perform(EM_SETCHARFORMAT, SCF_ALL, LongInt(#Format));
end;
end;
I also tried the EM_SETBKGNDCOLOR and that did not work.
I think there is more required to the EM_SETCHARFORMAT... but I am at a loss.
Any assistance would be appreciated.
Thanks
Barry

Transparent image control with resampling in Delphi

I have a form with a background image (painted on the form in Form1.Repaint).
What I am a looking for: A transparent image control, that can smoothly resize (resample) the loaded image.
(I need it to be transparent because the forms background image should be visible through)
What I've tried:
Standard TImage: It's transparent, but it does not resample.
Graphics32 / Image32: Resamples beautifully, but it's not transparent.
I have googled for several hours now for fixes or work-arounds, but without much of a solution. This has nothing to do with the image loaded into Image32 being transparent, but instead the background color of the control still being white (white = the color-property of the Image32 control, and setting it to clNone does not work). This is apparently as designed
GR32ex (The GR32 Extension Components Pack), which supposedly adds a Transparent-property, however it has not been updated in many years, and I can not install it. It throws a gazillion errors on Delphi 2010 and Graphics32 v. 1.9.
Can anybody think of a solution or workaround? All I want is a control with transparency and resampling.
Thanks!
I'm surprised that TImage32 doesn't do transparency. Are you really sure that is the case?
Anyway, if that is so, I would combine the transparency support of TImage with the re-sampling ability of TBitmap32 to build a solution that way. Keep the original image in a TBitmap32 instance. Whenever you need to load it into the TImage component, for example when re-sizing, use TBitmap32 to perform an in-memory re-size and load that re-sized image.
In fact, if you are already painting the form's background yourself, why not paint the image yourself and simply do away with the image control?
Update 1: Websearch reveals a simple way to make TImage32 transparent: http://graphics32.org/news/newsgroups.php?art_group=graphics32.general&article_id=9505
Update 2: The link above is now dead, and the newsgroups can only be accessed via NNTP. I can't be 100% certain, but I think that the linked post was by Michael Haralabos and contained the following file:
unit GR32_ImageEx;
// Transparent TImage32 by Michael Haralabos
interface
uses
Windows, Messages, Classes, GR32_Image, GR32;
type
TImage32Ex = class(TImage32)
private
FTransparent: Boolean;
procedure SetTransparent(const Value: Boolean);
public
procedure ExecClearBackgnd(Dest: TBitmap32; StageNum: Integer); override;
published
property Enabled;
property Transparent: Boolean read FTransparent write SetTransparent;
end;
procedure Register;
implementation
procedure TImage32Ex.ExecClearBackgnd(Dest: TBitmap32; StageNum: Integer);
var
P: TPoint;
SaveIndex: Integer;
begin
if FTransparent and Assigned(Parent) and
not (Assigned(Bitmap) and (BitmapAlign = baTile)) then
begin
SaveIndex := SaveDC(Dest.Handle);
GetViewportOrgEx(Dest.Handle, P);
SetViewportOrgEx(Dest.Handle, P.X - Left, P.Y - Top, nil);
IntersectClipRect(Dest.Handle, 0, 0, Parent.ClientWidth, Parent.ClientHeight);
Parent.Perform(WM_ERASEBKGND, Dest.Handle, 0);
Parent.Perform(WM_PAINT, Dest.Handle, 0);
RestoreDC(Dest.Handle, SaveIndex);
end
else
inherited;
end;
procedure TImage32Ex.SetTransparent(const Value: Boolean);
begin
if FTransparent <> Value then
begin
FTransparent := Value;
Invalidate;
end;
end;
procedure Register;
begin
RegisterComponents('Graphics32', [TImage32Ex]);
end;
end.
Another topic here suggests that this may be what the now dead link referred to: Delphi TImage32 - how to make the component invisible if no picture is loaded?

Extending DBGrid with some row colors

I want to extend DbGrid functionality to add colors on odd and even rows. So i wrote this
procedure TGridx.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
var
row : Integer;
begin
inherited;
row := Self.DataSource.DataSet.RecNo;
if (row mod 2 = 0) then
Self.Canvas.Brush.Color := FColor1 //some color
else
Self.Canvas.Brush.Color := FColor2; //some color
end;
What i am doing wrong ?
The event you want is called DBGridDrawColumnCell, and you need to decide whether to turn the DefaultDrawing property on or off, and the way you handle DBGridDrawColumnCell changes accordingly. For your case, you just set the colors, but leave DefaultDrawing true, and don't do any other canvas.Text or GDI drawing.
A recent question I asked here showed that in later Delphi versions (2010,Xe,Xe2) you ALSO sometimes need to call Canvas.Refresh for both TDBGRID and TListView, when changing canvas properties in ownerdraw events but that doesn't apply to delphi 7.
you should try also 3d party solution which are free, and extends already a lot the DBGrid, like the ones provided by the Jedi project
Opc0de, may be you should override not the "DrawCell" method but "DrawCellBackground"?
Try drawing the cell as well after the brush color is defined:
Self.Canvas.FillRect(ARect);

Resources