На этом шаге мы рассмотрим пример программы,
демонстрирующей опрос устройства с помощью потока.
Используя поток, мы сможем заставить нашу программу реагировать на подключение дискового устройства. При тестировании приложения в качестве дискового устройства использовался флэш-накопитель.
На форму следует поместить компоненты TLabel и TButton. Вид формы представлен на рис. 1.

Рис.1. Вид формы приложения
После запуска программа считает количество имеющихся на компьютере дисковых носителей. При нажатии кнопки "Пуск" запускается поток, который введет опрос следующего по счету дискового устройства. Когда устройство будет подключено, в компонент TLabel будет выведено соответствующее сообщение.
Проект приложения содержит два модуля. Текст модуля Unit1.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,unit2;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
PortThread: TPortThread;
public
{ Public declarations }
end;
var
Form1: TForm1;
hdevice: THandle; //дескриптор устройства
devcount: byte; //счетчик устройств
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
PortThread:=TPortThread.Create(false);
PortThread.FreeOnTerminate:=True;
PortThread.Priority:=tpIdle;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if PortThread<>nil
then
PortThread.Terminate;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
devcount:=0;
while hdevice<>INVALID_HANDLE_VALUE do
begin
//производим опрос устройства
hdevice:=CreateFile(PChar('\\.\PHYSICALDRIVE'+inttostr(devcount)),
0,
0,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if hdevice<>INVALID_HANDLE_VALUE
then
inc(devcount);
end;
end;
end.
Текст модуля Unit2.
unit Unit2;
interface
uses
Classes,Windows,SysUtils;
type
TPortThread = class(TThread)
private
{ Private declarations }
hdevice: THandle;
protected
procedure Execute; override;
procedure LabelOn;
procedure LabelOff;
end;
implementation
uses unit1;
{ TPortThread }
procedure TPortThread.Execute;
begin
{ Place thread code here }
while not terminated do
begin
hdevice:=CreateFile(PChar('\\.\PHYSICALDRIVE'+inttostr(devcount)),
0,
0,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if hdevice=INVALID_HANDLE_VALUE
then Synchronize(LabelOff)
else Synchronize(LabelOn);
sleep(1000);
end;
end;
procedure TPortThread.LabelOn;
begin
Form1.Label1.Caption:='Устройство подключено';
end;
procedure TPortThread.LabelOff;
begin
Form1.Label1.Caption:='Подключите устройство';
end;
end.
Текст этого примера можно взять здесь.
К приведенному выше описанию принципа работы программы можно добавить лишь то, что проверка наличия дискового устройства осуществляется с помощью функции Windows API CreateFile, которая при существовании дискового устройства с заданным индексом (в нашей программе он определяется переменной devcount) возвращает дискриптор данного устройства, в противном случае возвращает значение INVALID_HANDLE_VALUE. Также стоит обратить внимание на то, что цикл, выполняемый в потоке, будет работать до момента уничтожения потока, поэтому программа среагирует и на отключение того же дискового устройства, что было подключено нами после запуска потока.
На этом мы закончим краткое изложение организации и использования потоков.