Entice Designer + Resource Builder

Как и было обещано в предыдущей статье, я расскажу про одно из преимуществ DFL2 — а именно, комфортный дизайнер форм, который называется Entice Designer.

Entice Designer — это небольшая IDE, а также редактор графических интерфейсов для языка программирования D, поддерживающий такие тулкиты как DFL и DWT. Несмотря на то, что эта IDE разработана еще для DFL старой версии, тем не менее, она почти полностью совместима с DFL2 — и это не может нас не радовать (к тому же, это очень интересно в плане работы с GUI).

Сначала установим Entice Designer, скачав его отсюда. Нетрудно заметить, что и сам установочный пакет и сама среда визуальной разработки очень небольшие приложения (так, для справки: Entice Designer сама написана на D с применением тулкита DFL. Помимо этого, в репозитории примеров для DFL2, ссылка на который была в предыдущей статье, множество примеров сделано именно с применением Entice Designer).

Интерфейс Entice очень простой и интуитивно понятный, среда не перегружена лишним функционалом — при открытии программы мы увидим обычную серую стартовую страницу:

entice0_1_o

А теперь создадим небольшой демонстрационный проект: нажмем в ToolBox на стартовой странице кнопочку New… и откроется следующее диалоговое окошко:

entice1_0_o

В этом окошке нас интересует только один пункт — Main Form, позволяющий создать главное окно графического приложения (хотя, если вы интересуетесь Entice Designer как IDE то вероятно, вы захотите выбрать другой пункт — File), хотя дизайнер позволяет создавать и другие типы проектов. После выбора интересующего нас пункта потребуется ввести имя главной формы(Main Form name), имя файла (File name) с формой и место для сохранения всего проекта(Save in), а в пункте Save as нажав кнопочку Browse…, можно выбрать куда сохранится исходник.

После нажатия на кнопку Create получаем две вкладки — вкладка с формой, на которой можно размещать элементы управления (выбираются на панели ToolBox) и настраивать их свойства на панели расположенной справа, в которой отображается иерархия всех размещенных элементов начиная от формы и множество различных параметров под каждый компонент управления:

entice2_0_o

В нашем простейшем демонстрационном проекте мы не будет добавлять элементов управления, а будем работать с рисованием простой математической функции, а потому, следующая вкладка которая интересует нас — это вкладка собственно с кодом, находящаяся справа от вкладки с формой и имеющая то же самое имя, но уже с расширением, присущим файлам с исходным кодом на D:

entice3_0_o

Код для формы генерируется «на лету» и меняется при каждом изменении формы или компонентов на ней. Однако, в этом коде нас устраивает далеко не все — дело в том, что процедура main, которую создает Entice Designer отличается от процедуры main, которая требуется для приложений с DFL2, и потому основную процедуру приложения необходимо заменить на следующий код:

int main()
{
        int result = 0;
 
        try
        {
                // Application initialization code here.
 
                Application.enableVisualStyles();
                Application.run(new <Имя класса главной формы>);
        }
        catch(DflThrowable o)
        {
                msgBox(o.toString(), "Fatal Error", MsgBoxButtons.OK, MsgBoxIcon.ERROR);
 
                result = 1;
        }
 
        return result;
}

Что выглядит для нашего демонстрационного проекта примерно так в редакторе Entice:

entice4_2_o

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

Добавим в демонстрационный проект то, ради чего мы его создали, а именно отрисовку графики: для этого перегрузим метод onPaint и поработаем с графическим объектом Graphics, который по функциональности аналогичен классу Canvas из DGui (также получается из аргументов события PaintEvent — PaintEventArgs), написав вот такой код:

protected override void onPaint(PaintEventArgs ea)
{
		super.onPaint(ea);
		Pen p = new Pen(Color(0, 0, 255), 1);
		
		for (float i = -250; i < 250; i += 0.1)
		{
		   int X = 250 + cast(int) i;
                   int Y = 250 - cast(int) (10 * sin(i / 20.0));
                   ea.graphics.drawLine(p, X, Y, ++X, ++Y);
	        }
		
		
}

