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

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

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

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

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

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

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

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

Интервал:

Закладка:

Сделать

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

Тогда код новой оконной процедуры и код ее установки будет выглядеть так, как показано в листинге 1.7.

Листинг 1.7. Создание подкласса для особой обработки сообщения WM_KILLPFOCUS

var

OldWndProc: TFNWndProc;

function NewWindowProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM) : LRESULT; stdcall;

begin

if Msg = WM_KILLFOCUS then

// Обработка события

else

Result := CallWindowProc(OldWndProc, hWnd, Msg, wParam, lParam);

end;

...

// Установка новой оконной процедуры окну Wnd

OldWndProc := TFNWndProc(SetWindowLong(Wnd, GWL_WNDPROC, Longint(@NewWindowProc)));

...

Примечание

MSDN называет функции GetWindowLongи SetWindowLongустаревшими и рекомендует использовать вместо них GetWindowLongPtrи SetWindowLongPtr, совместимые с 64-разрядными версиями Windows. Однако до 2007-й версии Delphi включительно эти функции отсутствуют в модуле Windows, и при необходимости их следует импортировать самостоятельно.

Переопределять оконную процедуру с помощью SetWindowLongможно и у тех окон, оконная процедура которых была переопределена ранее. Таким образом создаются цепочки оконных процедур, каждая из которых вызывает предыдущую.

1.1.7. Создание окон средствами VCL

Теперь поговорим о том, как в VCL создаются окна. Речь здесь будет идти не о написании кода для создания окна с помощью VCL (предполагается, что читатель это и так знает), а о том, какие функции API и в какой момент вызывает VCL при создании окна.

Если смотреть код методов класса TWinControl, которые вызываются при создании и отображении окна, то найти там то место, когда окно создается, удается не сразу. На первый взгляд все выглядит так, будто этот код вообще не имеет отношения к созданию окна, как будто оно создается где-то совсем в другом месте, а TWinControlполучает уже готовый дескриптор. На самом деле окно создает, конечно же, сам TWinControl, а спрятано его создание в свойстве Handle. Метод GetHandle, который возвращает значение свойства Handle, выглядит следующим образом (листинг 1.8).

Листинг 1.8. Реализация метода TWinControl.GetHandle

procedure TWinControl.HandleNeeded;

begin

if FHandle = 0 then

begin

if Parent <> nil then Parent.HandleNeeded;

CreateHandle;

end;

end;

function TWinControl.GetHandle: HWnd;

begin

HandleNeeded;

Result := FHandle;

end;

При каждом обращении к свойству Handleвызывается метод HandleNeeded, который проверяет, создано ли уже окно, и если нет, создает его, попутно создавая, при необходимости, родительское окно. Таким образом, окно создается при первом обращении к свойству Handle.

Метод CreateHandle, который вызывается из HandleNeeded, выполняет непосредственно лишь несколько вспомогательных операций, а для создания окна вызывает еще один метод — CreateWnd(листинг 1.9).

Листинг 1.9. Реализация метода CreateWnd

procedure TWndControl.CreateWnd;

var

Params: TCreateParams;

TempClass: TWndClass;

ClassRegistered: Boolean;

begin

CreateParams(Params);

with Params do

begin

if (WndParent = 0) end (Style and WS_CHILD <> 0) then

if (Owner <> nil) end (csReading in Owner.ComponentState) and (Owner is TWinControl) then

WndParent TWinControl(Owner).Handle

else

raise EInvalidOperation.CreateFmt(SParentRequired, [Name]);

FDefWndProc := WindowClass.lpfnWndProc;

ClassRegistered := GetClassInfo(WindowClass.hInstance, WinClassName, TempClass);

if not ClassRegistered or (TempClass.lpfnWndProc <> @InitWndProc) then

begin

if (ClassRegistered then

Windows.UnregisterClass(WinClassName, WindowClass.hInstance);

WindowClass.lpfnWndProc := InitWndProc;

WindowClass.lpszClassName := WinClassName;

if Windows.RegisterClass(WindowClass) = 0 then RaiseLastOSError;

end;

CreationControl := Self;

CreateWindowHandle(Params);

if FHandle = 0 then RaiseLastOSError;

if (GetWindowLong(FHandle, GWL_STYLE) and WS_CHILD <> 0) and (GetWindowLong(FHandle, GWL_ID) = 0) then

SetWindowLong(FHandle, GWL_ID, FHandle);

end;

StrDispose(FText);

FText := nil;

UpdateBounds;

Perform(WM_SETFONT, FFont.Handle, 1);

if AutoSize then AdjustSize;

end;

Собственно создание окна опять происходит не здесь, а в методе CreateWindowHandle, который очень прост: он состоит из одного только вызова API-функции CreateWindowExс параметрами, значения которых берутся из полей записи Paramsтипа TCreateParams(листинг 1.10)

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

Интервал:

Закладка:

Сделать

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

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


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

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

x