Posts Tagged ‘Delphi’

I’m Touched

Monday, November 5th, 2012

Normally, when you fix a bug in a particular section of code, you also look at other bug and enhancement reports related to that area to see if you can also fix those issues, or implement those enhancements.  Otherwise you’re judging one report in that area against the other in terms of frequency and severity to determine which ones get addressed.

That’s why it came as quite a shock that in XE3 QC items 104640 (B3 opened 4/6/2012), and 107227 (B2 opened 7/19/2012) were addressed in amongst numerous others in the IDE, IDE\Code Editor category, but other QC  items relating to Code Completion were not, including my own QC99381 (B1 opened 7/27/2011).  It’s shocking because, I run into this code completion bug on a daily basis where the issues that got fixed appear to be edge cases.  In fact 104640 has a lower severity than my report, and was opened long after mine.  I don’t know what prioritization algorithm EMBT uses, but I find it baffling!  So that’s one major release of Delphi later, with several updates, and 4 hot fixes.

Addressing all issues in a specific area all at once, in my experience, works best.  That’s because the developers get their head into the problems, and code.  This takes a while, and it’s been proven that having developers juggle multiple things either concurrently or in quick serial succession, makes them less productive.  It’s simply the power of focus.  It also makes testing an area thoroughly easier, especially if it requires manual testing, requiring less time from Q&A.

Apparently breaking functionality in one release doesn’t necessitate fixing it, even in a following release that developers have to pay for.  How do you feel about that practice?  If a bug is introduced in a release should it be fixed and provided in that release for free?  Where would you draw the line knowing software is never perfect?

If Marco Cantu is indeed the special guest at CodeRage 7, and the announcement is indeed that he is the new Delphi Product Manager, I hope he is empowered to change the way QC items are handled.  As a developer who actually uses the tool, perhaps he will also address the poor template support, re-factoring, code navigation, and remove the half baked useless “features” like the Object Inspector Description pane (I currently use his package to hide it), and complete others like Error Insight that could be more useful with less false positives.  Let me be the first to wish him well in that role if the commentor Inside Embarcadero is right.

hcOPF - using Attribute OnChange Events

Monday, October 22nd, 2012

Althought hcOPF implements automatic calculations via a ThcCalcObject registered with the object metadata, it’s not the most efficient implementation.  Since the framework has no idea of the attribute dependancies in the calculation, it calls the CalcObject whenever an attribute of the object changes.  Of course it avoids doing so, during mass object attribute changes, such as when initializing the object, or reading it from the objectstore.  Nevertheless, you may encounter situations in which you want to optimize the calculation, such as when you make a database call.

Just like a TField object, a ThcAttribute implements an OnChange event that can be used implement calculations.  This is a much more efficient mechanism, but unfortunately does not benefit from the framework’s knowledge about the calculation, and cannot therefore automatically avoid triggering the calculation event during object reads or other mass object changes, such as object initialization or resetting object attributes after writing them to the objectstore.  It also suffers from the disadvantage that the code for multiple calculations is spread out across different event handlers instead of being in one place.  That said, any good framework does not box you in, so hcOPF allows you to use either method.

If you use the ThcAttribute event to perform the calculation, make sure to subscribe to the event early enough in the lifecycle of the object in an overridden method.  For instance, subscribing to the event for each object processed in the ThcObjectList.Load() method may be sufficient for most cases, but if you create individual objects for consumption, you should subscribe to the event in the ThcObject.Initialize method instead (recommended).  Also, be sure to check objectstate before performing the calculation.  Avoid trying to access attributes while they’re being initialized, or populated.  IOW, make sure the ObjectState = osNone and remember to fire the event in any ThcObject.Read() or ThcObject.ReadAttribute() override.

For example here is a possible event handler:

