Delphi: Как использовать безоконные элементы управления? - PullRequest
4 голосов
/ 23 февраля 2010

я знаю, что управление без окон не волшебство . Элемент управления без окон может иметь фокус ввода (например, Internet Explorer). Фокус ввода - не что иное как рисование:

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

В случае моего окна (Windows & reg;) я должен был бы знать, что мой дочерний элемент управления без окон (давайте притворимся это потомок TGraphicControl) получает события клавиатуры. Поэтому во время заполнения форм OnKeyDown, OnChar, OnKeyUp мне нужно было бы притворяться, что они переходят на мой дочерний контроль без окон.

Что я могу сделать, но это боль.

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

Что я могу сделать, но это боль.

А потом есть ActiveControl, который ничего не понимает, кроме TWinControl. Так что, если Delphi когда-либо попытается выяснить, на кого он сфокусирован, это сойдет с ума. Так что мне нужно иметь альтернативную реализацию ActiveControl.

Что я могу сделать, но это боль.

Другими словами: это просто слишком много работы? Я борюсь со всем, что есть у Delphi, и все, чтобы у меня было несколько десятков элементов управления без окон, доступных через ввод с клавиатуры? Дизайнеры Delphi никогда не задумывались об использовании интерактивных элементов управления без окон, и если я попытаюсь сейчас поработать с ними, я просто застряну в hurtlocker ?

Дельфи дал мне возможность помочь мне охотно, но я избрал путь боли.


Требуется дополнительное объяснение элементов управления без окон .

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

Например, почти каждый элемент управления, который вы видите в окне браузера Internet Explorer, является элементом без окна. На следующем скриншоте вы можете увидеть элемент управления edit , который вы можете ввести, и кнопку, которая (на этом скриншоте) имеет фокус:

alt text

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

Если бы я нажал Пробел , когда кнопка Google Search имеет фокус, он бы нажал кнопку. Это работает потому, что Microsoft написала целую библиотеку виджетов элементов управления. Эти элементы управления выглядят (почти) точно так же, как обычные общие элементы управления - они являются почти точными клонами общих элементов управления Windows вплоть до применяемых тем.

Mozilla Firefox и Google Chrome также используют библиотеку элементов управления виджетов. Они не используют встроенные оконные элементы управления Microsoft, но вместо этого используют библиотеку графических, интерактивных, безоконных виджетов .

И если у вас есть подходящая среда разработки, то безоконные виджеты работают так же, как "обычные" оконные элементы управления. GTK + - это библиотека виджетов, а Glade - IDE, которая позволяет вам размещать элементы управления в этой библиотеке виджетов.

Я не знаю, в какой среде разработки были созданы Firefox, Chrome или Blender, но их виджеты поддерживают элементы управления без окон.


Итак, теперь на мой вопрос.

Если я не ошибаюсь, мне кажется, что хотя Delphi поддерживает базу TControl (которая имеет ширину, высоту и может рисовать сама), она не может получить фокус клавиатуры. Мне кажется, что Borland никогда не проектировал VCL Delphi как универсальную библиотеку виджетов. Единственное доказательство, которое я должен подтвердить, это то, что ActiveControl формы - это TWinControl:

property ActiveControl: TWinControl;

Это не означает, что Delphi может быть или должен быть ограничен оконными элементами управления. Библиотека виджетов VCL может быть расширена для поддержки фокусировки на элементах управления без окон.

Но, возможно, Delphi уже поддерживает элементы управления без окон , и я просто не понимаю этого? В Delphi уже существует механизм поддержки фокусировки на TControl? Но я достаточно умный парень и уверен, что VCL Delphi не может делать то, что могут делать другие библиотеки виджетов.

Что затем приводит к другому вопросу: сколько будет работы над формами подкласса и такими, чтобы поддерживать его? Есть ли кто-то еще, возможно, кто-то в TeamB, кто намного умнее меня, кто уже попробовал, и пришел к выводу, что невозможно ?

Я сейчас спрашиваю, заранее, если попытка добавить поддержку управления без окон чертовски практически невозможна (т. Е. Бесполезна), так что я не буду тратить на это недели впустую. я пытаюсь использовать знания сообщества разработчиков Delphi.

Я задаю вопрос.

Ответы [ 7 ]

4 голосов
/ 23 февраля 2010

Бесполезно создавать элементы управления без окон и встраивать их в каркас Delphi VCL.

Вы привели Internet Explorer в качестве примера. Но в этом случае он полностью отвечает за все, что находится на нем. У него есть свое внутреннее представление о том, что такое активный контроль, но подумайте о том, как он выглядит со стороны: это всего лишь один гигантский контроль. Когда вы спрашиваете операционную систему о том, что находится в фокусе, у единственного элемента управления браузером он есть, независимо от того, какой из субконтролей браузера выглядит как для фокусировки.

Когда вы нажимаете Tab, ОС выглядит так, как будто браузер просто использует символ табуляции, как это делают элементы управления редактирования. Элементы управления Edit перемещают курсор на несколько пробелов и добавляют символы табуляции к их внутренним буферам; элементы управления браузера перемещают курсор в другую область дисплея.

