Wednesday, February 28, 2007

Documentation/Help In Delphi 2007 Part I

At lunch today I was asked by Allen Bauer to blog about one of the new to me areas of Delphi that I work on, Documentation/Help. In other words, I'm responsible for the F1 key in Delphi. I will also be discussing this topic at Code Rage. I think I'll have to break this up into a few posts due to time constraints.

There are four primary areas of the Documentation/Help system; Documentation (the doc content), Help Build (the process which converts the raw form of our content into the pretty text you read), Translation (we provide doc content in English, German, French and Japanese), Testing (validating that the context IDs are correct, doc is delivered and matches what we expect when you press F1 in the IDE), and IDE Help (meaning the F1 key in the IDE).

A few years back we made the switch from WinHelp to HTML2 Help. In this transition most of the doc content was migrated from RTF files to XML. XML is a much better format but requires a lot of tooling since the RTF files were pretty straight forward and the tooling was provided by Microsoft. But when I was tasked with "fixing F1" and after turning over all the rocks, looking under them and putting them back I found a few disturbing things out that I'm really embarrassed to even mention, but here goes. Our doc content was sitting on a server where the pubs team would just copy their modified files overwriting the old files, the help build system took over 12 hours to build one language and required human interaction to complete, I couldn't find our translated content, not everything was translated, content was missing, files were corrupt, and F1 didn't even work from the form designer.

I decided for obvious reasons to take a pragmatic approach to the problem; scientific, repeatable and well-defined. So first things first I fixed F1 on the form designer and we released a patch to Delphi 2006. Next I put all 38,000 doc files in a subversion repository and began searching through the servers to find the translated content. I'd like to mention that subversion can't handle 38,000 files x 4. Subversion may not be the best repository but it accomplishes the task of versioning the files so we'll stick with it until we can replace it with something better.

The next step was to scrap the old 12 hour help build system. Building help for all locals required someone to monitor a computer for nearly a week because human interaction was required. Since the next release of Delphi is simship (release all locals simultaneously) a full week of building the help wasn't going to fly. So we changed our build system to Doc-O-Matic. Chris White, a new Delphi R&D engineer, has been working with Tools Factory to get the Doc-O-Matic build system running and we are all very impressed with Doc-O-Matic. Currently the process is now around 3 hours and manually run each night. Soon we will get some new hardware and run four Cruise Control servers to build the help automatically each night and allow doc or translation to request a build when major changes are checked into the documentation repository. We will also add Zombie automation to verify the help works and the content.

In Part II I'll discuss the translation process, In Park III I'll give an overview of the help/documentation testing and in Part IV I'll discuss the F1 hurdles we faced and some of the new cool features.

Update After writing Part II I realised I forgot to mention testing, so I've modified a few sentences to discuss testing.

Part I
Part II
Part III
Part IV

Friday, February 23, 2007

COM Registration Under Microsoft Windows Vista

Steve Trefethen and I have both been working on Windows Vista and I must say there is not one redeemable feature of Windows Vista over Windows XP. I keep hearing how it looks like Mac OSX, but the only resemblance I've been able to find is when minimizing apps they slide into the taskbar.

Enough of my complaining, I had a real issue to discuss in this post, COM Registration. Chances are you will need to use COM objects when you start developing on Windows Vista and there is a real problem that UAC has created. You cannot register a COM object unless you are running as Administrator. I don't mean you have Administrator privileges, I mean the process is running under the Administrator account (root for you Linux heads). Things you took for granted in previous Windows versions like running regedit.exe from a command prompt like I normally do fails with "Access denied". You must run it from the Start Search menu item (similar to the old Run menu item), then grant access for the process to run. Most likely you will have to create a shortcut to 4NT or CMD and right click on it and choose "Run as administrator".

