Главная » C++, C++ Builder » Тестирование  компонента AngleText (повернутый текст) в CBuilder

0

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

Благодаря некоторым вещам, о которых вы уже узнали из этой книги, мы можем это сделать.

Как вы узнали из главы об использовании  VCL, компоненты могут создаваться программистом динамически во время исполнения. Мы можем воспользоваться этим для тестирования визуального представления компонента — того, с чем возникает, обычно, большая часть проблем. Следующий уровень тестирования будет необходим для сынсталлированного компонента, поскольку его интерфейс с Object Inspector стоит проверить.

Для тестирования нашего компонента  мы будем  использовать форму,  показанную на  рис. 14.2. Как вы видите, форма состоит из рамки рисования (paintbox)  и  двух  кнопок.  Кнопку используются для увеличения (>) и уменьшения (<) угла в управляющем элементе AngleText, который мы собираемся расположить на форме.

Рис. 14.2. Форма для тестирования компонента AngleText

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

void __fastcall TForm1::FormCreate(TObject *Sender)

{

pAngleText = new TAngleText(this); pAngleText->Parent = this; pAngleText->Top = PaintBox1->Top; pAngleText->Left = PaintBox1->Left;

pAngleText->Width = PaintBox1->Width;

pAngleText->Height = PaintBox1->Height; pAngleText->Angle = 0;

pAngleText->Font = Font; pAngleText->Color = Color; pAngleText->Text = "Проба пера";

}

Как можно видеть, мы устанавливаем значения свойств, задающих позицию и угол так же, как и Text, Color и Font. Перед тем как двигаться дальше должен  обратить ваше  внимание  на одну деталь, про которую я не упомянул раньше, и которая всплыла только сейчас. Свойство формы Font должно быть выбрано и  установлено в один из шрифтов TrueType (шрифты, перед названиями  которых  стоит  сдвоенная  буква  T),  поскольку  только  эти  шрифты  могут  быть

повернуты.

После того, как все установлено, при запуске формы в поле рамки рисования должна появиться наша строка текста («Проба пера»). Для того, чтобы иметь возможность изменять угол, добавьте два обработчика — для кнопок увеличения и уменьшения угла. Обработчику кнопки увеличения угла (>) должен соответствовать следующий код:

void __fastcall TForm1::IncrementClick(TObject *Sender)

{

// Увеличение на 10 градусов

pAngleText->Angle += 10.0;

}

Как вы можете видеть, поскольку свойство Angle расценивается как переменная-член класса, для ее изменения можно применять даже оператор +=. Остальная часть метода не  представляет особого интереса — в ней просто добавляется 10 градусов к текущему значению угла. Точно так же, с кнопкой уменьшения угла (<) должен быть связан метод DecrementClick, выглядящий следующим образом:

void __fastcall TForm1::DecrementClick(TObject *Sender)

{

// Уменьшение на 10 градусов

pAngleText->Angle += 10.0;

}

Последним шагом написания теста будет добавление экземпляра класса TAngleText в заголовочный файл формы. Добавьте заголовочный файл для TAngleText в заголовочный файл формы, открыв последний (щелкнув правой кнопкой мыши и выбрав Open Source/Header File в появившемся всплывающем меню) и затем выбрав в основном меню пункт File|Include Unit Hdr. Выберите из списка модуль TAngleText, а затем добавьте следующую строку в раздел приватных объявлений заголовочного файла формы:

private: // User declarations TAngleText *pAngleText;

Скомпилируйте и запустите приложение, и вы увидите компонент AngleText, отображенный  в центре формы, примерно как показано на рис. 14.3.

Рис. 14.3. Компонент AngleText во время исполнения теста

Теперь можно начинать тестирование. Нажмите кнопку увеличения угла. Как видите… ничего не произошло. Почему? Здесь кроется наша первая ошибка. Пытаясь найти источник проблемы мы обнаружим, что свойство Angle нашего компонента действительно изменяется (это можно увидеть в отладчике), но управляющий элемент на меняет положения текста. Почему? Хороший способ что-то понять в данной ситуации — это минимизировать окно формы, а потом вернуть его в нормальный размер. Текст внезапно повернется. Следовательно, проблема кроется в том, что компонент не перерисовывается должным образом. Собственно говоря, в данном случае проблема в том, что он вообще никак не перерисовывается.

Можно предложить два решения этой проблемы. Во-первых, мы можем вынудить пользователя перерисовывать компонент при нажатии кнопки. Это приведет к появлению всюду в коде пользователя следующих строк:

pAngleText->Angle += 10.0; pAngleText->Repaint();

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

Для того, чтобы справиться с этой проблемой самостоятельно, нам надо знать, когда изменяется угол, и при его изменении перерисовывать компонент. Метод Write  свойств  компонента вызывается, когда пользователь пытается изменить это свойство. Мы можем изменить компонент так, чтобы он сам перерисовывал себя, когда свойство Angle компонента изменяется. Измените заголовочный файл компонента TAngleText следующим образом:

class TAngleText : public TCustomControl

{

private:

double FAngle; int FXPos;

int FYPos; protected:

virtual void __fastcall Paint(void);

virtual void __fastcall SetXPos(int XPos ); virtual void __fastcall SetYPos(int YPos );  virtual void __fastcall SetAngle(double Angle ); public

    fastcall TAngleText(TComponent* Owner);

__published:

__property double Angle={read=FAngle, write=SetAngle};

__property int XPos={read=FXPos, write=SetXPos};

__property int YPos={read=FYPos, write=SetYPos};

__property Text;

__property Font;

__property Color;

};

А теперь добавьте код и в исходный файл компонента: void __fastcall TAngleText::SetAngle(double Angle)

{

if ( Angle != FAngle )

{

FAngle = Angle; Repaint();

}

}

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

После того, как вы добавите весь приведенный выше код и опять запустите приложение, компонент будет работать как должно, что показано на рис. 14.4. На этом  первая  часть тестирования — тестирование визуального отражения работы компонента, закончена.

Рис. 14.4. Корректно работающий компонент AngleText

Источник: Теллес М. – Borland C++ Builder. Библиотека программиста – 1998

По теме:

  • Комментарии