Tuesday, July 31, 2007

Amazon Groceries Coupon Code

Yesterday I posted about Amazon Groceries and you probably don't want to hear more about it but the Missus just ordered some more diapers and found a coupon code for Amazon Groceries where you save $10 if you buy $50 or more.

Just enter the coupon code: MEAL1000

I'm not sure how long the coupon code is valid for so better to use it sooner than later if there is something you can use or need. In our case we are about to run out of diapers and ten bucks is too good to pass up.

Okay, I'm done pushing Amazon now.


.NET Interop: Calling Managed from Unmanaged

I ran into another issue today when dealing with .NET Interop. This particular case had to do with invoking an unmanaged export. The exception happened on the .NET side but we never got to the exported method. To make a long story short the problem was the floating point control word wasn't set to what .NET expects. I have found this wasn't much of a problem with .NET 1.0 or 1.1 so something has obviously changed in .NET 2.0.

The moral of the story is to wrap every single one of your interop calls with this pattern:


var
SavedCW: Word;
begin
SavedCW := Get8087CW;
try
Set8087CW($027f);
// ToDo: Insert your interop code here.
finally
Set8087CW(SavedCW);
end;
end.

.NET Interop: Delphi for .NET Unmanaged Exports

There are times when you want to interop with .NET by write something in managed code and want to use it in native code but don't want to use COM Interop. A simple feature of Delphi for .NET is Unmanaged Exports. This allows you to export a function from an Assembly for use from native land. I know there have been a lot of articles about this over the years since Delphi for .NET was released but you can't have too many examples. So here is a simple example of creating an Unmanaged Export:

File | New | Delphi for .NET Projects | Library

Note: There are very few cases you want to use Library. Most of the time you want to use Package. Unmanaged Exports is one of the few reasons to use Library

Paste the following code into the .dpr file.


library netlib;

{$UNSAFECODE ON}

uses
SysUtils,
libunit in 'libunit.pas';

procedure Foo;
begin
WriteLn('Foo');
end;

exports
Foo;

end.


File | New | Delphi Projects | VCL Forms Application

Paste the following code into the .dpr file.


program app;

{$APPTYPE CONSOLE}

uses
Windows;

type
TFooProc = procedure; stdcall;

var
FooProc: TFooProc;
LibHandle: THandle;
begin
LibHandle := LoadLibrary(PChar('netlib.dll'));
if LibHandle <> 0 then
begin
try
@FooProc := GetProcAddress(LibHandle, 'Foo');
if @FooProc <> nil then
FooProc;
finally
FreeLibrary(LibHandle);
end;
end;
end.


When you run app.exe it will load the assembly netlib.dll, get the address of the exported function Foo and invoke it where Foo will print out the string 'Foo'.

Monday, July 30, 2007

Amazon Groceries




At the beginning of the month Amazon Associates sent me an email that they are basically trying to get more people to buy groceries through them. I usually disregard emails like this but I decided to take a look and noticed some pretty good prices on things we actually buy like CLIF bars and Seventh Generation diapers. Like anything I can't recommend anything to anyone that I haven't tried but I do buy stuff from Amazon so if they have something you need it is worth looking to save yourself some money by clicking on one of the anoying Amazon banners in this post.

Another interesting feature they've added is the "subscribe and save 15%". You choose to subscribe to the item and it will be shipped automatically to you every 1, 2, 3 or 6 months at a 15% discount. I haven't used this yet but it sounds interesting for those things like diapers that we know we will use.

Here is Amazon's marketing blurb:

"Why market Amazon Grocery products to your customers? Amazon Grocery offers over 22,000 non-perishable items including some of your favorite brands, shipped to your door, just like any other Amazon.com purchase. We've also recently introduced the Subscribe and Save program, which is a great way to save money on items you use routinely. Your visitor can sign up for routine convenient delivery of products such as coffee pods, shampoo, laundry detergent and diapers and receive a 15% discount off Amazon's already low prices and free shipping on these items."


My Recent MacPro Purchasing Experience

