Solved

Selection rectangle - how?

Posted on 1997-11-01
9
387 Views
Last Modified: 2010-04-03
How to draw a selection rectangle?

The followings do NOT work:

- shape : shapes are behind wincontrols
- form.onpaint : the painting is behind all controls

I tried to use a WM_MESSAGE handler as below (try-finally-s
are cut out for shortness):

--------- code ----------------- code ----------------------

type
  TMyForm= class(TForm)
    ...
  protected
    procedure WMPaint(var Msg: TWMPaint); message WM_PAINT;
  end;

...

procedure TMyForm.WMPaint(var Msg: TWMPaint);
var
  PS: TPaintStruct;
  DC: HDC;
begin
  inherited;

  DC:= BeginPaint(Handle, PS);
  with Canvas do begin
    Handle:= DC;
    {drawing to canvas with Rectangle() }
    Handle:= 0;
  end;
  EndPaint(Handle, PS);
end;

--------- end code ------------ end code ------------------

But nothing appears on the form. I guess it's still behind the
wincontrols.

So: how to draw a selection rectangle _in_front_of_everything_ on a form?

Only _working_solutions_ will be accepted.
0
Comment
Question by:krisz
  • 5
  • 3
9 Comments
 
LVL 1

Expert Comment

by:sassas081597
ID: 1349295
Use DrawFocusRect method of a component to view the nesessary rectangle. Use it again to hide it.
0
 
LVL 4

Expert Comment

by:StevenB
ID: 1349296
 I Use InvertRgn which performs a logical NOT on all the pixels within the given region. However, I'm using non windowed controls so I'm not sure if the advice will cross over.

  Steven.
0
 
LVL 1

Expert Comment

by:sassas081597
ID: 1349297
Hi Steven!
Can you describe more of your project. What do you need the Focus Rectangle for. May be you can give me more code.
As to non-windowed controls, they also have DrawFocusRect method and can display the rectangle of their Client Area.
SAS
0
 
LVL 1

Expert Comment

by:sassas081597
ID: 1349298
Only yet I Understood, what was ment.
Here is a component you need:
unit Span;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls;

type
  TShapePanel = class(TCustomPanel)
  private
    { Private declarations }
    FShape: TShapeType;
    procedure SetShape(v: TShapeType);
  protected
    { Protected declarations }
    procedure Paint;override;
  public
    { Public declarations }
    constructor Create(A: TComponent);override;
  published
    { Published declarations }
    property Shape: TShapeType read FShape write SetShape default stRectangle;
  end;

procedure Register;

implementation

constructor TShapePanel.Create (A: TComponent);
begin
     inherited Create(A);
     FShape:=stRectangle;
     Caption:='';
     Invalidate;
end;

procedure TShapePanel.SetShape(v: TShapeType);
begin
     if V<>FShape then
     begin
          FShape:=v;
          Invalidate;
     end;
end;

procedure TShapePanel.Paint;
var
  Rect: TRect;
  TopColor, BottomColor: TColor;
  FontHeight: Integer;
  a: Integer;
const
  Alignments: array[TAlignment] of Word = (DT_LEFT, DT_RIGHT, DT_CENTER);
