Friday, 13 February 2026

Mouse Wheel and TScrollBox

We had an issue where there was a TScrollbox on a form and the mouse wheel would not do the vertical scroll. The simplest solution I found for this was to do the following in the forms 'OnMouseWheel' event.

if MyScrollBox.BoundsRect.Contains(MyScrollBox.Parent.ScreenToClient(MousePos)) then
begin
  MyScrollBox.VertScrollBar.Position := MyScrollBox.VertScrollBar.Position -                   WheelDelta;
  Handled := True;
end; 



Thursday, 13 November 2025

SQL Server - Query to return list of tables and the space they use on disk

Below is a useful MS SQL Server query I use to get the list of database tables and information on how much disk space they use. The results are ordered by the size on disk descending.

SELECT 
    t.NAME AS TableName,
    s.Name AS SchemaName,
    p.rows AS RowCounts,
    CAST(ROUND(((SUM(a.total_pages) * 8.0) / 1024), 2) AS DECIMAL(18,2)) AS TotalSpaceMB,
    CAST(ROUND(((SUM(a.used_pages) * 8.0) / 1024), 2) AS DECIMAL(18,2)) AS UsedSpaceMB,
    CAST(ROUND(((SUM(a.data_pages) * 8.0) / 1024), 2) AS DECIMAL(18,2)) AS DataSpaceMB
FROM 
    sys.tables t
INNER JOIN      
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
    sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN 
    sys.schemas s ON t.schema_id = s.schema_id
WHERE 
    t.is_ms_shipped = 0
GROUP BY 
    t.Name, s.Name, p.Rows
ORDER BY 
    TotalSpaceMB DESC;

Wednesday, 12 March 2025

When to pass a dependency to a class?

I was speaking to another developer the other day and he insisted that if a class needs an instance of another class it should always be passed in an 'Init' method and not in the constructor. I disagreed with him on this and thought I should clarify when I think a dependency should be passed.

There are 2 options when passing a dependency to a class:

  1. Passing it as a parameter in the Create constructor.
  2. Passing it in a separate 'Init' method after creation. It does not have to be called 'Init'. 
When to use the 'Create' method and its advantages:
  • When the class absolutely needs the other class to operate properly.
  • Ensures the object is in a valid state immediately after creation.
  • Prevents accidental use of an uninitialized object.
  • Simplicity, it can lead to cleaner and more concise code.
When to use an 'Init' method and its advantages:
  • When the dependency could be seen as optional. The class can operate or partly operate without the other class. This can be done with the Create method, but passing it as nil.
  • Need delayed initialization.   
In most cases, the Create method (constructor) approach is preferred for better safety and reliability.


Monday, 13 January 2025

Should you write a website using Delphi?

Over the years I've written various websites some of which used Delphi to publish the pages. This method used HTML templates, JS and CSS files and the data from the database to stitched them together to produce the pages. The question is if I was to write a website from scratch would I still use this method or would I look at using a Javascript framework like ReactJS, Angular or Svelte? 

I'm sure the answer to this question would depend on the spec for the website, but here are some advantages and disadvantages of writing a website using Delphi.

Advantages:
  • If you have existing applications written in Delphi you can use existing code like common functions, classes and units that relate to your business, so there is no need to rewrite code in another language.
  • Time to develop the site could be shorter than using a framework like ReactJS, especially if you need to learn a new language.
  • Possible to implement JS libraries like Bootstrap.
  • Have front and backend code in the same project. Have a single service that is responsible for retrieving data from the database then using that data to produce the front end page.
Disadvantages:
  • You still have to write code in HTML, JS and CSS.
  • Compared to popular web development languages, Delphi lacks a vibrant ecosystem of web-specific tools, libraries, and frameworks.
  • Testing changes while developing is slow compared to other languages like ReactJS, which automatically refreshes the page you are viewing when you save a change.
  • Modern web development frameworks often come with built-in security measures (e.g., CSRF protection, SQL injection prevention). In Delphi, many of these must be implemented manually, increasing the risk of vulnerabilities.
  • Delphi's future as a web development platform is uncertain compared to the robust growth of modern web development languages.
  • Difficult to find Delphi developers, especially ones with web site development experience.
  • A lack of beginner-friendly tutorials, guides, and resources for web development in Delphi can make onboarding new developers more difficult.
