Tuesday, February 28, 2006

D2006: What on earth are these Explicit* properties in my DFM

If you need to make sure your application can still be compiled in previous Delphi versions you need to watch out for some new properties that are added by Delphi 2006 to your DFM. These new properties are for all TControl descendants and are called ExplicitTop, ExplicitLeft, ExplicitHeight and ExplicitWidth. These are not actually published properties; you won’t find them in the object inspector.

The Explicit* properties remember the previous bounds of a control before the Align or Anchor properties are changed from their defaults. The only time the Explicit* properties are not written is when the Align property is set back to its default value of alNone. This is when the Explicit* properties are actually used by the control to reset its bounds to what it was previously.

You can download the example here to play along at home if you like (executable included):
http://www.jed-software.com/files/ExplicitProps.zip

This example takes a TPanel and changes its align property value from

alNone -> alClient -> alNone

Example Usage:
  1. Run the application
  2. Click on the Get Values button
  3. Values from Figure 1 are displayed in the Memo control
  4. Click on the Align Client button
  5. Click on the Get Values button again and Figure 2 displays the added Memo control contents
  6. Click on the Align None button
  7. Click on the Get Values button a final time and the Memo control should have the same values added to it that were added in Step 3.



So what has changed?
In previous Delphi versions if the align property was changed to alClient and then back to alNone, the control would stay as if it was aligned client still. These new properties mean that the original bounds is restored when this occurs. As noted with the example.

When the panel was aligned client it up the left over client area of the form; as expected. When clicking on the Align None button the panel was restored back to its size prior to setting Align to alClient.

If you want to know the specific conditions for having these properties written to the DFM check out the DoWriteExplicit function in the DefineProperties method for TControl.





Figure 1



Align is alNone

ExplicitTop: 40

ExplicitLeft: 256

ExplicitHeight: 185

ExplicitWidth: 329

Top: 40

Left: 256

Height: 185

Width: 329

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






Figure 2



Align is alClient

ExplicitTop: 40

ExplicitLeft: 256

ExplicitHeight: 185

ExplicitWidth: 329

Top: 0

Left: 193

Height: 456

Width: 450

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






D2006: How to disable the IDEs gradient toolbars

A newsgroup poster recently asked if he could disable the gradient toolbars for BDS 2006. Unfortunately this is not possible within the IDE but it is possible with a little bit of code.

This post will probably not format too well!

  1. Save the code below in a unit called TBCAddIn.
  2. Create a New Win32 Package
  3. Add the TBCAddIn Unit to the Package
  4. Install the Package into the IDE
  5. Making the change configurable is an exercise left to the reader...

I installed the package and it worked. Restarting the IDE also showed the gradient disabled. Making additional toolbars visible while running the IDE also showed those toolbars with the gradient disabled.


Generated with HyperDelphi




unit TBCAddIn;

interface

type
TTBCConfig = class
public
class procedure SetGradient(const aVisible: Boolean);
end;

procedure Register;

implementation

uses
Classes
, Controls
, ComCtrls
, Windows
, ExtCtrls
;

procedure Register;
begin
// disable the toolbar gradient by default
TTBCConfig.SetGradient(False);
end;

{ TTBCConfig }

const
MAIN_WND_CLASS = 'TAppBuilder';

class procedure TTBCConfig.SetGradient(const aVisible: Boolean);
var
i: Integer;
lWinCtrl: TWinControl;
lWnd: Hwnd;
lCtrlBar: TControlBar;
begin
lWnd := FindWindow(MAIN_WND_CLASS, nil);
lWinCtrl := FindControl(lWnd);
if lWinCtrl <> nil then
begin
lCtrlBar := nil;
// find the control bar on the app builder form
for i := 0 to lWinCtrl.ControlCount - 1 do
begin
if lWinCtrl.Controls[i] is TControlBar then
begin
lCtrlBar := TControlBar(lWinCtrl.Controls[i]);
break;
end;
end;
if lCtrlBar <> nil then
begin
// disable/enable gradient for controlbar depending on parameter
if aVisible then
lCtrlBar.DrawingStyle := ExtCtrls.dsGradient
else
lCtrlBar.DrawingStyle := ExtCtrls.dsNormal;
for i := 0 to lCtrlBar.ControlCount - 1 do
begin
if lCtrlBar.Controls[i] is TToolbar then
begin
// disable/enable gradient for toolbars depending on parameter
if aVisible then
TToolbar(lCtrlBar.Controls[i]).DrawingStyle := ComCtrls.dsGradient
else
TToolbar(lCtrlBar.Controls[i]).DrawingStyle := ComCtrls.dsNormal;
end;
end;
end;
end;
end;

