Draw an image instead of window caption - delphi

I need to do something which seems to be easy, but I'm searching for days with no success.
I have a window of fixed size (say 500*250) and need to replace the whole caption bar with a fixed size JPEG (or better PNG) image (say 500*25).
There are lots of samples talking about Glass, Aero, DWM, blah blah blah. But I just need to draw a fixed image!
I've already tried this, but it doesn't work:
procedure TForm1.Button1Click(Sender: TObject);
var
bmp:TBitmap;
DC:HDC;
begin
DC:=GetWindowDC(form1.Handle);
bmp:=tbitmap.Create;
bmp.SetSize(500, 25);
bmp.Canvas.TextOut(5,5,'Helloooooooooooooooooo');
BitBlt(dc,0,0,500,25,bmp.Canvas.Handle,0,0,SRCCOPY);
bmp.Free;
ReleaseDC(form1.Handle,DC);
end;
It should work both on XP and Vista/7. Please help.
P.S: I have Delphi XE.

You can do so by using VCL Styles.
You can change the appearance of the Windows caption bar like that by using the Delphi integrated Bitmap style designer to change a custom style and then use that Style in your application.
If you don't want to enforce the style to the whole application you can set the StyleElements property of the form to only include seBorder, this means that only the border aka caption of your application will be rendered using your custom style.
If you're working in Delphi XE2 then you won't be able to use the StyleElements property but that is just a minor obstacle, it just means that you will have to resort to using StyleHooks to implement the same behaviour and there is enough documentation on how to do that here.
Sadly, if your Delphi version is older then XE2 then you won't be able to use VCL Styles.
Another but rather unpleasant way would be to create a borderless form by changing the BorderStyle property to bsNone and then implementing your image in a way that it would act as a title bar, processing all actions made on the image and sending appropriate Messages to the application.

You can either:
Intercept the WM_NCPAINT message and custom-draw the caption bar manually.
Remove the caption bar altogether, by using SetWindowRgn() or overriding the CreateParams() method to remove the WS_CAPTION style, and then use the form's OnPaint event, or even a TImage, to display the graphic at the top of the form's remaining client area.
The simplest solution would be to use CreateParams() and TImage.

Related

Delphi - Disable [x] Close Button in VCL Styles

I'd like disable [X] close Button with VCL Style in DX Berlin.
Wy this code do not work wiht VCL Style?
EnableMenuItem(GetSystemMenu(Form3.Handle, LongBool(False)),SC_CLOSE, MF_BYCOMMAND or MF_GRAYED);
If you set the action in the FormClose event to caNone, when you try to close the form (clicking on the red cross) nothing is going to happen. In this way you can disable the button.
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//You cannot type only caNone, otherwise you'll get a compiler error
Action := TCloseAction.caNone;
end;
You can find caNone in System.UITypes; read the documentation for more information.
When using VCL Styles by default style affect the appearance of fonts being used, client area of your form and also your forms border (this also include minimize, maximize and close buttons).
So from what I see you have two options:
You could change StyleElements property of your form to [seFont, seClient] which means that style will only be applied to used fonts and client area of your form but the border area of your form would be unstyled and rendered by OS.
You modify the style at runtime in order to achieve desired effect. Unfortunately I don't have enough experience with Styles to present you with an example of how to achieve this.

Change TToolBar background color

I got a problem, that I can't normally change the background color (e.g. clwhite) of TToolBar with its property ToolBar.Color. I'm not very experienced in Delphi and I find out two possible solutions, but still I'd like to know, how to change it proper way or why it's not possible.
1) Change style to Gradient, but it also changes the basic animations for buttons.
ToolBar.DrawingStyle := dsGradient
ToolBar.GradientStartColor := clWhite
ToolBar.GradientEndColor := clWhite
2) Put TToolBar inside TPanel with the following settings.
Panel.Color := clwhite
ToolBar.Parent := Panel
ToolBar.Align := alClient
ToolBar.Transparent := True
By default a TToolbar ignores its Color property.
Also by default the Transparent property is true, therefore whatever the color of the Toolbar's parent is will shine through.
If you look at the VCL source code you'll see that TToolbar does not do its own drawing; it is a wrapper around the ToolbarWindow32 Win32 common control in ComCtl32.dll.
This is the code that does the drawing.
When Windows XP was introduced Microsoft added UI themes and Borland supported this via VCL.Themes.TStyleManager.
You can change the appearance of Common Controls through the style manager: Project -> Options -> Appearance -> Custom Styles, but its hard to know what effect this has, because the IDE does not display the result (you can see it at run time) and you can only choose from a limited list of rather odd themes; also the feature is buggy.
The same goes for TPageControl/TTabSheet which does not publish its Color propery.
All the controls imported via ComCtl32.dll and implemented by VCL.ComCtrls suffer from these inconsistencies.
In short
There is nothing you can do to make TToolbar respect its Color property.
You've already found the workarounds, either:
Set a gradient with identical GradientEndColor and GradientStartColor, or
Place the toolbar on another control (e.g. a TPanel) and change the color of that control, because the toolbar is transparent the parent color will shine through.
You'll need to set the panel's BevelInner/BevelOuter to bvNone, or
Enable VCL styles and suffer all the issues related with that corporate tickbox anti-pattern.

