Andriy Gerasika's blog

System Font in Delphi Applications

Most Delphi applications are using MS Sans Serif 8 as their default font, meanwhile Windows XP system font is Tahoma 8.25 and Windows Vista system font is Segoe UI.

Below code makes Delphi applications use Windows system font:

procedure TForm1.FormCreate(Sender: TObject);
var
  NonClientMetrics: TNonClientMetrics;
begin
  NonClientMetrics.cbSize := SizeOf(NonClientMetrics);
  SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @NonClientMetrics, 0);
  Font.Handle := CreateFontIndirect(NonClientMetrics.lfMessageFont);
  if Scaled then
  begin
    Font.Height := NonClientMetrics.lfMessageFont.lfHeight;
  end;
end;

Large Fonts in Delphi Applications

99% of Delphi applications I have seen, do not support Large Fonts, or support it very badly. There is a Scaled property in TForm, people think it is about to scale the form in case of non-default DPI setting, but it is just not working properly.

Below code scales TForm the correct way:

procedure TForm1.FormCreate(Sender: TObject);
begin   
  Assert(not Scaled, 'TForm.Scaled property sucks, you should set it to False!');   
  if Screen.PixelsPerInch <> PixelsPerInch then
  begin     
    ScaleBy(Screen.PixelsPerInch, PixelsPerInch);   
  end; 
end;

Delphi stores design-time DPI of a form in PixelsPerInch property. This code handles scaling correctly even if some forms are designed in 96 DPI, and some forms in 120 DPI.

Object-oriented Windows API

Windows API functions are declared in structured programming style.

For example consider classical example of using critical sections:

procedure Test;
var 
  CS: TCriticalSection;
begin
  InitializeCriticalSection(CS);
  try
    EnterCriticalSection(CS);
    try
      //somecode
    finally
      LeaveCriticalSection(CS);
    end;
  finally
    DeleteCriticalSection(CS);
  end;
end;

Now consider the example rewritten in object-oriented Windows API:

procedure Test;
var
  NewCS: TNewCriticalSection;
begin
  NewCS.Initialize;
  try
    NewCS.Enter;
    try
      //somecode
    finally
      NewCS.Leave;
    end;
  finally
    NewCS.Delete;
  end;
end;

Bespoke the code is easier to read, the benefit is CodeInsight works nicely — type "NewCS." and press Control+Space…

Below unit implements new object-oriented Windows API:

unit NewWindows;

interface

uses Windows;

{$HINTS OFF}
type
  TNewCriticalSection = object
  private
    FOldCriticalSection: TRTLCriticalSection;
  public
    procedure Initialize; stdcall;
    procedure Delete; stdcall;
    procedure Enter; stdcall;
    procedure Leave; stdcall;
  end;
{$HINTS ON}
  
implementation

procedure TNewCriticalSection.Initialize; 
    external kernel32 name 'InitializeCriticalSection';
procedure TNewCriticalSection.Delete; 
    external kernel32 name 'DeleteCriticalSection';
procedure TNewCriticalSection.Enter; 
    external kernel32 name 'EnterCriticalSection';
procedure TNewCriticalSection.Leave; 
    external kernel32 name 'LeaveCriticalSection';

end. 

The trick is that Delphi object types are passed by value, hence when calling TNewCriticalSection.Initialize method, FOldCriticalSection field is occupying on the stack the same place argument of InitializeCriticalSection would do. Thus we can declare implementation of TNewCriticalSection.Initialize as external from kernel32.dll.

Risk Management

There are always risks associated with a project. Purpose of risk management is to ensure levels of risk and uncertainty are properly managed so that the project is successfully completed. It is important to understand Risk Management and employ contemporary risk management practices. This article contains common approach to Risk Management.

Risk Management Process

Risk identification begins in the early planning phase of the project. A Risk Management Excel Worksheet is started during the planning phase. Then, as scheduling, budgeting, and resource planning occur, the worksheet is updated to reflect further risks identified in the planning.

At this point, (or when a risk probability increases) the project manager and project team develop mitigation strategies that assess the impact of the problem. Mitigation strategies divide in two types:

  1. Preventative - planned actions to reduce the likelihood a risk will occur, and the seriousness if it does occur. In other words, what should we do now?
  2. Contingency - planned actions to reduce the seriousness of the risk if it does occur. In other words, what should we do if?

At project start-up, the Risk Management Worksheet is reviewed again, and any new risks are added to it. As the project progresses, members of project team identify new risk areas that are added to the Risk Management Worksheet.

Risk identification is a recurring event; it is not performed once and then set aside. Risk identification, management, and resolution continue after project initiation throughout the life of the project. New risks are developed as the project matures and external and internal situations change. Trigger dates are be included in the schedule for tracking risks.

Risk Management Worksheet

The Risk Management Worksheet records details of all the risks identified at the beginning and during the life of the project, their grading in terms of likelihood of occurring and seriousness of impact on the project, initial plans for mitigating each high level risk and subsequent results.

The Risk Management Worksheet usually includes:

  1. a unique identifier for each risk;
  2. a description of each risk and how it will affect the project;
  3. an assessment of the probability it will occur and the possible seriousness/impact if it does occur (low, medium, high);
  4. a grading of each risk according to a risk assessment table
  5. who is responsible for managing the risk;
  6. an outline of proposed mitigation actions (preventative and contingency); and
  7. costs for each mitigation strategy.