Вы думаете делать все это на Delphi TForm. Формы Delphi уже имеют структуру для управления активным контролем и обработки нажатий клавиш, и вам придется бороться со всем этим. Если вам нужны элементы управления без окон, перейдите по маршруту Internet Explorer и создайте собственный контейнерный элемент управления , чтобы удерживать их, чтобы вы могли нести ответственность за все, что происходит внутри него.

Ваш контейнер может быть элементом управления VCL, но вещи, которые вы на него надеваете, вероятно, не могут - они по-прежнему будут ожидать использования правил фокусировки и клавиатуры VCL. Заметьте, что вы не можете поместить обычные элементы управления Windows в Internet Explorer. Все, что вы помещаете туда, должно проходить через определенные интерфейсы ActiveX. Может быть, вам тоже понадобятся интерфейсы, или вы можете просто создать свой собственный набор классов управления, которые происходят от какого-то специального класса-предка, который вы разрабатываете, для работы с вашим контейнером. Не начинайте с TGraphicControl; он слишком укоренился в VCL, чтобы его можно было использовать в качестве основы для вашей библиотеки управления ответвлениями.

Будет много работы, но опять же, как и Internet Explorer.

4 голосов
/ 23 февраля 2010

Да, это бесполезно.
И это не вина Дельфи, ты просто сражаешься с самой Windows.
Если вам нужен элемент управления, который ведет себя как оконный элемент управления, используйте оконный.
И вы правы, пытаясь воссоздать весь стек API оконных элементов управления с нуля, это боль.

3 голосов
/ 23 февраля 2010

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

1 голос
/ 27 февраля 2010

fpGUI Toolkit является примером того, что вы хотите. Последний код fpGUI в репозитории исходного кода основан на многооконном дизайне. Это просто означает, что у каждого виджета / компонента есть дескриптор окна, но Windows или Linux ничего не делают с этим окном, кроме обычных уведомлений (mouseenter, mouseexit и т. Д.). fpGUI по-прежнему имеет полный контроль над тем, куда направляется каждый компонент, фокусируются ли они, как они выглядят и т. д. Некоторые виджеты / компоненты в fpGUI также являются компонентами без окон. Например: TfpgScrollbar, TfpgMainMenu, кнопка в ComboBox и т. д.

Если вам нужна настоящая неоконная версия, то есть имеется только одно окно верхнего уровня с дескриптором окна, все остальные виджеты / компоненты внутри этого окна фактически не существуют для ОС (у них нет дескрипторов окна) ), то fpGUI тоже может помочь. Первоначальный дизайн fpGUI Toolkit был основан на таком дизайне. Опять же, посмотрите в хранилище исходного кода ветку кода v0.4. В этом проекте fpGUI должен был обрабатывать абсолютно все, создавать события mouseenter / mouseleave, переводить системы координат для компонентов контейнера, обрабатывать (поддельные) состояния фокуса компонентов и т. Д. Да, первоначальный дизайн - это МНОГО работы, но тогда вы иметь очень переносимый фреймворк, который можно легко применить и к другим ОС.

И да, fpGUI полностью реализован на языке Object Pascal с использованием компилятора Free Pascal для обеспечения кроссплатформенной поддержки. В настоящее время fpGUI работает на устройствах Windows, Linux (32- и 64-разрядных), Windows Mobile и Embedded Linux (ARM).

1 голос
/ 23 февраля 2010

Большинство этих программ, скорее всего, изначально не разрабатывались с использованием инструментов типа RAD, поэтому у них не было другого выбора, кроме как заново изобрести колесо. Одним из самых больших преимуществ Delphi является глубокая поддержка VCL и сторонних компонентов для обеспечения желаемого вида.

Один метод, который я с большим успехом использовал для уменьшения количества оконных дескрипторов, используемых в приложении на основе сложных форм (подготовка налоговых деклараций), заключался в рисовании текста на холсте и перемещении одного потомка TCustomEdit в положение пользователя. редактировал. Было легко захватить клавиши TAB / Up / Down и переместить редактирование в соответствующую позицию. Задача, которую мы обнаружили, заключалась в том, чтобы нарисовать горячий прямоугольник вокруг поля мыши. В итоге мы получили массив сетки TObject, где элементом массива будет nil (без поля), TLIst (сетка содержит несколько полей) или класс, который содержит наш дескриптор поля. Это уменьшило количество проверок диапазона, которые мы должны были выполнить, так как более вероятно, что поле содержит только одно поле или не более 4 полей.

0 голосов
/ 24 февраля 2010

Я думаю fgGUI может помочь вам.

Сначала проверьте Wiki .

Я думаю, вы можете использовать этот фреймворк для своего приложения в Delphi, так как он полностью написан на Pascal. На самом деле он основан на FreePascal;)

НТН

0 голосов
/ 23 февраля 2010

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

У нас есть приложение, которое заполняет дюжину форм. Пользователь может заполнять дополнительные формы, а также изменять значения, которые заполняет само приложение.

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

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

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

...