I have waited to write this until the entire ordeal was over. A month and a half ago I purchased a MacPro from the online Apple Store to replace my Quad G5 so I could have just one computer at home to run Windows and also get a nice performance bump when running Aperture for my photography.

To make a long story as short as possible it arrived Dead on Arrival (DOA) and everyone I spoke with at AppleCare didn't know the DOA Policy (and I have spoke with a lot of people). On July 2nd I finally spoke with a Specialist that finally knew the DOA policy and actually tried to help and not tell me lies. The DOA policy reads:


Dead On Arrival (DOA) Product: System Failure Out of the Box
An Apple-branded hardware product is considered DOA if it shows symptoms of a hardware failure, preventing basic operability, when you first use it after opening the box. If you believe that your product is DOA, please call AppleCare Technical Support at 1-800-APL-CARE (1-800-275-2273) within 30 calendar days of the invoice date. AppleCare Technical Support will determine whether the product is DOA and offer you the following options:


* Replacement: Apple, at its expense, will ship another of the same product . AppleCare Technical Support will put you in touch with an AppleStore Sales Support Representative who will arrange for replacement and the DOA product’s return.

* Service: You may have the product repaired. However, once you choose that option, you may not request replacement of the product.

If AppleCare Technical Support determines that a returned product is not DOA, Apple will apply Apple’s standard product warranty to the product. Further, if AppleCare determines that you have misrepresented a returned product’s condition and that the product is not DOA, Apple may impose a $400 handling fee.

This DOA policy applies only to Apple-branded hardware products currently offered at the Apple Store. As new products are offered, Apple reserves the right to determine whether or not this policy applies. This DOA policy does not apply to third-party products that do not bear the Apple brand name. You must call the manufacturer directly with any third-party product issues.


My machine wouldn't reboot and only detected 2GB out of the 4GB of RAM so obviously it qualified for DOA. Whenever I spoke with anyone I asked for the replacement option but they knew nothing about it. So I had to take it in for servicing (yeah, a brand new machine) and the "Genius" at the Genius Bar didn't know the DOA policy either. I ended up picking the machine up July 3rd, running into Steve Wozniak buying another iPhone (his 3rd time at the Valley Fair store since the iPhone was released), and finding out that the case was scratched and chipped.

After a bit of going around in circles they offered me some compensation for the damaged case and the hassle. I am fairly happy with the outcome but I will never get my time back. Apple does have good customer service, and prides itself on that customer service, but things happen that are out of their control. I just happened to be on the happening end, but it's how the company handles it is what counts. Customer service is an interesting business to be in.

If you have a similar situation I suggest you ask for a specialist if the initial person answering the phone can't help you. I have found that not all specialists know what they are talking about so call back again and get someone else. Each time you call it will take about 15 minutes for the first person and may take much longer for the specialist. Before you call read the Policy. Actually before you order read the Policy. If you can buy it from a local store do so. In the case of ordering a computer any option that is not the default is a "custom" computer and is handled differently. Many of the stores carry popular custom configurations.

Sunday, July 29, 2007

Blogger New Poll Feature

In spirit of testing out Blogger's new Poll feature I added a poll to the sidebar this week. Although I notice that I added it on July 29th, set the ending date for August 3rd at midnight and the coundown say's only 4 days left. Hmmm. I wonder what it will say tomorrow.

Speaking of Blogger features that don't work, when are they going to fix the spell checker so it works under Safari?

Friday, July 27, 2007

Creating Gallery Plugins for Delphi and C++Builder

When creating gallery plugins with the IOTAWizardServices service using AddService and RemoveService I found that when adding a lot of gallery items there was a lot of housekeeping that needed to happen for each wizard. So I created a simple class called TWizardList that handles the monotony of adding and removing wizards. It really is quite simple, the code is below, but it sure made life a lot easier. Just create one of these per package, and free it on unit finalization and bam, instant gallery item registration and unregistration.

Feel free to use this class in any of your Delphi or C++Builder plugins. It really will save you some time.


unit IdeHelpers;

interface

uses
ToolsAPI;

type
TWizardList = class
private
FWizardService: IOTAWizardServices;
FItems: array of Integer;

public
constructor Create;
destructor Destroy; override;

