Урок: диалоговые виджеты. Часть 1


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



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

Подготовка фреймверка

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

  1. Перейдите по ссылке Скачать вверху этой страницы.
    Перейдите на страницу скачивания
  2. Кликните на кнопку скачивания на самой свежей версии фреймверка Nitisa чтобы скачать его.
    Нажмите на кнопку скачивания
  3. Если Вы авторизированны, скачивание начнется сразу же. Если Вы не авторизированны, появится следующее всплывающее окно, в котором можно войти(1), зарегистрироваться(2) или просто скачать фреймверк анонимно(3). Кликните на ссылку Нет, спасибо. Просто скачать чтобы начать скачивание.
    Кликните
  4. Распакуйте скачанный файл в корень диска C:. В действительности Вы можете распаковать его куда угодно, только не забудьте изменить пути соответственно в последующих пояснениях. В скачанном архиве находится папка с названием Nitisa-9.0.0, так что распакованный фреймверк будет в папке C:\Nitisa-9.0.0. Если Вы скачали другой выпуск, то часть названия с версией(9.0.0) будет отличаться.
    Папка с распакованным фреймверком
  5. Откройте файл решения фреймверка, который называется Nitisa.sln(Вы можете видеть его на картинке выше в правой нижней части) в Visual Studio.
  6. Выберите конфигурацию ReleaseRT(1) и платформу x86(2) и скомпилируйте сделав щелчек правой кнопкой мышы на папке Windows решения и кликнув в появившемся меню пункт Build(3). Мы пока будем делать только приложения под Windows. Если хотите, Вы можете собрать все решение, которое так же содержит проекты для платформ Android и Linux. Для платформы Linux Вам так же нужно будет настроить соединение с удаленной машиной Linux(реальной или виртуальной) на которой будет происходить сборка. Так же соответствующие компоненты Visual Studio должны быть установлены.
    Настройка и сборка фреймверка Nitisa
  7. Через несколько минут сборка фреймверка будет завершена и приложение Конструктора Форм (2), который мы будем использовать для создания форм и диалоговых виджетов, будет создано в папке C:\Nitisa-9.0.0\bin\Windows\x86\ReleaseRT (1).
    Файл приложения Конструктора Форм
  8. Измените конфгурацию на Debug и соберите папку Windows решения снова. Через несколько минут сборка будет завершена и файлы библиотек фреймверка будут созданы в папке C:\Nitisa-9.0.0\bin\Windows\x86\Debug.
    Файлы библиотек фреймверка

Здесь мы запускали сборку дважды. Первый раз для создания исполняемого файла Конструктора Форм и второй раз для получения файлов библиотек фреймверка, которые мы линкуем с нашим приложением. Конечно же мы могли не собирать решение второй раз, а просто использовать полученные при первой сборке библиотеки из папки C:\Nitisa-9.0.0\bin\Windows\x86\ReleaseRT. Однако лучше использовать отладочные версии библиотек при создании и отладке Ваших приложений, а уже потом, когда все хорошенько оттестировано, переключиться на финальную сборку и собрать продакшен версию приложения, которое работает с максимальной скоростью и производительностью.

