Archive for the ‘Programming’ Category

Custom Variant Wrapper for TDataset - Part 6

Wednesday, January 6th, 2010

In Part 5 we discussed casting our custom variant to and from other data types.  In this part we will discuss implementing dynamic functions and procedures.   Dynamic functions are implemented by overriding TPublishableVariantType.DoFunction and dynamic procedures are implemented by overriding TPublishableVariantType.DoProcedure.


Custom Variant Wrapper for TDataset - Part 5

Monday, January 4th, 2010

In Part 4 I showed you how to get and set dynamic properties of our custom variant.  In this part I will show how custom variants can be cast to and from other data types.


Custom Variant Wrapper for TDataset - Part 4

Friday, January 1st, 2010

In Part 3 we discussed clearing and copying our custom variant.  Next I am going to show you how to implement dynamic properties for our TDataset wrapper.  If you remember from the introduction to this series of articles, I wanted to be able to get the value of a dataset’s fields’ values using the name of the field as the property name.  Like this: variant.field_name.


Custom Variant Wrapper for TDataset - Part 3

Thursday, December 31st, 2009

In Part 2 I explained how to initialize a custom variant’s data structure and how to create a TCustomVariantType descendant to implement the methods required to make the variant useful.  Now I will start to explain which methods need to be implemented, what they do and how they do it.  In this part we will discuss clearing your variant and copying your variant to another variant.


Custom Variant Wrapper for TDataset - Part 2

Thursday, December 31st, 2009

In Part 1 of this series we discussed the data structure needed to hold your custom variant data.  In this article we will discuss the code needed to create an instance of your custom variant.


Custom Variant Wrapper for TDataset - Part 1

Wednesday, December 30th, 2009

This is the first in a series of articles that will attempt to document the process of creating a Delphi custom variant.  In this article I will cover the data structure required to define a custom variant.  Later articles will address the classes and methods that need to be implemented in order for you custom variant to be able to do any useful work.


Custom Variants in Delphi

Wednesday, December 30th, 2009

I was watching one of the CodeRage presentations the other day.  It was the one about domain specific languages by Marco Cantu.  In it he shows how custom variants can be used to implement a domain specific language in Delphi.  While I found the presentation interesting, I didn’t see much benefit to inventing one and using it in the type of programming that I do.  However, I can see a lot of applications for custom variants.

Unfortunately, Marco didn’t go into a lot of detail about exactly how custom variants are implemented.  So I started reading the Delphi Developers Guide.  It covers the necessary material but I found the explanations to be insufficient and I didn’t have the eureka moment that made everything clear enough to start implementing a custom variant.  So I went to the old standby, Google.  I didn’t find much there either.  One fairly length article that I did find basically parroted the Delphi documentation and examples and wasn’t much help either.

Anyway, I took the information that I could find and the VCL source code and dove in.   As a first project, I decided to implement a custom variant wrapper for the TDataset component that would allow me to access the dataset’s field’s values without have to use the excessively wordy and cumbersome dataset.FieldByName(”field_name“).Value syntax.  I wanted to be able to get a field’s value by using the field’s name as a property, like this, datasetVariant.field_name.  Where field_name is the name of the field in the database.

In a series of articles to follow, I am going to try to document my experiences and discoveries in the hope that; (1) it will serve as a memory aid to me if I ever have to do this again and (2) it will help someone else along the road to their own custom variant.  Wish me luck.

Part 1 - Variant Data Structures
Part 2 - Initializing the Variant
Part 3 - Copying and Clearing the Variant
Part 4 - Implementing Dynamic Properties
Part 5 - Casting the Variant to a Different Data Type
Part 6 - Implementing Dynamic Functions and Procedures

DestroyHandle and Delphi 2007

Wednesday, November 18th, 2009

Back in the good old days, when Windows 98 was king of the desktop, it didn’t matter how much memory your system had there was a hard limit on the number of resources (like window handles) that could be active at any one time.  This caused me problems with some of my larger applications.  They kept maxing out the active resources.

To get around this problem, there as a little trick that you could use with Delphi 5 to free the resources used by a window that was not visible.  To free the resources you used TWinControl.DestroyHandle to free the handles for the window that was about to be hidden and all of its child windows.  So this code went into all of my larger programs 10 or 11 years ago and everything was golden.  I even forgot that I had put the resource saving code into the programs.

So, skip forward 10 or 11 years and I am merrily porting my programs from Delphi 5 to Delphi 2007.  All of a sudden I start to encounter strange problems.  For example, I had a ComboBox on a page in a page control.  If I left the page containing the ComboBox and then returned to that page, the ComboBox’s drop down list was cleared.  I spent many hours debugging this to absolutely no avail. Until I finally stumbled across my little resource saving fiddle.  I removed that code from the program and now everything works as it should.  Fortunately, since Windows 98 is long dead (or should be) this code is no longer necessary so removing it isn’t going to cause me any heartache (I hope).

Codegear (now Embarcadero) obviously changed something in the implementation of the DestroyHandle method.  No wonder I am sick of programming. :(

How to Create an Active Form in Delphi 2007

Wednesday, November 11th, 2009

I spent a couple of hours frustrating myself today trying to remember how to create an active form using Delphi 2007.  I knew that I had done it before, but do you think I could remember how?  No way! So to avoid future frustrations I decided to write it down.

Before you can create an active form, you first need to create a new project by selection File | New | Other | Activex | Activex Library.  Once that step is done, you can create the active form by selecting File | New | Other | Activex | Active Form.  Leaving out the first step will cause you to slowly go crazy while you search all of the Delphi project item categories for the active form wizard without finding it.

Indy “Connection Closed Gracefully” Errors

Monday, October 5th, 2009

I was being plagued by “Connection closed gracefully” errors in an application that uses the Indy TIdHttp component to communicate with a remote server.  Periodically, I would get one of these exceptions.  Basically, this should be no big deal.  It just means that the remote server closed the connection before the transaction was complete.  i.e. I had sent the request but before I got the response, the remote server closed the connection.  So, just close the connection and try again after a suitable interval you say.  Well that is what I thought, but calling TIdHttp.Disconnect, waiting a bit and sending the request again just resulted in the same error over and over and over and over …

It turns out, that if there is any data left in Indy’s input buffer simply calling disconnect doesn’t actually get rid of the connection.  The connection lingers on until the input buffer is emptied.  In order to get rid of the connection completely you need to flush the input buffer by calling TIdHttp.IOHandler.InputBuffer.Clear after calling TIdHttp.Disconnect.  Completely inobvious and  not documented at all as far as I can tell.