Solved

Controlling the available client area of a control

Posted on 2002-07-23
5
550 Views
Last Modified: 2010-10-05
I'm writing a new control that inherits from TCustomPanel and it will draw a Caption area similar to a Form at the top of the panel. However when components are dropped on the panel they can overwrite this Caption area.
Is there someway of controlling the available client area of a control

Thanks

Jo
0
Comment
Question by:nnbbb09
  • 2
  • 2
5 Comments
 
LVL 7

Expert Comment

by:Cynna
ID: 7172487
Didn't test it, but reducing your component client area should work. To do this, override GetClientRect method like this:



// .....

protected
 function GetClientRect: TRect; override;


// .....

function TmyPanel.GetClientRect: TRect;
begin
  with Result do begin
       Left     := Self.Left;
       Top      := CaptionAreaHeight; // <- this will reduce components client area
       Right    := Self.Width;
       Bottom   := Self.Height;
  end;
end

0
 
LVL 3

Author Comment

by:nnbbb09
ID: 7172830
Tried it for a descendent of TPanel but the painting of the control was very unpredictable.

Jo
0
 
LVL 14

Expert Comment

by:DragonSlayer
ID: 7173275
An easier way would be to add another TPanel, align it to Top. :)
0
 
LVL 7

Accepted Solution

by:
Cynna earned 100 total points
ID: 7174558

DragonSlayer,

I'm afraid adding another panel, won't prevent other controls from showing on top of it...
This "compound" alternative could for example be made by using 3 panels:
one as a base, second as a caption area (top aligned), and third as
actuall panel body (client aligned). But this, on the other hand,
induces various other complications; for example, "caption area" will
still accept components.

But, if you don't want to use multiple components, caption area must be
a non-client one.


Jo,

OK, let's give it one more try...
It boils down to separating client from non-client area on your panel.

You can choose between two solutions:

a) Easy - let the OS draw fixed caption area for you. You do it like this:

TmyPanel = class(TCustomPanel)
protected
   procedure CreateParams(var Params: TCreateParams); override;

//.....

procedure TmyPanel.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do Style := Style or WS_CAPTION;
end;


b) Harder - you define your own non-client area using WM_NCCALCSIZE (Non-client calculate size) message:

TmyPanel = class(TCustomPanel)
protected
   procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE;

//.....

procedure TmyPanel.WMNCCalcSize(var Message: TWMNCCalcSize);
begin
  inherited;
  // Increase non-client area, thus reducing component client area:
  with Message do Inc(CalcSize_Params.rgrc[0].Top, CaptionAreaHeight);
end;

Either solution will add a non-client area to your panel, but solution b)
will let you choose its size (through CaptionAreaHeight variable).
Anyway you choose, you'll have to draw your title bar on this area,
using WM_NCPAINT (Non-client paint) message.


Below is the demo code that exposes you a non-client area canvas that
you can draw on (using b) solution, for example):

TmyPanel = class(TCustomPanel)
protected
   procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE;
   procedure WMNCPaint(var Message: TMessage); message WM_NCPAINT;

//.....

procedure TmyPanel.WMNCPaint(var Message: TMessage); // handle paint of NC area
var dc:  HDC;
    CACanvas: TCanvas;
begin
  inherited;
  dc := GetWindowDC(Handle);
  CACanvas:=TCanvas.Create;
  with CACanvas do begin
       Handle:=DC;
       // ----- < drawing on Caption area Canvas > -------
       // Do your stuff here...for example:
          Brush.Color := clNavy;
          Rectangle(0, 0, Width, CaptionAreaHeight);
          with Font do begin
              Color:=clYellow;
              Name:='Arial';
              Height:=CaptionAreaHeight-1;
          end;
          TextOut(1,1, 'My special caption');
       // ----- </ drawing on Caption area Canvas > -------
       Handle:=0;
  end;
  ReleaseDC(Handle, dc);
  CACanvas.Free;
end;
0
 
LVL 3

Author Comment

by:nnbbb09
ID: 7175082
Cynna,

I went for the second option. It's a great solution and exactly what I'm looking for.

Thanks

Jo
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question