Создание пустого проекта

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

  1. Создайте новый проект Windows Desktop Application(2) из шаблонов Visual C++(1) в Visual Studio. Дайте ему имя DialogBoxApp(3). Мы так же предполагаем, что Ваше решение находится в папке C:\Projects. Если это не так, Вы знаете что делать: просто примите к сведению что Вам нужно поменять все пути соответственно при выполнении следующих шагов.
    Создание проекта
  2. Удалите все файлы и папки из решения(насовсем) и добавьте к решению новый файл исходного кода main.cpp(1). Поместите в этот файл код стандартной функции WinMain(2).
    Добавьте main.cpp
  3. Сделайте щелчек правой кнопкой мышы на имени проекта и кликните на Properties или откройте меню Projects и кликните на Properties там для открытия окна настройки проекта. Выберите VC++ Directories справа(1) и добавьте путь к папке с Nitisa и подпапке Packages внутри в свойство Include Directories как показано на картинке ниже(2). Добавьте так же путь к скомпилированным библиотекам Nitisa в свойство Library Directories(3). Этим шагом мы указали Visual Studio где ей смотреть заголовочные файлы Nitisa и файлы библиотек для линковки с приложением. Мы показали наиболее распространенный способ как это делается: все что нужно - это указать где находится фреймверк, пакеты в нем и его скомпилированные библиотеки(вспомните предидущую главу). При использовании других конфигураций и платформ, Вам просто нужно будет подправить пути к скомпилированным библиотекам в настройках проекта. Все остальное остается без изменений.
    Настройка папок проекта
  4. Перейдите в C/C++ → Code Generation и измените Runtime Library на Multi-threaded Debug (/MTd) как показано ниже. Мы скомпилировали фреймверк в конфигурации Debug в предидущем параграфе. В этой конфигурации используется именно такая Runtime Library. Если Вы скомпилируете фреймверк в конфигурации DebugRT или ReleaseRT, Вам нужно будет использовать настройку Runtime Library Вашего приложения соответственно Multi-threaded Debug DLL(/MDd) или Multi-threaded DLL (/MD). То есть настройка Runtime Library Вашего приложения должа быть такой же как эта же настройка с котрой скомпилированы библиотеки Nitisa.
    Изменение Runtime Library
  5. Перейдите в C/C++ → Language и удалите значение из Conformance mode. Изменение этой настройки не обязательно и не относится к фреймверку, однако из-за нее могут возникнуть ошибки на этапе компиляции в некоторых заголовочных файлах Windows, если оставить значение этой настройки по умолчанию.
    Очистка Conformance mode
  6. Перейдите в C/C++ → Precompiled Headers и измените настройку Precompiled Header на Not Using Precompiled Headers. Так же очистите значение настройки Precompiled Header File. Вы, конечно же, можете захотеть использовать предкомпилировапнные заголовки и это нормально и это будет отлично работать с фреймверком Nitisa. Мы не используем их здесь для упрощения.
    Отключение использования предкомпилированного заголовка
  7. Примените изменения и закройте интерфейс настройки проекта. Настройка завершена. Вы даже можете скомпилировать проект и проверить нет ли на данном этапе никаких ошибок. Если Вы сделали все как описано выше, то проект скомпилируется и слинкуется успешно и Вы сможете найти исполняемый файл Вашего приложения DialogBoxApp.exe в папке C:\Projects\DialogBoxApp\Debug.
    Исполняемый файл пустого приложения

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

Использование виджетов в режиме диалоговых виджетов

Некоторые существующие виджеты, как Вы уже могли заметить, показывают диалоговые формы для получения данных от пользователя. Например, FindDialog показывает форму для поиска текста, виджет SysOpenDialog показывает форму для выбора файла, и так далее. Некоторые из таких виджетов могут работать как в режиме обычных форм так и в режиме диалоговых виджетов. Режим формы у них используется по умолчанию. Один их таких виджетов это виджет ColorDialog, который используется для показа интерфейса выбора цвета. Давайте сначала посмотрим как его использовать по умолчанию.

  1. Откройте Конструктор Форм. Как Вы наверное помните из предидущей главы, это файл C:\Nitisa-9.0.0\bin\Windows\x86\ReleaseRT\FormBuilder.exe
  2. Разместите виджет Button на форме.
  3. Установите Caption кнопки в Select color....
  4. Сделайте двойной клик на событии OnClick кнопки чтобы сгенерировать имя события.
  5. Разместите виджет ColorDialog со вкладки Dialogs на форме.
  6. Установите Name формы в FormMain
  7. Разместите виджет Panel(панель) на форме.
  8. Устновите свойство Caption панели в пустую строку.
  9. Вы так же можете передвигать и изменять размер кнопки, панели и формы для того, чтобы все выглядело красивее, например, как показано на картинке ниже.
  10. Сохраните форму в папку с Вашим проектом в файл FormMain.nfr. Когда мы сохраняем форму в Конструкторе Форм, он так же генерирует заголовочный файл с классом прототипом формы с названием I + имя формы + .h. В нашем случае файл будет называться IFormMain.h.
