ПредишенСледващото

Тази книга започва с факта на това, което други книги обикновено приключиха. Ще говорим за основните положения на DirectDraw, но само в общи линии. Reader - опитен програмист, но запознати с DirectDraw - ще бъде в състояние да отиде до скорост. След това преминете към други теми, толкова интересно, колкото е полезно.

Целта на тази книга - да се науча да работя с DirectDraw, вместо да предоставят някои "структурна рамка" или нестандартни API, което ще извърши работата за вас. Демо програми, написани на C ++ и MFC използват, но не за да скриете всички технически подробности. C ++ и MFC - отлични инструменти, тъй като с тяхна помощ, всяко приложение могат да пишат по няколко различни начина. Примери за тази книга е написана така, че в същото време по-структуриран и лесен за четене проекти, които да покажат, че и защо се случва в програмата.

В допълнение DirectDraw, в много случаи се използва DirectInput библиотека. Строго погледнато, при програмирането на графика за Windows, можете да направите, без да е DirectInput, но тя все още е на стойност като се възползват от. Тя работи по-бързо от традиционните средства за Windows аз, и включени в DirectX, така че да се работи с него не изисква никаква допълнителна SDK.

Книга: Графика за Windows инструменти DirectDraw

Инициализиране на DirectDraw

Раздели на тази страница:

(Функция наричаме CreateEx ()) Действителната създаването на прозореца кара Windows да изпратите съобщение на нашата молба WM_CREATE. Клас DirectDrawWin прихваща това съобщение манипулатор OnCreate (). създаден от ClassWizard (вж. Обява 3.1).

Обявата 3.1. Функция DirectDrawWin :: OnCreate ()

вътр DirectDrawWin :: OnCreate (LPCREATESTRUCT) DirectDrawEnumerate (DriverAvailable, това);
IF (totaldrivers == 0) AfxMessageBox ( "Не бяха открити DirectDraw драйвери");
върне 1;
>
Int driverindex = SelectDriver ();
ако (driverindex<0) TRACE("No DirectDraw driver selectedn");
върне 1;
> Иначе ако (driverindex> totaldrivers-1) AfxMessageBox ( "Невалиден DirectDraw шофьор selectedn");
върне 1;
>
LPDIRECTDRAW ddraw1;
DirectDrawCreate (водача [driverindex] .guid, ddraw1, 0);
HRESULT R;
R = ddraw1-> QueryInterface (IID_IDirectDraw2, (невалидни **) ddraw2);
ако (г = S_OK!) AfxMessageBox ( "DirectDraw2 интерфейс не се поддържа");
върне 1;
>
ddraw1-> Release (), ddraw1 = 0;
ddraw2-> SetCooperativeLevel (GetSafeHwnd (), DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX);
ddraw2-> EnumDisplayModes (0, 0, това DisplayModeAvailable);
qsort (displaymode, totaldisplaymodes, sizeof (DisplayModeInfo), CompareModes);
Int initmode = SelectInitialDisplayMode ();
ако (ActivateDisplayMode (initmode) == FALSE) връщане 1;
връщане 0;
>

Всички инициализиране DirectDraw работи във функцията OnCreate () (с подкрепата на редица допълнителни функции). Процесът на инициализация се състои от седем етапа:

• Получаване на списък с всички DirectDraw шофьори.

• Избор на DirectDraw шофьори.

• подготовката за работа на DirectDraw с избрания драйвер.

• Създаване на повърхности за кандидатстване.

Всички тези стъпки са разгледани в следващите раздели.

Първи DirectDraw списък шофьори

DirectDrawEnumerate () функция може да отнеме два аргумента: указател към косвено наричаме функция (обаждане) и указател към данните, определени от приложението, които се предават на тази функция се нарича. В нашия случай, аргументите са имплицитно, наречени функция DriverAvailable () и указател към DirectDrawWin клас (това). функция DriverAvailable () се определя както следва:

BOOL WinAPI DirectDrawWin :: DriverAvailable (LPGUID GUID, LPSTR низходящо, LPSTR име, LPVOID п) DirectDrawWin * победа = (DirectDrawWin *) р;
ако (зимно> totaldrivers> = MAXDRIVERS) върне DDENUMRET_CANCEL;
DriverInfo информация = зимно> водача [зимно> totaldrivers];
ако (GUID) info.guid = (GUID *) новия байт [sizeof (GUID)];
memcpy (info.guid, GUID, sizeof (GUID));
> Друго info.guid = 0;
info.desc = strdup (низходящо);
info.name = strdup (наименование);
зимно> totaldrivers ++;
върнете DDENUMRET_OK;
>

На първо място, указател към данните, определени приложения (р), се превръща в указател към класа DirectDrawWin на (победа). От DriverAvailable на функцията () е декларирана като статично (косвено, наречени функции се изисква да бъде статичен), то за разлика от обичайни функции в клас не са обхванати от правилата на автоматичен достъп; съответно, достъп до променливи и функции, необходими за изпълнение на победата на клас от показалеца.

