I have a added components on a form object dynamically
Edit1 := TEdit.Create(form3);
I have got the object form3 of Tform class. Now what i want to do is I want to create a component template of form3 so that I can just drag and drop that component template on any of my other from and all the components present in it will be automatically available for me to use. Can any one help me with how to about doing component template?
From the second part of your question it seems you want to make a reuseable Frame that you can drop at design time on a form, and drag it around. Frames can be dropped multiple times on multiple forms. Changes in the design are reflected in the copies. Create a frame with File > New > Frame (Delphi 7) or File > New > Other > Delphi Projects > Delphi Files > VCL Frame (XE2).
However, if the components therein should also be visible during designing, then you have to create those controls also at designtime. A frame works exactly like a normal form, so there should be no problem there. Controls generated in code will only show up at runtime, which is just fine if you want that.
Related
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.
Simply put your moving code needs to do this:
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.
When the mouse moves, if FDragControl is not nil, move the control. This code lives in an OnMouseMove event handler.
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.
// 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/
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.
I am starting on my first application using delphi (using delphi XE 2) and I'm trying to piece my way through creating the GUI right now.
I'm trying to use a TpageControl to keep things separated and simple but when I try to place a component on a tabsheet it shows on all of them. According to what I have read the components placed on each given tab are only supposed to show in that one.
Basically I want each tab to operate as a separate form. Does anyone have any tips and/or tutorials on working with the Tpagecontrol in order to do what I have described?
Thanks.
Just have a look at the structure and you will see why this happens.
Button1 and Button2 seems to be related to TabSheet1, but looking at the structure you will see, that the parent of Button1 is Form1 and the parent of Button2 is TabSheet1.
If you switch to TabSheet2 Button1 is still visible, but Button2 is not.
But you can drag drop the controls within the structure panel from actual parent to a new parent.
I have created a component inheriting TFrame and added an ActionList and ToolBar to the frame as I want to make a base form available to other projects and developers. The question is: how can I expose the ActionList property at design time? The ActionList is showing in the object inspector and I can see it's events and properties, but the actions inside the ActionList are not available at design time.
More details:
I have created a class inheriting from TFrame and added an TActionList in the Delphi IDE designer. Then I added it to a package and installed it as a component. Now I can drop that component on a form and it adds the whole frame I designed to the form. I see the ActioList in the object inspector, but the problem is I cannot see the actions inside the ActionList. I need to add actions to ActionList on the forms which are using the component.
I implemented two menu items for my component in Delphi IDE with TComponentEditor descendant. They're both supposed to be used with "right-clicking" a component on the form. But can I do this for component that is currently hidden (concealed) by other components? So I select a component with other tools (for example object inspector) and would like to activate one of my context menu items.
Shift-F10 doesn't work (at least in D5).
Bringing the component to top for this task is not an option.
Right-click the component in the Object TreeView (Shift-Alt-F11).
D7: Menu > View > Object TreeView
XE2: Menu > View > Structure
Or make a property editor with paDialog in the attributes and forward the Edit method to your component editor. Then double clicking that property or clicking the ellipsis will bring up the component editor, just like the Colums property for TDBEdit does.
If you feel like writing a something mimicking Delphi IDE's Object TreeView, I suggests you the following resources:
Populating all controls of a container object using recursion (Blog post). Using TVirtualTreeView like the Delphi IDE is better than the stock TTreeView to my opinion.
Study the commercial TLMDComponentTree
of the LMD IDE-Tools (Excerpt: This powerful control allows to use a Delphi IDE like Object TreeView. Collections, child controls etc. are automatically handled).
Is it possible to create an MDI application using FireMonkey in a traditional sense of many documents forms/frames and one master form?
I'm specifically interested since there are no MDI controls on forms anymore.. Has it been replaced with something different?
EDIT: Adding to the question, when I create child forms they all showed separately in taskbar, even the OpenDialogs..
Here's one approach you can use:
1) Create your individual forms as normal, except use a TLayout, call it "LayoutMain", (aligned alClient) as the parent of all controls on that form.
2) On your "master form", when you want to bring a form instance in to behave as it would as an MDI interface, create a TLayout (call it "FormContainer" or something), place as a child of that (aligned to top) another TLayout (call it "FormHeader"), containing the individual controls for the Form Caption, the Minimize/Maximize/Close buttons and anything else you'd like on the "frame" heading. This is called a Composite.
3) Create an instance of your child form (but don't show it), then parent that instance's primary TLayout "LayoutMain" to your main form's TLayout "FormContainer".
4) On the TLayout previously mentioned (with the name "FormHeader"), give it OnMouseDown and OnMouseMove events to provide the ability to drag it around the Master Form.
When you want to maximize the child form inside the master form, you'd just set the outer TLayout "FormContainer" align property to alClient, remembering to store its original Top, Left, Width and Height values within the the form's instance so you can recall them when pressing the Restore button.
True, this is a fairly involved solution, but to the very best of my knowledge this is the only way you're going to achieve what you're trying to do with FireMonkey as it exists today (circa Update 2).
I wouldn't expect Embarcadero to provide any form of MDI emulation as part of FireMonkey "out of the box", as MDI is considered an old-fashioned approach.
The more modern solution would be to use Docking, as the RAD Studio IDE itself does. This provides the very best of both worlds, giving the user the freedom to choose what child forms they want to link into the master form, or display outside of that on their own (or any combination of docked arrangements).