function Add(const Wizard: IOTAWizard): Integer;
procedure Remove(Value: Integer);
end;

implementation

{ TWizardList }

constructor TWizardList.Create;
begin
FWizardService := nil;
end;

function TWizardList.Add(const Wizard: IOTAWizard): Integer;
var
Index: Integer;
begin
if FWizardService = nil then
FWizardService := BorlandIDEServices as IOTAWizardServices;

Result := FWizardService.AddWizard(Wizard);
Index := Length(FItems);
SetLength(FItems, Index + 1);
FItems[Index] := Result;
end;

procedure TWizardList.Remove(Value: Integer);
var
Index: Integer;
begin
if FWizardService = nil then
FWizardService := BorlandIDEServices as IOTAWizardServices;

FWizardService.RemoveWizard(Value);

for Index := 0 to Length(FItems) - 1 do
begin
if FItems[Index] = Value then
begin
FItems[Index] := -1;
end;
end;
end;

destructor TWizardList.Destroy;
var
Index: Integer;
begin
if FWizardService <> nil then
begin
for Index := 0 to Length(FItems) - 1 do
begin
if FItems[Index] <> -1 then
FWizardService.RemoveWizard(FItems[Index]);
end;
end;

inherited;
end;

end.

Wednesday, July 25, 2007

Who Can Beat Voldemort?



Seeing as how this is a very Harry Potter month and after reading the Gizmodo post "Voldemort Vs. Terminator, Who Wins?" yesterday we got into the discussion of who can beat Voldemort? Terminator obviously would lose because Voldemort has magic. Gandalf the White (obviously Gandalf the Gray is no match) would be a good match in my opinion but David Lock beieves that J.R.R. Tolkien magic is no match for J. K. Rowling magic. Sauron is probably a good match to Voldemort. Optimus Prime probably has as much luck as the Terminator. Professor X or Magneto might be a good match.

I think it is safe to say the champion of this battle needs to have special powers other than super strength. Some argued that Superman has all those abilities but Voldemort would just summon some kryptonite leading to Superman's demise. Neo from the Matix has a good chance if Voldemort was in the Matrix. Galactus or Silver Surfer might have be able to take on Voldemort.

And last but not least what about the characters from Star Wars: Luke Skywalker, Obi-wan Kenobi, Yoda, Darth Vader and the Emperor. I think the Emperor would just blow the planet up with the Death Star, done end of story. Vader would do a super Jedi choke hold. I guess I'm not seeing much of a chance for Luke or Obiwan so that doesn't say much for the light side of the Force.

Who do you think could take Voldemort?

Friday, July 20, 2007

.NET string vs StringBuilder

David Lock, our resident game programming expert, has just posted a real life example about his experience between .NET string vs StringBuilder. In short if you are going to modify the string then .NET string bad and StringBuilder good.

VMWare Converter Worked when Parallels Transporter Failed

Last week I wrote about how Parallels Transporter failed to import a Windows 2000 computer and it was suggested to try VMWare Converter. Well VMWare Converter worked great. Thanks for the advice. I figured I'd give Parallels Transporter one more try and I imported the VMWare VM into Parallels and that worked too. I guess Parallels Transporter either doesn't work with Windows 2000 or something on that particular system causes problems.

The Mac version of VMWare Player is VMware Fusion which is currently in beta. In the mean time you can down load the beta from here. There is a note at the top of the page that if you pre-order VMWare Fusion you can get it for $39.99 at a 50% savings. Here is a video of a Unity a cool new feature in VMWare Fusion:



This is the first time I used Parallels or VMWare on Mac and I found that one feature was really anoying compared to VMWare and Microsoft Virtual PC when running on Windows. When running in the VM the mouse cursor is totally owned by the VM window. To get the mouse cursor back you must press CTRL + ALT (Control + Option on my Mac) for Parallels and Control + Command for VMWare Fusion. It seems that VMWare's Unity feature doesn't work on Windows 2000 so I'm going to install Windows XP and probably Windows Vista to see what the user experience is.

Update: I just installed Windows XP and the VMWare tools were able to install unlike the Windows 2000 VM and this mouse problem is solved. So I take everything back.

