Solved

Run time component design

Posted on 2003-11-20
5
502 Views
Last Modified: 2010-04-05
Good Day!
 
I'm to Implement Delphi-like component editor. I would very grateful if You could give me, if it's possible, a little hint or example how to implement the following features:
 
1. Dots (Coordinates Net) on the form during the Design time. Are they simply drawn on form's Canvas?
 
2. How to implement Black selection of the controls, when they are clicked at design time? Further, I do not know how to do the Resize of controls when they are draged by this black outlinement by mouse.
 
3. How to implement moving of the controls on the form?
I've done it by allowing dragging and accepting it everywhere, but I have not obtained smooth movement as it's in Delphi. During the Drag operation my controls blink and move unsmoothly...
 
If you could answer me, I would be very very thankful.
 

Andrew Petuchov
0
Comment
Question by:apetuchov
5 Comments
 
LVL 5

Expert Comment

by:snehanshu
ID: 9788210
Andrew,
  I don't know of any freeware, but we use Dream Designer and it's great!
http://www.dream-com.com/designer.html
...Shu
0
 

Author Comment

by:apetuchov
ID: 9788260
Thank you, Shu. The fact is i have to write it by myself. It's my univercity course project, you know...
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9788298
Well,
  If no body posts by tomorrow, then I shall try to find alternate solutions (if there are) and let you know.
  Cheers!
...Shu
0
 
LVL 33

Accepted Solution

by:
Slick812 earned 125 total points
ID: 9790048
hello apetuchov, there are several Methods to do what you say, here is one that uses an "OverLay" control to draw the sizing blocks and allow resizing and moving, this is slightly diferent than the Delphi  IDE, and draws the entire control moving instead of the focus rectangle.
Here is the code for this CtrlSizer Unit - -


unit CtrlSizer;

interface

uses
  Classes, Windows, Messages, Controls, StdCtrls;

type
  TCtrlSizer = class (TCustomControl)
  private
    FControl: TControl;
{FControl is set to the Control that will be moved and sized by this}
    NoSize: Boolean;
    FRectAry: array [1..8] of TRect;
    FPosAry: array [1..8] of Integer;
  public
    constructor Create (AOwner: TComponent; AControl: TControl);
    procedure CreateParams (var Params: TCreateParams); override;
    procedure CreateHandle; override;
    procedure NcHitTest (var Msg: TWmNcHitTest); message WM_NCHITTEST;
    procedure WmSize (var Msg: TWmSize); message WM_SIZE;
    procedure LButtonDown (var Msg: TWmLButtonDown); message WM_LBUTTONDOWN;
    procedure WmMove (var Msg: TWmMove); message WM_MOVE;
    procedure Paint; override;
    procedure SizerControlExit (Sender: TObject);
  end;

implementation

uses
  Graphics;

constructor TCtrlSizer.Create (AOwner: TComponent; AControl: TControl);
var
Rec: TRect;
begin
  inherited Create (AOwner);
  FControl := AControl;
  if AControl is TComboBox then
  NoSize := True else
  NoSize := False;
  // assign an OnExit
  OnExit := SizerControlExit;
  // set the size and position
  Rec := FControl.BoundsRect;
  InflateRect (Rec, 2, 2);
  BoundsRect := Rec;
  // set the parent to FControl parent
  Parent := FControl.Parent;
  // create an array of positions
  FPosAry [1] := htTopLeft;
  FPosAry [2] := htTop;
  FPosAry [3] := htTopRight;
  FPosAry [4] := htRight;
  FPosAry [5] := htBottomRight;
  FPosAry [6] := htBottom;
  FPosAry [7] := htBottomLeft;
  FPosAry [8] := htLeft;
end;

procedure TCtrlSizer.CreateHandle;
begin
inherited CreateHandle;
{as soon as this window is created, give it focus}
SetFocus;
end;

