Читать книгу Иcпользование API на Delphi 7 (Сергей Николаевич Талипов) онлайн бесплатно на Bookz
bannerbanner
Иcпользование API на Delphi 7
Иcпользование API на Delphi 7Полная версия
Оценить:
Иcпользование API на Delphi 7

4

Полная версия:

Иcпользование API на Delphi 7

Сергей Талипов

Иcпользование API на Delphi 7

ЛЕКЦИЯ №1

1. РАБОТА С INI – ФАЙЛАМИ

Ini-файл – это текстовый файл, в котором информация сгруппирована по секциям, ключам. Данные файлы широко применяются во многих приложениях и в операционной системе Windows для хранения различных программных данных и настроек пользователя. В таком файле можно хранить, например, положение окон программы, дату, время и продолжительность работы программы, пути к разным данным и данным, выбранные в программе настройки пользователя Ниже приведена структура и пример Ini-файла:


Для работы с Ini-файлами применяется дополнительный модуль Delhi «inifiles». Ссылку на данный модуль необходимо прописать в разделе «uses» работающей с Ini-файлами форме программы. Вся работа с Ini-файлами осуществляется через тип «TiniFile» модуля «inifiles». Основные методы данного типа следующие:


CreateОткрытие Ini-файла для чтения или записиFreeЗакрытие открытого Ini-файлаUpdateFileОбновляет данные из/в файла на дискеSectionExistsПроверка существования в файле данной секцииValueExistsПроверка существования в файле ключа в данной секцииReadSectionsПолучение перечня всех секций файлаEraseSectionУдаление данной секции со всеми ее ключамиDeleteKeyУдаление ключа в данной секцииReadSectionПолучение перечня ключей данной секцииReadSectionValuesПолучение значений всех ключей (с именами) данной секцииReadStringЧтение строкового значения из ключа данной секцииReadBoolЧтение логического значения из ключа данной секцииReadDateЧтение даты из ключа данной секцииReadDateTimeЧтение даты и время из ключа данной секцииReadFloatЧтение вещественного значения из ключа данной секцииReadIntegerЧтение целого значения из ключа данной секцииReadTimeЧтение времени из ключа данной секцииWriteStringЗапись (обновление) строкового значения в ключ данной секцииWriteBoolЗапись логического значения в ключ данной секцииWriteDateЗапись даты в ключ данной секцииWriteDateTimeЗапись даты и времени в ключ данной секцииWriteFloatЗапись вещественного значения в ключ данной секцииWriteIntegerЗапись целого значения в ключ данной секцииWriteTimeЗапись времени в ключ данной секции

Рассмотрим на подробном примере процедуру записи информации в Ini-файл:

procedure TForm1.Button3Click(Sender: TObject);

var t_Ini: TIniFile;

  k: integer; s, path_pr, nfile: string; td: tdatetime;

begin

  k:=736; s:='Okey'; td:=now;

  path_pr:=ExtractFilePath(application.exename) +'tsn.ini';

  t_Ini := TIniFile.Create(nfile);

  try

  with t_Ini do begin

     WriteInteger('TSN', 'str1', k);

     WriteFloat('TSN', 'str2', 736.123);

     WriteString('TSN', 'str3', s);

     WriteDate('TSN', 'str4', strtodate('01.02.2012'));

     WriteTime('TSN', 'str5', td);

     Writebool('TSN', 'str6', true);

  end;

  except

    showmessage('Нет доступа к Ini-файлу !');

  end;

  t_Ini.Updatefile; t_Ini.Free;

end;


Рассмотрим на примере процедуру считывания ранее сохраненной информации из Ini-файла:


procedure TForm1.Button4Click(Sender: TObject);

var t_Ini: TIniFile;

  k: integer; s, path_pr, nfile: string; td: tdatetime;

