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.
Tuesday, July 31, 2007
Amazon Groceries Coupon Code
Posted by
Chris Bensen
at
10:00 PM
0
comments
.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.
Posted by
Chris Bensen
at
9:00 AM
2
comments
.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'.
Posted by
Chris Bensen
at
8:00 AM
2
comments
Labels: Delphi
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."
Posted by
Chris Bensen
at
5:00 PM
0
comments
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.
Posted by
Chris Bensen
at
8:00 AM
1 comments
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?
Posted by
Chris Bensen
at
12:06 PM
5
comments
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.
Posted by
Chris Bensen
at
10:30 AM
0
comments
Labels: C++Builder, Delphi
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?
Posted by
Chris Bensen
at
10:00 PM
9
comments
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.
Posted by
Chris Bensen
at
4:00 PM
0
comments
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.
Posted by
Chris Bensen
at
8:30 AM
6
comments
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;
Posted by
Chris Bensen
at
8:30 AM
5
comments
Labels: Delphi
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.
Posted by
Chris Bensen
at
8:00 PM
6
comments
Labels: Delphi