Тестовая форма для виджета ColorDialog

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

Теперь перейдите в Visual Studio с пустым проектом, который мы создали ранее, и сделайте следующее:

  1. Добавьте новый заголовочный файл с именем FormMain.h в проект и поместите в него следующее содержимое. Это заголовочный файл с объявлением нашей формы. Мы добавили множество коментариев в него, так что Вы легко сможете понять значение каждой строчки.
    #pragma once
    
    // Подключение файла с прототипом формы, который был сгенерирован Конструктором Форм, когда мы сохранили форму 
    #include "IFormMain.h"
    
    // Так как мы разрабатываем с помощью фреймверка Nitisa, мы можем просто разместить все в этом пространстве имен для избежания добавления везде "using namespace nitisa" 
    namespace nitisa
    {
        // По умолчанию Конструктор Форм генерирует класс прототипа формы в этом пространстве имен. Так что мы так же разместим финальный класс формы в нем 
        namespace app
        {
            // Это наш класс формы, который необходимо наследовать от класса прототипа формы сгенерированного когда мы сохранили форму в Конструкторе Форм 
            class CFormMain :public IFormMain
            {
            protected:
                // Здесь находятся методы, которые будут вызываться при наступлении различных событий. Мы добавили один, когда сделали двойной клик на событии "OnClick" кнопки. 
                // Если на Вашей форме много элементов, то легко забыть о каких-то из них. Мы рекомендуем просто открыть заголовочный файл с прототипом формы, найти там секцию "protected", и увидеть все методы, которые Вам нужны. 
                void Button1_OnClick(IControl *sender) override;
            public:
                // Конструктор формы 
                CFormMain();
            };
    
            // Переменная, в которой будем хранить экземпляр формы 
            extern CFormMain *FormMain;
        }
    }
    
  2. Добавьте новый файл исходного кода в проект и назовите его FormMain.cpp. Поместите в него следующее содержимое. Этот файл содержит реализацию методов нашей формы, которые мы объявили в заголовочном файле. В этом файле так же находится множество коментариев для лучшего понимания того что там происходит.
    // Подключение заголовочного файла с классом окна для нашей платформы 
    #include "Platform/Core/Window.h"
    
    // Подключение заголовочного файла с OpenGL рендером для нашей платформы 
    #include "Platform/Core/Renderer.h"
    
    // Подключение объявления нашей формы 
    #include "FormMain.h"
    
    namespace nitisa
    {
        namespace app
        {
            // Глобальная переменная для экземпляра формы. Будем использовать ее позже 
            CFormMain *FormMain{ nullptr };
    
            // Конструктор формы 
            CFormMain::CFormMain() :
                // Вызов конструктора родительского класса. Ему нужно передать объекты платформенного окна и рендера 
                IFormMain(CWindow::Create(), CRenderer::Create())
            {
                // Нам здесь не нужно ничего делать 
                // Вся настройка и создание UI(интерфейса пользователя) сделаны в классе IFormMain, сгенерированном Конструктором Форм 
            }
    
            // Метод, который вызывается когда пользователь кликает на кнопке 
            void CFormMain::Button1_OnClick(IControl *sender)
            {
                // Показываем интерфейс выбора цвета. Метод возвращает "true" если пользователь потвердждает выбор цвета 
                if (m_pColorDialog1->Execute())
                    // Если пользователь потвердил выбранный цвет, то устанавливаем цвет фона панели в этот цвет 
                    m_pPanel1->setBackgroundColor(m_pColorDialog1->getColor());
            }
        }
    }
  3. Отредактируйте файл main.cpp чтобы он был таким как ниже. Это стандартная часть для всех приложений созданных с помощью фреймверка Nitisa.
    #include <Windows.h>
    
    // Подключение файла с менеджером приложения для нашей платформы 
    #include "Platform/Core/Application.h"
    
    // Подключение файла с объявлением нашей формы 
    #include "FormMain.h"
    
    // Указываем линковщику, что мы хотим слинковать приложение с библиотекой ядра фреймверка. Обязательно 
    #pragma comment(lib, "Nitisa.lib")
    
    // Указываем линковщику, что мы хотим слинковать приложение с библиотекой Стандартного(Standard) пакета так как мы используем виджеты из этого пакета 
    // При использовании виджетов на форме из какого-нибудь пакета, нужно слинковать приложение с библиотекой этого пакета 
    // Библиотеки для линковки так же можно указать в настройках проекта, однако мы предпочитаем этот способ, так как он более нагляден 
    #pragma comment(lib, "Standard.lib")
            
    // Указываем линковщику, что мы хотим слинковать приложение с библиотекой с платформо-зависимым кодом. Обязательно в большинстве случаев 
    #pragma comment(lib, "Platform.lib")
            
    #pragma comment(lib, "opengl32.lib") // Линкуем с библиотекой OpenGL 
    
    int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR, INT)
    {
        nitisa::CApplication app; // Создание приложения 
        app.CreateForm(&nitisa::app::FormMain); // Создаем нашу форму. Наличие переменной для нее делает возможным использование "CreateForm", однако форма так же может быть создана как обычно с помощью оператора "new" 
        app.setMainForm(nitisa::app::FormMain); // Указываем приложению, что форма является главной формой приложения 
        app.Run(); // Запуск приложения 
        return 0;
    }
  4. Теперь можно скомпилировать(собрать) и запустить приложение. Если Вы кликните на кнопке Select color..., появится интерфейс для выбора цвета и если Вы кликните на кнопке OK, то цвет панели поменяется на выбранный.
    ColorDialog в виде обычной формы

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

  1. Переключитесь на приложение Конструктор Форм, где все еще открыта наша форма или откройте Конструктор Форм снова и откройте форму в нем, если Вы его закрыли. Измените виджету ColorDialog свойство UseDialogBox на true и сохраните форму. Вы по прежнему сможете собрать и запустить приложение без каких-либо изменений в коде, однако, если Вы его запустите, то сразу же заметите изменения.
    ColorDialog в виде диалогового виджета