Risk Management Worksheet is kept throughout the project, and changes regularly as existing risks are re-graded in the light of the effectiveness of the mitigation strategy and new risks are identified.

Risk Management Worksheet is amended by conducting a number of meetings or brainstorming sessions involving (as a minimum) the Project Manager, Project Team members, Project Executive, Customer (via Instant Messaging or Phone).

The Risk Management Worksheet is visited weekly with re-evaluation of the risks occurring on a monthly basis. On an agreed regular basis a Risk Status Report is conducted to the Customer, as a part of Project Status Report.

Risk Management Responsibility

Project Manager is responsible for monitoring and managing all aspects of the risk management process, including:

  1. development of the Risk Management Worksheet;
  2. development of risk mitigation strategies;
  3. continual monitoring of the project to identify any new or changed risks;
  4. continual monitoring of the effectiveness of the Risk Management Worksheet and
  5. regular reports on status of risks to the Customer.

Note: In very large projects, the Project Manager may choose to assign risk management activities to a separate Risk Manager, but the Project Manager still retains responsibility.

Other Project Team members assist with the identification, analysis and evaluation of risks and assist in the development of the Risk Management Worksheet. They are also responsible for risk mitigation strategies.

Project Executive provides input into the Risk Management Worksheet, especially assessment of potential risks and risk mitigation strategies. They are also responsible for some risk mitigation strategies.

Customer oversees the Risk Management Worksheet in its periodic review. They are responsible for ensuring an effective risk management process is in place throughout the life of the project.

The following table summaries the roles and responsibilities of personnel and customer in the Risk Management process.

Personnel\Customer Role and Responsibility
Customer Identify Risks, Monitor Risk Status
Project Executive Identify Risks, Develop Mitigating Strategies, Monitor Risks Status
Project Manager Identify Risks, Develop Mitigating Strategies, Monitor Risk Status, Report Risk Status
Project Team Identify Risks, Develop Mitigating Strategie

Attached you can find sample Rish Management Worksheet and Risk Status Report templates.

Change Control Management

Change Control management is needed to prevent chaos when changes happen rapidly to the project. 

Key points of Change Control Management

  1. Changes are reviewed by Project Manager and Senior Developers/Testers. Project Manager is responsible for estimating impact of changes to Project Plan.
  2. If change has technical merits, side-effects, or it is estimated to break project plan, objectives of the change should be either weakened, or it should be rejected (if it does not concern critical requirements), or it should be billed at a separate price.
  3. Changes are sent to entire project team by email, and discussed at project team meeting.
  4. Changes are documented and stored in Version Control System for the sake of Configuration Management.

Configuration Management

Software configuration management is an important element of software quality assurance.

The following configuration items should be maintained in the Version Control System:

  • Project Specification
  • Project Plan
  • Project Requirements Specification
  • Project Prototype
  • User Manual
  • Design Specification
  • Preliminary Design
  • Detail Design
  • Source Code
  • Test Plan
  • Test Cases and recorded results
  • Installation Manual
  • Executable Programs
  • Bug reports
  • Feature requests
  • Change orders
  • Standards and procedures

This gives possibility to transparently handle version problems when several concurrent processes are in-place:

  1. Version 1.0 development is finished, Version 1.0 Support Centre has been created, it is fixing bugs to Version 1.0, releasing new versions of Version 1.0
  2. Version 2.0 development is in place
  3. Version 3.0 development is only planned
  4. Changes happen

The streamlined approach to configuration management will allow handling above situations without interfering either in project plan, source code, deliverables, documentation, user manuals, bug reports, etc.

FastCode Library for Delphi

If you believe you've optimized your Delphi application to the max, and there is no room for performance improvement, then you should check out following site: http://sourceforge.net/projects/fastcode

Project Fastcode is competition of assembler developers on rewriting certain Delphi RTL functions to processor-specific code, utilizing extra instruction sets like SSE, SSE2, etc. This way Fastcode winners achieve 2x-4x performance boost compared to classic i386 implementations.

Each function in Fastcode project has 5 variants, each variant is optimized for certain processor architecture:

  • {function_name}_Blended - optimized for <= Pentium processors (employs i386, MMX instruction sets)
  • {function_name}_Pentium3 - optimized for Pentium 3 processors (employs i386, MMX, SSE)
  • {function_name}_Pentium4Northwood - optimized for Pentium 4 processors, Northwood kernel (employs i386, MMX, SSE, SSE2)
  • {function_name}_Pentium4Presscot - optimized for Pentium 4 processors, Presscot kernel (employs i386, MMX, SSE, SSE2, SSE3)
  • {function_name}_AthlonXP - optimized for Athlon XP (employs 3D-Now)
  • {function_name}_Opteron - optimized for Opteron (employs ???)

I have put together a package allowing you start on using Fastcode just in 5 mins. It contains units that auto-determine your CPU type and auto-patch VCL to use Fastcode. The following Fastcode functions are included:

  • Move - 200% performance boost
  • FillChar - 200-400% performance boost
  • Pos - 200-300% performance boost
  • CompareText - 200% performance boost

I recommend using this package in non-GUI application servers, facilitating strong memory usage, etc.

Despite it will not make your application incredibly fast, overall speed up will be about 5%.

Syndicate content