So now let's look at registering your COM object. Take midas.dll as an example. It was written a lone time ago, before UAC. If in a non Administrator privileged command prompt you type "tregsvr midas.dll" you get "Call to DllRegisterServer was successful!", but it actually wasn't. So what happened? tregsvr doesn't have privileges to touch the registry so the DllRegisterServer in midas.dll failed. The implementation of DllRegisterServer in midas.dll could do potential harm to your system so Windows doesn't allow it access to the registry calls and there are sufficient checking down on those calls for DLLRegisterServer to return an error to tregsvr so the tregsvr reports a success. This can happen with any COM DLL so you can't rely on a call to tregsvr (or regsvr32) like in the good old days. Pre UAC COM objects need to be tested and verified and always registered in from an Administrator privileged account. This means that features in Delphi you've grown to know and love like Run | Register ActiveX Server will fail under Vista because of UAC.

Thursday, February 22, 2007

New Canon 1D Mark III Camera

And I thought my 1D Mark II was fast. This new camera features 10.1-megapixel self cleaning sensor capable of 10 frames per second with a 30 frame buffer from ISO 10 to 6400. I'm told that the list price will be $3999 and that it doesn't use the same batteries as the older 1D series cameras which is a bummer.

I predict a 1Ds Mark III with 20.2-megapixel, self cleaning sensor capable of 5 frames per second with a 15 frame buffer from ISO 10 to 6400 to be out later this year.

Wednesday, February 14, 2007

Happy Birthday Delphi

Today Delphi is 12 years old. Delphi was officially launched February 14th 1995. I officially started working at Borland as an intern June that same year fresh out of high school so I remember that year well. Let's hear it for Delphi!

Side-by-Side COM Registration Part II

I've been meaning to expand on Part I of Side-by-Side COM Registration for some time but other things have gotten in the way. The major road block is getting Side-by-Side working 100%. I can get it working in the simple case, even the complex case, but not the super complex case. In other words, the Delph IDE. Until then I don't want to increase the amount of misinformation out there on the subject, and believe me, there really is a lot. Of misinformation that is. One valuable piece of information has been recently published on MSDN Manifest Files Reference. Believe it or not, the information up on MSDN until this article went up was wrong. Thus far I'm glad to say I haven't posted any misinformation, just not enough to actually get Side-by-Side working in a complex case.

Tuesday, February 13, 2007

Using LoadTypeLib and LoadTypeLibEx

When most people use COM they stumble through it and if it works they just go with it. If you don't stumble with COM you probably can ignore this post but somehow I'd be willing to bet you'll read on. There are little idiosyncrasies in COM, ActiveX or COM Interop that aren't documented, so here's a little piece of information about type libraries. To load a type library into memory and get a pointer to the ITypeLib interface use the function LoadTypeLib.

HRESULT LoadTypeLib(const OLECHAR FAR *szFile, ITypeLib FAR* FAR *pptlib);

LoadTypeLib is the foundation of COM. Any call to LoadTypeLib will register the type library if it is not already registered. That's why Microsoft invented this function:

HRESULT LoadTypeLibEx(LPCOLESTR szFile, REGKIND regkind, ITypeLib** pptlib);

Any function is better with an "Ex" on the end. If you just want to go spelunking around in a type library and don't want it registered then use LoadTypeLibEx and pass in REGKIND_NONE as the regKind parameter. Problem is if your type library references other type libraries and they are in the current directory and they are not registered then they will be after this call, but the type library you passed in as the szFile parameter won't get registered.

Sunday, February 11, 2007

New Photo Of The Week

Copyright © 2007 Chris Bensen. All rights reserved.

It has been a few weeks since I've updated the photo of the week becoming more of a photo of the month. So this month, here is a photo I took this winter at Natural Bridges State park here in Santa Cruz. We had a long stretch of low tides right at sunset. I wish it had lasted more than 5 minutes, but it was an absolutely stunning 5 minutes!

Friday, February 9, 2007

Oldie But Goodie COM/ActiveX Article

Recently I ran across this page on the Borland website Overview of COM technologies. If you are new to COM or just want to freshen up on COM basics it is a great read.

Thursday, February 8, 2007

64-bit Windows XP Conundrum Continued...

I can't print to the office printer. There is no 64-bit driver for the Canon supper fax, scanner, copier we have. After looking around there aren't very many 64-bit printer drivers.