Предже всего интерфейс выбора цвета выглядит немного по другому теперь. В режиме диалогового виджета он использует диалоговый виджет в качестве базового класса, а не форму. Виджет для этих целей называется DialogBoxEx. Он является частью Стандартного(Standard) пакета. Внешний вид этого виджета отличается от внешнего вида формы по умолчанию. Это объясняет немного другой внешний вид. Вы также можете использовать этот виджет в качестве базового класса для разработки Ваших собственных диалоговых виджетов или использовать другие доступные.

Следующее отличие заключается в том, что метод Execute() виджета ColorDialog возвращает true сразу же, а не ждет пока пользователь подтвердит выбор цвета. Вы можете заметить это по изменению цвета панели на черный, который является цветом по умолчанию виджета ColorDialog. И теперь, когда пользователь подтверждает выбор цвета, цвет панели не меняется. Вскоре мы объясним как это исправить.

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

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

Давайте теперь посмотрим как исправить подтверждение выбора цвета. У диалоговых виджетов, так же как у форм, есть методы Show() и ShowModal(). Первый работает у обоих одинаково. Второй же в случае формы ждет пока форма не закроется и результат вызова метода соответствует результату с которым закрыли форму, однако в диалоговых виджетах он возвращает управление обратно сразу же. Виджет ColorDialog использует Color Form. В обычном режиме это обычная форма, в то время как в режиме диалогового виджета она, соответственно, реализована как диалоговый виджет. Метод Execute() виджета ColorDialog просто использует метод ShowModal() этой формы и, таким образом, он возвращает управление обратно сразу же в режиме диалоговых виджетов, абсолютно так же как метод ShowModal(). Для получения информации о том, что пользователь подтвердил выбор цвета нужно использовать слушателя. Давайте посмотрим как его добавить и использовать.

  1. Добавьте объявление следующего класса в private секцию класса CFormMain в файле FormMain.h. Этим действием мы объявили класс для слушателя.
    // Этот маленький класс реализует слушателя, который используется для получения уведомлений о подтверждении выбора цвета пользователем 
    // Класс должен реализовать интерфейс IColorDialogListener. Так что он должен его наследовать 
    class CColorDialogListener :public virtual standard::IColorDialogListener
    {
    private:
        // В этом члене будет храниться указатель на нашу форму 
        CFormMain *m_pForm;
    public:
        // У слушателя есть только один метод, который вызывается, когда пользователь подтверждает выбор цвета, и мы используем его для обновления цвета панели 
        void OnApply(standard::IColorDialog *sender) override;
    
        // Конструктор 
        CColorDialogListener(CFormMain *form);
    };
  2. Добавьте также строчку кода CColorDialogListener m_cColorDialogListener; в private секцию класса формы сразу после объявления класса слушателя.
  3. Измените файл FormMain.cpp следующим образом. Здесь мы просто добавили реализацию методов класса слушателя, вызов конструктора слушателя в конструкторе формы, присоединение слушателя к виджету ColorDialog и немного изменили код события кнопки.
    // Подключение заголовочного файла с классом окна для нашей платформы 
    #include "Platform/Core/Window.h"
    
    // Подключение заголовочного файла с OpenGL рендером для нашей платформы 
    #include "Platform/Core/Renderer.h"
            
    // Подключение объявления нашей формы 
    #include "FormMain.h"
    
    namespace nitisa
    {
        namespace app
        {
            // Глобальная переменная для экземпляра формы. Будем использовать ее позже 
            CFormMain *FormMain{ nullptr };
    
            // В конструкторе мы просто сохраняем указатель на форму 
            CFormMain::CColorDialogListener::CColorDialogListener(CFormMain *form) :
                m_pForm{ form }
            {
    
            }
    
            // При подтверждении выбора цвета мы обновляем цвет панели 
            void CFormMain::CColorDialogListener::OnApply(standard::IColorDialog *sender)
            {
                m_pForm->m_pPanel1->setBackgroundColor(m_pForm->m_pColorDialog1->getColor());
            }
    
            // Конструктор формы 
            CFormMain::CFormMain() :
                // Вызов конструктора родительского класса. Ему нужно передать объекты платформенного окна и рендера 
                IFormMain(CWindow::Create(), CRenderer::Create()),
                // Создание слушателя и передача ему указателя на эту форму 
                m_cColorDialogListener{ this }
            {
                // Нам здесь не нужно ничего делать 
                // Вся настройка и создание UI(интерфейса пользователя) сделаны в классе IFormMain, сгенерированном Конструктором Форм 
    
                // Устанавливаем слушателя ColorDialog 
                m_pColorDialog1->setListener(&m_cColorDialogListener);
            }
    
            // Метод, который вызывается когда пользователь кликает на кнопке 
            void CFormMain::Button1_OnClick(IControl *sender)
            {
                // Показываем интерфейс выбора цвета 
                m_pColorDialog1->Execute();
            }
        }
    }
  4. Скомпилируйте и запустите приложение. Теперь Вы можете увидеть, что мы добились правильного поведения, когда пользователь подтверждает выбор цвета и цвет панели больше не меняется сразу же после клика на кнопке.