procedure TCtrlSizer.CreateParams (var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := Params.ExStyle + WS_EX_Transparent;
{the WS_EX_Transparent allows the control under this (FControl)
to be Painted first and change the pixels on this control, ,
then does not do an Erase Background}
end;

procedure TCtrlSizer.SizerControlExit (Sender: TObject);
begin
{when this control looses focus, Free it}
Free;
end;

procedure TCtrlSizer.LButtonDown (var Msg: TWmLButtonDown);
begin
{to mouse move this control use the Caption Hit Test
message SC_DRAGMOVE, which is Hex $F012}
Perform(wm_SysCommand, $F012, 0);
end;

procedure TCtrlSizer.Paint;
var
i: Integer;
begin
{this will paint 8 small black sixing rectangles}
Canvas.Brush.Color := clBlack;
{if NoSize then I do Not draw the Top and Bottom Rects}
for i := 1 to  8 do
  if not(NoSize and ((i = 2) or (i = 6))) then
    Canvas.Rectangle(FRectAry [i].Left, FRectAry [i].Top,
      FRectAry [i].Right, FRectAry [i].Bottom);
end;

procedure TCtrlSizer.NcHitTest(var Msg: TWmNcHitTest);
var
Pt1: TPoint;
i: Integer;
begin
Pt1 := Point(Msg.XPos, Msg.YPos);
Pt1 := ScreenToClient(Pt1);
Msg.Result := 0;
{the NoSize is True for TComboBoxes, because the Height
is NOT Changable in Design or Run Time,
So I change the HitTest to Only give Left and Right side Hits}
if NoSize then
  begin
  for I := 1 to  8 do
    if PtInRect(FRectAry[i], Pt1) then
    case i of
      1: Msg.Result := FPosAry[8];
      2: Msg.Result := 0;
      3..5: Msg.Result := FPosAry[4];
      6: Msg.Result := 0;
      7..8: Msg.Result := FPosAry[8];
      end;
  end else
  for i := 1 to  8 do
    if PtInRect (FRectAry[i], Pt1) then
      Msg.Result := FPosAry[i];
       
// if the return value was not set
if Msg.Result = 0 then
inherited;
end;

procedure TCtrlSizer.WmSize (var Msg: TWmSize);
var
  Rect1: TRect;
begin
  Rect1 := BoundsRect;
  InflateRect (Rect1, -2, -2);
  FControl.BoundsRect := Rect1;

  // setup Rectangle sizes
  FRectAry[1] := Rect(0, 0, 5, 5);
  FRectAry[2] := Rect(Width div 2 - 3, 0, Width div 2 + 2, 5);
  FRectAry[3] := Rect(Width - 5, 0, Width, 5);
  FRectAry[4] := Rect(Width - 5, Height div 2 - 3, Width, Height div 2 + 2);
  FRectAry[5] := Rect(Width - 5, Height - 5, Width, Height);
  FRectAry[6] := Rect(Width div 2 - 3, Height - 5, Width div 2 + 2, Height);
  FRectAry[7] := Rect(0, Height - 5, 5, Height);
  FRectAry[8] := Rect(0, Height div 2 - 3, 5, Height div 2 + 2);
end;

procedure TCtrlSizer.WmMove (var Msg: TWmMove);
var
Rect1: TRect;
begin
Rect1 := BoundsRect;
InflateRect (Rect1, -2, -2);
FControl.Invalidate; // repaint the control
FControl.BoundsRect := Rect1;  // move the control
end;

end.


- - - - - - - - - - - -  - - -  - -  - - - - - - - - - - - - - - -  - - - - -  - - - - -

to use this add the CtrlSizer to your uses clause, and then put a SizerAttach procedure in your forms Class Defintion, and add the SizerAttach Procedure to your code - -

  TForm1 = class(TForm)
    but_Exit: TButton;
    procedure but_ExitClick(Sender: TObject);
    procedure SizerAttach(Sender: TObject);
  private
    { Private declarations }
    CtrlSizerHandle: Cardinal;
    CSizer1: TCtrlSizer;


 - - - -

procedure TForm1.SizerAttach(Sender: TObject);
begin
CSizer1 := TCtrlSizer.Create(self, Sender as TControl);
CtrlSizerHandle := CSizer1.Handle;
end;

procedure TForm1.FormClick(Sender: TObject);
begin
if CtrlSizerHandle = windows.GetFocus then
  FreeAndNil(CSizer1);
end;

 - - - - - -  - - - -  - - - - - - - - - - - - -

and in each Control you want to have become a Sizer Control when the user clicks it, , then in that Control's OnEnter event type in SizerAttach
- - - - - some controls you will need to use the OnClick event

ask questions if you need more information
0
 
LVL 1

Expert Comment

by:pr_wainwright
ID: 9792839
Andrew,
            RALib for Delphi (not RXLib) has a Delphi IDE clone called RADOctober with source code included. It is not complete but works very well including a form designer & object inspector etc. It can be downloaded from Delphi Super Page, just search for 'ralib'.

Regards
Paul.
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
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…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

757 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

22 Experts available now in Live!

Get 1:1 Help Now