Update: Alt + Tab (Option + Tab on the Mac) doesn't seem to switch tabs in a my remote desktop session from VMWare Fusion. Also for some reason Unity put a link to Internet Explorer on my Dock. Naturally this bugs me because I didn't put it there. I'm sure there is a logical reason I just haven't figured it out yet.

Update: I figured out why Internet Explorer shows up in the Dock. Any running application in the VM shows up in the dock when running Unity. Duh!



Also the Eject button doesn't work when running a VM from VMWare. I hope they fix this before they ship. It is a pain to suspend the VM just to put a CD in the drive.

Interesting side note, if you do a Google search for "parallels transporter" my last post on this subject ranks #4.

Thursday, July 19, 2007

Checking the Windows Version

Sometimes there is a need to detect which operating system the application is running on. In Menus.pas you can find the following code but a bit more spread out so I've consolidated it here into a nice easy to read chunk:

Note: The checks are for that version or later.

var
Win98Plus, Win2K, WinXP, WinVista, Win7: Boolean;
begin
Win98Plus := (Win32MajorVersion > 4) or
((Win32MajorVersion = 4) and (Win32MinorVersion > 0));
Win2K := (Win32MajorVersion > 4) and
(Win32Platform = VER_PLATFORM_WIN32_NT);
WinXP := CheckWin32Version(5, 1);
WinVista := CheckWin32Version(6, 0);
Win7 := CheckWin32Version(6, 1)
end;

Wednesday, July 18, 2007

Choosing Variable Names

Recently I've been looking at some of the VCL and VCL Form Designer code having to do with themeing where I've encountered variable names like UnthemedDesigner. As a result I find code like this:


if not UnthemedDesigner then
begin
FHasManifest := True;
Result := FHasManifest;
end
else
begin

// Do something else...
end;

When variable names are carefully chosen it sure can make everyone's life a lot easier. But then I wouldn't have anything to blog about. So here is a quick list off the top of my head when naming something.

Singular noun consisting of a class, interface, record, variable, field, accessor method, exception. For example: TControl, TButton.

Plural noun consisting of a variable or field holding a collection. For example: Items, Classes.

Verbs consisting of methods. For example: Dispose, GetItems, Delete.

Adjectives consisting of interface and boolean. For example: IDisposable, cloneable, IsEnabled.

Names should not be negative. "Un", "Not", etc should be avoided for clarity.

I'm sure you've seen similar lists before. If you haven't then you should go buy and read the book Design Patterns: Elements of Reusable Object-Oriented Software.

Monday, July 16, 2007

Default IDE Options when Importing a Type Library

Last week I posted How to Import a Type Library from the Command Line. Today I'm posting which of these options are the defaults for the IDE. This is useful if you want to reproduce what the IDE is doing from the command line and since the defaults are not exactly identical I thought it would be useful to have a list published.


  • -C- C++ Import file (the IDE will control this option)
  • -P- PASCAL Import file (the IDE will control this option)
  • -Ha+ Create IDE component for Controls
  • -Hs+ Create IDE component for Servers
  • -Hr+ Generate component registration
  • -O+ Generate CoClassCreator wrappers
  • -R+ Process dependent type libraries
  • -W+ Emit warnings in files
  • -Wc+ Emit comments in filesx
  • -Yc+ [CanCreate]
  • -Cd+ Generate dispinterfaces
  • -Cu+ Expose namespace with 'using'
  • -Ps+ Map dual HRESULT to safecall
  • -Cw+ BCB-style event server events
  • -Ct+ Force the use of a _TLB file


So there you have it, the defaults the IDE uses for the first time ever documented.

Point and Shoot Cameras

The Missus and I have been in the market for a good quality point and shoot camera for quite some time. It's a market where there are so many choices it'll make your head spin and making a decision is next to impossible without just closing your eyes and playing pin the tail on the donkey. We finally made a decision and purchased the Canon Elph SD1000. In case anyone else is interested, here is the entire market of cameras narrowed down to the ones that I feel have good value for the money with the emphasis on being a convenient camera for a mom to carry around.

Canon Elph SD1000