procedure TMyself.HairColorChanged(Sender :TObject);
  if (ObjectState = osNone) then
    FQuery.SQL.Text := Format('select HairColor from fnRandomHairColor(%d)',

and in the Read() override:

procedure TMyself.Read(Source :ThcObjectStore; WithChildren :boolean = True);
  inherited Read(Source,WithChildren);
  HairColor.OnChange.FireEvent(HairColor);  //Sender should always be the attribute

Falling through the Cracks

Tuesday, October 16th, 2012

After my last post I was asked by a prominent EMBT team member why I titled the post the way I did.  I responded right away, and got a courteous “thanks for the feedback” response that also posed some additional questions.  I responded and asked a very specific and some general questions to which I have not received any reply.  That was on October 2nd.  I pinged the EMBT representative one week later on the 9th with a friendly reminder that I was waiting for a reply.  I am still waiting for a response to both my original email and the ping.

I know we’re all busy, and sometimes things fall through the cracks.  I have personally been guilty of not responding to an email because I flagged it as a todo item, and never got back to it.  That said, when I receive a follow up request, I make sure to jump on it right away and apologize for not responding sooner.  No one likes to be ignored…it doesn’t make them feel like a valued customer.  To add insult to injury, it makes people feel used when they respond to your questions, but you do not reciprocate.  The Dale Carnegie program is based on the premise that people will generally respond in kind.  I was told when I took the course that it doesn’t work with everyone, and if it doesn’t work, there is really nothing you can do about it…you just have to write it off as a lost cause.

I am the proud father of two daughters.  I teach my children that when asked a question they are to respond to the question, and that it’s not acceptible to answer a question with a question.  If they don’t respond, they are being rude and disrespectful to the person that posed the question, essentially saying to them “I got what I wanted and that’s all that matters…it’s not worth my time to respond to you”.  To say that you listen to your customers, and then ignore them is hypocrosy, something I will not accept in my life on a personal level, and try to avoid on a professional level.

I’m not sure whether the EMBT rep’s email is malfunctioning, or they have been swamped creating 31 days of XE3 videos and travelling.  I do know that this isn’t the first time I asked an EMBT rep questions, and never got a response.  Mike Rozlog said he would get answers for me about specific questions I asked during the XE2 World Tour.  I pinged him months later and never got a response.  Shortly afterwards, he left EMBT.  Is it corporate culture?  Avoidance of tougher issues?  Poor email management or ineffective delegation,  that gives a negative perception?  I’ll let you be the judge….

These are not the errors you are looking for….

Thursday, October 11th, 2012

Recently the DBA made some database changes in my current project and we started seeing a new error in the Eurekalog reports from my Delphi front-end.  The interesting thing is that the error message was actually a warning message from SQL Server 2008 R2.  The message is ‘Warning : null value was eliminated by an aggregate or other SET operation’.  The DBA had found from previous experience that ADO doesn’t always report the actual error, but a preceding message output to the console in a stored proc.

We decided to write a test stored proc and call it from Delphi, confirming his past experience.  I modfied my code to look through the ADO Error collection, and found the source of the exception.  As a result, I have modified hcOPF to provide access to the error collection via the new Errors function on the IhcStoredProc interface.  I have populated this TStringList in the event of an error with the ADO error collection messages.  The original Exception is re-raised, but now you can catch it, and access the actual source of the exception.  I have also stubbed out the DBX implementation.

An additional note about ADO; due to a sporadic bug we encountered with ADO I use the AddParameter method to create and populate stored procedure parameters through hcOPF.  The parameters must be created in the same order as they are defined in the stored procedure since ADO seems to ignore the parameter name when populating the proc parameters.  Using the stored procedure Refresh method followed by SetParamValue calls resulted in sporadic “Parameter @XXX not found” errors.  This appears to be a known issue with ADO that you can read about here.  Since making this change we have not had a single such error report.

EMBT Surveys the Damage

Sunday, September 30th, 2012

If you’re an XE2 user you probably just got an email from DavidI with a link to a new SurveyMonkey survey EMBT has published aimed at XE2 users who have not upgraded to XE3.  One might think they are seeing few XE2 users upgrade to XE3 despite their “bonus” pack.  It’s a positive move on EMBT’s part, showing they are at least concerned with the situation.  Make sure to give them your opinion, including issues like this!

EMBT Cross Promotions

Wednesday, September 26th, 2012

Anyone who has seen all the cross promotional bundling (or bungling if you prefer ;) ) offers that EMBT has been making with Rad Studio and Delphi might be amazed that EMBT has not done something about IBConsole.  I previously blogged about the buggy and unintuitive interface, and was not surprised to hear that most Interbase users have opted to add IBExpert or Database Workbench to their toolkit.

Considering Database Workbench now has a free lite version, it seems like a no-brainer that EMBT should dump IBConsole, and partner with Upscene, or HK-Software to bundle one or more of these free tools with at least the Interbase developer edition. 

After all, my parents taught me that if “you’re going to to something, do it to the best of your ability or not at all”.  Assuming I was competent, that translated to “Do it well or not at all”.  Distributing IBConsole with Interbase provides a negative impression of the product. But wait!  Doesn’t EMBT also sell database tools?

Buying the Privilege to Beta Test

Thursday, September 6th, 2012

I just read JT’s latest post about the virtues of XE3, and was appalled by the last paragraph “*Access to mobile beta requires an active XE3 Professional Edition or higher developer license“.

