Метод SprGo (Point (X1, Y1), Point (X2, Y2), t); - делает спрайт видимым при движении из одной позиции (X1, Y1) в другую (X2, Y2) в течении того или иного времени (t).
Рассмотрим пример использования спрайтов. На форме расположены 6 спрайтов и 4 кнопки.
В зависимости от нажатия той или иной кнопки происходят события – летит ракета, сверхновая звезда сталкивается с Солнцем и происходит взрыв и т.д.
Листинг программы:
//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#include <math.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma link "MChSpBg"
#pragma link "MChSprt"
#pragma resource "*.dfm"
TForm1 *Form1;
bool CollideFlip,Exploding;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//----------------------------------------------------------------------
void __fastcall NoCollide(TDateTime AtTime)
{
if (CollideFlip) MessageBeep(MB_OK);
CollideFlip=False;
}
//----------------------------------------------------------------------
void __fastcall OnCollide(TMChSprite *SprCollided ,TDateTime AtTime)
{
if (SprCollided==Form1->MChSprite2)
{
// MessageBeep(MB_ICONASTERISK);
if (! CollideFlip)
{
MessageBeep(MB_ICONASTERISK);
CollideFlip=True;
}
if (Form1->MChSprite4->SprNextPos.x<int((Form1->MChSpriteBgr1->ClientWidth)/2))
{
if (Form1->MChSprite4->SprIndex<Form1->MChSprite3->SprIndex)
Form1->MChSpriteBgr1->BgrSprIndexExchangeZ(Form1->MChSprite4->SprIndex,
Form1->MChSprite3->SprIndex);
}
else
{
if (Form1->MChSprite4->SprIndex>Form1->MChSprite3->SprIndex)
Form1->MChSpriteBgr1->BgrSprIndexExchangeZ(Form1->MChSprite4->SprIndex,
Form1->MChSprite3->SprIndex);
}
}
}
//--------------------------------------------------------------------
void __fastcall OnExplosion(TMChSprite *SprCollided ,TDateTime AtTime)
{
if (Exploding)
{
// SprCollided->SprStop;
// SprCollided->SprHide;
}
if ((! Exploding) && (SprCollided==Form1->MChSprite1))
{
Exploding=True;
Form1->MChSprite2->SprColliding=true;
Form1->MChSprite5->SprColliding=true;
Form1->MChSprite6->SprCruise(20);
}
}
//---------------------------------------------------------------------
TPoint __fastcall Sprite6PosFunc(TDateTime AtTime)
{
Form1->MChSprite6->SprSetScale(1.25*(AtTime-Form1->MChSprite6->SprTimeStarted)
*24.0*60.0*60.0*5.0);
// if ((AtTime-Form1->MChSprite6->SprTimeStarted)*24.0*60.0*60.0>17.0)
// Form1->MChSprite6->SprHide;
return(Point(int((Form1->MChSpriteBgr1->ClientWidth)/2),
int((Form1->MChSpriteBgr1->ClientHeight)/2)));
}
//-----------------------------------------------------------------------
TPoint __fastcall Sprite4PosFunc(TDateTime AtTime)
{
double x,y,alpha;
alpha =2*3.14*(AtTime-Form1->MChSprite3->SprTimeStarted)*24.0*60.0+(90.0+0.0)/180.0*3.14;
x= Form1->MChSpriteBgr1->ClientWidth /2.0 +
(Form1->MChSpriteBgr1->ClientWidth /3.0)*cos(alpha);
y= Form1->MChSpriteBgr1->ClientHeight /2.0 +
- (Form1->MChSpriteBgr1->ClientWidth /3.0)*sin(alpha);
Form1->MChSprite4->SprSetScale(1-0.9*sin(alpha));
return(Point(int(x),int(y)));
}
//-----------------------------------------------------------------------
TPoint __fastcall Sprite3PosFunc(TDateTime AtTime)
{
double x,y,alpha;
alpha=-2*3.14*(AtTime-Form1->MChSprite3->SprTimeStarted)*24.0*60.0+(90.0-180.0)/180*3.14;
x= Form1->MChSpriteBgr1->ClientWidth /2.0 +
(Form1->MChSpriteBgr1->ClientWidth /3.0)*cos(alpha);
y= Form1->MChSpriteBgr1->ClientHeight *0.5 +
-(Form1->MChSpriteBgr1->ClientWidth *0.55)*sin(alpha);
if (x>=(Form1->MChSpriteBgr1->ClientWidth)/2)
Form1->MChSprite3->SprSetScaleX( (1-1.0*sin(alpha)));
else Form1->MChSprite3->SprSetScaleX(-(1-1.0*sin(alpha)));
if (y<(Form1->MChSpriteBgr1->ClientHeight)/2)
Form1->MChSprite3->SprSetScaleY( (1-1.0*sin(alpha)));
else Form1->MChSprite2->SprSetScaleY(-(1-1.0*sin(alpha)));
return(Point(int(x),int(y)));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Exploding=false;
MChSprite2->SprShowAt(Point(int((Form1->MChSpriteBgr1->ClientWidth)/2),
int((Form1->MChSpriteBgr1->ClientHeight)/2)));
MChSprite3->SprPosFunc=Sprite3PosFunc;
MChSprite4->SprPosFunc=Sprite4PosFunc;
MChSprite6->SprPosFunc=Sprite6PosFunc;
MChSprite6->SprHideAfter=true;
MChSprite6->SprOnCollide=OnExplosion;
MChSprite4->SprOnCollide=OnCollide;
MChSprite4->SprNoCollide=NoCollide;
MChSprite3->SprCruise(-1);
MChSprite4->SprCruise(-1);
MChSprite6->SprMoveTo(Point(int((Form1->MChSpriteBgr1->ClientWidth)/2),
int((Form1->MChSpriteBgr1->ClientHeight)/2)));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Exploding=false;
MChSprite6->SprSetScale(0.2);
MChSprite6->SprMoveTo(Point(int((Form1->MChSpriteBgr1->ClientWidth)/2),
int((Form1->MChSpriteBgr1->ClientHeight)/2)));
Form1->MChSprite1->SprColliding=true;
Form1->MChSprite6->SprColliding=true;
Form1->MChSprite1->SprGo( Point(Form1->MChSpriteBgr1->ClientWidth,0),
Point(int(Form1->MChSpriteBgr1->ClientWidth/2),
int(Form1->MChSpriteBgr1->ClientHeight/2)), 5 );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
MChSprite5->SprColliding=False;
MChSprite5->SprHideAfter=True;
MChSprite5->SprGo(Point(Form1->MChSpriteBgr1->ClientWidth,
Form1->MChSpriteBgr1->ClientHeight),
Point(0,0), 20);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Exploding=false;
MChSprite1->SprColliding=false;
MChSprite2->SprColliding=false;
MChSprite5->SprColliding=false;
MChSprite6->SprColliding=false;
MChSprite6->SprHide();
MChSprite5->SprHideAfter=true;
MChSprite2->SprShowAt(Point(int((Form1->MChSpriteBgr1->ClientWidth)/2),
int((Form1->MChSpriteBgr1->ClientHeight)/2)));
MChSprite3->SprCruise(-1);
MChSprite4->SprCruise(-1);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
Используя рассмотренный пример, можно изучить практически все свойства спрайтов.
4.11 Объектная технология OLE2
Фирма Microsoft включила в систему Windows 95 подсистему внедрения и связывания объектов. В общем виде OLE2 позволяет пользователю получить доступ к объектам разработанных систем в приложении, с которым он работает. Например, работая в Word, можно вызвать таблицу Excel, обработать определенным образом данные, а результат запомнить в Word. Кроме этого автоматизация OLE2 позволяет программисту включать в свои программы разработанные компоненты, например Word.
Основа OLE2 - Com -компонентная модель объекта (ComponentObjectModel), которая предусматримает модульность и совместитмость во взаимодействии между компонентами, написанными на разных языках. Соm определяет двоичный интерфейс, независимый от языка программирования, который может вступать в коммуникацию с другими компонентами, ничего не зная о них. Объекты, ориентированные на внешнее использование и доступные только из программы называются автоматными объектами OLE. Рассмотрим пример программы, которая вызывает Word, создает новый файл и записывает в Word содержимое компонента Edit.
//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include <OleAuto.hpp> //подключение средств автоматизации OLE
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Variant V;
try {
V = CreateOleObject("Word.Basic");
}
catch(...){
ShowMessage("Не могу запусть Word");
throw;
Close();
}
V.OleProcedure("AppShow");
V.OleProcedure("FileNew");
V.OleProcedure("Insert", Edit1->Text);
}
//---------------------------------------------------------------------------
Рассмотрим как работает програмы.
Прежде всего необходимо указать в программе команду подключения средств, отвечающей за автоматизацию OLE #include <OleAuto.hpp>.
Далее по команде V = CreateOleObject ("Word.Basic"); вызываем Word, делаем приложение видимым по команде V.OleProcedure ("FileNew"); создаем новый документ по команде V.OleProcedure ("FileNew"). Команда V.OleProcedure ("Insert", Edit1->Text); текст из редактора Edit и записывает в Word).
Как видно, в программе используются средства обработки исключений
try {
V = CreateOleObject("Word.Basic");
}
catch(...){
ShowMessage("Не могу запусть Word");
throw;
Close();
которые в случае ошибки закрывают программу.
Кроме рассмотренного примера для автоматизации OLEсуществуют стандартные объекты OCX, которые похожи на визуальные компоненты C++Builder, но на самом деле являются самостоятельными объектами.
Объекты OCX могут быть включены в программу не только на C++Builder, но и Delphi. Но в отличии от компонент C++Builder - они не включаются в код программы, поэтому при распространении программного обеспечения, использующего компоненты OCX необходимо распространять и сами компоненты OCX.
4.12 Библиотеки DLL
DLL (DinamicLinkLibrary) - динамически присоединяемая библиотека, используется для хранения функций и ресурсов отдельно от исполняемого файла. Обычно в программах статистической сборки функции, ресурсы, процедуры и т.д. компонуются в исполняемом файле, использование же DLL позволяет наиболее часто используемые процедуры, функции или ресурсы хранить в DLL и загружать их из DLLпо мере необходимости - это динамическое присоединение.
Обычно DLL не загружается в память пока это не необходимо, но будучи загружена, она делает доступными функции, процедуры или ресурсы для любой программы и для любых языков программирования, которые могут работать с DLL.
Рассмотрим пример создания DLL, коорая кодирует строку. Кодировка происходит путем сдвигов кода символа на еденицу вправо.
Для создания библиотеки SUM.DLL необходимо выполнить шаги:
1.Запустить C++ Builder. и выполнить File|New и выбрать пиктограмму DLL.
2.Набрать код:
//Генерирует C++Builder
#include <vcl\vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
// Important note about DLL memory management:
//
// If your DLL exports any functions that pass String objects (or structs/
// classes containing nested Strings) as parameter or function results,
// you will need to add the library BCBMM.LIB to both the DLL project and any
// EXE projects that use the DLL. This will change the DLL and its calling
// EXE's to use the BCBMM.DLL as their memory manager. In these cases,
// the file BCBMM.DLL should be deployed along with your DLL.
//
// To avoid using BCBMM.DLL, pass string information using "char *" or
// ShortString parameters.
//---------------------------------------------------------------------------
USERES("sum.res");
//---------------------------------------------------------------------------
void ViewForm();
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
return 1;
}
//Набираемыйкод
#include "sum.h"
//---------------------------------------------------------------------------
char FileName[256];
void SayHello()
{
GetModuleFileName( NULL,FileName, sizeof (FileName) );
MessageBox ( NULL, FileName, "Hello from:", MB_OK );
}
int Sum(int a,int b)
{
return a + b;
}
char* Codec(char *eptr)
{
int x,l;
char ch;
l = strlen(eptr);
if(eptr[l-1] != '`') {
for(x=0; x<l;x++) {
ch = eptr[x];
ch = (char)((int)ch + 1);
eptr[x] = ch;
}
eptr[l] = '`';
eptr[l+1] = '\0';
} else {
for(x=0; x<l-1;x++) {
ch = eptr[x];
ch = (char)((int)ch - 1);
eptr[x] = ch;
}
eptr[l-1] = '\0';
}
return eptr;
}
void InvokeYesNoDialog()
{
ViewForm();
}
//---------------------------------------------------------------------
void ViewForm()