Читаем Графика DirectX в Delphi полностью

xDir : Integer =4; // Текущее приращение координаты X

yDir : Integer =4; // Текущее приращение координаты Y

rcScreen : TRECT; // Позиция окна, используется для оконного режима

rcViewport : TRECT; // Область вывода, 640x480

rcWindow : TRECT; // Структура для хранения позиции окна на экране

flgWindowed : BOOL = False; // Текущий режим работы приложения

Код обработчика создания окна будет вызываться при каждом переключении режима:

procedure TfrmDD.FormCreate(Sender: TObject);

var

hRet : HRESULT;

begin

// Обнуляем все объекты DirectDraw

FDDClipper := nil; // Объект отсечения будет удаляться дважды,

FDDSBack := nil; // можно этого и не выполнять, но для корректности

FDDSPrimary := nil; // первого вызова FormCreate лучше все-таки сделать

FDD := nil;

//В зависимости от режима задаем стиль рамки и видимость курсора

if flgWindowed then begin

BorderStyle := bsSizeable; // Обычный стиль, с областью заголовка

ShowCursor(True);

end

else begin

BorderStyle := bsNone; // Без рамки и области заголовка

ShowCursor(False);

end;

// Создается главный объект DirectDraw

hRet := DirectDrawCreateEx (nil, FDD, IDirectDraw7, nil);

if Failed(hRet) then ErrorOut(hRet, 'DirectDrawCreateEx');

// Инициализация поверхностей

if Failed (InitSurfaces(Handle)) then Close;

FActive := True;

end;

Процедура инициализации поверхностей объединяет в себе оба подхода, изученные нами для полноэкранного и оконного режимов:

function TfrmDD.InitSurfaces(Window : THandle) : HRESULT;

var

hRet : HRESULT;

ddsd : TDDSURFACEDESC2;

ddscaps : TDDSCAPS2;

p : TPoint;

begin

if flgWindowed then begin // Оконный режим

// Получить обычный доступ

hRet := FDD.SetCooperativeLevel(Window, DDSCL_NORMAL);

if Failed(hRet) then begin Result := hRet;

ErrorOut(hRet, 'SetCooperativeLevel');

Exit;

end;

// Получаем размеры области вывода и границы экрана

Windows.GetClientRect(Window, rcViewport);

Windows.GetClientRect(Window, rcScreen);

// Находим позицию клиентской области окна на экране

р.Х := rcScreen.Left;

p.Y := rcScreen.Top;

Windows.ClientToScreen(Window, p);

OffsetRect(rcScreen, p.X, p.Y);

// Создаем первичную поверхность

ZeroMemory(@ddsd, SizeOf(ddsd));

with ddsd do begin

dwSize := SizeOf(ddsd);

dwFlags := DDSD_CAPS;

ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE;

end;

hRet := FDD.CreateSurface(ddsd, FDDSPrimary, nil);

if Failed(hRet) then ErrorOut(hRet, 'CreateSurface FAILED');

// Для оконного приложения создаем объект отсечения

hRet := FDD.CreateClipper(0, FDDClipper, nil);

if Failed(hRet) then ErrorOut(hRet, 'CreateClipper FAILED');

// Ассоциируем отсечение с окном приложения

FDDClipper.SetHWnd(0, Window);

FDDSPrimary.SetClipper(FDDClipper) ;

FDDClipper := nil;

// Создаем поверхность заднего буфера, непосредственного вывода with ddsd do begin

dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS;

dwWidth := 640;

dwHeight := 480;

ddsCaps.dwCaps := DDSCAPS_OFFSCREENPLAIN;

end;

hRet := FDD.CreateSurface(ddsd, FDDSBack, nil);

if Failed(hRet) then ErrorOut(hRet, 'CreateSurface2 FAILED');

end

else begin // Полноэкранный режим

// Задаем режим исключительного доступа

hRet := FDD.SetCooperativeLevel(Window, DDSCL_EXCLUSIVE or

DDSCL_FULLSCREEN);

if Failed(hRet) then ErrorOut(hRet, 'SetCooperativeLevel FAILED')

// Видеорежим 640x480x8

hRet := FDD.SetDisplayMode(640, 480, 8, 0, 0) ;

if Failed(hRet) then ErrorOut(hRet, 'SetDisplayMode FAILED');

// Размер области вывода и границ окна, одинаковые значения

SetRect(rcViewport, О, О, 640, 480);

CopyMemory (OrcScreen, @rcViewport, SizeOf(TRECT));

// Создаем первичную поверхность с одним задним буфером

ZeroMemory(@ddsd, SizeOf(ddsd));

with ddsd do begin

dwSize := SizeOf(ddsd);

dwFlags := DDSD_CAPS or DDSD_BACKBUFFERCOUNT;

ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE or DDSCAPS_FLIP or

DDSCAPS_COMPLEX;

dwBackBufferCount := 1;

end;

hRet := FDD.CreateSurface(ddsd, FDDSPrimary, nil);

if Failed(hRet) then ErrorOut(hRet, 'CreateSurface FAILED');

ZeroMemory(@ddscaps, SizeOf(ddscaps));

ddscaps.dwCaps := DDSCAPS_BACKBUFFER;

hRet : = FDDSPrimary.GetAttachedSurface(ddscaps, FDDSBack);

if Failed(hRet) then ErrorOut(hRet, 'GetAttachedSurface FAILED');

end;

Result := DD_OK;

end;

Как я уже говорил, код, связанный с созданием объектов, вызывается при каждом переключении режима:

procedure TfrmDD.FormKeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

if (Key = VK_RETURN) and (ssAlt in Shift) then begin // Переключение

FActive := False; // На время переключения запрещаем перерисовку

flgWindowed := not flgWindowed; // Меняем значение флага

FormCreate(nil); // Удаляем и заново восстанавливаем объекты end else

if (Key = VK_ESCAPE) or (Key = VK_F12) then Close;

end;

При перерисовке окна отображаем и перемещаем круг, а затем выводим текст подсказки:

function TfrmDD.UpdateFrame : BOOL;

var

ddbltfx : TDDBLTFX; // Для очистки фона

DC : HOC; // Ссылка на контекст, нужна для функций GDI

hOldBrush : HBrush; // Объект фона hOldPen : HPen; // Объект карандаша

begin

// Очистка окна

ZeroMemory(@ddbltfx, SizeOf(ddbltfx));

ddbltfx.dwSize := SizeOf(ddbltfx);

ddbltfx.dwFillColor := 0;

FDDSBack.Bit(nil, nil, nil, DDBLT^COLORFILL or DDBLT_WAIT, @ddbltfx);

// Получение контекста

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных