0

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.

Delphi.Boy
  • 1,199
  • 4
  • 17
  • 38
  • 2
    Try to follow [`this article`](http://delphihaven.wordpress.com/2010/04/19/setting-up-a-custom-titlebar/). – TLama Jun 09 '13 at 18:33
  • Please don't put tag information in your title. The tagging system here is very good at classifying things, and doesn't need help. :-) Please see [Should questions include "tags" in their titles?](http://meta.stackexchange.com/q/19190/172661). Thanks. – Ken White Jun 10 '13 at 00:50

2 Answers2

4

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.

Community
  • 1
  • 1
Peter
  • 2,977
  • 1
  • 17
  • 29
  • Thanks. I edited my question to include the version of Delphi I'm using. It's XE. So I can't use StyleElements, right? – Delphi.Boy Jun 09 '13 at 15:43
  • @Delphi.Boy, StyleElements property was added in XE3, not to worry tho, it's just a minor setback, thanks to RRUZ who's done amazing work on Styles you can use his examples on how to turn off Vcl styles by registering a StyleHook, for example you should look at the following question : http://stackoverflow.com/questions/8598728/how-to-disable-vcl-styles-in-delphi – Peter Jun 09 '13 at 15:57
  • 2
    @Peter, VCL styles were added in Delphi XE2. With XE you're out of luck. – TLama Jun 09 '13 at 17:18
  • @Peter, I read the post you suggested, but really didn't understand what's going on. They were talking about 'disabling' VCL Styles and I don't even have them! If my requirement can be done with StyleHook, show me a good example that works under XE. Thanks. – Delphi.Boy Jun 10 '13 at 11:59
  • @Delphi.Boy , I've updated my answer after TLama reminded me that you can't use VCL Styles if you are on Delphi XE, simply put , you'll either have to use the last option that I listed or one of the two options that Remy listed, you also might want to check the link that Tlama posted under your question, tho that is specific to only Windows Vista+ – Peter Jun 10 '13 at 12:04
  • @Peter, Thanks again. I managed to look at the source code of a skinning library, and much to my surprise it used some code similar to what I've posted above. Painting on caption bar with GetWindowDC, ... :( – Delphi.Boy Jun 10 '13 at 13:14
2

You can either:

  1. Intercept the WM_NCPAINT message and custom-draw the caption bar manually.

  2. 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.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks for SetWindowRgn suggestion. I don't want to remove WS_CAPTION, because my window will loose the 'appearing' effect on Windows 7. BTW, does somebody know the correct name of this effect? – Delphi.Boy Jun 10 '13 at 11:56
  • @Remy +1 for providing more solutions – Peter Jun 10 '13 at 12:05
  • @Remy, intercepting WM_NCPAINT and drawing on caption doesn't work under 7. Just like the code I added to my question. If I change destination x and y in BitBlt to 100 and 100 it draws my text inside client area, but painting on caption remains a mystery! – Delphi.Boy Jun 10 '13 at 13:11