Make FireMonkey TListBox in XE5 transparent

I have done some FireMonkey stuff in XE2, in this case I'm having troubles with a customized TListBox.
In XE2 I built this customized TListBox by removing it's background and surrounding rectangle (basically I only need the 'grouping of child items' functionality provided by TListBox. This was simple, drop a TListBox, hit 'edit custom style', select the background rectangle, edit the fill and the stroke and you're golden.
Now we're moving to XE5 and I cannot reproduce the same behavior. Using the style book editor I can see the background (which is now TStyleObject and not TRectangle), but I cannot make the changes I could make before. I see tutorials on how to add stuff to a TListBox, but not on how to take default behavior away.
Can someone explain how to achieve this specific behavior, or point me towards a good tutorial?
Try changing the StyleLookup property of the list box to transparentlistboxstyle

Firemonkey style inheritance?

I've just started with Firemonkey, and still have a lot to learn with regards to the usage of styles, but there is something I can't get figure out.
I've learned how to simulate a TListView using styles. So I've made a style which adds a progress bar to a list item, let's call this ListItemStyleProgressBar.
Now I'd like two ListView instances on my form, one where the font of the TListItem is red, and one where the font is blue. How to achieve this? Can I make an style which 'inherits' from ListItemStyleProgressBar (ListItemStyleProgressBarRed)?
Next to that, I'd like to be able to 'style' these two listview instances, so have a style which shows a light back and a style which shows a dark back.
What confuses me is it seems the styling is needed to add functionality (add a TProgressBar to a TListItem) as well as to do styling for this added functionality.
Can anyone tell me what I'm missing here?
No. There is no inheritance mechanism for styles. There are two ways to solve your problem:
1) Create two (or more) very similar styles to represent each 'look'.
2) Make the changes at run-time either with the OnApplyStyleLookup method or, if you have a custom control, by overriding the ApplyStyle method.
In the latter case you'll need something like this:
procedure TMyClass.ApplyStyle;
var O: TFMXObject;
begin
O := FindStyleResource('background');
if O is TRectangle then
TRectangle(O).Fill.Color := claRed;
end;

How to change caption font color on TCheckBox, TRadioButton, TGroupBox?

I don't know what my problem is, but I cannot set the font color in DEx2 for controls like TCheckBox, TRadioButton, TGroubBox, and TRadioGroup. It doesn't matter if I do it in the IDE or programmatically.
I have set my form color to clBlack and want my captions to be clWhite, but they won't render any color but clBlack. When I assign a color on a form's OnShow event and step through it in the debugger, it shows the value I assigned it, but on the screen it is still black.
I am not using styles or anything else. Any ideas?
Here is a sample form:
white on black example http://www.skippix.us/temp/Delphi-Font-Problem.bmp
When you uses the windows themes in an application, most of the custom settings like the font colors are ignored. As workaround and depending of the component you can ownerdraw the control (only when this feature is supported), override the paint method in order to use your own color in the font (TRadioGroup, TGroupBox), and for components like TCheckBox and TRadioButton (which are WinAPI controls wrappers) you must intercept the WM_PAINT windows message and implement your own code to draw the control.
Also starting with Delphi-xe2 you can use the vcl styles which allow you to change the appearance of the controls, from here (and when is possible) you can modify the style hooks to apply your own font colors and other customizations.
A simple and easier workaround is to create a checkbox without caption and add a label after it. You can easily change the label's color. You can also create a new component that binds a label to the checkbox itself. That's what worked for me on Delphi 2007.
It will work under the following setting:
Project Options > Application > Runtime Themes = none

Resources