So now, not only do you have to expend the effort to beta test, you have to pay for the privilege, and it’s inferred that mobile development will likely become a new SKU.  What about all the people who bought XE2 for the promised mobile development with early, often, and regular updates to FireMonkey ?  They’re left with something that JT admits requires substantial effort to produce a mobile application for a full 2 years.

It really seems like EMBT is trying to maintain or increase sales by putting the screws to it’s existing customers by changing the EULA, and requiring upgrades to the latest version in order to see what’s coming down the pipe, but didn’t make it for XE3.

It’s one thing to ask your users to have faith that you will eventually deliver on grandiose plans with limited resources and an apparent lack of focus, and quite another to ask them for money at the same time.  I would encourage the Delphi community to let EMBT know what your think of these decisions both vocally and with your wallet.

A Sinking Ship or a Submarine?

Monday, September 3rd, 2012

The departure of Barry Kelly, a compiler engineer, at a time when EMBT is devoting quite possibly the most effort on their compilers in a long time, is certainly not a good sign for EMBT.  Especially when he says “I was in the same position for more than six years, but I didn’t necessarily want to be pigeonholed as a compiler guy”.  What that says to me, is that EMBT has some serious human resource issues.  Keeping talented and devoted staff is a necessity for any IT company.  You are only as good as your people.  When people leave without having another position, it usually indicates major organizational dysfunction.

I’ve also heard that EMBT is losing senior staff because salaries have not been increased since EMBT bought CodeGear, and Barry’s statement that “I’d fallen out of love with Delphi, and could no longer motivate myself to try and make it better - the gap I’d try to bridge would be a gap too far for the market to bear.” is also very disconcerting.

I remember when I worked for a ticketing company (I would be interested in doing that again - too bad Gateway isn’t hiring remote developers).  I was gung ho to make the software the best of the best, but due to technical limitations we couldn’t do so without some significant re-engineering.  Management would not approve the work, and financially the company was in a holding pattern, unable to compete and grow without the necessary technical, marketing and process changes.  The company was public, and initially I thought the possibilities were endless.  As an insider I was privy to some of the politics, bad decisions, and lack of vision.  I eventually fell out of love with the idea of spending my career there, and left.  I was the first rat to leave the sinking ship, and many followed shortly after I left.  Within a year the company’s stock price fell from their IPO to $0.13/share and within 2 years they closed the doors.

I certainly hope that EMBT does not follow this pattern, and their Delphi sales figures seem to indicate that is not the case, but for how long?  I’ve read the XE3 release notes, and although the presentation is tomorrow here in Calgary, there doesn’t seem to be anything worth upgrading for.  Actions for FMX are one of the few features I would like, and IMHO they should have been included in one of the promised updates for XE2.  The real news seems to be that iOS support is being dropped (at least for now), and there is nothing for Android, or Linux yet because EMBT’s new compilers are not ready.  Another year has gone by, and nothing monumental has been produced, and since I’ve seen little in the way of QC fixes, I don’t believe XE3 is the result of CANI (constant and never ending improvement).  They’re also bundling it out of the gate with other third party products in an effort to create the perception of more value.

If you look at some of the decisions made by EMBT as of late, I really begin to wonder.  The EULA fiasco seems to be yet another way that EMBT is alienating their existing customers.  Add to that, not following through on the promised early, often, and regular updates to FireMonkey, not fixing QC reports in a timely fashion, and not concentrating on core functionality that only EMBT can do, (like compilers - object binding is already available in hcOPF, tiOPF, and Bold to name a few), and the picture of a company who has no clear objectives,  leadership and a poor relationship with their user community starts to take form.  If you’re having problems keeping your existing users happy, it’s really hard to attract new ones.  This is not very different than Borland in it’s later days (is EMBT also doing ALM?).  Perhaps too many old Borland employees in key positions came to EMBT through the CodeGear purchase and are reverting to old behaviours.

I hope for the community’s sake I’ve succumbed to the dark side thanks to reading too many of Joylon’s posts :-) but when you start to see negativity seeping into other community bloggers that are normally quite positive it’s hard to keep kidding yourself.  Hopefully, EMBT is not a sinking ship, but rather a submarine (they move faster under water than on the surface, and are very effective in their role by keeping a low profile).  Otherwise, my current Delphi contract might be my last…and that would truly make me sad.

hcOPF - Configuring XE2 for Compilation

Friday, May 4th, 2012

It is not necessary to change the DCP output folder because the defaults automatically take into account compiling for different platforms.  In the Tools - Options - Library settings if you select Win32 you will notice that the Package output directory is set to:


