А. Григорьев - О чём не пишут в книгах по Delphi

Тут можно читать онлайн А. Григорьев - О чём не пишут в книгах по Delphi - бесплатно ознакомительный отрывок. Жанр: comp-programming, издательство БХВ-Петербург, год 2008. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    О чём не пишут в книгах по Delphi
  • Автор:
  • Жанр:
  • Издательство:
    БХВ-Петербург
  • Год:
    2008
  • Город:
    СПб
  • ISBN:
    978-5-9775-019003
  • Рейтинг:
    4.25/5. Голосов: 81
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

А. Григорьев - О чём не пишут в книгах по Delphi краткое содержание

О чём не пишут в книгах по Delphi - описание и краткое содержание, автор А. Григорьев, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Рассмотрены малоосвещённые вопросы программирования в Delphi. Описаны методы интеграции VCL и API. Показаны внутренние механизмы VCL и приведены примеры вмешательства в эти механизмы. Рассмотрено использование сокетов в Delphi: различные механизмы их работы, особенности для протоколов TCP и UDP и др. Большое внимание уделено разбору ситуаций возникновения ошибок и получения неверных результатов в "простом и правильном" коде. Отдельно рассмотрены особенности работы с целыми, вещественными и строковыми типами данных, а также приведены примеры неверных результатов, связанных с ошибками компилятора, VCL и др. Для каждой из таких ситуаций предложены методы решения проблемы. Подробно рассмотрен синтаксический анализ в Delphi на примере арифметических выражений. Многочисленные примеры составлены с учётом различных версий: от Delphi 3 до Delphi 2007. Прилагаемый компакт-диск содержит примеры из книги.

Для программистов

О чём не пишут в книгах по Delphi - читать онлайн бесплатно ознакомительный отрывок

О чём не пишут в книгах по Delphi - читать книгу онлайн бесплатно (ознакомительный отрывок), автор А. Григорьев
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

<���Имя программы> "%1"

Если существуют разные варианты запуска одного файла (т.е. как в нашем случае — open и view), они различаться дополнительным параметрами. В частности, в нашем примере для открытия для редактирования не будут требоваться дополнительные параметры, для открытия для просмотра в качестве второго параметра должен передаваться кляч v, т.е. в реестр для этой команды будет записана такая строка:

<���Имя программы> "%1" v

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

Листинг 1.47. Анализ командной строки

procedure TDKSViewMainForm.FormShow(Sender: TObject);

var

OpenForView: Bооlean;

begin

// Проверяем наличие ключа "/v" в качестве второго параметра

OpenForView := (ParamCount > 1) and (CompareText(ParamStr(2), '/v') = 0);

if ParamCount > 0 then OpenFile(ParamStr(1), OpenForView);

...

end;

B более сложных случаях (например, при большем числе команд для ассоциированного файла) анализ командной строки будет сложнее, но его принципы останутся теми же.

1.3.2.3. Поиск уже запущенной копии приложения

Во многих случаях желательно не давать пользователю возможности запустить второй экземпляр вашего приложения. В 16-разрядных версиях Windows все приложения выполнялись в одной виртуальной машине, и каждому из них через переменную HPrevInstanceпередавался дескриптор предыдущей копии. По значению HPrevInstanceпрограмма легко могла найти свой предыдущий экземпляр или определить, что других экземпляров нет, если HPrevInstanceравна нулю. В 32-разрядных версиях эта переменная для совместимости оставлена, но всегда равна нулю, т.к. предыдущая копия работает в своей виртуальной машине, и ее дескриптор не имеет смысла. Альтернативного механизма обнаружения уже запущенной копии система не предоставляет, приходится выкручиваться своими силами.

Для обнаружения уже запущенного приложения многие авторы предлагают использовать именованные системные объекты (мьютексы, семафоры, атомы и т.п.). При запуске программа пытается создать такой объект с определенным именем. Если оказывается, что такой объект уже создан, программа "понимает", что она — вторая копия, и завершается. Недостаток такого подхода — с его помощью можно установить только сам факт наличия предыдущей копии, но не более того. В нашем случае задача шире: при запуске второго экземпляра приложения должен активизироваться первый, а если второму экземпляру была передана непустая командная строка, первый должен получить эту строку и выполнить соответствующее действие, поэтому описанный способ нам не подходит.