begin

  path_pr:=ExtractFilePath(application.exename) +'tsn.ini';

  t_Ini := TIniFile.Create(nfile);

  try

  with t_Ini do begin

     k:=ReadInteger('TSN', 'str1', -1); showmessage(inttostr(k));

     s:=ReadString('TSN', 'str3', '-1'); showmessage(s);

     td:=ReadDate('TSN', 'str4', strtodate('1.1.2000'));

     showmessage(datetostr(td));

     showmessage(floattostr(ReadFloat('TSN', 'str2', -1.123)));

     showmessage(timetostr(ReadTime('TSN2', 'str5', now)));

     showmessage(inttostr(byte(ReadBool('TSN2', 'str6', false))));

  end;

  except

    showmessage('Нет доступа к Ini-файлу !');

  end;

  t_Ini.Free;

end;


ЛЕКЦИЯ №2

1. РАБОТА С РЕЕСТРОМ WINDOWS


Реестр Windows – это база данных, в которой операционная система Windows и внешние программы сохраняют нужные им данные. Логическая структура реестра напоминает строение Ini-файла, отличие состоит в том, что Ini-файл состоит из разделов (секций) и ключей раздела со значениями, а реестр состоит из разделов, вложенных подразделов (неограниченное число) и ключей (параметров) разделов/подразделов со значениями.


Реестр Windows имеет древовидную структуру, подобную файловой системе, где разделы и подразделы соответствуют каталогам и подкаталогам, а ключи со значениями – именам файлов:


Рис. 1


Любая программа может сохранять свои данные или в реестре Windows или в Ini-файлах. Достоинства и недостатки использования реестра и Ini-файлов следующие:


ПараметрИспользование реестра WindowsИспользование Ini-файловПеренос данных с компьютера на компьютерТрудность переноса данных с использованием экспорта/импорта ветвей реестра через программу редактора реестра («regedit»)Легкость переноса данных путем простого копирования Ini-файла с одного компьютера на другойМодификация данныхЧерез функции прикладной программы или программу редактора реестраЧерез функции прикладной программы или корректировки в обычном текстовом редактореПривязка к конкретному пользователю WindowsАвтоматически на уровне операционной системы через корневой раздел «HKEY_CURRENT_USER»Трудно через функции прикладной программыПривязка к конкретному компьютеруАвтоматически на уровне операционной системы через корневой раздел «HKEY_LOCAL_MACHINE»Трудно через функции прикладной программы

Таблица 1


Реестр состоит из шести корневых разделов, два из которых представляют наибольший интерес: раздел «HKEY_LOCAL_MACHINE» предназначен для хранения данных, доступных всем пользователям Windows, а раздел «HKEY_CURRENT_USER» хранит данные, доступные только для текущего пользователя Windows. Другие корневые разделы обычно используются только операционной системой и некоторыми системными программами.


Язык программирования Delphi 5 позволяет производить с реестром Windows любые манипуляции через подключение модуля «Registry» в разделе «interface -> uses». Рассмотрим на примере основные базовые операции при записи и считывании данных с реестра:


procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

{ Процедура записи данных в реестр }

var Reg: tRegistry;