Tuesday, February 6, 2007

Apple Commercial for Vista

This is by far the funniest Mac PC ad yet. My copy of Vista is on it's way. I can't wait!

Update YouTube took the commercial down. You can go to the Apple website to watch them". This one is called Security.

Dual Mice

Most people talk about having two monitors hooked up to their computer. Well I have two mice hooked up to mine; one on each side of the keyboard. Why do I have two mice you might ask? Well there are times when I like to use a mouse with my left hand and times when I like my right. Copy and pasting things requires use of the right mouse because the left hand is busy with CTRL, X, C and V keys. Use the number pad and I use the left mouse. Someone else comes into my office and wants to drive and we don't have to fight over a mouse, we each got one. Give it a try. I guess you have to be ambidextrous first. It just takes some practice.

Saturday, February 3, 2007

MSBuild and InstallAware in the Next Version of Delphi and C++Builder

Normally I couldn't say anything, but given that there have been some press releases and announcements I won't be disclosing anything you didn't already know. Two big features already being talked about are MSBuild as the new Delphi and C++Builder build system and the new installer by InstallAware.

It has taken a while getting used to typing "msbuild debug" instead of "make debug" from being engrained in my over the years, but I like the advantages of MSBuild. Being able to compile identically from the IDE and the command line is a huge advantage. And the performance ain't too shabby either.

The technology behind the installer seems really cool. I think everyone will see a lot of benefits and I'm really stoked that it's written in Delphi. I think InstallAware Express will make deploying Delphi and C++Builder applications a breeze.

Thursday, February 1, 2007

64-bit Windows XP Conundrum

I am blessed to be one of the few Delphi R&D engineers running 64-bit Windows XP. I've been running 64-bit Windows for a little under a year now and I can honestly say if you want to avoid a headache do yourself a favor and continue running 32-bit Windows. Here are a few things I've run into and the work arounds.

xsd.exe fails to run under 64 bit Windowx XP with the error:

Error: The CodeDom provider type "Microsoft.VJSharp.VJSharpCodeProvider, VJSharp CodeProvider, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" could not be located.

The problem is that xsd.exe is a .NET application that floats. This means that if it runs on a Win32 system it runs as Win32, if it runs on a Win64 system it runs as Win64. Problem, J# is not Win64 so the code provider does not exist. This is a bug on Windows 64 bit. You can make it work by creating an application, I called mine txsd.exe, that references xsd.exe and just calls it's main. txsd.exe is a non-floating application so it forces xsd.exe to be run in Win32.

dbgclr.exe doesn't debug 32-bit by default on a 64-bit machine. To get a working copy of dbgclr.exe, install Visual Studio (the free version should work) and then copy dbgclr.exe from a 32-bit machine. Then it'll run like a champ. For some reason Visual Studio installs something that is required by dbgclr.exe.

iTunes 7 doesn't run, I have to continue to run iTunes 6. The funny thing is (and what made me thing of writing this blog post) is that I just got a reply to by bug report that Apple QA can't reproduce the bug. Anyone else have this problem that can shed some light on the issue?

Delphi/C++Builder 2006 Not Saving Changes

There is a bug where the type library editor may not save your changes: 29215. The current work around is to build your project after you do a save. The Quality Central entry states that the bug was introduced in Update 2, but the fact is the bug has been around since Delphi 3 and just now manifested itself differently. You can tell if the type library was completely saved if the save all icon on the toolbar is grayed out.

Chances are if you create COM objects and are using the type library editor you will never see this bug, but when it does happen you will loose the changes you made to the type library. If you close the project, open just the .tlb file in the Type Library Editor, add what would have been created and reopen your project everything will be back to where you expected it.

Not that it matters, but the reason for the bug is architectural in nature. When the IDE was redesigned (codename Galileo) lots of changes took place, one of which required a change with how the IDE interacted with the type library. This change exposed a flaw in the architecture of how the type library editor determines if the internal representation of the type library was modified or not (in other words does the .tlb need to be saved).

Update: This bug has been fixed in Delphi 2007