-
DalÜφ program, kter²m se budeme zab²vat je aplikace DirectDraw. Tento program
vy₧aduje nainstalovan² b∞hov² DirectDraw na poΦφtaΦi. To je souΦßstφ
operaΦnφch systΘm∙ Windows 98 a Windows 2000 (NT verze 5.0). Pokud pou₧φvßme
Windows NT 4, musφme mφt nainstalovan² alespo≥ Service Pack 3, kter² obsahuje
DirectDraw 3.0. Zda DirectDraw je na naÜem systΘmu zjistφme jednoduÜe tak,
₧e se podφvßme do adresß°e Windows\System nebo do adresß°e Winnt\System32
zda zde existujφ soubory DDRAW.DLL a DSOUND.DLL.
DirectDraw umo₧≥uje v prost°edφ Windows provßd∞t velmi rychlΘ grafickΘ
operace (umo₧≥uje p°φm² p°φstup do videopam∞ti na grafickΘ kart∞). Pro
dobrΘ v²sledky je vhodnΘ mφt na grafickΘ kart∞ alespo≥ 2 Mslabik pam∞ti.
DirectDraw umo₧≥uje vytvo°it vyrovnßvacφ pam∞¥, kreslit do nφ a pak ji
p°esunout do viditelnΘ oblasti v naÜφ videopam∞ti. Pokud jsme v exklusivnφm
re₧imu a mßme dostatek videopam∞ti k ulo₧enφ jak primßrnφ a zadnφ vrstvy
ve video RAM, pak operace p°epnutφ nenφ kopφrovacφ procedura, ale jednoduchß
zm∞na adresy bloku pam∞ti urΦujφcφ viditelnou oblast pam∞ti grafickΘ karty.
Operace je velmi rychlß a prob∞hne v synchronizaci s obnovovacφ operacφ
naÜeho monitoru. DirectDraw m∙₧eme pou₧φt k provßd∞nφ dokonal²ch animacφ.
K≤d naÜφ aplikace je nejjednoduÜÜφ mo₧n² program DirectDraw. Je to
p°φklad DDX1 z SDK Microsoft DirectDraw, kter² je p°epsßn do prost°edφ
zalo₧enΘm na formulß°i (k≤d pou₧φvß objekt TTimer namφsto volßnφ
SetTimer
a reaguje na udßlosti typu OnKeyDown namφsto p°φmΘho zpracovßnφ
zprßv WM_KEYDOWN; zvyÜuje to Φitelnost programu).
K≤d naÜeho programu mß nßsledujφcφ metody:
-
Konstruktor - provßdφ inicializaci prom∞nn²ch.
-
OnDestroy formulß°e - ruÜφ vrstvy p°φmΘho kreslenφ vytvo°enΘ v metod∞
Start.
-
Start - Volß DirectDrawCreate, kterß inicializuje DirectDraw
a vracφ ukazatel na objekt DirectDraw. Dßle volßme SetCooperativeLevel
pro p°epnutφ do exklusivnφho re₧imu, volßme SetDisplayMode k p°epnutφ
na 8 bitovΘ rozliÜenφ 640 x 480, volßme CreateSurface k vytvo°enφ
primßrnφ vrstvy, volßme GetAttachedSurface k zφskßnφ ukazatele na
zadnφ vrstvu, vybarvφme primßrnφ i zadnφ vrstvu Φernou barvou a umφstφme
na nich text k jejφch rozliÜenφ a povolφme ΦasovaΦ.
-
OnKeyDown formulß°e - reaguje na stisk klßvesy, kterou u₧ivatel
provede p°epnutφ do exklusivnφho re₧imu a zahßjφ demonstraci. Reaguje takΘ
na stisk F12 nebo Esc k ukonΦenφ aplikace.
-
OnPaint formulß°e - zobrazφ text uprost°ed obrazovky. Tato metoda
nenφ volßna, kdy₧ program je v exklusivnφm re₧imu.
-
OnTimer ΦasovaΦe - P°epφnß mezi primßrnφ a zadnφ vrstvou. Toto je
klφΦovß metoda, ve kterΘ je ukßzßno p°epφnßnφ mezi vrstvami, kterΘ provßdφme
p°i animaci. Tato metoda je problematickß, proto₧e pot°ebujeme nejrychlejÜφ
mo₧nΘ p°epφnßnφ. Pro dokonalou animaci pot°ebujeme 25 p°epnutφ za sekundu.
Podφvejme se na nßÜ program. ZaΦneme v²voj novΘ aplikace. Na formulß° vlo₧φme
komponentu Timer. Do deklarace t°φdy formulß°e p°idßme nßsledujφcφ
soukromΘ slo₧ky (je zde i jedna metoda):
LPDIRECTDRAW
lpDD; // objekt
DirectDraw
LPDIRECTDRAWSURFACE
lpDDSPrimary; // primßrnφ vrstva DirectDraw
LPDIRECTDRAWSURFACE
lpDDSBack; // zadnφ vrstva DirectDraw
BOOL
bActive; // je aplikace aktivnφ?
BYTE phase;
AnsiString FrontMsg;
AnsiString BackMsg;
void __fastcall Start();
Nßsleduje v²pis celΘho zdrojovΘho souboru formulß°e. Podφvejte se jak
jsou jednotlivΘ metody naprogramovanΘ a aplikaci vyzkouÜejte.
#include <vcl.h>
#include <ddraw.h>
#pragma hdrstop
#include "Main.h"
#pragma resource "*.dfm"
#define TIMER_ID
1
#define TIMER_RATE
500
TForm1 *Form1;
///////////////////////////////////////
// Konstruktor
///////////////////////////////////////
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
lpDD = NULL;
phase = 0;
bActive = False;
FrontMsg = "Front buffer (F12 or Esc
to quit)";
BackMsg = "Back buffer (F12 or Esc
to quit)";
}
///////////////////////////////////////
// Obsluha OnDestroy formulß°e
///////////////////////////////////////
void __fastcall TForm1::FormDestroy(TObject
*Sender)
{
if(lpDD != NULL)
{
if(lpDDSPrimary != NULL)
{
lpDDSPrimary->Release();
lpDDSPrimary
= NULL;
}
lpDD->Release();
lpDD = NULL;
}
}
///////////////////////////////////////
// Metoda Start
///////////////////////////////////////
void __fastcall TForm1::Start()
{
HRESULT ddrval;
DDSURFACEDESC ddsd;
DDSCAPS ddscaps;
HDC DC;
char buf[256];
ddrval = DirectDrawCreate(NULL, &lpDD,
NULL);
if(ddrval == DD_OK)
{
// zφskßnφ exklusivnφho
re₧imu
ddrval = lpDD->SetCooperativeLevel(Handle,
DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN);
if(ddrval == DD_OK)
{
ddrval = lpDD->SetDisplayMode(640,
480, 8);
if(ddrval
== DD_OK)
{
// vytvo°enφ primßrnφ a zadnφ vrstvy
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
DDSCAPS_FLIP |DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1;
ddrval = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
if(ddrval == DD_OK)
{
// zφskßnφ ukazatele na zadnφ vrstvu
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps,
&lpDDSBack);
if(ddrval == DD_OK)
{
// zobrazenφ textu
if (lpDDSPrimary->GetDC(&DC) == DD_OK)
{
SetBkColor(DC, RGB(0, 0, 255));
SetTextColor(DC, RGB(255, 255, 0));
TextOut(DC, 0, 0, FrontMsg.c_str(), FrontMsg.Length());
lpDDSPrimary->ReleaseDC(DC);
}
if (lpDDSBack->GetDC(&DC) == DD_OK)
{
SetBkColor(DC, RGB(0, 0, 255));
SetTextColor(DC, RGB(255, 255, 0));
TextOut(DC, 0, 0, BackMsg.c_str(), BackMsg.Length());
lpDDSBack->ReleaseDC(DC);
}
// Povolenφ ΦasovaΦe
Timer1->Enabled = True;
bActive = True;
return;
}
}
}
}
}
wsprintf(buf, "Direct Draw Init Failed
(%08lx)\n", ddrval);
MessageBox(Handle, buf, "ERROR", MB_OK);
Close();
}
///////////////////////////////////////
// Obsluha stisku klßvesy
///////////////////////////////////////
void __fastcall TForm1::FormKeyDown(TObject
*Sender, WORD &Key,
TShiftState Shift)
{
switch (Key)
{
case VK_F3:
Start();
break;
case VK_ESCAPE:
case VK_F12:
Close();
break;
}
}
///////////////////////////////////////
// Obsluha OnPaint formulß°e
///////////////////////////////////////
void __fastcall TForm1::FormPaint(TObject
*Sender)
{
RECT rc;
SIZE size;
char szMsg[]="Page Flipping Test:
Press F3 to start, F12 or Esc to exit";
if (!bActive)
{
HDC DC = GetDC(Handle);
rc = GetClientRect();
GetTextExtentPoint(DC,
szMsg, lstrlen(szMsg), &size);
SetBkColor(DC, RGB(0,
0, 0));
SetTextColor(DC, RGB(255,
255, 0));
TextOut(DC, (rc.right
- size.cx)/2, (rc.bottom - size.cy)/2,
szMsg, sizeof(szMsg)-1);
ReleaseDC(Handle, DC);
}
}
///////////////////////////////////////
// Obsluha OnTimer
///////////////////////////////////////
void __fastcall TForm1::Timer1Timer(TObject
*Sender)
{
HDC DC;
if (lpDDSBack->GetDC(&DC) == DD_OK)
{
if(phase)
{
SetBkColor(DC,
RGB(0, 0, 255));
SetTextColor(DC,
RGB(255, 255, 0));
TextOut(DC,
0, 0, FrontMsg.c_str(), FrontMsg.Length());
phase = 0;
}
else
{
SetBkColor(DC,
RGB(0, 0, 255));
SetTextColor(DC,
RGB(0, 255, 255));
TextOut(DC,
0, 0, BackMsg.c_str(), BackMsg.Length());
phase = 1;
}
lpDDSBack->ReleaseDC(DC);
}
while(1)
{
HRESULT ddrval;
ddrval = lpDDSPrimary->Flip(NULL,
0);
if(ddrval == DD_OK) break;
if(ddrval == DDERR_SURFACELOST)
{
ddrval = lpDDSPrimary->Restore();
if(ddrval
!= DD_OK) break;
}
if(ddrval != DDERR_WASSTILLDRAWING)
break;
}
}
V aplikaci jsou p°epφnßny jednotlivΘ vrstvy (obsahujφ pouze text).
-
DalÜφ aplikace se podobß p°edchßzejφcφ. Po obrazovce se v nφ pohybuje zelen²
kruh. ZaΦneme v²voj novΘ aplikace. Formulß° nynφ nechßme prßzdn². Jako
soukromΘ slo₧ky formulß°e nynφ vlo₧φme:
LPDIRECTDRAW
lpDD;
LPDIRECTDRAWSURFACE
lpDDSPrimary;
LPDIRECTDRAWSURFACE
lpDDSBack;
BOOL FActive;
BYTE FPhase;
RECT FShapeRect;
int FValueAdd;
AnsiString FrontMsg;
AnsiString BackMsg;
void __fastcall Start();
MESSAGE void Run(TMessage &Message);
void DrawShape(HDC &DC);
Je zde takΘ provedeno mapovßnφ zprßvy:
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_RUNAPP, TMessage,
Run);
END_MESSAGE_MAP(TForm);
Nßsleduje v²pis zdrojovΘho souboru formulß°e (obsluhy OnDestroy,
OnKeyDown
a
OnPaint
jsou stejnΘ jako v p°edchozφ aplikaci a nejsou zde uvedeny):
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
lpDD = NULL;
FPhase = 0;
FActive = False;
FrontMsg = "Front buffer (F12 or Esc
to quit)";
BackMsg = "Back buffer (F12 or Esc
to quit)";
FShapeRect = Rect(25, 25, 50, 50);
FValueAdd = 2;
}
///////////////////////////////////////
// SpuÜt∞nφ programu
///////////////////////////////////////
void TForm1::Run(TMessage &Message)
{
do {
Timer1Timer(NULL);
Application->ProcessMessages();
} while (FActive);
}
///////////////////////////////////////
// Zprßvy WM_TIMER
///////////////////////////////////////
void __fastcall TForm1::Timer1Timer(TObject
*Sender)
{
HDC DC;
if (lpDDSBack->GetDC(&DC) == DD_OK)
{
DrawShape(DC);
lpDDSBack->ReleaseDC(DC);
}
while(1)
{
HRESULT ddrval;
ddrval = lpDDSPrimary->Flip(NULL,
0);
if(ddrval == DD_OK) break;
if(ddrval == DDERR_SURFACELOST)
{
ddrval = lpDDSPrimary->Restore();
if(ddrval
!= DD_OK)
break;
}
if(ddrval != DDERR_WASSTILLDRAWING)
{
FActive =
False;
Close();
}
}
}
/* Nezapome≥te, ₧e mßme dv∞ vrstvy. Kdy₧
ruÜφme star² obrßzek, musφme
provΘst dv∞ iterace zp∞t a ne
jednu. */
void TForm1::DrawShape(HDC &DC)
{
HBRUSH Brush, OldBrush;
Brush = CreateSolidBrush(RGB(0, 0,
0));
OldBrush = SelectObject(DC, Brush);
Ellipse(DC, FShapeRect.left - FValueAdd,
FShapeRect.top,
FShapeRect.right - FValueAdd,
FShapeRect.bottom);
SelectObject(DC, OldBrush);
DeleteObject(Brush);
FShapeRect.left += FValueAdd;
FShapeRect.right += FValueAdd;
if (FShapeRect.right > 637)
{
FValueAdd = -2;
}
if (FShapeRect.left < 3)
{
FValueAdd = 2;
}
Brush = CreateSolidBrush(RGB(0, 255,
0));
OldBrush = SelectObject(DC, Brush);
Ellipse(DC, FShapeRect.left, FShapeRect.top,
FShapeRect.right, FShapeRect.bottom);
SelectObject(DC, OldBrush);
DeleteObject(Brush);
}
Metoda Start se liÜφ pouze v n∞kolika mßlo °ßdcφch. Namφsto
(na konci obsluhy):
// Povolenφ ΦasovaΦe
Timer1->Enabled = True;
bActive = True;
return;
je zde nynφ:
// Povolenφ ΦasovaΦe
PostMessage(Handle, WM_RUNAPP, 0, 0);
return;
Program vyzkouÜejte.
-
DalÜφ program ukazuje animaci vφce objekt∙ pomocφ DirectDraw. Po p°epnutφ
do exklusivnφho re₧imu je nakresleno n∞kolik barevn²ch objekt∙ (kruh∙ a
Φtverc∙). Ka₧d² tvar se pohybuje po svΘ vlastnφ drßze. Nynφ jsou v programu
dv∞ hlavnφ t°φdy: TDrawShape (reprezentuje jeden tvar zobrazen²
na obrazovce; ka₧dß instance mß mφsto, tvar, sm∞r a barvu - volßnφ metody
Draw
p°esune objekt na dalÜφ mφsto na jeho drßze) a TForm1 (tento objekt
°φdφ b∞h programu; obsahuje objekt TList ve kterΘm jsou ulo₧eny
jednotlivΘ tvary). HlaviΦkov² soubor mß nßsledujφcφ obsah:
#ifndef MainH
#define MainH
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Menus.hpp>
#include <ExtCtrls.hpp>
#define WM_RUNAPP WM_USER
#define CIRCLETYPE 0
#define RECTTYPE 1
class TDrawShape : public TObject
{
private:
int FX;
int FY;
int FX1;
int FY1;
int FMoveValX;
int FMoveValY;
int FShapeType;
RECT FPrevRect, FPrevRect2;
TColor FColor;
RECT __fastcall GetRect(){return Rect(FX,FY,FX1,FY1);}
void __fastcall SetRect(RECT R)
{
FX = R.left; FY = R.top;
FX1 = R.right; FY1 = R.bottom;
}
public:
__fastcall TDrawShape(int ValX, int
ValY)
{ FMoveValX = ValX; FMoveValY
= ValY; }
__fastcall TDrawShape(int ValX, int
ValY, int X, int Y, int AType,
TColor AColor);
void Move();
void Draw(HDC &DC);
__property RECT ShapeRect={read=GetRect,
write=SetRect};
__property int ShapeType={read=FShapeType,
write=FShapeType};
__property TColor Color={read=FColor,
write=FColor};
};
class TForm1 : public TForm
{
__published:
void __fastcall FormDestroy(TObject
*Sender);
void __fastcall FormKeyDown(TObject
*Sender, WORD &Key,
TShiftState Shift);
void __fastcall FormPaint(TObject
*Sender);
private:
LPDIRECTDRAW
lpDD;
LPDIRECTDRAWSURFACE
lpDDSPrimary;
LPDIRECTDRAWSURFACE
lpDDSBack;
BOOL FActive;
BYTE FPhase;
RECT FShapeRect;
TList *FShapeList;
int FValueAdd;
void BuildList();
void DrawShape(HDC &DC);
void PerformAction();
MESSAGE void Run(TMessage &Message);
void __fastcall Start();
public:
__fastcall TForm1(TComponent* Owner);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_RUNAPP, TMessage,
Run);
END_MESSAGE_MAP(TForm);
};
extern TForm1 *Form1;
#endif
Zdrojov² soubor formulß°e obsahuje:
#include <vcl.h>
#include <ddraw.h>
#pragma hdrstop
#include "Main.h"
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TDrawShape::TDrawShape(int ValX,
int ValY, int X, int Y,
int AType, TColor AColor)
{
FMoveValX = ValX;
FMoveValY = ValY;
ShapeRect = Rect(X, Y, X+25, Y+25);
ShapeType = AType;
Color = AColor;
}
void TDrawShape::Move()
{
FPrevRect2 = Rect(FPrevRect.left,
FPrevRect.top, FPrevRect.right, FPrevRect.bottom);
FPrevRect = Rect(FX, FY, FX1, FY1);
FX += FMoveValX;
FY += FMoveValY;
FX1 += FMoveValX;
FY1 += FMoveValY;
if (FX1 > 637) FMoveValX = -2;
if (FX < 3) FMoveValX = 2;
if (FY1 > 477) FMoveValY = - 2;
if (FY < 3) FMoveValY = 2;
}
void TDrawShape::Draw(HDC &DC)
{
HBRUSH Brush, OldBrush;
Brush = CreateSolidBrush(RGB(0, 0,
0));
OldBrush = SelectObject(DC, Brush);
if (FShapeType==CIRCLETYPE)
Ellipse(DC, FPrevRect2.left-1,
FPrevRect2.top-1, FPrevRect2.right+1,
FPrevRect2.bottom+1);
else if (FShapeType == RECTTYPE)
Rectangle(DC, FPrevRect2.left-1,
FPrevRect2.top-1,
FPrevRect2.right+1, FPrevRect2.bottom+1);
SelectObject(DC, OldBrush);
DeleteObject(Brush);
Move();
Brush = CreateSolidBrush(FColor);
OldBrush = SelectObject(DC, Brush);
if (FShapeType==CIRCLETYPE) Ellipse(DC,
FX, FY, FX1, FY1);
else if (FShapeType == RECTTYPE) Rectangle(DC,
FX, FY, FX1, FY1);
SelectObject(DC, OldBrush);
DeleteObject(Brush);
}
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
lpDD = NULL;
FPhase = 0;
FActive = False;
FShapeRect = Rect(25, 25, 50, 50);
FValueAdd = 2;
BuildList();
}
void TForm1::BuildList()
{
FShapeList = new TList();
FShapeList->Add(new TDrawShape(-2,
2, 175, 175, CIRCLETYPE, clLime));
FShapeList->Add(new TDrawShape(2,
2, 125, 125, RECTTYPE, clBlue));
FShapeList->Add(new TDrawShape(2,
-2, 200, 200, RECTTYPE, clYellow));
FShapeList->Add(new TDrawShape(2,
-2, 75, 75, CIRCLETYPE, clRed));
FShapeList->Add(new TDrawShape(-2,
2, 325, 350, RECTTYPE, clPurple));
FShapeList->Add(new TDrawShape(-2,
-2, 275, 250, CIRCLETYPE, clFuchsia));
FShapeList->Add(new TDrawShape(-2,
2, 125, 325, CIRCLETYPE, clTeal));
FShapeList->Add(new TDrawShape(2,
2, 350, 175, RECTTYPE, clNavy));
FShapeList->Add(new TDrawShape(2,
-2, 150, 250, CIRCLETYPE, clOlive));
FShapeList->Add(new TDrawShape(-2,
2, 225, 25, CIRCLETYPE, clSilver));
}
void __fastcall TForm1::FormDestroy(TObject
*Sender)
{
TDrawShape *Shape;
int i;
for (i = 0; i < FShapeList->Count;
i++)
{
Shape = (TDrawShape*)FShapeList->Items[i];
delete Shape;
}
delete FShapeList;
if(lpDD != NULL)
{
if(lpDDSPrimary != NULL)
{
lpDDSPrimary->Release();
lpDDSPrimary
= NULL;
}
lpDD->Release();
lpDD = NULL;
}
}
void __fastcall TForm1::Start()
{
HRESULT ddrval;
DDSURFACEDESC ddsd;
DDSCAPS ddscaps;
char buf[256];
ddrval = DirectDrawCreate(NULL, &lpDD,
NULL);
if(ddrval == DD_OK)
{
ddrval = lpDD->SetCooperativeLevel(Handle,
DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN);
if(ddrval == DD_OK)
{
ddrval = lpDD->SetDisplayMode(640,
480, 8);
if(ddrval
== DD_OK)
{
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
DDSCAPS_FLIP | DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1;
ddrval = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
if(ddrval == DD_OK)
{
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps,
&lpDDSBack);
if(ddrval == DD_OK)
{
PostMessage(Handle, WM_RUNAPP, 0, 0);
return;
}
}
}
}
}
wsprintf(buf, "Direct Draw Init Failed
(%08lx)\n", ddrval);
MessageBox(Handle, buf, "ERROR", MB_OK);
Close();
}
void __fastcall TForm1::FormKeyDown(TObject
*Sender, WORD &Key,
TShiftState Shift)
{
switch (Key)
{
case VK_F3:
FActive
= True;
Start();
break;
case VK_ESCAPE:
case VK_F12:
FActive
= False;
Close();
break;
}
}
void __fastcall TForm1::FormPaint(TObject
*Sender)
{
RECT rc;
SIZE size;
char szMsg[] = "Page Flipping Test:
Press F3 to start, F12 or Esc to exit";
if (!FActive)
{
HDC DC = GetDC(Handle);
rc = GetClientRect();
GetTextExtentPoint(DC,
szMsg, lstrlen(szMsg), &size);
SetBkColor(DC, RGB(0,
0, 0));
SetTextColor(DC, RGB(255,
255, 0));
TextOut(DC, (rc.right
- size.cx)/2, (rc.bottom - size.cy)/2,
szMsg, sizeof(szMsg)-1);
ReleaseDC(Handle, DC);
}
}
void TForm1::Run(TMessage &Message)
{
do {
PerformAction();
Application->ProcessMessages();
} while (FActive);
}
void TForm1::PerformAction()
{
HDC DC;
if (lpDDSBack->GetDC(&DC) == DD_OK)
{
DrawShape(DC);
lpDDSBack->ReleaseDC(DC);
}
while(1)
{
HRESULT ddrval;
ddrval = lpDDSPrimary->Flip(NULL,
0);
if(ddrval == DD_OK) break;
if(ddrval == DDERR_SURFACELOST)
{
ddrval = lpDDSPrimary->Restore();
if(ddrval
!= DD_OK) break;
}
if(ddrval != DDERR_WASSTILLDRAWING)
{
FActive =
False;
Close();
}
}
}
void TForm1::DrawShape(HDC &DC)
{
TDrawShape *Shape;
int i;
for (i = 0; i < FShapeList->Count;
i++)
{
Shape = (TDrawShape*)FShapeList->Items[i];
Shape->Draw(DC);
}
}
Pokuste se pochopit, jak program pracuje a vyzkouÜejte jej.