At $210 this is an excellent camera, small light weight and fast with emphasis on small and lightweight. The image quality is good too, but like any point and shoot it takes it's best photos in good light. Due to the nature of the small sensor they just can't avoid the laws of physics. I looked at the other Elphs and similar Nikon cameras but none had better image quality. The only other feature I was looking for was image stabilization but that jumps another $100 or more and at that point I'd rather get the Panasonic LX2 I've listed below. Also a lot of people make purchase decisions based on pixel count so this Elph is often overlooked for other models. Remember it is the quality of the pixels that count, not the pixel count.

Panasonic Lumix DMC-LX2

The LX2 is the same camera as the Leica D-LUX 3 but with a price tag of $405 instead of a $600. The extra money gets you slightly different image processing, a nice clean Leica metal body. Basically you pay a lot for the name.

The LX2 has really good image quality in good light conditions. I would probably have taken this camera instead of SLR on hikes because it is so small and light. Once it gets dark or you want to take photos indoors the Elph has a small edge due to the noise in Panasonic sensors. The key features on the LX2 are image stabilisation, 16x9 aspect ratio, Leica lens, RAW and wide angle. All features are very unique making this a very interesting camera.

Canon G7

The G7 appears to have it all, image stabilization, good telephoto, ability to use Canon flashes for good indoor photos and fairly small. We couldn't find any store that carried the G7 just to hold. Fortunately a friend has one and he really likes it, but at $500 and a lot larger than the Elph we decided that it didn't quite fit our needs. I call it the El Camino of cameras; Neither a car nor a truck but has the disadvantages of both. Seriously though, it was just a matter of value and performance and an SLR takes much better photos.

Ricoh Caplio GX100

Ricoh has recently been selling cameras in the US again and the $600 GX100 looks really interesting. I didn't get a chance to hold one in my hands but it looks like what a traditional range finder camera should look like. After all my research the advantages of this camera is better image quality than the Panasonic LX2 or G7, RAW, image stabilization, wide angle, and full manual controls that are nobs. Awesome camera, just has a high price tag for a mom to carry around. If I were looking for a light weight camera then it would be between this and the Panasonic LX2. The decision would be tough because the question is the extra $200 worth the difference.

Canon EOS 400D / Digital Rebel XTi

Then there is the Canon 400D/XTi at $663. The Rebel has a slight edge over the Nikon 40Dx because it has sensor cleaning. The viewfinder in the Nikon is hardly any different between the cameras and nearly every other feature is equivalent. For some people there may be some feature that matters but don't underestimate sensor cleaning. To buy a set of cleaning brushes it costs $100! The other reason for the Canon is I already have a lot of lenses that the Missus could use. If quality is a concern then in the digital market nothing beats any digital SLR. The sensors are much larger which allows them to capture more quality light.

PHP 4 End of Life Announcement

Last Friday I noticed this note on www.php.net:

"Today it is exactly three years ago since PHP 5 has been released. In those three years it has seen many improvements over PHP 4. PHP 5 is fast, stable & production-ready and as PHP 6 is on the way, PHP 4 will be discontinued.

The PHP development team hereby announces that support for PHP 4 will continue until the end of this year only. After 2007-12-31 there will be no more releases of PHP 4.4. We will continue to make critical security fixes available on a case-by-case basis until 2008-08-08. Please use the rest of this year to make your application suitable to run on PHP 5.

For documentation on migration for PHP 4 to PHP 5, we would like to point you to our migration guide. There is additional information available in the PHP 5.0 to PHP 5.1 and PHP 5.1 to PHP 5.2 migration guides as well."

Friday, July 13, 2007

Backing Up Your Blogger Blog

Last weekend I was talking to a friend and she mentioned that a while back when blogger did some internal migration she lost one of her almost dozen blogs. Not exactly sure how you keep track of a nearly a dozen blogs but I guess it goes to show you how popular blogging is. At any rate my first thought was "don't you back up your important blog data", but I held my tongue because I'm not backing up my blog either. So I started looking into how to back up my Blogger blog. In my short search I came across a blog post How to Back Up Your Blogger Blog. The best way appears to have each message and comment emailed to yourself and in the unlikely event of a Blogger failure the blog could be recreated. What a pain. I think if someone wanted to make a cool blogger backup application there could be a market for it. I'd sure use it.