DirectDraw е DriverAvailable () функция по веднъж за всеки открит шофьор. Всеки път, когато на повикване се прехвърля три информационен обект: GUID, описание и име. GUID (глобално уникален идентификатор) еднозначно идентифицира шофьора. Описание и име са конците за неформална идентификация на шофьора. DriverAvailable () функция съхранява информация за всеки шофьор в масива с името на водача и следи броя на шофьорите в променливите totaldrivers. И накрая, DriverAvailable () връща DDNUMRET_OK. което показва, че прехвърлянето на водачите трябва да се продължи. При получаване на код за връщане DDENUMRET_CANCEL DirectDraw драйвера на спира трансфера.

Избирането на водача

В края на краищата на водача DirectDraw ще бъдат изброени, OnCreate () функция избира един от тях. Избирането на драйвер по подразбиране може да се замени с производните класове чрез виртуална SelectDriver (функция). Ако се върнем към обява 3.1, ние виждаме, че стойността, върната от SelectDriver (). Той се използва като двигател на индекс масив (започвайки от нула и стойността на индекса). Индексът показва GUID (и следователно, на водача) се използва за инициализиране DirectDraw. Версия SelectDriver () от класа DirectDrawWin изглежда така:

виртуална Int SelectDriver () връщане 0;
>

Int bounceWin :: SelectDriver () Int numdrivers = GetNumDrivers ();
ако (numdrivers == 1) връщане 0;
CArray шофьори;
за (INT I = 0; и GetDriverInfo (I, 0 низходящо, име);
drivers.Add (низходящо);
>
диалоговия DriverDialog;
dialog.SetContents (водачи);
ако (dialog.DoModal () = IDOK!) връщане 1;
върне dialog.GetSelection ();
>

Тази функция първо определя броя на откритите драйвери GetNumDrivers () функция. които просто връща стойността на частните променливи totaldrivers. Ако системата се среща само един водач, не е необходимо да се покаже менюто, така че функцията връща 0, да се използва основният двигател.

Класове получени от DirectDrawWin. може да реализира SelectDriver () функция по други начини. Представете тук изпълнението е прост и гъвкав, но може да искате да се инициализира всеки шофьор и проверка за специфични възможности. В някои приложения функция SelectDriver () може да се използва, за да изберете шофьорите, най-добре отговаря на посочените критерии.

Инициализиране на DirectDraw

Третата задача, изпълнява функцията OnCreate (), - инициализиране на DirectDraw. Отново цитирам съответния фрагмент в Обява 3.1:

LPDIRECTDRAW ddraw1;
DirectDrawCreate (водача [driverindex] .guid, ddraw1, 0);
HRESULT R;
R = ddraw1-> QueryInterface (IID_IDirectDraw2, (невалидни **) ddraw2);
ако (г = S_OK!) AfxMessageBox ( "DirectDraw2 интерфейс не се поддържа");
върне 1;
>
ddraw1-> Release (), ddraw1 = 0;
ddraw2-> SetCooperativeLevel (GetSafeHwnd (), DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX);

Инициализация DirectDraw

Фиг. 3.9. диалоговия прозорец за избор на шофьор на

След интерфейса DirectDraw се инициализира, може да се използва за получаване на указател към DirectDraw2 интерфейс. За да направите това, обадете се на функция QueryInterface () и да премине GUID DirectDraw2 интерфейс. определено име IID_IDirectDraw2. Ако QueryInterface на повикване () не успее, програмата показва диалогов прозорец и изходи а. В действителност, ние изискваме от присъствието на DirectX библиотека версия 2 или по-висока (защото DirectDraw2 интерфейс за първи път в DirectX 2). Ако QueryInterface на повикване () е успешно, ddraw1 показалка е освободен. Алтернативно се обадите функции и интерфейси, DirectDraw DirectDraw2 не се препоръчва, така че освобождаването на показалеца на интерфейса DirectDraw гарантира, че останалата част от кода ще бъде използван само DirectDraw2 интерфейс.

HRESULT WinAPI DirectDrawWin :: DisplayModeAvailable (LPDDSURFACEDESC низходящо, LPVOID п) DirectDrawWin * победа = (DirectDrawWin *) р;
инт брои = зимно> totaldisplaymodes;
ако (брои == MAXDISPLAYMODES) връщат DDENUMRET_CANCEL;
зимно> displaymode [брой] .width = desc-> dwWidth;
зимно> displaymode [брой] .height = desc-> dwHeight;
зимно> displaymode [брой] .depth = desc-> ddpfPixelFormat.dwRGBBitCount;
брои ++;
върнете DDENUMRET_OK;
>

виртуална Int SelectInitialDisplayMode () = 0;

Int BounceWin :: SelectInitialDisplayMode () Int I, nummodes = GetNumDisplayModes ();
DWORD т, Н, D;
за (I = 0; и ако (т == desiredwidth з == desiredheight г == desireddepth) замяна;
>
за (I = 0; I> nummodes; и ++) GetDisplayModeDimensions (I, W, Н, D);
ако (г == desireddepth) замяна;
>
връщане 0;
>

На предпоследния етап активира избрания режим. За тази функция цел ActivateDisplayMode (). който всъщност изпълнява задачата на последния етап (създаването на повърхностите на приложение). Кодът на тази функция е показана на Обявата 3.2.

Обявата 3.2. ActivateDisplayMode () функция

Подкрепете проекта - споделете линка, благодаря!