end.

Wednesday, February 22, 2006

D2006: Disabling Breakpoints quickly

I always found it very frustrating when disabling a breakpoint required me to right click on the breakpoint, navigate a context menu that really wasn't a context menu but an everything plus some breakpoint specific items. It was cumbersome and inefficient. I disliked it so much I requested a change in the form of a QualityCentral report.

In Delphi 2006 this request was addressed. It was implemented using the Ctrl key instead of the Shift key, but that isn't important. You can now disable breakpoints without having to invoke that horrid context menu.

Report No: 10468 ( RAID: 219303 ) Status: Closed
Shift clicking on an active breakpoint should disable it
http://qc.borland.com/wc/qcmain.aspx?d=10468

This report is about the horrid context menu contents:

Report No: 25363 ( RAID: 205492 ) Status: Open
The breakpoints context menu has irrelevant items on it.
http://qc.borland.com/wc/qcmain.aspx?d=25363


You might be aware that the breakpoint window got some improvements in Delphi 2005 as well by adding a checkbox next to the breakpoint for quickly enabling and disabling breakpoints. The problem with this is that it takes time to work out where the breakpoint you are currently looking at is in the list to disable it. I created a QualityCentral report for this also:

Report No: 11862 ( RAID: 221907 ) Status: Open
Breakpoint view should sync with selected breakpoint
http://qc.borland.com/wc/qcmain.aspx?d=11862

Here are a couple of other breakpoint specific reports that I've made.

Report No: 15395 ( RAID: 238643 ) Status: Open
Breakpoint view should allow me to select several breakpoints and then add them all to a specific group
http://qc.borland.com/wc/qcmain.aspx?d=15395

Report No: 15394 ( RAID: 46571 ) Status: Open
Breakpoint View should support multiple selection
http://qc.borland.com/wc/qcmain.aspx?d=15394

Report No: 10484 ( RAID: 222329 ) Status: Open
The breakpoint view needs to have a column to show that line of code the breakpoint is on.
http://qc.borland.com/wc/qcmain.aspx?d=10484

Report No: 25364 ( RAID: 205494 ) Status: Open
Add additional context menu items when clicking on a breakpoint.
http://qc.borland.com/wc/qcmain.aspx?d=25364

Feel free to Rate/Vote on these items if you feel they could improve your productivity in a future Delphi release.

Sunday, February 12, 2006

DCM: Version 3 UI Feedback requested

As most are aware BDS 2006 introduces a new "personality" loading capability. It is this capability that has kept me from updating Delphi Configuration Manager to properly support 2006 (Well that, and the lack of donations...).

While I don't think the "personality" loading was implemented as well as it could have been by Borland I am going to support it in the next version of DCM. Doing so means that DCM requires a user interface change and a number of code changes.

I've been adding the support today and have taken screenshots of 3 possible user interfaces to represent a loaded BDS 2006 configuration.

Take a look and feel free to comment. All would require further refinement but hopefully the functionality is obvious (if it isn't let me know about that as well).



Personality specific packages are loaded under the Packages key. Packages that are not personality specific load as a child to the Package node, otherwise the package is loaded as a child of that personality. The Personality Filter combo box would allow you to just display a specific personality to modify.



Personality specific packages are loaded in another tree next to the Assemblies and Package listings. The Personality Filter combo box would allow you to just display a specific personality to modify in the Personality tree. The filter would not effect the tree in the left pane.



Similar to the second item except the personality view is displayed using a different widget which allows you to enable/disable actual personalities. This functionality would be available in the previous views also except it would be in the Menu or on the Toolbar.


Also expect to see the package description without having to select a package. It has been a common request that I will be implementing - just haven't gotten around to it yet.

As usual you can contact me directly or leave a comment.

Friday, February 10, 2006

I need 3 more beta testers...

If you have some spare time to help test a couple of new Delphi/C++Builder components please send me an email. My contact information is available from http://www.jed-software.com.

What is it for you ask... Perhaps this link will provide some clues...

http://jedqc.blogspot.com/2005/12/jed-qc-gets-supertooltip-treatment.html