begin

  Reg:=tRegistry.Create;

  Reg.RootKey:=HKEY_LOCAL_MACHINE;

  try

    if Reg.OpenKey('\Software\TSN736\', true) then begin

      if not Reg.KeyExists('setup') then Reg.CreateKey('setup');

      if Reg.OpenKey('\Software\TSN736\setup', false) then begin

        Reg.WriteInteger('Left', form1.left); Reg.WriteInteger('Top', form1.top);

        Reg.CloseKey;

      end;

    end;

  finally

    Reg.Free;

  end;

end;


procedure TForm1.FormCreate(Sender: TObject);

{ Процедура чтения данных с реестра }

var Reg: tRegistry;

begin

  Reg:=tRegistry.Create;

  Reg.RootKey:=HKEY_LOCAL_MACHINE;

  try

    if Reg.OpenKey('\Software\TSN736\setup', false) then begin

       try form1.left:=Reg.ReadInteger('Left'); except; end;

       try form1.top:=Reg.ReadInteger('Top'); except; end;

        Reg.CloseKey;

    end;

  finally

    Reg.Free;

  end;

end;



ЛЕКЦИЯ №3

1. ПРЕОБРАЗОВАНИЕ ТИПОВ. ДОСТУП К ОБЪЕКТАМ И КОМПОНЕНТАМ ЧЕРЕЗ УКАЗАТЕЛИ


При написании обработчиков событий для компонент практически всегда в процедуру передается указатель «Sender» типа «TObject». Данный указатель как правило указывает (ссылается) на тот визуальный компонент, который вызывает данную процедуру. Параметр «Sender» является некоторым усовершенствованным аналогом ссылочной переменной языка Pascal.


Использование параметра «Sender» позволяет делать процедуры – обработчики событий универсальными, позволяющими работать не с одним конкретным компонентом, а с несколькими, имеющими одинаковый тип. Например, можно написать процедуру перемещения кнопки по экрану и привязать эту процедуру ко всем кнопкам формы, после чего все кнопки также смогут перемещаться по экрану. Для этого в процедуре-обработчике необходимо пользоваться только «Sender» конструкциями, а не явными указаниями на компоненты.


Рассмотрим способы доступа к компонентам через указатель «Sender» и методы преобразования типов:


procedure TForm1.Button2Click(Sender: TObject);

var s: TObject; ss: string;

{ Пример опознания типа объекта по указателю "Sender" }

begin

  s:=Sender; { или так: s:=button2; }

  ss:='tbutton'; { запишем имя типа кнопки в строк. переменную }

  if s.ClassNameIs(ss) then showmessage('Кнопка!');

  if (s is tbutton) then showmessage('Это кнопка типа "TButton" !')

    else showmessage('Это "'+s.ClassName+'" !');

  { Можно так }

  try (s as tbutton).caption:='Ok!!!'; except end;

  { Или так }

  tbutton(s).caption:='Ok!!!';

  { Или вот-так, если свойство не "Protected" и не "Read-only" }

  tcontrol(s).left:=300;

end;


ЛЕКЦИЯ №4

1. ТЕХНОЛОГИЯ ПЕРЕТАСКИВАНИЯ ОБЪЕКТОВ «DRAG & DROP»


Технология «Drag & Drop» («Перетащи и кинь») предназначается для перемещения (перетаскивания) данных из одних визуальных компонент в другие в процессе работы программы с помощью мыши. Данная технология делает интерфейс программы более удобным и быстрым и используется во многих системных и прикладных Windows-программах.


Технология «Drag & Drop» позволяет, например, копировать строку текста (пункт) из одного компонента формы «ListBox» в другой компонент «ListBox» или предложение из одного компонента «Memo» в другой компонент «Memo». Технология «Drag & Drop» позволяет перемещать данные из любого визуального компонента в любой другой визуальный компонент для любой формы текущего приложения. С окнами других приложений данная технология по умолчанию не работает.


Для перетаскивания данных из одних визуальных компонент в другие с помощью технологии «Drag & Drop» необходимо на этапе создания программы настроить компоненты на данную технологию и запрограммировать алгоритм их поведение при перетаскивании из (в) них данных.


Для того, чтобы компонент смог «откликаться» (выделять перетаскиваемый компонент другим цветом и менять форму курсора) на начало процесса перетаскивания из него данного, необходимо его свойству «DragMode» присвоить значение «dmAutomatic». После этого компонент сможет предоставлять выделенное данное в распоряжение технологии «Drag & Drop» для перетаскивания.


Edit1.DragMode:=dmAutomatic; ListBox1.DragMode:=dmAutomatic;


Компонент, давший данное для перетаскивания, отдает управление Widows и выходит из участия из процесса перетаскивания. Далее Windows следит за тем, куда пользователь перемещает данное по компонентам формы. Как только данное будет находится над каким-нибудь визуальным компонентом, Windows вызовет у него событие «OnDragOver» и передаст в соответствующую ему процедуру – обработчик данное о том, от кого (какого компонента) прибыло перетащенное данное. Компонент, над которым находится перетаскиваемое данное, в процедуре-обработчике события «OnDragOver» анализирует его и если ему оно нужно, то устанавливает параметру процедуры «Accept» значение «true», или значение «false» в противном случае. Значение «Accept» равное «true» озночает, что компонент не возражает принять «зависшее» над ним данное.


procedure TForm1.Edit1DragOver(Sender, Source: TObject; X, Y: Integer;

                  State: TDragState; var Accept: Boolean);

{ Можно принять (едиту), если "кидается" на него метка или данные из лист-бокса}

begin Accept := (Source is TEdit) or (Source is TListBox); end;


Если данное переместится на другой компонент, или пользователь отменит перетаскивание клавишей клавиатуры «Esc», то компонент «забывает» о «зависшем» над ним данным и нечего больше не предпринимает. Если же пользователь отпустил данное над компонентом, то у компонента возникает событие «OnDragDrop».


В обработчик события «OnDragDrop» передается данное о том, кто послал данное и в какое место компонента его кинули. Именно данная процедура обработчик (у компонента-приемника данного) реализует алгоритм перемещения данного с другого компонента в данный. Операционная система Windows в данной технологии служит только посредником для визуального отображения процесса перетаскивания, и не участвует в фактической обработке процесса переноса данных.


В процедуре – обработчике события «OnDragDrop» необходимо программно реализовать алгоритм перемещения информации из одного визуального компонента, в другой.


procedure TForm1.Edit1DragDrop(Sender, Source: TObject; X, Y: Integer);

{ Обработка факта "кидка" для едита; Sender – на кого кинули; Source – что кинули (кого) }

begin { Если кинули из лист-бокса, то …}

   if Source is TListbox then with Sender as TEdit do begin

       Text:=(Source as TListbox).items[(Source as TListbox).itemindex];

          { если кинули из другого едита , то … }

    end else (Sender as TEdit).Text:=(Source as TEdit).text;

end;



ЛЕКЦИЯ №5

1. СОЗДАНИЕ КЛИЕНТ – СЕРВЕРНЫХ СИСТЕМ

С ИСПОЛЬЗОВАНИЕМ СОКЕТНОЙ ТЕХНОЛОГИИ ПРОТОКОЛА TCP/IP


В настоящее время наиболее распространенным протоколом передачи данных в локальной сети и Интернет является протокол TCP/IP. Данный протокол позволяет передавать любые данные на любое расстояние. Протокол – это специальное программное обеспечение, входящее в операционную систему, которое реализует прием и передачу данных по сети.


При связи двух программ (компьютеров) между собой по сети через протокол TCP/IP для каждой программы операционная система создает (открывает) свой «сокет». Сокет – это буфер (канал) обмена данными по сети. Сокет открывается для конкретного экземпляра программы для указанного сетевого адреса (идентифицирующий компьютер в сети) и порта TCP/IP (идентифицирующий конкретную сетевую программу). Каждый сокет получает от операционной системы уникальный номер (дескриптор, хэндл).


При обмене данными по протоколу TCP/IP одна машина обычно выступает в роли "сервера", другая – в роли "клиента". Клиент, как и сервер, может передавать и принимать данные, отличие между ними заключается в том, что программа "сервер" может одновременно работать с несколькими "клиентами", а "клиент" – только с одним сервером. На рис. 1 показана схема модели клиент – серверного взаимодействия на основе сокетов для протокола TCP/IP.


Для создания сокетного клиента TCP/IP в Делфи используется компонент «ClientSocket», а для создания сокетного сервера компонент «ServerSocket». Используя свойства, методы и события данных компонент создадим программы «клиент» и «сервер».



2. СОЗДАНИЕ ПРОГРАММЫ TCP/IP – КЛИЕНТ НА ОСНОВЕ СОКЕТОВ


Компоненты программы – клиента:

ClientSocket1: TClientSocket – компонент сокета клиента;

Edit1 – IP-адрес сервера;

Edit2 -порт TCP/IP;

Memo1 – посылаемые на сервер данные;

ListBox1 – получаемые с сервера данные;

Button1 – активизация клиента (подключение);

Button2 – посылка данных;

Button3 – отключение клиента.


Свойства ClientSocket1:

ClientType – тип передачи данных по протоколу TCP/IP (блочная передача, не блочная);

Active – открытие/закрытие связи с сервером (сокета);

Address – IP адрес сервера TCP/IP;

Host – имя сервера TCP/IP (задается либо адрес, либо хост сервера);

Port – номер порта TCP/IP сервера;

Socket – объект доступа к сокету.



События ClientSocket1:

OnConnect – подключение к серверу;

OnDisconnect – отключение от сервера;

OnError – ошибка при подключении к серверу;

OnRead – чтение данных с сервера.

В процедуры-обработчики данных событий

передается параметр «Socket» типа

“TCustomWinSocket”. Данный параметр имеет

свойство «Socket . ReceiveText» – хранящий принятые с сервера данные.


Методы ClientSocket1:

Socket . SendText – отправка текста на сервер;

Open – подключение к серверу (открытие сокета);

Close – отключение от сервера (закрытие сокета).



procedure TForm1.Button1Click(Sender: TObject);

{ Подключение к серверу }

begin

  { Если соединение уже установлено – прерываем его }

  ClientSocket1.Close;

  { Устанавливаем не блочную передачу/прием данных }

  ClientSocket1.ClientType:=ctNonBlocking;

  { Присваиваем свойствам Address и Port нужные значения }

  ClientSocket1.Address := Edit1.Text; ClientSocket1.Port := StrToInt(Edit2.Text);

  { Пытаемся открыть сокет и установить соединение с сервером }

   ClientSocket1.Open;

end;


procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

{ Отключение от сервера }

begin

  ClientSocket1.Close;

end;


procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);

