Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 402
  • Last Modified:

Selection rectangle - how?

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
krisz
Asked:
krisz
  • 5
  • 3
1 Solution
 
sassas081597Commented:
Use DrawFocusRect method of a component to view the nesessary rectangle. Use it again to hide it.
0
 
StevenBCommented:
 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
 
sassas081597Commented:
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
sassas081597Commented:
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
 
kriszAuthor Commented:
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
 
sassas081597Commented:
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
 
kriszAuthor Commented:
Not enough. OnDraw and OnPaint events called _before_ the
wincontrols draw themselfs. I want to draw something over them.
0
 
sassas081597Commented:
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
 
kriszAuthor Commented:
Please wait. I'll look into that.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

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