Читаем О чём не пишут в книгах по Delphi полностью

Нажатие на кнопку BtnBroadcast приводит к широковещательной отправке сообщения. Отправить широковещательное сообщение можно двумя способами: функцией PostMessage с адресатом HWND_BROADCAST вместо дескриптора окна и с помощью функции BroadcastSystemMessage. Первый вариант позволяет отправить сообщения только окнам верхнего уровня, не имеющим владельца в терминах системы. Таким окном в VCL-приложении является только невидимое окно приложения, создаваемое объектом Application. Главная форма имеет владельца в терминах системы — то самое невидимое окно приложения. Поэтому широковещательное сообщение, посланное с помощью PostMessage, главная форма не получит, это сообщение пришлось бы ловить с помощью события Application.OnMessage. Мы здесь применяем другой способ — отправляем сообщение с помощью функции BroadcastSystemMessage, которая позволяет указывать тип окон, которым мы хотим отправить сообщения. В частности, здесь мы выбираем тип BSM_APPLICATION, чтобы сообщение посылалось всем окнам верхнего уровня, в том числе и тем, которые имеют владельца. При таком способе отправки главная форма получит это широковещательное сообщение, поэтому его обработку можно реализовать в главной форме.

<p>1.2.6. Пример ButtonDel</p>

Программа ButtonDel демонстрирует, как можно удалить кнопку в обработчике нажатия этой кнопки. Очень распространенная ошибка — попытка написать код, один из примеров которого приведен в листинге 1.32.

Листинг 1.32. Неправильный вариант удаления кнопки в обработчике ее нажатия

procedure TForm1.Button1Click(Sender: TObject);

begin

 Button1.Free;

end;

Рассмотрим, что произойдет в случае выполнения этого кода. Когда пользователь нажимает на кнопку, форма получает сообщение WM_COMMAND. При обработке форма выясняет, что источником сообщения является объект Button1 и передает этому объекту сообщение CN_COMMAND. Button1, получив его, вызывает метод Click, который проверяет, назначен ли обработчик OnClick, и, если назначен, вызывает его. Таким образом, после завершения Button1Click управление снова вернется в метод Click объекта Button1, из него — в метод CNCommand, из него — в Dispatch, оттуда — в WndProc, а оттуда — в MainWndProc. А из MainWndProc управление будет передано в оконную процедуру, сформированную компонентом с помощью MakeObjectInstance. В деструкторе Button1 эта оконная процедура будет уже удалена. Таким образом, управление получат последовательно пять методов уже не существующего объекта и одна несуществующая процедура. Это может привести к самым разным неприятным эффектам, но, скорее всего, — к ошибке Access violation (обращение к памяти, которую программа не имеет права использовать). Поэтому приведенный в листинге 1.32 код будет неработоспособным. В классе TCustomForm для безопасного удаления формы существует метод Release, который откладывает уничтожение объекта до того момента, когда это будет безопасно, но остальные компоненты подобного метода не имеют.

Примечание

Метод TCustomForm.Release на поверку тоже оказывается не совсем безопасным — подробнее об этом написано в разд. 3.4.3.

Очевидно, что для безопасного удаления кнопки эту операцию следует отложить до того момента, когда все методы удаляемой кнопки уже закончат свою работу. Вставить требуемый код в обработчик WM_COMMAND формы достаточно сложно, поэтому мы будем использовать другой способ: пусть обработчик кнопки посылает форме сообщение, в обработчике которого она будет удалять кнопку. Здесь важно, что сообщение посылается, а не отправляется, т. е. ставится в очередь, из которой извлекается уже после того, как будет полностью обработано сообщение WM_COMMAND. В этом случае методы удаляемой кнопки не будут вызваны, и удаление пройдет без неприятных последствий.

Как раз для подобных случаев и предусмотрена возможность определять свои сообщения, т. к. ни одно из стандартных для наших целей не подходит. Свое сообщение мы будем посылать только одному окну, без широковещания, поэтому для него вполне подходит диапазон сообщений класса. Номер сообщения становится известным на этапе компиляции, поэтому для обработки этого сообщения мы можем применить самый удобный способ написать метод-обработчик с помощью директивы message. С учётом всего этого код выглядит следующим образом (листинг 1.33).

Листинг 1.33. Модуль главной формы программы ButtonDel

unit BDMain;

interface

uses

 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных