4
votes

My goal is to create a simple forms editor like the one that we find on Delphi IDE.

Right now the user can select and add the components making it parent of a TPanel that is the holder of the form. For simplicity, please consider also TPanel as the visual components added to the form.

I have 2 missing parts I want to find out ideas/code to help complete:

1 - how to move the created visual component? The same effect that in IDE for moving the visual component, for example Tpanel, around, chaning its top and left position 2 - how to draw that hooks for the component with focus on the form editor 3 - how to resize using the hooks

I only want the part related to handle the visual part. I am not generating DFM or anything like that.

3

3 Answers

5
votes

Simply put your moving code needs to do this:

  1. When the mouse goes down, check if the mouse position is over a control that can be dragged. If so, then set a variable named FDragControl to refer to that control. This code lives in an OnMouseDown event handler.
  2. When the mouse moves, if FDragControl is not nil, move the control. This code lives in an OnMouseMove event handler.
  3. When the mouse goes up, set FDragControl to nil.

That's pretty much all there is to it. The main nuance is that you must also remember the X, Y values of the mouse when the drag commenced. So in your OnMouseDown handler you write:

FStartMousePos := Point(X, Y);
FStartDragControlPos := Point(FDragControl.Left, FDragControl.Top);

And then in the OnMouseMove your position code reads:

FDragControl.Left := FStartDragControlPos.X + (X-FStartX);
FDragControl.Top := FStartDragControlPos.Y + (Y-FStartY);

You will also need to capture the mouse when you start dragging.

The resizing code is similar. Again, you need to decide in the OnMouseDown that you are resizing rather than dragging, but the code still involves handling mouse down, move and up events.

As for painting, you need to force a repaint whenever one of your event handlers changes a property that will influence the visual appearance of your form. You can use the value of FDragControl to decide whether or not to use special drawing of your control and indicate that it is being dragged. And likewise for resizing.

I've not coded up a full working implementation since your question is high level and conceptual. The implementation is down to you.

2
votes

// I have made this an answer as I have just read your latest update which really should have been made as an edit to your original question but, anyway.

You can download the Cindy Components Pack and use the cyResizer Component which will do pretty much everything you need and is very customisable as well.

You can download it from here: http://sourceforge.net/projects/tcycomponents/

1
votes

Searching more for an answer I could find these articles:

How to Move and Resize Controls at Run Time http://delphi.about.com/library/weekly/aa102505a.htm

How to Add Size Handles to Controls being Resized at Run-Time http://delphi.about.com/library/weekly/aa110105a.htm

Pretty much with all the information to complete this task with source code example.

These articles show how to implement and use a TMover class. I have done it and work correctly.

I have also downloaded the TcyComponents Pack and used the TcyResizer. It is a full featured form editor with pretty much everything that is required for a Delphi like forms editor. I recommend. It comes with source code and works fine with XE2 version.