Для решения задачи нам подойдут почтовые ящики (mailslots). Это специальные системные объекты для односторонней передачи сообщений между приложениями (ничего общего с электронной почтой эти почтовые ящики не имеют). Под сообщением здесь понимаются не сообщения Windows, а произвольный набор данных (здесь больше подходит скорее термин "дейтаграмма", а не "сообщение"). Каждый почтовый ящик имеет уникальное имя. Алгоритм отслеживания повторного запуска с помощью почтового ящика следующий. Сначала программа пытается создать почтовый ящик как сервер. Если оказывается, что такой ящик уже существует, то она подключается к нему как клиент и передает содержимое своей командной строки и завершает работу. Сервером в таком случае становится экземпляр приложения, запустившийся первым, — он-то и создаёт почтовый ящик. Остальным экземплярам останется только передать ему данные.

Примечание

В случае аварийного завершения программы система сама закроет все открытые ею дескрипторы, поэтому даже если первая копия будет снята системой и не сможет корректно закрыть дескриптор почтового ящика, ящик будет уничтожен и не помешает пользователю запустить новую копию программы.

Почтовый ящик лучше создать как можно раньше, поэтому мы будем его создавать не в методе формы, а в основном коде проекта, который обычно программист не исправляет. В результате код в dpr-файле проекта будет выглядеть так, как показано в листинге 1.48.

Листинг 1.48 Создание почтового ящика в главном файле проекта

const

MailslotName = '\\.\mailslot\DelphiKingomSample_Viewer_FileCommand';

EventName = 'DelphiKingdomSamplе_Viewer_Command_Event';

var

ClientMailslotHandle: THandle;

Letter: string;

OpenForView: Boolean;

BytesWritten: DWORD;

begin

// Пытаемся создать почтовый ящик

ServerMailslotHandle := CreateMailSlot(MailslotName, 0,

MAILSLOT_WAIT_FOREVER, nil);

if ServerMailslotHandle = INVALID_HANDLE_VALUE then

begin

if GetLastError = ERROR_ALREADY_EXISTS then

begin

// Если такой ящик уже есть, подключаемся к нему, как клиент

ClientMailslotHandle := CreateFile(MailslotName, GENERIC_WRITE,

FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

// В зависимости от того, какие переданы параметры, формируем

// строку для передачи предыдущему экземпляру. Первый символ

// строки - команда:

// e - открыть файл для редактирования

// v — открыть файл для просмотра

// s — просто активизировать предыдущий экземпляр

// Для команд e и v к строке, начиная со 2-го символа,

// добавляется имя файла

if ParamCount > 0 then

begin

OpenForView := (ParamCount > 1) and

(CompareText(ParamStr(2), '/v') = 0);

if OpenForView then Letter := 'v' + ParamStr(1)

elsе Letter := 'e' + ParamStr(1);

end

else Letter := 's';

// Отправляем команду в почтовый ящик

WriteFile(ClientMailslotHandle, Letter[1], Length(Letter),

BytesWritten, nil);

// Сигнализируем об отправке данных через специальное событие

CommandEvent := OpenEvent(EVENT_MODIFY_STATE, False, EventName);

SetEvent(CommandEvent);

// Закрываем все дескрипторы

CloseHandle(CommandEvent);

CloseHandle(ClientMailslotHandle);

end;

end

else

begin

// Создаем событие для сигнализирования о поступлении данных

CommandEvent := CreateEvent(nil, False, False, EventName);

// Выполняем обычный для VCL-приложений цикл

Application.Initialize;

Application.CreateForm(TDKSViewMainForm, DKSViewMainForm);

Application.Run;

// Закрываем все дескрипторы

CloseHandle(ServerMailslotHandle);

CloseHandle(CommandEvent);

end;

end.

Теперь осталось "научить" первую копию приложения обнаруживать момент, когда в почтовом ящике оказываются сообщения, и забирать их оттуда. Было бы идеально, если при поступлении данных главная форма получала бы какое-то сообщение, но готового такого механизма, к сожалению, не существует. Из положения можно выйти, задействовав события.

Примечание

События — это объекты синхронизации, использующиеся в системе. Событие может быть взведено и сброшено. С помощью функции WaitForSingleObjectможно перевести нить в состояние ожидания до тех пор. пока указанное событие не будет взведено. Подробное рассмотрение объектов синхронизации выходит за рамки нашей книги; они детально описаны, например, в [2].

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


А. Григорьев читать все книги автора по порядку

А. Григорьев - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




О чём не пишут в книгах по Delphi отзывы


Отзывы читателей о книге О чём не пишут в книгах по Delphi, автор: А. Григорьев. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x