Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Controlling the available client area of a control

Posted on 2002-07-23
5
Medium Priority
?
566 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 400 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

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

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

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
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…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Suggested Courses

636 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