and the DCP output directory is set to:


which works great since the IDE is a 32 bit EXE and this folder will be on the search path so the IDE can load the design-time packages.  This provides backwards compatibility, but the moment you start compiling the same package for additional targets it becomes cumbersome.

If you select Win64 or OSX you will notice that the package output directory changes to:


It’s interesting that you cannot modify the Library Path globally, so if you have a product that compiles for multiple platforms you have to add the necessary bits into each Platform’s version of the Library Path.  This is an enhancement I have suggested in QC#105378 .  Personally I have always preferred explicit specification rather than implicit, and as such I think the default Package output directory should be:


and likewise the default DCP paths should be:


This is sort of like defining a class as

TMyObject = class


TMyObject = class(TObject)

I believe consistency in usage promotes more readable and thus more maintainable code and IDE environments.  From my experience it’s also easier to manually purge your output folders, and confirm the appropriate units are being generated if a consistent directory structure is used.  If you agree, please vote for QC #105377.

In the case of hcOPF the Library Path needs to contain the following:


If you happen to notice that the Path is greyed when you add it to the dialog, don’t panic.  For some reason, the Directories dialog has problems validating Paths that contain $(Platform)  which is evident by the first path in the list


also appearing in grey.  I have entered a QC report (#105375) for this, so please vote for it.

So DCP and BPL output folders are handled by default in a suitable fashion by the IDE, unless you’re like me and prefer a more uniform directory structure in which case you can change the Win32 DCP and BPL path defaults in the Tools - Options - Library dialog.  If you change these paths, packages which do not have an override value specified in their Project - Options, will output to the new default directories.

At a minimum developers need to make sure their Unit output path does not collide which means using a structure something like .\Lib\D16\$(Platform)\$(Config) as I alluded to in my previous post.  This is also handled by default if you’re creating new packages in XE2.  If you’re upgrading existing packages, make sure to set the unit output path to use $(Platform)\$(Config) as well.

One thing I find intriguing is that under Project - Options for ‘DCP output directory’ there is an entry for the Target ‘Debug Configuration - All Platforms’, yet there is not one for ‘Release Configuration - All Platforms’.  Maybe someone can explain this one to me…

hcOPF - Time to Start Monkeying Around

Monday, April 30th, 2012

I’ve put quite a bit of effort as of late getting hcOPF ready for Win64 compilation, and as part of that effort, re-factoring it to support FireMonkey.  The actual code and package changes were relatively minor when compared with trying to understand what was required.  To me this validates the design of the framework that it can be adapted rather easily to support new frameworks and platforms.

There are no new recommended guidelines for DesignTime and RunTime packages AFAIK now that XE2 supports FMX and VCL.  To complicate things further, add in Unit Scope Names, the fact that the IDE automatically renames FMX package projects when you target the OS/X, and all the conditional directive permutations, and it can drive you bananas!

On top of that, the IDE does not provide default guidance when upgrading packages from earlier IDE versions.  It does not default the unit output directory to .\$(platform)\$(config) as it does for new ones, so when you compile for one platform you overwrite your DCUs for another, and really confuse things.  For this reason, you might notice that for All configurations - All platforms hcOPF uses a unit output directory of $(hcOPF)\Lib\D16\$(Platform)\$(Config) where $(hcOPF) points to the root directory of the framework.  It would be great if there was an environment variable for the IDE version.  Then you could use something like $(hcOPF)\Lib\$(DelphiVersion)\$(Platform)\$(Config).

I am pleased to announce that hcOPF now supports FireMonkey (Win32/64 and OSX32) as well as VCL Win32/64 targets with a few caveats:

1) when compiling for the Mac or any 64 bit target you must skip compilation of the design time packages.

2) The HengenOPFValidatorsFMX/VCL packages do not support 64 bit targets since it uses the open source PerlRegEx component instead of the RegEx support present in XE and above.

3) Certain packages of course cannot be used on certain platforms like ADO and the Validators on the Mac since they have Windows specific implementations.

4) As always some packages require third party commercial libraries, such as the HengenDevExpressXXX packages which require the Developer Express Quantum Grid suite (highly recommended).

5) Win32 BPLs go into the default $(BPLDir) and those for OSX32 and Win64 go into their respective subdirs

In a future version I hope to add support for iOS as well as providing validator support for FMX.  Currently hcOPF will not compile using FPC because it does not support the implements interface delegation syntax that EMB’s compiler does.  Eventually I plan to support FPC and SQLite.

If you want to start Monkeying around with hcOPF, check out the FireMonkey SVN branch.