Delphi

59K

Solutions

12

Articles & Videos

16K

Contributors

Delphi is the most powerful Object Pascal IDE and component library for cross-platform Native App Development with flexible Cloud services and broad IoT connectivity. It provides powerful VCL controls for Windows 10 and enables FMX development for Windows, Mac and Mobile. Delphi is your choice for ultrafast Enterprise Strong Development™. Look for increased memory for large projects, extended multi-monitor support, improved Object Inspector and much more. Delphi is 5x faster for development and deployment across multiple desktop, mobile, cloud and database platforms including 32-bit and 64-bit Windows 10.

Share tech news, updates, or what's on your mind.

Sign up to Post

In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy required) or matrix math.  Since I rarely have need for either, operator overloading has remained one of those areas that I thought would be an interesting area to try to get into.

I recently had another coding requirement.  I mention it here because that need collided with the idea of operator overloading to make me consider operator overloading for an entirely new reason (to me).  I am writing a language parser.  This involves reading in characters one at a time and breaking them into tokens.  A big part of my coding along these lines, in the past, has been to make use of a Set Of Char.  This allows me to write very naturally flowing, easy to ready code such as:

function SkipWhiteSpace(var C : PChar) : boolean;
const
  WhiteSpace = [#9, #10, #13, ' '];

begin
  While (C^ <> #0) and (C^ in WhiteSpace) do
    inc(C);
  Result := C^ <> #0;  //fail if at the end
end;

Open in new window


This is simply an example of how things might have looked.  There are several things wrong with this code since Delphi 2009 introduced Unicode strings.

If you attempt to use a set of character to do the same kind of test on characters in the newer versions of Delphi you get a warning:

W1050 WideChar reduced to byte char in set expressions.  Consider using 'CharInSet' function in 'SysUtils' unit.

To avoid this, you could change:

(C^ in WhiteSpace)

Open in new window

to
(CharInSet(C, WhiteSpace))

Open in new window

1
Independent Software Vendors: We Want Your Opinion
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Introduction

Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid.

By the 4th update to Delphi XE2 and FireMonkey, I was ready to give up but then I stumbled on a video created by Marco Cantù which introduced me a bit more to FireMonkey and the fact that all visual objects are derived from TLayout - and more importantly - are Styleable.  He showed how one can change the style of any object to make changes to the base object to make it appear different - like adding a picture to a TListBoxItem.

I am now going to impart some of this knowledge to you.

TListView's replacement

As I've already mentioned, TListView does not exist as a visual component in FireMonkey - we now have TListBox.  If we go ahead and create a new FireMonkey HD Application, add a TListBox onto the form, and then double-click it, we will get the Items Designer open.  We can now add items, and you'll see that the Items property is a collection of TListBoxItem

Items Designer
Listbox On Form
Essentially, what we are going to do is change the Style of the ListBoxItem so that it includes a lot more than just one text field, and then when we add items to the listbox at run time, we're going to tell it to use our new style.

Styling the Style

With your horrible looking …
3
 

Expert Comment

by:cutemonster
Comment Utility
Great tutorial,
can you show me how to attach a click event on each button or image?
thank you very much!!!
0
 
LVL 1

Expert Comment

by:Gary4
Comment Utility
Hi,

Nice tutorial.

Does this also apply to XE5?

I'm also a bit confused about how to do this in mobile apps.  Especially since I don't see the edit custom style.
0

Introduction

I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need.
This article will address some of the concepts when dealing with a multithreaded delphi database application.
Shared resource protection
Query connection from thread
Displaying thread results

Sketching the problem
Our only remaining oracle 9 production database on a 7 years old server repeatedly lost disk access.  The oracle db has been due for replacement for a few years, but vendor issues have prevented this. A other server was setup and I moved the db.  Off course the hardware wasn't exactly the same and soon people complained about performance.  
This was odd, taken into account the more  recent hardware.

I won't go into detail about the oracle performance tuning.  After some searching we found some differences but most eye-catching was disk sorting.  A unsorted query took 500ms, but sorted it took 8 seconds.  Playing around with sort_area_size fixed this, but after some time other connection problems occurred.

I decided to play around with some database parameters to find out what the best settings would be.  I needed something to see impact on query execution time when changing parameters.  I'm not a guru at oracle performance tuning, so i setup a test system to play around with.

Specs for the Delphi test application
I wanted a …
2
 
LVL 9

Expert Comment

by:ITugay
Comment Utility
Big work. Readable and usefull:)
Best regards.
0
Hello everybody

This Article will show you how to validate number with TEdit control,

What's the TEdit control?

TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text.

Usually, programmer use OnKeyPress event to validate number input (Integer for example) like the following example

 
procedure TForm1.Edit12KeyPress(Sender: TObject; var Key: Char);
begin
  if not (Key in [#8, '0'..'9']) then Key := #0;
end;

Open in new window


What problems aren't covered by OnKeyPress event?

OnKeyPress event analyzes keyboard inputs, but doesn't work with Copy/Paste or Ctrl + V keyboard shortcut, for that i found that, OnChange event is better to catch any kinds of inputs.

My idea basing on Undo and ClearUndo procedures of TEdit Control.

What's Undo and ClearUndo procedure?

Undo and ClearUndo procedure used by components belong to TCustomEdit class (such TEdit, TMaskedit, TMemo, TRichEdit...), we call Undo procedure to cancel all changes made to the TCustomEdit text since the last call to the ClearUndo procedure, and we call ClearUndo to commit changes to TCustomEdit text, after the excecuting of ClearUndo procedure,  Undo procedure does nothing until the TCustomEdit text has.a new changes.

The method I will use with OnChange event work like the following statement:

if TEdit input change is valid value then ClearUndo else Undo

Validate Number by type

The following example show you how to validate an Integer.
 

Open in new window

2
 
LVL 45

Expert Comment

by:aikimark
Comment Utility
Where is the cursor after the undo?
0
 
LVL 9

Author Comment

by:Mahdi78
Comment Utility
And even after the ClearUndo, the cursor tun into ghost :D
It's enough to add the following code in the end of event

SetCursorPos(Mouse.CursorPos.X, Mouse.CursorPos.Y);
0
Have you ever had your Delphi form/application just hanging while waiting for data to load?
This is the article to read if you want to learn some things about adding threads for data loading in the background.

First, I'll setup a general application with the irritating behaviour.
Second, I'll add a first step to separate the data loading into 2 procedures: GatheringData and ShowingData
Last, I'll use a thread inside the GatheringData procedure

1. The irritating application

This application loads a stringgrid with some data.
It takes about 30 seconds to create the data in the stringlist
This long time is simulated using sleep
form code:
 
unit uEEMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, StdCtrls, ExtCtrls;

const WaitSleep = 500;

type
  TfrmEEThreads = class(TForm)
    pnlOptions: TPanel;
    btnShowData: TButton;
    sgData: TStringGrid;
    procedure btnShowDataClick(Sender: TObject);
  private
    procedure LoadGrid(grid: TStringGrid);
    procedure LoadData(List: TStrings);
    procedure ShowData(grid: TStringGrid; List: TStrings);
  end;

var
  frmEEThreads: TfrmEEThreads;

implementation

{$R *.dfm}

procedure TfrmEEThreads.btnShowDataClick(Sender: TObject);
begin
  // Call procedure and pass grid to load
  LoadGrid(sgData);
end;

procedure TfrmEEThreads.LoadGrid(grid: TStringGrid);
var List: TStrings;
begin
  // Create some data in a stringlist
  List

Open in new window

11
 

Expert Comment

by:starhu
Comment Utility
Thank you aikimark. I did it and I succeeded.

I new about Select all, and how to use copy/paste, but a download project would be even much faster (about 3-5 seconds).
0
 

Expert Comment

by:deyoz
Comment Utility
Thank you so much, Geert! The article is really helpful.
0
Creating an auto free TStringList

The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list.

In such cases, you have to create your object, try it, and finally block to make sure your resources are properly destroyed. You end up with code like the following
var
  List: TStringList;
begin
  List := TStringList.Create;
  try
    //Some code to process the List
  finally
    FreeAndNil(List);
  end;

Open in new window


Here we have four extra lines of code that we could eliminate.

Imagine if you forgot to free the list, ran the the function a couple of times and suddenly your application is consuming an unimaginable amount of memory: ... mmm not good.
It would be nice if you just created the list and never worried about adding code to destroy it.

So let's create a StringList that frees itself.

I define an interface and add the common methods I would need from the TStringList;
I commonly use Count, Strings and Text. You can add others as you wish.

type
  IAutoFreeStringList = interface
  ['{20C54556-714C-4478-AF2D-D8F37219E36E}']
    function GetListCount: Integer;
    function GetListStrings(Index: Integer): string;
    function GetListText: string;
    function List: TStringList;
    procedure PutListStrings(Index: Integer; const S: string);
    procedure SetListText(const Value: string);

    function Add(const S: string): 

Open in new window

1
 
LVL 37

Expert Comment

by:Geert Gruwez
Comment Utility
Nice article.

More suggestions: AddStrings and using a variable in DisplayList procedure

procedure TForm1.DisplayList(InList: TStrings; AList: TStringList);
begin
  InList.BeginUpdate;
  try
    InList.Add('');
    InList.AddStrings(AList);
  finally
    InList.EndUpdate;
  end;
end;

procedure TForm1.PlayWithList;
var
  ITempList: IAutoFreeStringList;  //remember to use interface
  I: Integer;
begin
  Randomize;

  ITempList := TAutoFreeStringList.Create;

  for I := 1 to 10 do
    ITempList.Add(IntToStr(Random(100)));

  //Pass the Objects List to this functions
  DisplayList(ListBox1.Items, ITempList.List);
  SortList(ITempList.List);
  DisplayList(ListBox1.Items, ITempList.List);

  //work direcly with the list
  ITempList.Clear;
  for I := 1 to 10 do
    ITempList.Add(IntToStr(Random(100)));

  DisplayInList(ListBox2.Items, ITempList.List);

  ITempList.Sort;
  DisplayInList(ListBox2.Items, ITempList.List);
end;



0
 
LVL 15

Expert Comment

by:ericpete
Comment Utility
ewangoya,

Congratulations! Your article has been published.

ericpete
Page Editor
0
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech.

SAPI Installation
First you need to install the SAPI type library, the type library is attached to this tutorial, into Delphi.

In the Delphi IDE install a new component via the menu:
Component > Install Component...   (See Step 1 Image)
Step 1 Image

Select the 'Into new package' Tab, then click on the 'Browse' button, Select the '.PAS' file included in the type library attachment.   (See Step 2 Image)
Step 2 Image
Create a new package file name such as 'Speech.dpk'. Enter a package description such as 'Windows Speech API'. (See Step 2 Image)

Click on 'OK', when prompted to build then install the package, click on the 'Yes' button. (See Step 3 Image)
Step 3 Image
You should get a prompt saying that new components have been installed. (See Step 4 Image)
Step 4 Image
Simple Text To Speech
Create a new application.

Find the 'SpVoice' component, and drag it onto your form. (See Step 5 Image)
Step 5 Image
Add an edit box and a button to the form and, on the button onclick event handler, enter the following code:

procedure TForm1.Button1Click(Sender: TObject);
begin
if not (Edit1.Text = '') then
SpVoice1.Speak(Edit1.Text, SVSFDefault);
end;

Open in new window


When the user enters something into the textbox the SAPI says the text outloud. (See Step 6 Image).
Step 6 Image

Change Voice Speed

Add a TrackBar component to your form (TrackBar is found in the win32 pallette). On the trackbar onchange event handler add the code below:


Open in new window

0
 
LVL 15

Expert Comment

by:ericpete
Comment Utility
flexiwebsw,

Congratulations! Your article has been published.

ericpete
Page Editor
0
 

Expert Comment

by:fdecker
Comment Utility
How do you set the input for speech recognition? spMMAudioIn1.DeviceID := my_integer gives an error. This worked in SAPI 5.1. I am using SAPI 5.4.
0
Objective:
- This article will help user in how to convert their numeric value become words.

How to use
1. You can copy this code in your Unit as function
2. than you can perform your function by type this code

The Code
 
function TISupport.NTW(ChkER: boolean; ER: string; D: double): string;
const
  Ones: array[0..9] of string = ('Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine');
  Teens: array[10..19] of string = ('Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen');
  Tens: array[2..9] of string = ('Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety');
  Suffix: array[0..5] of string = ('Hundred', 'Thousand', 'Million', 'Billion', 'Trillion', 'Quadrillion');
var RStr, sDec, sFrac: string;
    vFrac: double;
    I, vDec : integer;
    TruncTens, TruncHund, TruncThou, TruncMio, TruncBio, TruncTril, iD: Int64;
    ReadFrac: boolean; 
    function fTensENG(xD: integer): string;
    var BTStr: string;
    begin
       if (xD >= 0) and (xD <= 9) then BTStr := Ones[xD] else
       if (xD >= 10) and (xD <= 19) then BTStr := Teens[xD] else
       if (xD >= 20) and (xD <= 99) then
       begin
          if (StrToInt(RightStr(IntToStr(xD), 1)) = 0) then
             BTStr := Tens[StrToInt(LeftStr(IntToStr(xD), 1))]
          else
             BTStr := Tens[StrToInt(LeftStr(IntToStr(xD), 1))] + ' ' +
                      

Open in new window

3
This article explains how to create forms/units independent of other forms/units object names in a delphi project.

Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi project. In Delphi this is easy, just use the "Add file to project (Shift+F11)" to add the unit from the other project,
add name of the unit to your other unit uses implementation and the form is available in this project. But then ... you hit compile ... the compiler starts complaining with errors like
Form2 not found

Open in new window


Let's consider the following problem: The application needs a name and description for a new article from the user.

Most Delphi programmers would solve this problem with a form like this:
Create a new Form, give it a new name (frmNewArticle), put a TEdit (editArticleName),  a TMemo (memoArticleDescr) and a button (btnOk, modalresult = mrOk) on it, and then call that new form from the main form like this:  
procedure TfrmMain.btnGetNewArticleClick(Sender: TObject);
var 
  frm: TfrmNewArticle;
begin
  frm := TfrmNewArticle.Create(Self);
  try
    if frm.ShowModal = mrOk then 
    begin
      labelArticleName.Caption := frm.editArticleName.Text;
      memoArticleDescr.Text := frm.memoArticleDescr.Text;
    end;
  finally
    FreeAndNil(frm);
  end;
end;     

Open in new window

the unit code for the frmNewArticle form could look like this:
unit uNewArticle;
 
interface
    
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Buttons, StdCtrls, ExtCtrls;
  
type
  TfrmNewArticle = class(TForm)
    editArticleName: TEdit;
    labelArticleName: TLabel;
    memoArticleDescr: TMemo;
    labelArticleDescr: TLabel;
    btnOk: TBitBtn;
    btnCancel: TBitBtn;
  end;
 
var 
  frmNewArticle: TfrmNewArticle;
   
implementation 
 
{$R *.dfm } 
   
end.

Open in new window

7
 
LVL 3

Expert Comment

by:KarlisB
Comment Utility
Man, where where you 2 months ago.
wait, where was I that i didn't saw this article???

well, I did same in similar maner :)
0
 
LVL 7

Expert Comment

by:samenglish
Comment Utility
Thanks for sharing your expertise.
0
Introduction
The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small printer symbol. This port is known as LPT port or printer port. We can program this port for device control and/or data transfer, in projects of robotics, electronics and even LCD interfacing. In this article, I'll show the basics of parallel port and some programming principles using the LPTPort Component.

Parallel Port Concepts
The parallel port was initially designed to connect a printer to the computer, however we can program this port for many more applications beyond that.
The parallel port can be used for two main reasons: device control and communication. We can program the parallel port for both functions. The parallel ports are easier to program and faster compared to serial ports. However the main disadvantage is that it needs more transmission lines (9 in comparison to the 3 lines used in serial port). Because of this, parallel ports are not used in long distance communications. So let's see the basic differences between the transmission of parallel port and serial port (Figure 1).
In serial ports, we have two data pins: one for transmission and the other for reception. To send data in serial port, it has to be sent one bit after another with some extra bits like start bit, stop bit and parity bit …
8
 
LVL 14

Expert Comment

by:systan
Comment Utility
hi
can this be used to program a full scree video with lots of led light for displaying images or letters for street advertisement?
0
Enroll in June's Course of the Month
LVL 9
Enroll in June's Course of the Month

June’s Course of the Month is now available! Experts Exchange’s Premium Members, Team Accounts, and Qualified Experts have access to a complimentary course each month as part of their membership—an extra way to sharpen your skills and increase training.

The uses clause is one of those things that just tends to grow and grow.
Most of the time this is in the main form, as it's from this form that all others are called.
If you have a big application (including many forms),
the uses clause in the interface and implementation section gets very big and messy.

Wouldn't it be nice to move all those child form unit names away from the main form ?

Well there is a way !
Just create a unit and alias the form types and procedures/functions and use only this unit in the main form uses clause

Let's consider a form for a user name (uGetUserName),
a form for selecting email adresses from a grid (uSelectEmails),
and a form for showing a grid with data from a table (uGridTableData)
all used from the main form.

so the implementation uses would have 3 units in it:
uses 
  uGetUserName, uSelectEmails, uGridTableData;

Open in new window


the unit code would look something like this
unit uMainForm; 
 
interface 
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls;
  
type
  TfrmMain = class(TForm)
    labelUserName: TLabel;
    btnGetUserName: TBitBtn;
    editEmailTo: Edit;
    btnGetEmailTo: TBitBtn;
    btnShowGridData: TBitBtn;
    procedure btnGetUserNameClick(Sender: TObject);
    procedure btnGetEmailToClick(Sender: TObject);
    procedure btnShowGridDataClick(Sender: TObject); 
  end; 
 
var
  frmMain: TfrmMain; 
 
implementation 
 
uses 

Open in new window

6
 
LVL 8

Expert Comment

by:BdLm
Comment Utility

does delphi has a similar feature as namespace in C++ ?
0
 
LVL 4

Expert Comment

by:rotem156
Comment Utility
very nice tip, thank you.
0
A lot of questions regard threads in Delphi.  
One of the more specific questions is how to show progress of the thread.  
Updating a progressbar from inside a thread is a mistake.
A solution to this would be to send a synchronized message to the main thread.
This message would then contain the progress of the thread from 0 to 100.
 

1. Setting the progress bar


The progressbar will be displaying from 0 to 100
Property Max = 100
Property Min = 0
 

2. The base thread: TProgressThread


I defined a thread class for sending messages back via a synchronize procedure
type
  TProgressProc = procedure (aProgress: Integer) of object; // 0 to 100
 
  TProgressThread = class(TThread)
  private
    FProgressProc: TProgressProc;
    FProgressValue: integer;
    procedure SynchedProgress;
  protected
    procedure Progress(aProgress: integer); virtual;
  public
    constructor Create(aProgressProc: TProgressProc; CreateSuspended: Boolean = False); reintroduce; virtual;
  end;
 
{ TProgressThread }
 
constructor TProgressThread.Create(aProgressProc: TProgressProc; CreateSuspended: Boolean = False); 
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate := True;
  FProgressProc := aProgressProc;
end;
 
procedure TProgressThread.Progress(aProgress: Integer);
begin
  FProgressValue := aProgress;
  Synchronize(SynchedProgress);
end;
 
procedure TProgressThread.SynchedProgress;
begin
  if Assigned(FProgressProc) then
    FProgressProc(FProgressValue);
end;

Open in new window

 

3. Define your own thread: TMyThread


Now define your own thread as a descendant of the TProgressThread.
This thread just counts to 100 over 100 seconds
type
  TMyThread = class(TProgressThread)
  protected
    procedure Execute; override;
  end; 
procedure TMyThread.Execute; 
var I: Integer;
begin
  Progress(0);
  for I := 1 to 100 do 
  begin 
    Sleep(1000);
    Progress(I);
  end;
end;

Open in new window

 

4. Define the procedure to adjust the progress bar position


This procedure will receive the messages from the progress thread.
type  
  TForm1 = class(TForm)
    ProgressBar1: TProgressBar;
  private
    procedure UpdateProgressBar(aProgress: Integer);
  end; 
procedure TForm1.UpdateProgressBar(aProgress: Integer);
begin
  ProgressBar1.Position := aProgress;
  ProgressBar1.Update; // Make sure to repaint the progressbar
end;

Open in new window

 

5. Start a thread from the form


This starts the progress thread
type
  TForm1 = class(TForm)
    btnStart: TButton;
    procedure btnStartClick(Sender: TObject);
  private
    fMyThread: TMyThread;
  end;   
procedure TForm1.btnStartClick(Sender: TObject);
begin
  if not Assigned(fMyThread) then 
    fMyThread := TMyThread.Create(UpdateProgressbar);
end;

Open in new window

 

6. Complete code


Here is a copy of the complete unit
 

Open in new window

14
 
LVL 14

Expert Comment

by:systan
Comment Utility
Lol ..... Wow, do you think you could do that?  I think you have no time for that!
Anyway OTL is just another method of threading, I still don't see the big impact, because I didn't see any binary samples yet.

3 beers is enough, would not make you drunk.
0
 
LVL 14

Expert Comment

by:systan
Comment Utility
Geert, can you correct this solution, seems I don't know if I got it correct as this article says.
http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_26640643.html

is it wrong?
0

Delphi

59K

Solutions

12

Articles & Videos

16K

Contributors

Delphi is the most powerful Object Pascal IDE and component library for cross-platform Native App Development with flexible Cloud services and broad IoT connectivity. It provides powerful VCL controls for Windows 10 and enables FMX development for Windows, Mac and Mobile. Delphi is your choice for ultrafast Enterprise Strong Development™. Look for increased memory for large projects, extended multi-monitor support, improved Object Inspector and much more. Delphi is 5x faster for development and deployment across multiple desktop, mobile, cloud and database platforms including 32-bit and 64-bit Windows 10.