Archive for January, 2010

Internal Errors Need better Exposure

Sunday, January 24th, 2010

Tonight I was trying to install some hcOPF objects into the D7 IDE so I could use the design-time functionality to bind UI controls to the attributes of an object.  I created a package, included all units I thought were needed and then added all implicitly imported units or the packages that contained them.  I then tried a Build and got an ‘Internal Error U1295′ at the line where I include hcDevExpress in my Implementation section.

I thought I would Google the error, and I came up with a measly 4 hits with no answers, only others asking questions, although many of the pages had to be translated by Google.  I did stumble upon an article from Steve Trefethen here.  Oddly enough, searching EDN didn’t find anything on U1295, and searching on “internal errors” brought back results for multiple products.  It seems weird that there is no product filter in the advanced search options.  Furthermore, the Additional Compiler Messages window, which I didn’t even know existed after all these years, until I read Steve’s article, gave this link which is pretty much the article Steve published (nice circular reference).

So here I am, a Delphi developer for many years pulling my hair out (what little is now left) because I have to figure out what is going on by trial and error.  I can only imagine how souring an experience this would be for a Delphi newcomer.  You would think after 15 years a product might have more comprehensive documentation, especially on it’s support site.  Perhaps a more descriptive error message might have be in order, and then additional documentation would not be necessary.  Granted I am not using using the latest Delphi release, mainly because I am performing a large scale refactoring and I’m still a CodeRush addict, and this project has a single datamodule with a large number of queries which loads much faster in D7 than D2010.

Based on Steve’s article and my own experience, I re-compiled all my hcOPF IDE packages, and after the IDE died once, and I had to kill the process, I finally got the business object package installed.  As I suspected, I am using conditional compilation to include CodeSite messages etc, and if I compile a project that does not use packages with different conditional directives or compiler options than used to compile the packages, I often get into this kind of situation (not always the same Internal Error).  It makes for sporadically painful development experience, so I would welcome any suggestions from package developers who dog food their product as it evolves.

The Cost of Progress

Sunday, January 17th, 2010

Ok I admit it.  I’m a bit of a hoarder.  I finally went through all my old paperwork and shredded everything that I didn’t need to keep for the CRA (Canada Revenue Agency).  Amidst 15 years of paperwork I came across the following:

Delphi 2 - The First 32 bit Windows Release

Delphi 2 - The First 32 bit Windows Release

I ordered and returned Delphi 1.  It was an impressive product, but it was so new no one was using it, so it was a little hard to justify the money (I was even poorer then).  When Delphi 2 shipped, Delphi became my development tool of choice and has been ever since.

Embarcadero’s current pricing at the on-line Canadian store is $922.64.  I wonder how they determined that price.  It’s not rounded to the nearest dollar, or priced so it appears below some psychological threshold.  Even after GST is applied, it’s an odd figure.

Anyway, I wondered how much Delphi 2 would have been sold for in today’s dollars, so I used 3% inflation annually, compounded on a yearly basis and it worked out to $635.29 CAD.  The current price is 1.45 times the adjusted cost of Delphi 2.

There are certainly more features in the box, but do you think it’s worth the price?

hcOPF UIObjectBinder gets DesignTime Support

Monday, January 4th, 2010

I used to have some design-time support for the principle objects in the framework, but in my experience component and property editors are non-trivial to write, and the framework was evolving so much that I was constantly breaking all the design-time code.  I decided to back burner design-time support until hcOPF was more mature.  I am happy to announce that ObjectBinding design-time support is now available.

You can now design your objects, install the objects into the IDE, and bind their attributes to form controls without writing a single line of code.  Here is a screenshot of the ObjectListMgr demo showing the design-time support.

Many thanks to Developer Express, not only for donating a license to their DevExpress QuantumGrid Suite so I can continue to support it with hcOPF, and for allowing Richard Morris to share their technique for delegating properties to child objects.  You can find that article here.

UIObjectBinder Design-Time Support

hcOPF Error Indicators

Monday, January 4th, 2010

The JCL and JVCL are a humungous collection of useful components and routines for Delphi.  Kudos to the team that maintains and develops them.  I have used the JCL/JVCL on a number of projects now, and my only complaint is that you can’t really pick and choose what components you want to use.

This came to light once again when I decided I wanted to use the TJvErrorIndicator component with the hcOPF.  I used a single unit from the JVCL and the next thing I knew, I had 3 more packages to distribute; the JCL, JVclCore and JvValidators.

One of the things I like most about Delphi compared to .NET is the ability to create an application with a minimal footprint.  Since I have open sourced hcOPF, I also don’t want to force anyone to adopt any components they don’t wish to use, or deploy anything larger than necessary.

I have looked through the dependancies, and there is really no need for most of the classes I am forced to deploy, they just happen to be in the same unit as something else.  I really wish the Jedi would adopt the SRP (Single Responsibility Principle) for units so I could pick and choose.  As a result, I am thinking about going over to the dark side and ripping out the ErrorIndicator code to create my own unit for hcOPF.  Not exactly an ideal scenario as I cannot contribute back any changes as easily, nor can I benefit as easily from any future enhancements the Jedi make.

Another annoyance is that for some reason the LIBSUFFIX directive is not currently being used for the Jedi packages from D7 up.  As a result I have to change the required package dependancy list for each project for each version of Delphi I am trying to support, rather than simply referencing, for example, JvCore.dcp I have to reference JvCoreD7, or JvCoreD14 etc.  I have reported this issue, and am assured it will be fixed in a future release.

Like other developers I often look to the community for guidelines on naming, code organization, and programming techniques.  What ever happened to dclPackageName${LIBSUFFIX} for design-time packages and PackageName${LIBSUFFIX} for run-time?  What is the recommended standard now?

hcOPF IsValid()

Monday, January 4th, 2010

Recently I have been enhancing the built-in validation capabilities of hcOPF in preparation for using it in a client project that requires visual error indicators, and flexible data entry.

I have introduced the concept of a Validator which is much like a database check constraint within the OPF layer, but it takes the concept much further.  The IsValid() method appears at both the object level and attribute definition level.  To enable support for any conceivable validation requirement, developers can override the default implementation on ThcObject, and attach custom validators to a ThcAttributeDef instance.

Validators are employed by the Mediators in the framework to take the string value from their associated control and after ensuring that it can be converted to the datatype of the associated attribute without a range error, their IsValid() method is called.  The prototype for IsValid at both the Object and Attribute level is as follows:

function IsValid(ValidationErrors :ThcValidationErrorList = nil):boolean;

IsValid() takes a list which is created by the developer and is used by the framework to collect any validation errors and their associated attributes.  The list can then be used to display the error information to the user, and controls containing invalid attribute values can be focused using the new UIObjectBinder.FocusControlForAttribute() method.

IsValid() has a default parameter of Nil so you aren’t obligated to pass it an instance of a ThcValidationErrorList.  This may seem strange, but it’s for a very good reason.  If you’re like me, and think that one of the best features of Delphi are TActions, then you don’t have to suffer the overhead of repeatedly clearing and populating the validation error list whenever a TAction.OnUpdate event handler executes.

For an example of how to use ThcValidators check out the ObjectListMgr project in the Demos/ObjectListMgr folder.