In Conclusion:

While Delphi has its strengths, its disadvantages for web development primarily revolve around the lack of modern web development focus, limited developer availability, higher costs, and the complexity of implementing web-specific features. For teams already invested in Delphi or needing tight integration with Delphi-based systems, it can be a viable option, but for new projects or those targeting modern web standards, other technologies may be more practical.

Below is a table from ChatGPT with some security vulnerabilities & considerations:


Sunday, 8 December 2024

Should naming procedures Setup and Teardown be reserved for unit testing?

I recently came across some code a developer had done where they had named 2 public procedures 'Setup' and 'Teardown', when I fist saw these I instinctively thought of unit tests and thought that class might relate to unit testing. After looking into the code it was apparent that these procedures where meant to be called after an object of the class was created and before the object was freed, but had nothing to do with unit testing.

Even though there are no restrictions on using these words for procedures I do think it is best practice not to use them in production code and name them something different like 'InitializeResources' and 'CleanupResources'. I think keeping procedures 'Setup' and 'Teardown' specifically for testing maintains a clear distinction between testing and application logic, which can be beneficial for maintainability.

Wednesday, 24 July 2024

Why change how a Web Broker service works?

I have a web service (web broker) that works fine and each request is sent to a corresponding object that relates to the request and the response is returned, for example the /customerinfo request (GET) calls an object that is private to the TWebModule that returns customer information.

procedure TMyWebModule.CustomerInfoAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
    Response.Content := FCustomers.CustomerInfo(Request);
end; 

BTW, this is not the actual code, but is just an example. This works fine and has been working fine for some time. However, another developer has come up with what they consider a better way fo doing this. First, they add a property of TWebRequest to all objects that use TWebRequest, so in this example the FCustomer object has a WebRequest property. Then in the BeforeDispatch set the WebRequest property of all the web module objects (not just the one that relates to the request) to the web request. The advantage of this is so that you do not need to pass in the WebRequest in the action e.g.

procedure TMyWebModule.CustomerInfoAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
    Response.Content := FCustomers.CustomerInfo;
end; 

They have also proposed that we could also set the TWebResponse on all the objects to that then all you need to do is this.

procedure TMyWebModule.CustomerInfoAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
    FCustomers.CustomerInfo;
end; 

The other change that is being proposed is to add validation to the TWebRequest, by having a new class that descends from TWebRequest, lets call it TMyWebRequest and this will have validation code, so that you can call something like MyWebRequest.Validate it will do some validation. Currently there is a validation class that takes the TWebRequest, but this would be removed and the TMyWebRequest would validate itself.

In the AfterDispatch method it will iterate through all the objects and set the MyWebRequest property to nil.

There are a few things I am not keen about with making these changes. 

  • I don't like the idea of descending from TWebRequest just to add some validation methods, and much prefer having validation classes that are responsible for doing the validation.
  • Currently passing TWebRequest makes it clear and explicit that the parameter is expected, making it easier to trace.
  • The current way keeps the responsibility of handling the request and response with the action.
  • It is setting the MyWebRequest property of all the objects, even though it is only required for the object that will be called, for example it sets the MyWebRequest property on the Order, Product, System and Customer objects even though it is only the Customer object that will be called with that requrest.
  • It means that a developer can use both methods, this could cause confusion.
  • It will take some time to change all the services to work this new way. 

The benefits I can see from doing this are:

  • Reduce the number of parameters passed.
I cannot see any real benefits from making these changes, or am I missing something?


Friday, 24 November 2023

How to write try finally blocks

 I recently came across code another developer had done and they write try..finally blocks like the following:

procedure TSomeClass.DoSomething: string;
var
    myClass: TMyClass;
begin
    myClass := nil;
    try
        myClass := TMyClass.Create;
        // Do stuff
    finally
        myClass.Free;
    end;
end;

Were I would write it as follows:

procedure TSomeClass.DoSomething: string;
var
    myClass: TMyClass;
begin
    myClass := TMyClass.Create;
    try
        // Do stuff
    finally
        myClass.Free;
    end;
end;

I always create the object on the line before the try and would not set the object to nil just before creating it. I believe setting the object to nil before creating it and putting the create after the try to not be the correct way and do not know the reasoning why the developer does it like this.