Running Windows and Delphi on a Mac

Developers running Windows and Delphi on a Mac has been an increasing trend around the office and posts on blogs lately from Dan Miser, David Glassborow and Steve Trefethen. Any given meeting is likely to be 50% Mac laptops.

I too have joined the masses but with a MacPro instead of a MacBook Pro. I don't like laptops. Sure they have their place, but I prefer to sit at a desk when I work and not have the monitor down where my hands are. I've been using a G5 Mac as my primary computer at home for the last few years to do my photography and personal computing. I use Remote Desktop to connect to my computer at work and my home Windows system (which is going away now). Remote Desktop leaves something to be desired. You can only run one instance unless you make a copy of the application, and it crashes, it crashes a lot.

The Missus and I have been taking some video of our daughter and when people ask how I made the DVD I start sounding like the Mac vs PC commercials. Yeah, iDVD, iMovie and Aperture just work and they are simple. Dead simple in fact. The experience is pretty good. Only problem I've had was my MacPro arrived DOA and it has been a mess dealing with customer service. Worst customer service experience I've ever had in fact. Going on a month and I'm still dealing with it.

Thursday, July 12, 2007

Parallels Transporter

Yesterday I tried to run Parallels Transporter on an old Windows 2000 machine but it failed. I need this OS because a printer that my wife uses will only print from Windows 2000 and I'd like to have a VM so I don't have to keep the hardware around. I'm really bummed it didn't work. Has anyone else tried this and been successful? Does anyone know of any other software that will convert an already running and booting hard drive into a VM?

Please Update Your Feed

Dan Miser mentioned that I should use FeedBurner to serve up my blog's feed. So it's done but I still need to add some FeedFlare. Eventually I'll have my blog updated with all the snazzy features available. But until then, please update your feeds to the feed below:

Wednesday, July 11, 2007

How to Import a Type Library from the Command Line

I am kind of biased but I think one of the most useful utilities in the Delphi or C++Builder bin directory is tlibimp.exe. In case you don't know what tlibimp.exe does, it allows you to use COM objects as if they are native interfaces, and .NET objects can be treated as COM objects, so there is a lot of potential here. This is the command line version of the Import Component Wizard, but who wants to use the IDE when we've got command line!

One of the most common problems users of Delphi run into only a few options are available from the IDE. Here is a list of all the options provided by tlibimp:

Borland TLIBIMP Version 11.0
Copyright (c) 1997-2005 Borland Software Corporation
Syntax: TLIBIMP [options]

Files to Generate (Required):
-C- C++ Import file
-P- PASCAL Import file
-Ic- CORBA IDL file
-Ip- PASCAL CORBA stubs & skeletons

Customize code generated:
-Ha+ Create IDE component for Controls
-Hs+ Create IDE component for Servers
-Hr+ Generate component registration
C++ options:
-Cd- Generate dispinterfaces
-Cm- Map disp interfaces to dual
-Cn Set namespace name
-Cs+ declspec(__selectany) for GUIDs
-Ct+ Force the use of a _TLB file
-Cu+ Expose namespace with 'using'
-Cv+ BCB4-style server events
-Cw- Use disp. in Control wrappers

Ignore Flags: -Ya- All special flags,
-Yh- [Hidden]

Debug Build Options:
-G+ Show Debug output
-Gr Read & write out type library
-It IDL file parser test

Output File Options:
-D Output directory path
-Fe TLB suffix (-Fe- none)
-Ft TLB filename (no suffix)
-Ce OCX suffix (-Ce- none)
-Co OCX filename (no suffix)
-Hpa Set palette name
-Hps Set palette name

PASCAL options:
-Ps+ Map dual HRESULT to safecall
-Pt- Map all HRESULT to safecall

MISC options:
-O+ Generate CoClassCreator wrappers
-R+ Process dependent type libraries
-XM- Use MS-style getter/setter
-W+ Emit warnings in files
-Wc+ Emit comments in files
-Yc+ [CanCreate],
-Yp- [Predefined], -Yr- [Restricted]

