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

Здесь есть возможность читать онлайн «А. Григорьев - О чём не пишут в книгах по Delphi» — ознакомительный отрывок электронной книги совершенно бесплатно, а после прочтения отрывка купить полную версию. В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Город: СПб, Год выпуска: 2008, ISBN: 2008, Издательство: БХВ-Петербург, Жанр: Программирование, на русском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

О чём не пишут в книгах по Delphi: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «О чём не пишут в книгах по Delphi»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

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

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

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

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

При перехвате сообщения WM_PAINTлюбого компонента, на котором расположены неоконные визуальные компоненты, может возникнуть проблема с перерисовкой этих компонентов. Чтобы продемонстрировать способ решения этих проблем, разместим на панели компонент TLabel, который заодно будет показывать пользователю реакцию на двойной щелчок правой кнопкой мыши. В результате получается окно, показанное на рис. 1.9. При двойном щелчке правой кнопкой мыши на панели надпись Сделайте двойной щелчок правой кнопкойперемещается в то место, где находится курсор. Чтобы перехватить оконную процедуру панели, следует написать метод, который ее подменит, а адрес старого метода сохранить в предназначенном для этого поле. Сам перехват будем осуществлять в обработчике события OnCreateформы (листинг 1.29).

Рис 19Окно программы PanelMsg Листинг 129 Перехват обработчика сообщений - фото 9

Рис. 1.9.Окно программы PanelMsg

Листинг 1.29. Перехват обработчика сообщений панели

type

TForm1 = class(TForm)

Panel: TPanel;

Label1: TLabel;

procedure FormCreate(Sender: TObject);

private

// Здесь будет храниться исходный обработчик сообщений

// панели

FOldPanelWndProc: TWndMethod;

// Этот метод будет перехватывать сообщения,

// предназначенные панели

procedure NewPanelWndProc(var Msg: TMessage);

end;

...

procedure TForm1.FontCreate(Sender: TObject);

begin

FOldPanelWndProc := Panel.WindowProc;

Panel.WindowProc := NewPanelWndProc;

end;

Сам перехватчик выглядит так, как показано в листинге 1.30.

Листинг 1.30. Метод-перехватчик сообщений панели

procedure TForm1.NewPanelWndProc(var Msg: TMessage);

var

NeedDC: Boolean;

PS: TPaintStruct;

PanelCanvas: TCanvas;

begin

if Msg.Msg = WM_RBUTTONDBLCLK then

begin

Label1.Left := Msg.LParamLo;

Label1.Top := Msg.LParamHi;

Msg.Result := 0;

end

else if Msg.Msg = WM_PAINT then

begin

// Проверяем, был ли запрошен контекст устройства

// обработчиком, стоящим раньше по цепочке, и если не

// был, то запрашиваем его.

NeedDC := Msg.WParam = 0;

if NeedDC then Msg.WParam := BeginPaint(Panel.Handle, PS);

// Вызываем старый обработчик WM_PAINT. Его нужно

// вызывать обязательно до того, как мы начнем рисовать

// на поверхности что-то свое, т.к. в противном случае

// это что-то будет закрашено стандартным обработчиком.

POldPanelWndProc(Msg);

// При использовании графических функций API самое

// неудобное - это вручную создавать и уничтожать кисти,

// карандаш и т.п. Поэтому здесь создается экземпляр

// класса TCanvas для рисования на контексте устройства

// с дескриптором, полученным при вызове BeginPaint.

PanelCanvas := TCanvas.Create;

try

PanelCanvas.Handle := Msg.WParam;

FanelCanvas.Pen.Style := psClear;

PanelCanvas.Brush.Style := bsSolid;

PanelCanvas.Brush.Color := clWhite;

PanelCanvas.Ellipse(10, 10, Panel.Width - 10, Panel.Height - 10);

PanelCanvas.Brush.Color := clYellow;

PanelCanvas.Rectangle(100, 100, Panel.Width - 100, Panel.Height - 100);

finally

PanelCanvas.Free;

end;

// В данном случае панель содержит визуальный неоконный

// компонент TLabel. Отрисовка неоконных компонентов

// происходит при обработке WM_PAINT родительского

// компонента, т.е. здесь она была выполнена при вызове

// стандартного обработчика. Таким образом, сделанный

// рисунок закрасил не только фон панели, но и

// неоконные компоненты. Чтобы компоненты были поверх

// рисунка, их приходится перерисовывать еще раз,

// вызывая protected-метод PaintControls. Это не очень

// эффективно, т.к. получается, что компоненты рисуются

// дважды: в стандартном обработчике и здесь. Но

// другого способа решить проблему, видимо, нет. Если

// бы на панели лежали только оконные компоненты,

// вызывать PaintControls не понадобилось, поскольку то, что

// мы рисуем на панели, не может затереть поверхность

// лежащих на этой панели других окон.

TFakePanel(Panel).PaintControls(Msg.WParam, nil);

// Если мы получали контекст устройства, мы же должны

// освободить его.

if NeedDC then

begin

EndPaint(Panel.Handle, PS);

Msg.WParam := 0;

end;

end

else FOldPanelWndProc(Msg);

end;

Так как в наш обработчик поступают все сообщения, передающиеся в оконную процедуру панели, начинается он с проверки того, какое сообщение пришло. Сначала реализуем реакцию на WM_RBUTTONDBLCLKпросто перемещаем метку Label1на то место, где пользователь щелкнул мышью. Затем обнуляем результат, давая понять системе, что сообщение полностью обработано. Вызов унаследованного обработчика в данном случае не выполняем, потому что никакая унаследованная реакция на данное событие нам не нужна. Обработка сообщения WM_PAINTсложнее. Сначала необходимо разобраться с контекстом устройства, на котором будет производиться рисование. Вообще говоря, обработчик WM_PAINTдолжен получать этот контекст с помощью функции BeginPaint. Но если до написанного нами кода сообщение WM_PAINTуже начало обрабатываться, то контекст устройства уже получен, а вызывать BeginPaintдва раза нельзя. В этом случае контекст устройства передаётся через параметр сообщения WParam. Соответственно, обработка сообщения WM_PAINTначинается с того, что мы проверяем, равен ли нулю параметр wParam, и если равен, то получаем контекст устройства, а если не равен, используем то, что передано.

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

Интервал:

Закладка:

Сделать

Похожие книги на «О чём не пишут в книгах по Delphi»

Представляем Вашему вниманию похожие книги на «О чём не пишут в книгах по Delphi» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


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

Обсуждение, отзывы о книге «О чём не пишут в книгах по Delphi» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x