begin
  Rect := GetClientRect;
  with Canvas do
  begin
    Brush.Color := Color;
    FillRect(Rect);
    case FShape of
    stRectangle: Rectangle(Rect.Left,Rect.Top,Rect.Right, Rect.Bottom);
    stSquare:    begin
                      If Rect.bottom-Rect.top>=Rect.Right-Rect.Left then
                         A:=Rect.Right-Rect.Left
                      else
                         A:=Rect.bottom-Rect.top;
                      Rectangle(Rect.Left,Rect.Top,Rect.Left+a, Rect.Top+a);
                 end;
    stRoundRect: RoundRect (Rect.Left,Rect.Top,Rect.Right,Rect.Bottom,6,6);
    stRoundSquare:begin
                      If Rect.bottom-Rect.top>=Rect.Right-Rect.Left then
                         A:=Rect.Right-Rect.Left
                      else
                         A:=Rect.bottom-Rect.top;
                      RoundRect(Rect.Left,Rect.Top,Rect.Left+a, Rect.Top+a,6,6);
                 end;
    stEllipse:   Ellipse(Rect.Left,Rect.top,Rect.Right,Rect.Bottom);
    stCircle:    begin
                      If Rect.bottom-Rect.top>=Rect.Right-Rect.Left then
                         A:=Rect.Right-Rect.Left
                      else
                         A:=Rect.bottom-Rect.top;
                      Ellipse(Rect.Left,Rect.Top,Rect.Left+a, Rect.Top+a);
                 end;
    end;//case
    Brush.Style := bsClear;
    Font := Self.Font;
    FontHeight := TextHeight('W');
    with Rect do
    begin
      Top := ((Bottom + Top) - FontHeight) div 2;
      Bottom := Top + FontHeight;
    end;
    DrawText(Handle, PChar(Caption), -1, Rect, (DT_EXPANDTABS or
      DT_VCENTER) or Alignments[Alignment]);
  end;


end;

procedure Register;
begin
  RegisterComponents('SAS', [TShapePanel]);
end;

end.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:krisz
ID: 1349299
Both answers are wrong. As I said, I want to place more
wincontrol descendants on a container. Wincontrols hide
any drawing on the parent control.

Panel has no paint or draw event. I can use a paintbox on the
same form, but the paintbox is behind all windowed controls,
so any drawing will be covered by them.

The forms onpaint event is called before painting the contents
of the form, so form.onpaint good for drawing background, but
now it's unuseable.

Answer rejected until you give me a detailed and working example.
0
 
LVL 1

Expert Comment

by:sassas081597
ID: 1349300
Would you like to have a Panel (or smth like it) with onDraw event? No problem. If it will be your choice, I can send you a solution for testing. However answer this question before.
0
 

Author Comment

by:krisz
ID: 1349301
Not enough. OnDraw and OnPaint events called _before_ the
wincontrols draw themselfs. I want to draw something over them.
0
 
LVL 1

Accepted Solution

by:
sassas081597 earned 150 total points
ID: 1349302
Try this component.

unit WPB;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls;

type
  TWinPaintbox = class(TCustomControl)
  private
    { Private declarations }
    FOnPaint: TNotifyEvent;
  protected
    { Protected declarations }
    procedure Paint;override;
  public
    { Public declarations }
    constructor Create(A: TComponent);override;
    property Canvas;
  published
    { Published declarations }
    property Align;
    property Color;
    property DragCursor;
    property DragMode;
    property Enabled;
    property Font;
    property ParentColor;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property Visible;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDrag;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnPaint: TNotifyEvent read FOnPaint write FOnPaint;
    property OnStartDrag;
  end;

procedure Register;

implementation

constructor TWinPaintbox.Create (A: TComponent);
begin
     inherited Create(A);
     ControlStyle := ControlStyle + [csReplicatable];
     Width := 105;
     Height := 105;
     Caption:='';
     Invalidate;
end;


procedure TWinPaintbox.Paint;
begin
  if csDesigning in ComponentState then
    with Canvas do
    begin
Font := Font;
Brush.Color := Color;  
      Pen.Style := psDash;
      Brush.Style := bsClear;
      Rectangle(0, 0, Width, Height);
    end;
  if Assigned(FOnPaint) then FOnPaint(Self);
end;

procedure Register;
begin
  RegisterComponents('SAS', [TWinPaintbox]);
end;

end.
0
 

Author Comment

by:krisz
ID: 1349303
Please wait. I'll look into that.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Windows Drag & Drop Location 2 94
Sending Gmail through Delphi 3 91
How to call a form that is in a DLL  from an application? 13 64
Find and Replace Stream with 0s 8 56
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

914 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now