-Pu Generate Pascal UI file
-Xd+ Generate DispInterfaces
-Yi+ Ignore Standard Type Libraries

That's a lot of options. Some options are obsolete such as the CORBA options but we leave them in case they are being used.

Internally Delphi uses a lot of code generated by tlibimp to communicate to the .NET services such as MSBuild, the .NET designers, and a lot of internal services. The command line we use is:

tlibimp.exe -P+ -Ha- -Hr- -Hs- -R- -D .tlb


  • -P+ to generate Pascal
  • -Ha- to not generate IDE components for Controls
  • -Hr- to not generate component registration
  • -Hs- to not generate IDE components for Servers
  • -R- to not process dependent type libraries
  • -D to generate the .pas files to the specified directory
  • this is the type library to import

Note that the -Yc option has changed from off to on in Delphi and C++Builder 2007. For a little history CanCreate flag is typically used in Visual Basic libraries and defaults to off. This means that VB objects aren't meant to be created. But after years of bug reports I decided to change the default of this option to on so now we ignore the flag.

Tuesday, July 10, 2007

Microsoft Help2 Plugin Feature

There have been a couple of requests for a way to plug third-party help into CodeGear's help. There is actually a very easy way of doing this with the new plug-in feature that Microsoft introduced to the Help2 system in .NET 2.0. All you need to do is register your help to it's own namespace and then there is one line that says plug-in your namespace into ours (borland.bds5). This will make your help show up under our namespace and our IDE will treat it just like it was ours.

If you use h2reg like we do, all you need to add is two lines. For example, if your namespace was called Foo, then add the following line in the "[Reg_Plugin]" section of the ini file:

borland.bds5|_DEFAULT|Foo|_DEFAULT|COL_Master.HxA

The same line goes into the "[UnReg_Plugin]" section.

There is an annoying feature of dexplore.exe (Microsoft's Help2 viewer) that rears its ugly head when you go to register help that you should be aware of. Dexplore doesn't allow you to change any namespace registration while it is running. This wouldn't be a bad thing, except sometimes when you close dexplore, it decides it wants to run in the background without telling you. So check your task manager for it before you change any registration.

If you don't have a registration tool already, you can use our copy of h2reg that we install with our products, but if you do this you cannot redistribute h2reg with your own product. You can buy your own license for $100 dollars.

Guest Bloggers

I have opened up my blog to other CodeGear R&D Engineers. The first guest blogger is Chris White, an R&D Engineer working on the BDS development team at CodeGear. I work closely with Chris White on the Help system.

Delphi Tips And Tricks: Turn Off Code Folding

Every once in a while, like today, I'm working with some very large files (tlibimp generated Office files that are 85,000+ lines if you must know) and the editor is very slow. The first thing I do is narrow the problem down and submit a bug. But at the end of the day I need to get work done like all of you, so I turn off code folding, which brings us to today's Delphi tip. Press CTRL + Shift + K + O and the little icons in the gutter will go away and you'll get back some CPU time. Now this doesn't solve the entire problem, the parser is still being run in the background but the IDE is more usable.

Update: Currently the IDE defaults to a maximum of 10,000 regions. There is a regkey that controls the maximum number of region:


$(HKCU_BDS_ROOT)\Editor\Options

Make a REG_DWORD value called CppMaxStructureRegions and set it to whatever value you want.

Monday, July 9, 2007

More Good Practices When using Version Control




Last week I wrote about only committing one bug fix to the version control system per checkin and to not batch up the changes for later with one large checkin. You can read about it here. Today I want to talk about working on a branch.

When working on a branch, many people batch up their changes and do one huge merge at some later point in time. I don't like to do this. I like to follow a process that lets my brain work on more challenging things, so my process is simple. I fix one bug, check it into the branch I'm working on (as I stated before), then merge that change into the other branch, test it, then commit it to that branch. By doing it this way I complete each task and don't ever think about it again, I reduce human error when performing the merge, and other code that relies on my changes will be easy to merge since all dependencies have already been merged.