В редакторе Entice это выглядит так:

entice9_0_o

После того, как код закончен нужно его откомпилировать в чем нам сам Entice Designer и поможет, для чего в меню Project и выбираем пункт Compile Command, в результате появляется небольшое окно с текстовым полем, в которое нужно ввести команду компиляции (см. предыдущую статью, там команда есть) с точностью до файла(!), так как не предусмотрено никаких переменных, чтобы такую строку определить обобщенно:

entice5_0_o

Жмем кнопку ОК, а после нее нажимаем клавишу F7 или идем в меню Project и выбираем пункт Compile. Все! Компиляция окончена:

entice6_0_o

[accordion][panel intro="Код всего приложения под спойлером."]

/*
	Generated by Entice Designer
	Entice Designer written by Christopher E. Miller
	www.dprogramming.com/entice.php
*/

import dfl.all;
import std.math : sin;



class PolarGraphics: dfl.form.Form
{
	this()
	{
		initializePolarGraphics();
		
		//@  Other PolarGraphics initialization code here.
		
	}
	
	
	private void initializePolarGraphics()
	{
		// Do not manually modify this function.
		//~Entice Designer 0.8.5.02 code begins here.
		//~DFL Form
		text = "Polar Graphics";
		clientSize = dfl.all.Size(484, 461);
		//~Entice Designer 0.8.5.02 code ends here.
	}
	
	protected override void onPaint(PaintEventArgs ea)
	{
		super.onPaint(ea);
		Pen p = new Pen(Color(0, 0, 255), 1);
		
		for (float i = -250; i < 250; i += 0.1)
		{
		   int X = 250 + cast(int) i;
                   int Y = 250 - cast(int) (10 * sin(i / 20.0));
                   ea.graphics.drawLine(p, X, Y, ++X, ++Y);
	        }
		
		
	}
}


int main()
{
	int result = 0;
	
	try
	{
		// Application initialization code here.
		
		Application.enableVisualStyles();
		Application.run(new PolarGraphics);
	}
	catch(DflThrowable o)
	{
		msgBox(o.toString(), "Fatal Error", MsgBoxButtons.OK, MsgBoxIcon.ERROR);
		
		result = 1;
	}
	
	return result;
}

[/panel][/accordion]

Результат компиляции прост как пробка - отображается уже всем надоевшая волна синусоиды:

entice10_0_o

А теперь, после успешного завершения пыток демо-проекта стоит обратить на возможности этой компактной IDE, которая также как и CodeBlocks, позволяет изменить текущую подсветку синтаксиса, добавляя в нее новые ключевые слова:

entice7_0_o

Также, если вас заинтересует разработка графических приложений на DFL2, то вам придется по вкусу, пункт View API доступный из меню Help, который отображает иерархию как стандартной библиотеки D, так и DFL:

entice8_0_o

Оставим пока в покое Entice и рассмотрим программку под названием Resource Builder:

rb0_0_o

Что делает эта программка? Resource Builder - это мощная программа для манипулирования ресурсами программ: иконками приложений, встроенными картинками, файлами-описаниями версий (manifest файлы или файлы манифестов) и прочим.

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

Создаем (или копируем уже существующий) файл иконки для нашего приложения (файл должен быть либо с расширением *.ico, либо с расширением *.png) в папку с исходным кодом приложения, открываем Resource Builder и в панели слева жмем на пункт Icon:

rb1_0_o

Ничего сложного: жмем кнопку Browse и выбираем файл нашей иконки, жмем ОК - и все, иконка добавлена в ресурсный файл.

После этого, отредактируем манифест-файл, для чего на той же самой панели слева, где мы выбирали пункт Icon, выбираем пункт Version Info и заполняем нужные поля:

rb2_0_o