{ Прием текста от сервера }

begin

  ListBox1.Items.Text:=Socket.ReceiveText;

end;


procedure TForm1.Button2Click(Sender: TObject);

{ Отправка текста на сервер }

begin

  if ClientSocket1.Socket.SendText(Memo1.lines.Text)=0 then

     MessageDlg('Не могу отправить данные на сервер',

        mtError,[mbOk], 0) else showmessage('Ok!');

end;


procedure TForm1.ClientSocket1Error(Sender: TObject;

  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);

{ Произошла ошибка соединения с сервером }

begin

  ErrorCode:=0; MessageDlg('Нет связи с сервером', mtError,[mbOk], 0);

end;


procedure TForm1.Button3Click(Sender: TObject);

{ Отключение от сервера }

begin

  ClientSocket1.Close;

end;


procedure TForm1.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);

{ Факт подключения к серверу }

begin

  ListBox1.Items.Text:='On line…';

end;


procedure TForm1.ClientSocket1Disconnect(Sender: TObject;

  Socket: TCustomWinSocket);

{ Факт отключения к серверу }

begin

  ListBox1.Items.Text:='Off line…';

end;



3. СОЗДАНИЕ ПРОГРАММЫ TCP/IP – СЕРВЕР НА ОСНОВЕ СОКЕТОВ


