• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 572
  • Last Modified:

Controlling the available client area of a control

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
nnbbb09
Asked:
nnbbb09
  • 2
  • 2
1 Solution
 
CynnaCommented:
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
 
nnbbb09Author Commented:
Tried it for a descendent of TPanel but the painting of the control was very unpredictable.

Jo
0
 
DragonSlayerCommented:
An easier way would be to add another TPanel, align it to Top. :)
0
 
CynnaCommented:

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
 
nnbbb09Author Commented:
Cynna,

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

Thanks

Jo
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

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.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now