Подтвердить что ты не робот

Какая разница между CreateWnd и CreateWindowHandle?

Компоненты Delphi имеют CreateWnd и CreateWindowHandleDestroyWnd и DestroyWindowHandle). Они оба должны быть переопределены потомками, верно? И не предназначалось для вызова, за исключением базовой реализации VCL?

Какая разница между ними; когда должен быть переопределен любой из них?

4b9b3361

Ответ 1

До сих пор большинство ответов здесь в значительной степени на марке, и вам было бы неплохо прислушаться к их советам. Однако в этой истории есть немного больше. К вашему конкретному вопросу о том, когда вы переопределите тот или иной, я немного потрудился.

CreateParams();

В общем, большую часть времени вам действительно нужно переопределить CreateParams(). Если все, что вы хотите сделать, - это подкласс (вспомните подкласс Windows style)? См. Работу Petzold по разработке Windows) существующий класс управления и завершите его в элементе управления VCL, вы делаете это из CreateParams. Вы также можете контролировать, какие биты стиля установлены и другие различные параметры. Мы очень упростили процесс создания "подкласса". Просто вызовите CreateSubClass() из вашего метода CreateParams(). См. Основные элементы управления VCL для примера, такого как TCheckBox или TButton.

CreateWnd();

Вы бы переопределили это, если вам нужно немного поработать с дескриптором окна после его создания. Например, если у вас есть элемент управления, который является каким-то списком, деревом или иным образом требует конфигурации после создания, вы можете сделать это здесь. Вызовите унаследованный CreateWnd, и когда он вернется (вы знаете, что у вас есть действительный дескриптор, если вы вернетесь из CreateWnd, потому что он вызовет исключение, если что-то пойдет не так), просто примените свою дополнительную магию. Обычный сценарий - взять данные, которые кэшируются в списке экземпляров TStrings и фактически переместить его в базовый элемент управления окном. TListBox - классический пример этого.

CreateWindowHandle();

Мне нужно было обновить свою память на этом, но кажется, что это один, редко, если вообще когда-либо, переопределяется. В немногих случаях внутри самого VCL кажется, что он используется для работы с определенными версиями Windows и локальными странностями с некоторыми элементами управления, такими как TEdit и TMemo. Другой более четкий случай - в самом TCustomForm. В этом случае он поддерживает новую модель интерфейса MDI (интерфейс mutli-document). В этом случае дети MDI не могут быть созданы с использованием обычного API CreateWindowEx(), вам нужно отправить сообщение в родительский фрейм MDI, чтобы фактически создать дескриптор. Таким образом, единственная причина, чтобы преодолеть этот метод, заключается в том, что фактический процесс создания дескриптора выполняется с помощью средства, совершенно отличного от старого try-and-true CreateWindowEx().

Я заметил, что ваш вопрос просто спрашивал о процессе создания, но есть соответствующие методы, которые в некоторых случаях переопределяются как для уничтожения дескрипторов, так и для "вуду", который иногда окружает релаксацию рук. Но это другие темы, которые должны быть рассмотрены отдельно: -).

Ответ 2

CreateWnd сначала вызывает CreateParams, а затем вызывает CreateWindowHandle, используя созданные Params. Как правило, вы переопределяете CreateWnd и CreateParams, а не CreateWindowHandle.

Надеюсь, это поможет!

Ответ 3

Кто делает что:
CreateWnd - это генеральный подрядчик, который создает полностью сформированное окно для WinControl.
Во-первых, он должен установить необходимые атрибуты для WindowClass, вызвав CreateParams и убедившись, что он правильно зарегистрирован.
Затем он получает фактически созданное окно, вызывая CreateWindowHandle, который возвращает полученную ручку из ОС.
После этого у нас есть действующее окно, способное обрабатывать сообщения, а CreateWnd выполняет окончательный уход, настраивая различные визуальные аспекты, такие как размер, шрифт и т.д.

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

Ответ 4

Я уверен, что окончательный ответ может исходить только от людей, участвующих в создании VCL (Allen?), но IMHO должен быть отменен виртуальный метод с наименьшей ответственностью/который является самым низким в цепочке вызовов, Поэтому я всегда переопределял CreateParams() и CreateWindowHandle(). Это похоже на хорошую подгонку, поскольку оба они называются CreateWnd(), и оба делают только одну особую вещь.

В конце концов, это, вероятно, вопрос предпочтения.