Вот так вот мы можем обработать подтверждение выбора цвета в режме диалоговых виджетов виджета ColorDialog. Между прочим, это изменение кода так же будет работать и в случае, если изменить свойство UseDialogBox на false снова.

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

  1. Добавьте следующее подключение заголовочного файла в файл FormMain.cpp сразу после подключения заголовочного файла с рендером. Этой строкой мы подключили объявление диалогового виджета выбора цвета, который используется виджетом ColorDialog, к нашему файлу.
    #include "Standard/Forms/Color/DialogBoxColor.h"
  2. Добавьте следующие две строки кода в метод Button1_OnClick формы сразу после показа интерфейса выбора цвета методом Execute(). Первая строка устанавливает нужный цвет фона диалогового виджета с интерфейсом выбора цвета, а вторая просто устанавливает ему нужный размер и положение.
    m_pColorDialog1->getDialogBox()->setBackgroundColor(getBackgroundColor());
    m_pColorDialog1->getDialogBox()->AutoResize(true);

Если Вы запустите приложение и кликните на кнопке Select color..., Вы увидите изменения. Цвет фона интерфейса выбора цвета теперь такой же как и у главной формы, а его расстояния у границ одинаковые со всех сторон.

ColorDialog в виде диалогового виджета, финальная версия