Тут тоже ничего запредельного: CompanyName - имя компании или организации, выпустившей программу; FileVersion - текущая версия файла; FileDescription - краткой описание назначения файла; InternalName - внутренее имя программы для операционной системы; LegalCopyright - владелец или владельцы прав на программу; LegalTrademarks - зарегистрированные торговые марки (нафига это надо нам, непонятно...); OriginalFilename - оригинальное имя файла (имя файла до изменений); ProductName и ProductVersion - соответственно имя продукта и его версия. Кроме того, можно выбрать операционную систему (точнее к какому семейству принадлежит операционная система, для которой написано приложений) и тип файла, но советую эти значения не трогать.
На этом редактирование окончено, нажимаем кнопку Compile и получаем:

rb3_0_oв папке проекта два файла <имя ресурса>.rc и <имя ресурса>.res, а также папку в которой лежат файлы, использованные для получения ресурса.

Вот собственно и все, что нам было нужно от Resource Builder, теперь прикрепим полученный ресурс к самому приложению, для чего откроем исходный код приложения и после секции import вставим следующую строку:

const char* IDI_ICON1 = cast(char*) "ICON_0";

где "ICON_0" - это название-идентификатор для иконки, который можно увидеть (и изменить) при создании ресурса с иконкой, посмотрев поле Resource ID в окне New ICON Resource.

Добавим в конструктор класса(метод this) нашей формы следующий код:

icon = new Icon(LoadIconA(GetModuleHandleA(null), IDI_ICON1));

После этого, внесем изменения в строку компиляции проекта, изменив ее следующим образом:

dmd -de -w -property -release -O -m32 -X -IC:\D\dmd2\windows\import dfl_debug.lib ole32.lib oleAut32.lib gdi32.lib Comctl32.lib Comdlg32.lib advapi32.lib uuid.lib ws2_32.lib -L/SUBSYSTEM:WINDOWS <имя файла приложения.d> <имя файла ресурса.res>

И как результат, получаем приложение с иконкой и описанием( в данном случае, приложение называется polar), доступным, если в контекстном меню для файла выбрать пункт Свойства:

res0_0_o

[accordion][panel intro="И наконец, весь код демонстрационного проекта (спрятано под спойлер)."]

/*
	Generated by Entice Designer
	Entice Designer written by Christopher E. Miller
	www.dprogramming.com/entice.php
*/

import dfl.all;
import std.math : sin;

const char* IDI_ICON1 = cast(char*) "ICON_0";


class PolarGraphics: dfl.form.Form
{
	this()
	{
		initializePolarGraphics();
		
		//@  Other PolarGraphics initialization code here.
		
	}
	
	
	private void initializePolarGraphics()
	{
		// Do not manually modify this function.
		//~Entice Designer 0.8.5.02 code begins here.
		//~DFL Form
                icon = new Icon(LoadIconA(GetModuleHandleA(null), IDI_ICON1));
		text = "Polar Graphics";
		clientSize = dfl.all.Size(484, 461);
		//~Entice Designer 0.8.5.02 code ends here.
	}
	
	protected override void onPaint(PaintEventArgs ea)
	{
		super.onPaint(ea);
		Pen p = new Pen(Color(0, 0, 255), 1);
		
		for (float i = -250; i < 250; i += 0.1)
		{
		   int X = 250 + cast(int) i;
                   int Y = 250 - cast(int) (10 * sin(i / 20.0));
                   ea.graphics.drawLine(p, X, Y, ++X, ++Y);
	        }
		
		
	}
}


int main()
{
	int result = 0;
	
	try
	{
		// Application initialization code here.
		
		Application.enableVisualStyles();
		Application.run(new PolarGraphics);
	}
	catch(DflThrowable o)
	{
		msgBox(o.toString(), "Fatal Error", MsgBoxButtons.OK, MsgBoxIcon.ERROR);
		
		result = 1;
	}
	
	return result;
}

[/panel][/accordion]

Добавить комментарий