Компоненты программы – сервера:

ServerSocket1: TServerSocket – компонент – сокет сервера TCP/IP;

Edit1 – IP-адрес сервера;

Memo1 – посылаемые на клиент данные;

ListBox1 – полученные от клиента данные;

Button1 – запуск сервера;

Button2 – остановка сервера;

Button3 – отправка данных на клиенты.


Свойства ServerSocket1:

Active – запуск/остановка сервера (сокета);

Port – номер порта TCP/IP сервера;

Socket – объект доступа к сокету;

Socket . ActiveConnections – количество подключенных к серверу клиентов.


События ServerSocket1:

OnClientConnect – подключение клиента к серверу;

OnClientDisconnect – отключение клиента от сервера;

OnClientError – ошибка связи с клиентом;

OnClientRead – получение данных от клиента;

OnListen – ожидание подключения клиента.

В процедуры-обработчики данных событий передается параметр

«Socket» типа “TCustomWinSocket”.

Данный параметр имеет свойство

«Socket . ReceiveText» – хранящий принятые с клиента данные.


Методы ServerSocket1:

Socket . Connections[i] . SendText – отправка на i-й клиент текста;

Open – активизация сервера (открытие сервера);

Close – деактивизация сервера (закрытие сервера).

(!) Каждый сокет имеет свойство «Socket . SocketHandle» – уникальный дескриптор данного сокета, используемый для идентификации клиента (в обработчике события «OnClientRead».


procedure TForm2.Button1Click(Sender: TObject);

{ Определяем порт и запускаем сервер }

begin

  ServerSocket1.Close; ServerSocket1.Port := StrToInt(Edit1.Text); ServerSocket1.Open;

end;


procedure TForm2.Button2Click(Sender: TObject);

{ Останавливаем сервер }

begin

  ServerSocket1.Close; ListBox1.Items.Text:='Server is stop.';

end;


procedure TForm2.ServerSocket1ClientError(Sender: TObject;

  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);

{ Произошла ошибка связи с клиентом }

begin

  MessageDlg('Нет связи с клиентом', mtError,[mbOk], 0);

end;


procedure TForm2.ServerSocket1ClientRead(Sender: TObject;

  Socket: TCustomWinSocket);

{ Получение данного с клиента }

begin

  Listbox1.Items.Text:=Socket.ReceiveText;

end;


procedure TForm2.Button3Click(Sender: TObject);

{ Отправка данных на клиент }

label 1;

begin

  with ServerSocket1.Socket do begin

    if ActiveConnections=0 then goto 1;

    if Connections[0].SendText(Memo1.Lines.text)=0 then

     1: MessageDlg('Не могу отправить данные на клиент',

        mtError,[mbOk], 0) else showmessage('Ok!');

  end;

end;


procedure TForm2.ServerSocket1ClientConnect(Sender: TObject;

  Socket: TCustomWinSocket);

{ Запрет доступа "вторым" клиентам }

begin

  if ServerSocket1.Socket.ActiveConnections>1 then abort;

end;


procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);