! Единственное важное замечание, которое можно здесь сделать - это то, что в целях оптимизации диалоговое окно виджета ColorDialog, и всех виджетов, которые используют диалоговые окна, может быть недоступно до тех пор, пока не будет затребовано его отображение. Вот почему мы получаем к нему доступ и изменяем его свойства, а так же вызываем методы, только после вызова Execute() из ColorDialog, а не до.

И последнее улучшение здесь, которое мы хотели бы показать, это проверка того находится ли ColorDialog в режиме диалогового виджета или нет перед получением доступа к его диалоговому виджету, а так же проверка что метод Execute() вызвался успешно. Это последнее улучшение делает нашу простую форму полностью совместимой с обоими режимами: как с режимом диалоговых виджетов, так и с режимом обычных форм. Это так же делает наш код универсальным, что значит что в нем не требуется делать никаких изменений при смене режима. Все что требуется при таком изменении это компиляция проекта и все. Вы так же можете увидеть, что мы добавили булевский член класса m_bDialogBoxAdjusted (установленный в false в конструкторе формы) для предотвращения подстройки диалогового виджета каждый раз, когда пользователь кликает на кнопке Select color.... Это просто оптимизация, так как после первой подстройки диалогового виджета он остается в правильном состоянии и последующая подстройка не требуется.

// Метод, который вызывается когда пользователь кликает на кнопке 
void CFormMain::Button1_OnClick(IControl *sender)
{
    // Показываем интерфейс выбора цвета и подстраиваем диалоговый виджет при необходимости и если это режим диалоговых виджетов 
    if (m_pColorDialog1->Execute() && m_pColorDialog1->isUseDialogBox() && !m_bDialogBoxAdjusted)
    {
        // Устанавливаем цвет фона диалогового виджета в тот же цвет, что у нашей формы 
        m_pColorDialog1->getDialogBox()->setBackgroundColor(getBackgroundColor());
        // Автоматически подстраиваем размер и положение диалогового виджета 
        m_pColorDialog1->getDialogBox()->AutoResize(true);
        // Устанавливаем флаг, чтобы не менять положение и размер диалогового виджета каждый раз, когда показываем интерфейс выбора цвета 
        m_bDialogBoxAdjusted = true;
    }
}

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

Вы можете найти исходный код проекта, который мы только что завершили, в папке Windows → Tutorials → DialogBox решения Nitisa. Проект называется TestColorDialog.


Если Вам нравится проект Nitisa Вы можете поддержать нас небольшим пожертвованием или выбрать использование одного из платных планов для поддержки дальнейшей разработки проекта.