It was discovered that some of the functionality in the Rush API was broken by Delphi 5. This plug-in corrects the problem.
The install also includes an optional plug-in called Form Utilities. This is similar to the plug-in for CodeRush versions 3 and 4, found here. This version is much more powerful.
Details of the Fix
(For CodeRush Plug-In Developers)
In Delphi 5, the CodeRush method AddMenuItemToForm became broken by changes in the Delphi source code. In addition, the CodeRush event OnMenuPopup was not triggering for menus on forms, frames, and data modules. The Form Popup Fix plug-in corrects both of these problems.
If you would like to add your own custom menu items to a form, the Form Popup Demo download is a sample plug-in that demonstrates advanced techniques that you can use (like enabling/disabling conditionally, adding check state indicators next to your menu items, and adding bitmaps to form menu items).
This demo plug-in requires that Form Popup Fix be installed to compile.
Note: This fix is incorporated into CodeRush 6 and later versions, so any code you write with this fix may require slight adjustments (e.g., "FormMenuItemManager" will need to be replaced with "CodeRush", and the calls to IgnoreFormMenuPopup and WatchFormMenuPopup won't be necessary).
Details of the Form Utilities Plug-In
Form Utilities is a powerhouse set of form-based solutions, designed to eliminate the tedium of form design. Briefly, here are the solutions:
Power control selections (select children, select siblings, etc.)
Component type conversion (based on Ray Lischner's expert)
Quick property set (set anchors and alignment without jumping to the object inspector)
Copy selected component names
Form Layout Manager - This is new, extremely powerful form design technology. Note: Be sure to read and/or print the documentation that appears the first time you use it.
Power Control Selections
This feature provides the abiltiy to control how groups of controls are selected on a form. When the right click menu is invoked on a form, the following menu appears:
The sub-menu under Select offers four options, three of which react based upon the exact object that was right-clicked on:
Children - all child components of the object that was clicked on will be selected. Thus, if you right-click on a panel and select this option, every component parented to the panel will be selected.
Siblings - all components that are siblings to the clicked component will be selected, that is, all components that share a common parent. Thus, if you have a panel containing several controls and you click one of the controls parented by the panel and then select this menu option, all controls parented by that panel will become selected.
<selected component> Siblings - similar to the Siblings option, above. The difference here is that only siblings of the same component type will be selected. Thus if we have a panel containing some TLabels and TEdit controls and we right click on a TLabel, this menu option will read "TLabel Siblings". Selecting this option will cause all TLabels parented to the panel to become selected.
All - all components will be selected.
Component Type Conversion
The CodeRush Component Converter converts component classes from one type to another, preserving existing properties and events whenever possible. This operation is not undoable, and so it is highly recommended that you save your work before converting components, in the event that the conversion differs from your expectations.
You can specify a component type to convert to, and whether the conversion scope is restricted to the selected components, the entire form, or the entire project. See below:
Quick Property Set
This feature allows you to quickly and easily set the Align and Anchor properties of a component without having to jump to the Object Inspector. Simply right-click on the compnent you wish to update. To set the Align property, the following menu appears:
To set the Anchors property, the following menu appears:
Notice the submenu allows you to select specific or shortcut coordinates to anchor.
Copy Selected Component Names
This is a handy little feature that allows you to quickly copy the names of all the selected components to the clipboard. If multiple components are selected, the file names will be separated by carriage returns.
Form Layout Manager
The CodeRush Form Layout Manager is the command and control center for all your form layout needs. This is nothing short of the ultimate in form designer technology.
The Form Layout Manager provides the following solutions:
The Form Layout Manager is a powerful tool. Spending a few minutes to learn its capabilities can save you tens, even hundreds, of hours in the future. When it is invoked a dialog appears, as shown below:
The following topics will help you get up to speed quickly:
IMPORTANT: Due to Delphi's inability to undo changes made to the form, modifications made by the Form Layout Manager are not reversible. For this reason, it is recommended that you save the form before invoking the Form Layout Manager. You should also keep a recent backup of your source files, including *.dfms, in case you make a change that you want to undo at a later time. Also, use the Preview Changes button to review your changes before applying them.
The Form Layout Manager analyzes Delphi forms, and arranges controls into groups (object lists in memory) that represent rows and columns. This group information is used for alignment, resizing, setting tab order, configuring shortcuts and setting the FocusControl property of TLabels.
A form can have any number of rows or columns (depending on component complexity), and rows and columns are bound by parenting controls (so all the controls in a given row or column will always share the same parent).
Before using the Form Layout Manager, you should click the Setup tab and specify your row and column component grouping constraints. These are the amounts in pixels that the leading edges of components in rows and columns may vary from the leading edge of the leftmost or topmost component in the group.
For rows the leading edge is determined by the Top property of the highest component in the row, and for columns the leading edge is determined by the Left property of the leftmost component in the column.
So if the Rows setting is 14, you can imagine a horizontal path exactly 14 pixels high, aligned with the Top of the highest component in the row. Any other controls with a Top property that falls within this 14-pixel high path will be included in this particular row.
To illustrate this example, take a look at the image below and the explanation that follows.
In this image, Button3 is the topmost control in the row. The tops of Button1 and Button2 fall within this 14-pixel path, but the top of Button4 falls outside the path. A layout like this would result in at least one row, consisting of Button1, Button2, and Button3.
Depending on other controls that may be placed on the form, Button4 could ultimately become part of a column and/or part of a different row of controls.
It is also possible for Button4 to be an orphan control (e.g., it doesn't belong to any column or row group). Orphan controls cannot be automatically resized or positioned, however they can still be automatically named and have shortcuts established for them.
You may be wondering what you can do if Button4 really should be part of the existing row. There are two options available: You can either manually move Button4 up a bit on the form before invoking the Form Layout Manager (so it's Top property is within 14 pixels of Button3's Top property), or you can increase the Component Grouping Rows setting to a larger value.
To see the rows on your form, click the Show rows checkbox in the Display Options group box.
This logic also holds true for columns (just rotate the logic and the imaginary path 90 degrees).
Tip: A setting of 14 seems to work out well for most layouts. You may want to increase or decrease these values depending on your initial precision when dropping components on a form (smaller values require a greater degree of manual precision on your part). Don't forget, you can turn on the Show rows and Show columnsdisplay options to visually see the row and column groupings on the form.
When you invoke the Form Layout Manager, you may already have one or more components selected on the form. Depending on what is selected, different scope options will be available. Using the Scope options can be very powerful and allow you to quickly enforce custom guidelines upon different groups of controls.
The Scope options are also useful for focusing in on a particular aspect of the form when performing Quality Assurance. This is because display options only apply to the components in scope.
The available scopes are explained below:
All controls. All controls on the form will be affected by the changes you apply. This includes non-visual components for the AutoNaming functionality.
Selected controls. Only the controls that are selected on the form will be affected by the changes you apply.
Within selected controls. Only controls parented by selected controls on the form will be affected by the changes you apply.
For example, you may want to have controls (that happen to be parented by group boxes or panels) to have a left-to-right tab order, but you may want the parenting controls to have a top-to-bottom tab order. You apply these choices quickly by selecting the parenting controls before invoking the Form Layout Manager. Then it is simply a matter of choosing Within selected controls and applying a left-to-right tab order, followed by the Selected controls scope for a top-to-bottom tab order.
The Form Layout Manager's display options are quite powerful, and can quickly reveal hard-to-find layout problems. The display options are also useful for understanding the impact of non-visual changes (like setting the FocusControl property of a TLabel).
Tip: The Scope setting (discussed in the previous section) determines which components the display options apply to. If the display options are only drawing on a portion of the components that you expect, select a higher scope (like "All controls"). Alternatively, if the form is cluttered with too many details, you might want to select a lower scope (like "Selected controls").
IMPORTANT: The display options reflect the actual values on the form. If the values are not what you are expecting (in other words, the changes you're making in the dialog do not result in an apparent change the displayed information), chances are that the Preview Changes toggle button is not pushed down. Be sure to click this button so it's in the down position if you want to see how the changes will impact the form.
The display options are discussed below:
Show tab order - This option allows you to see the tab order of controls on the form. Tab order is color-coded to indicate the parenting level within the form. Top-level controls are drawn in yellow, while second-level controls are drawn in light red, etc. If a component's TabStop property is False, then the tab order indicator will be drawn in a darker shade to indicate that it is invalid as a tab stop, even though it displays a value for its TabOrder property.
Show component names - This option allows you to see the names of components on the form.
Show FocusControl links - This option allows you to see FocusControl links. FocusControl links are drawn as arrows pointing from the right edge of the label to the left edge of the referenced control.
Show rows & Show columns - These options display the rows and columns of components on your form, as analyzed by the Form Layout Manager. Rows are indicated by a horizontal blue line spanning from the first control to the last control in the row, while columns are indicated by a vertical red line.
The Form Layout Manager makes it easy to see your changes before they are applied to the form. Just depress the Preview Changes button to see how the changes will affect controls on the form.
You can apply any changes you've made so far by clicking the Apply Changes button. Doing so applies the changes and disables any pages that you've enabled (the individual pages are described in the next section, below).
Note: If you make a change to a control and the Preview Changes button is in the down position, you may notice the controls on the form quickly adjust a bit before seeing your changes. This is expected behavior; the Form Layout Manager must restore the original layout of your form before applying any new changes for the preview.
IMPORTANT: Because Delphi is unable to undo the changes you make to a form (regardless of whether you're using the Form Layout Manager or making those changes by hand), it is recommended that you save the form before invoking the Form Layout Manager. It is also a good idea to have a recent backup of the *.pas and *.dfm on hand, in case you want to revert to a previous form layout.
If you need to work with distinct settings that must be applied to different forms, you can set up styles to represent each of the settings and switch to them quickly from within the Form Layout Manager.
You can change settings instantly by selecting a new style from the combo box. If you think you might want to return to your current settings at some point in the future (e.g., after selecting a different style), simply save the current settings to the appropriate style before loading the new settings.
To save the current settings, click the Save Style button to the right of the style combo box.
You can either select an existing style to replace or specify a new name. Click OK to save the settings.
Styles are stored in *.flm files (flm = Form Layout Manager) located in your CodeRush Share directory (the location of the Share directory is specified in the CodeRush Options dialog). The file format is similar to an INI file.
The Position tab allows you to control how components will be positioned and aligned on the form.
By default, all positioning functionality is disabled. Control alignment, row and column spacing, and control spacing can each be individually enabled as desired. To enable control alignment, check the Align controls checkbox; to enable row and column distribution, check the Distribute rows & columns checkbox; to enable individual component positioning within a row or column, check the Distribute controls checkbox.
Note: Some options in the Control Spacing group conflict with options in the Row & Column Spacing group. The dialog logic will resolve these conflicts automatically, so you may see a change in one group affecting values in the other. In general, you'll want to use the Row & Column Spacing options all the time, and only rarely will need to use the Control Spacing options.
The options on this page are described below:
The settings in this group box determine the alignment of components in rows and columns.
Tip: The Center alignment is recommended for rows consisting of TLabels and the controls that they focus to (as long as the controls are all around the same height as a TEdit or a TComboBox).
Tip: Keep the Preview Changes button in the down position while you work with these options to immediately see the impact of your changes.
The options in this group box determine the spacing between rows or columns. This option allows you to specify the distribution mechanism and the Form Layout Manager will calculate the distances, treating entire rows and columns as single entities.
The options for row and column spacing are:
Distribute - calculates the distance between the first and last rows (or columns) sharing the same parent, and then distributes the inner rows (or columns) evenly between the outside rows (or columns). This option requires at least three rows (or three columns) of controls that share a similar parent, otherwise it will have no effect.
Exactly - allows you to specify a distance, and only requires two rows (or two columns) to perform its functionality.
At Least - allows you to specify a distance, and only requires two rows (or two columns) to perform its functionality. This option preserves the existing space unless it falls below an amount you specify.
For the Exactly and At Least options, the distance can be measured from similar edges (top for rows, or left for columns) or from the space between the rows and columns. This is explained in greater detail in the Tip below.
Tip: The distance for spacing can be measured by the distance between leading edges of columns or rows (determined by the leftmost control in a column or the topmost control in a row), or it can be measured as the distance between the two closest edges (determined by the two closest controls in the neighboring rows or columns). If you have rows consisting of controls with varying heights, or if you have columns consisting of controls of varying widths, you typically want use the space between the closest edges (depress the appropriate Spacing Option button to the right of the spin edit). The Form Layout Manager will provide additional information on these options when you focus or select them (the Show Hints checkbox must be checked to enable viewing of the hints).
The options in this group box determine the spacing between components within individual rows or columns.
Note: If you want to adjust the entire row or column as a group, use the Row & Column Spacing options instead, discussed above. This option is useful when you need greater individual control over controls in columns or rows.
The options for control spacing are:
Distribute - calculates the distance between the first and last controls in a row or column, and then distributes the inner controls evenly between the outside controls. This option requires that the row or column contain at least three controls, otherwise it will have no effect.
Exactly - allows you to specify a distance, and only requires two controls (in the row or column) to perform its functionality.
At Least - allows you to specify a distance, and only requires two controls (in the row or column) to perform its functionality. This option preserves the existing space unless it falls below an amount you specify.
For the Exactly and At Least options, the distance can be measured from similar edges (left edge of controls in rows, or top edge of controls in columns) or from the space between the controls in the row or column. This is explained in greater detail in the Tip below.
Tip: The distance for spacing can be measured from the left or top edges of controls (in rows or columns, respectively), or it can be measured as the distance between the two closest edges. If you have columns consisting of controls with varying heights, or if you have rows consisting of controls of varying widths, you typically want use the space between the closest edges (depress the appropriate Spacing Option button to the right of the spin edit). The Form Layout Manager will provide additional information on these options when you focus or select them (the Show Hints checkbox must be checked to enable viewing of the hints).
The Borders tab determines whether parent controls will be resized to enforce one or more internal borders (with respect to the child controls that they parent). Group boxes and panels are considered parents (any TWinControl descendant that is capable of accepting components dropped on it can be a parent). Bevel controls are not considered parent controls.
By default, all resizing features are disabled. If you want to resize the form (or frame) to fit around the child controls it parents, select the Resize form to fit children checkbox. If you want to resize the parent controls to fit around the child controls they parent, select the Resize parent controls to fit children checkbox.
The options in the Parent Control Inside Borders group box allow you to specify an inside border that may be applied to parent controls. Borders can be selectively enabled and disabled by clicking the corresponding Enable/Disable button. If a border is enabled, the edge of the parent control will be positioned the given distance away from closest edge of all the controls it parents.
The Lock button in the center of the page allows you to lock the Top, Bottom, and Right spin edits so that they will always match the value for the Left spin edit.
Tip: If your form is complex and has many levels of parented controls, it is recommended that you select only the parent controls you want to work with, and choose the Selected controlsscope.
Note: Group boxes and their descendants actually draw on the insides of their borders. The inside top of the group box includes the caption, which can further increase the size of the border needed for the top position. If you're working with group boxes, you may need to experiment with appropriate values. Use the Preview Changes button to see the impact of your changes before committing.
The Tab Order page determines how the tab order will be adjusted for components on the form.
By default, the automatic tab ordering functionality is disabled. To enable it, select the Adjust tab order checkbox. You can then specify Left to right or Top to bottom ordering.
Tip: If you need to apply a different ordering (e.g., Left to right vs. Top to bottom) to different component groups on the form, select the component groups which have a common ordering and use the Selected componentsscope.
Tip: To see the results of the tab order change before applying them, be sure to select the Show tab order display option and depress the Preview Components button.
The Shortcuts tab determines whether shortcuts will be set for components on the form. You can also control whether a TLabel's FocusControl property will be set.
To assign shortcuts to the components in scope, select the Assign accelerator shortcuts checkbox. To set the FocusControl property for TLabels (and their descendants) in scope, select the Set TLabel FocusControl property checkbox.
Tip: To see the results of the FocusControl change before applying it is applied, be sure to select the Show FocusControl linksdisplay option and depress the Preview Components button.
The options for this page are described below:
Target control is right of TLabel - The target control (e.g., the control that will ultimately be referenced by the FocusControl property) appears to the right of the TLabel.
Target control is below TLabel - The target control appears below the TLabel.
Replace existing - Existing FocusControl properties and shortcuts are replaced.
Note: The Replace existing option has additional significance when assigning shortcuts automatically, even if you're doing it for the first time (and shortcuts have not yet been defined). Normally shortcuts are assigned to the first available letter or number appearing in the caption. If the Replace existing option is selected, and a shortcut for a particular caption is not available (in other words, every letter and number in a control's caption has already been assigned as shortcuts to other controls on the form), then the Form Layout Manager will perform a "deep evaluation" of all shortcuts, producing an optimum shortcut configuration (changing previously assigned shortcut keys as needed to maximize the ratio of shortcut keys to controls).
Tip: Always have the Replace existing checkbox checked when you are assigning shortcuts (see previous note for an explanation).
The AutoName page determines how unnamed components will be automatically renamed according to your name composition standards.
By default, the auto-naming functionality is disabled. To automatically name unnamed components in scope, select the Auto-name unnamed components checkbox.
The Form Layout Manager will rename components that have not yet been manually named by changing Delphi's default name (which is the ClassName without the leading "T", plus one or more digits to ensure uniqueness). The new name will be composed from a "short name" for the component class, plus a possible "descriptor".
The short name is an abbreviation for the component that you specify. For example, you might specify a "Lbl" for a TLabel, "Edt" for a TEdit, and "Cmb" for TComboBoxes.
The descriptor is derived from a key string property you specify, or the Caption property if published by the component being renamed. If the component being renamed is a data-aware control, the Form Layout Manager will evaluate the data links, tracing back to a table name (providing one is specified in the TableName property of a TTable or inside a SELECT statement of the SQL property of a TQuery.
This newly composed name may be followed by one or more digits to ensure uniqueness on the form.
The options for this dialog are described below:
Short name + key property value - Name composition will consist of the short name followed by the descriptor. For example, if a TLabel had a caption of "Hello World", the new name would be LblHelloWorld.
Key property value + short name - Name composition will consist of the descriptor followed by the short name. For example, if a TLabel had a caption of "Hello World", the new name would be HelloWorldLbl.
Include parenting group box caption in name - Checking this option will include additional text in the new name if the control being renamed is directly parented by a group box. The additional text will appear before the normal descriptor, and will be taken from the caption.
Include table name in data aware components - If this option is checked, the name of the table that the data aware control is associated with will appear in the new name, in addition to the value for the DataField property. This option only applies to data aware components that publish a DataField property. Data-aware components that do not publish a DataField property but do publish a DataSource property (e.g., TDBNavigators, TDBGrids, etc.) will use the table name as the descriptor regardless of this setting.
Rename unidentified components - If this option is selected, unidentified components (components without preset short names) will be AutoNamed using a generated short name. Click the [...] button on this page to create short names for unidentified components (details on this appear below). If you clear this checkbox, unidentified components will not be renamed.
Note: The Form Layout Manager install includes a set of default component abbreviations for many VCL components, stored in ComponentPrefixes.ini (which is copied to your CodeRush Share directory). You can edit this file in a text editor, or you can use the Component Name Composition dialog.
Note: If a TWinControl component has no caption, but is pointed to by the FocusControl property of a TLabel on the form, the TLabel's Caption is used as the descriptor for the TWinControl.
Note: If a TControl is without a Caption property (or its caption is empty), and the control is not pointed to by the FocusControl property of a TLabel on the form, but it does have an Action associated with it, then the Form Layout Manager will use the linked TAction's Caption property as the descriptor for the TControl.
To illustrate this point, just drop down some TLabels and TWinControls (e.g., TEdits, TComboBoxes, TListBoxes, etc.) that they will send focus to. Drop all of these controls on a new form, as follows:
Next, just set the captions for the three TLabels using the Object Inspector...
Now, bring up the Form Layout Manager. Get things nicely aligned, and set up the FocusControl links...
Finally, switch to the AutoName tab, and check the Auto-name unnamed components checkbox.
Because the TLabel FocusControl properties are pointing to the TEdits and the TComboBox, the Form Layout Manager is able to get the appropriate descriptor from the corresponding TLabels.
Tip: For best results (like the example above), set FocusControl links (if applicable) before AutoNaming.
Changing Short Names & Key Properties
You can change short names and key properties for the components by clicking the [...] button on the AutoName page. This will display the Component Name Composition dialog, shown below:
The list on the left in this dialog shows all components currently installed on Delphi's component palette. To change a short name, select a component in the list, specify its abbreviation and press Enter (or select a different component from the list). You can also specify an optional key property for this component.
Note: It is unnecessary to specify the Caption or Text properties as key properties. The Form Layout Manager will already look for these properties if they are published by the component that is being renamed. Only specify a key property if you want the text from that property to be included in the name composition. For example, with TTables you might want to use the TableName property as the key property.
Changes in the Component Name Composition dialog are saved immediately to a file in your CodeRush Share directory (you can check or change this directory with the CodeRush Options dialog). This makes it easy for a team to standardize on component naming conventions. The file name is ComponentPrefixes.ini.
Note: When the Form Layout Manager gets the text from a key property, it looks for a "." and strips all text on and after the dot. So in the case of the TTable example above, if a component named "Table1" had its TableName property set to "clients.db", the new name for this table could be "TblClients" (depending on your settings).
Note: If components belonging to a collection editor (e.g., TActions in a TActionList) are renamed, the collection editor may still show the old names when you return to the form. To update its contents, simply close and then reopen the collection editor (reopen it by double-clicking on the TActionList).
Tip: You can enter the names of components that are not on the Delphi component palette by manually editing this file. This is useful for components that may appear on the form but are not on the component palette (like the TTabSheets that are part of the TPageControl component, TActions, TForms, etc.).
Tip: You might consider having controls with similar functionality share identical short names. For example, a TDBEdit and a TEdit could both use the same short name of "Edt". This would make it easy to find them in an alphabetical listing in an Object Inspector drop-down list, for example (providing you've selected to have the short name added before the descriptor).
Tip: Give the form a caption before AutoNaming if you haven't yet named the form.
Tip: To see the results of the automatic naming before applying them, be sure to select the Show component namesdisplay option and depress the Preview Components button.
Note: When previewing this option, the names of the components on the form are actually changed. This means that the form declaration in the source code will be changed as well during the preview (and when you apply changes). On forms with a large number of controls, this preview can take some time on slower machines (e.g., 1-3 seconds), so you may want to apply this change before exploring other options (so previews for your other changes are more responsive).
Note: While the Form Layout Manager will rename components on the form and in the class declaration, it will not rename any existing references to those components in the implementation. For this reason you should use the AutoName feature before you write code that references the unnamed components.
Another great use for the Form Layout Manager is in the area of quality assurance for forms. By selectively turning on appropriate display options, you can quickly identify problems in tab order, component naming, and focus control in existing forms.
You can also use the Form Layout Manager to correct these problems, as well as correcting problems that may not be intuitively obvious, like conflicting shortcut key assignments, or slightly misaligned components.
Copyright 2004 Ackerson Software, All Rights Reserved.
Form Popup Fix
Author: Eagle Software
Created: November 30, 1999
Plug-In Type: Standard
Options Page: No
This plug-in is NOT currently supported.
This plug-in is not the property of Developer Express; it is the sole property of its author. As such, Developer Express cannot be held liable for any incidental damages that may be related to the usage of this plug-in.