Как работает GUI Framework? - PullRequest
7 голосов
/ 24 мая 2010

Я был в Интернете в поисках ответа на этот вопрос, и мой вопрос таков: Как работает GUI Framework? например, как работает Qt, есть ли книги или веб-сайты на тему написания инфраструктуры GUI с нуля? а также должен ли фреймворк вызывать методы из фреймворка GUI операционной системы?

- Спасибо всем, кто нашел время, чтобы попытаться ответить на этот вопрос, и простите меня, если я что-то написал с ошибкой.

Ответы [ 3 ]

5 голосов
/ 24 мая 2010

Структура GUI, такая как Qt, обычно работает, беря примитивные объекты существующей ОС (окна, шрифты, растровые изображения и т. Д.), Заключая их в более нейтральные к платформе и менее неуклюжие классы / структуры / дескрипторы, и предоставляя вам функциональностьВам нужно будет манипулировать ими.Да, это почти всегда подразумевает использование собственных функций ОС, но это НЕ ДОЛЖНО - например, если вы разрабатываете API для отрисовки пользовательского интерфейса OpenGL, большая часть графического интерфейса базовой ОС даже не будет работать,и вы будете делать почти все самостоятельно.

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

4 голосов
/ 18 сентября 2018

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

Сначала вам нужна хорошая библиотека для рисования. Минимальная функциональность для этой библиотеки - рисование обрезанных прямоугольников (с использованием шаблонов), линий, растровых изображений и шрифтов. Вы можете обмануть, создав шрифты в виде растровых изображений, а обрезанный прямоугольник - это просто набор горизонтальных линий.

Теперь вам нужны как минимум драйверы для мыши, клавиатуры и таймера (если они еще не предоставлены операционной системой). В общем, вам нужно будет обнаружить клавиши, символьные клавиши (например, Shift и т. Д.), Движения мыши и щелчки мыши. Основные функции таймера позволят вам обнаружить двойной щелчок.

Затем вам нужно создать структуру данных окна . Эта структура данных должна иметь координаты, то есть прямоугольник, ссылку на родительское окно (если не верхнее окно) и оконную функцию, т.е. функцию, которая будет вызываться, когда это окно должно обрабатывать некоторые события.

Как только вы сможете рисовать на экране, вам понадобятся функции алгебры прямоугольников . Вам нужна хотя бы хорошая функция для вычисления пересечения прямоугольников и быстрое разрешение относительно абсолютных координат . Например - если у вашего дочернего окна есть родитель, тогда его 'x и y должны рекурсивно добавляться к родителю x и y, пока вы не достигнете верхнего окна.

На данный момент у вас есть: - примитивные графические функции, - оконная конструкция, - драйвер мыши, драйвер клавиатуры и таймер, - арифметика прямоугольника.

Теперь вы можете написать свою функцию сбора основного события . Эта функция будет работать постоянно. Его целью будет для обнаружения событий и отправки сообщений в правильные окна . Что такое событие? Хорошо, когда вы запускаете вашу программу, сохраняйте координаты мыши x и y. Затем в цикле проверьте, не изменились ли они. Если они изменились, найдите окно в этой позиции ... и отправьте ему событие WM_MOUSEMOVE. Ваша функция сбора урожая должна обрабатывать: - мышь двигается - щелчки мышью - двойной щелчок мышью (запомните последний щелчок и положение, измерьте время и решите, двойной это щелчок или нет) - таймер событий - изменения буфера клавиатуры ...

Теперь вы должны иметь возможность отправлять события в Windows. Но вам действительно нужен механизм для этого. Это комбинация очереди сообщений и оконной процедуры . Обычно это работает так: каждое окно имеет оконную процедуру, которая обычно принимает четыре аргумента: идентификатор сообщения (то есть движение мыши, сообщение рисования), дескриптор окна, параметр 1 и параметр 2. Вы можете вызвать эту оконную процедуру напрямую, используя что-то вроде функции send_message. Или вы можете отправить этому окну сообщение через функцию post_message. Это поместит сообщение в очередь, и окно будет обрабатывать сообщения одно за другим, в конечном итоге получая это сообщение. Так почему вы должны вызывать одни сообщения напрямую и ставить другие в очередь? Из-за приоритета. Видите ли, щелчок клавиатуры может подождать некоторое время, прежде чем обрабатывается. Но перерисовка окна должна быть завершена немедленно, чтобы предотвратить мерцание и неправильные данные на экране.

Таким образом, ваша функция crop_events отправляет сообщения в окна, используя post_message и send_message. И ваш оконный насос сообщений получает их, используя типичный насос сообщений, подобный этому:

while (pmsg = get_message ()! = NULL) send_message (pmsg-> id, pmsg-> hwnd, pmsg-> p1, pmsg-> p2);

get_message просто получает сообщение из очереди и вызывает отправку сообщения. Просто, да? Ну, не совсем так. Таким образом, вы будете получать только сообщения драйвера в окна, но вам также понадобятся некоторые функции для перерисовки окон , их перемещения и т. Д. При создании функции move_window, resize_window, show_window и Функция hide_window, ваши координаты окна будут меняться. Части других окон будут открыты (если верхнее окно было перемещено или закрыто). Вам необходимо рассчитать, на какие окна влияют изменения координат, и отправить сообщение рисования в эти окна (чтобы перекрасить только те части, которые были обнаружены - помните, у вас есть отсечение функции рисования, так что это будет работать).

Эти функции вводят сообщения msg_paint, msg_move, msg_resize, msg_hide ...

Наконец, вам нужно поддерживать иерархию окон . Ваше верхнее окно должно быть рабочим столом. У него должны быть дочерние окна (верхние окна приложения). Эти окна могут иметь дополнительные дочерние окна (кнопки, поля редактирования и т. Д.). Очевидная структура для их хранения - дерево окон . Когда вы обнаруживаете щелчок мышью, вы должны пройти по дереву окон и сделать это умным способом (выяснить, у кого есть фокус, кто модальный и т. Д.), Чтобы отправить сообщение в нужное окно. И когда вы рисуете, вы также должны пройти через всех детей, чтобы увидеть, кто открыт, а кто нет. И последнее, но не менее важное: вам нужно обрабатывать прямоугольник мыши как верхнее окно, чтобы предотвратить мерцание мыши, когда окна перерисовываются или (с использованием таймеров и событий msg_paint) анимируются.

Это примерно так.

0 голосов
/ 24 мая 2010

Создание структуры GUI - это не процесс 1,2,3.

Все, что я могу сказать, это взглянуть на некоторые из этих IDE с открытым исходным кодом, например, Исходный код Netbeans .

Заглянуть внутрь кода, а затем собратьвся IDE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...