{ Остановка сервера }

begin

  ServerSocket1.Close;

end;


procedure TForm2.ServerSocket1Listen(Sender: TObject;

  Socket: TCustomWinSocket);

{ Ожидание подключения клиентов }

begin

  ListBox1.Items.Text:='Server is active…';

end;


ЛЕКЦИЯ №6

1. РАЗРАБОТКА DLL – БИБЛИОТЕК


Язык программирования Delphi является языком визуального объектно-ориентированного программирования (ООП). В современных программах, совместно с ООП, очень часто используется и модульный принцип создания программ. Наибольшее развитие данная технология получила в форме разработки динамически загружаемых DLL-библиотек. DLL-библиотека представляет собой отдельный файл с расширением «DLL», в котором находятся какие-либо процедуры и функции. Они становятся доступными при подключении к программе DLL-файла.


При подключении DLL-библиотеки к программе она загружается в оперативную память компьютера и находится там до завершения программы. Если запускается несколько программ, и всем им нужна одна и таже DLL-библиотека, то она загрузится в память в одном экземпляре, а выгрузится из памяти при закрытии последней (использующей библиотеку) программы.


При одновременной работе нескольких программ с одной и той же DLL-библиотекой обеспечивается независимость переменных DLL-модуля для каждой прикладной программы. Таким образом получается, что процедуры и функции загружаются в одном экземпляре, а переменные DLL копируются для каждой прикладной программы отдельно.


Прикладная программа на Delphi может подключать DLL-библиотеку двумя способами: динамическим и статическим. При статическом способе DLL-библиотека автоматически подключается при запуске программы и автоматически деактивируется при ее завершении. Если указанный DLL-файл будет не найден, то возникнет ошибка выполнения программы. При динамическом способе DLL-библиотека подключается и отключается в нужное программисту время, при этом обеспечивается контроль над ошибочными ситуациями (например, если DLL-файл не найден).

bannerbanner