Переключение между оконным и полноэкранным режимами

Привет всем кому интересны мои уроки...

Продолжим изучать D3D8 и в данном уроке мы научимся в реальном времени переключаться между оконными и полноэкранными приложениями, зачастую эта возможность очень нужна. В принципе ничего нового для вас здесь не будет. Здесь обобщены некоторые подходы из прошлых уроков и дано решение, как осуществить то, что задумано в теме этого урока.

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


D3DDISPLAYMODE	d3dwindm;

а инициализировать его будем сразу после того как создали D3D8 в функции AppInit() . Самое начало данной функции будет выглядеть следующим образом :


//-----------------------------------------------------------------------------
// Name: AppInit()
// Desc: Initializes Aplication
//-----------------------------------------------------------------------------
bool AppInit (HINSTANCE hThisInst, int nCmdShow)
{
	srand (time(0)); // randomize timer
	p_d3d = Direct3DCreate8 (D3D_SDK_VERSION);
	p_d3d->GetAdapterDisplayMode (D3DADAPTER_DEFAULT, &d3dwindm);

	if(!DialogBox (hThisInst, MAKEINTRESOURCE(IDD_STARTUP), 
			0, (DLGPROC) StartUp_dlg_proc)) return false;
	if(!WindowInit (hThisInst, nCmdShow)) return false;

	//-----------------------------------------------------------------------------

	ZeroMemory (&d3dpp, sizeof(d3dpp));

	if(isFullScreen)
	{
		d3dpp.BackBufferWidth = d3ddm[iModeNum].Width;
		d3dpp.BackBufferHeight = d3ddm[iModeNum].Height;
		d3dpp.BackBufferCount = 3;
		d3dpp.FullScreen_RefreshRateInHz = d3ddm[iModeNum].RefreshRate;
		d3dpp.BackBufferFormat = d3ddm[iModeNum].Format;
	}
	else
	{
		d3dpp.BackBufferFormat = d3dwindm.Format;
	};

	d3dpp.Windowed = !isFullScreen;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;


	//-----------------------------------------------------------------------------

	p_d3d->CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, 
			D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
			&d3dpp, &p_d3d_Device);

.
.
.
.
};

до этого момента у нас информация об текущем разрешении экрана узнавалась лишь перед самой инициализацией оконного D3D8.

Теперь мы можем приступить к реализации задуманного в заголовке урока. Все это я поместил в функцию обработки сообщений главного окна :


case WM_LBUTTONUP:
{
	if(!isFullScreen)
	{
		if(!DialogBox (hInst, MAKEINTRESOURCE(IDD_STARTUP),
				 hWnd, (DLGPROC) StartUp_dlg_proc)) return false;

		ZeroMemory (&d3dpp, sizeof(d3dpp));
		if(isFullScreen)
		{
			SetWindowLong (hWnd, GWL_STYLE, WS_POPUP);
			SetWindowPos (hWnd, 0, 0, 0, d3ddm[iModeNum].Width,	
						d3ddm[iModeNum].Height, 0);
			d3dpp.BackBufferWidth = d3ddm[iModeNum].Width;
			d3dpp.BackBufferHeight = d3ddm[iModeNum].Height;
			d3dpp.BackBufferCount = 3;
			d3dpp.FullScreen_RefreshRateInHz = d3ddm[iModeNum].RefreshRate;
			d3dpp.BackBufferFormat = d3ddm[iModeNum].Format;
		}
		else
		{
			SetWindowLong (hWnd, GWL_STYLE, 
				GetWindowLong(hWnd, GWL_STYLE) |
				 WS_CAPTION | WS_SYSMENU);
			SetWindowPos (hWnd, 0, (d3dwindm.Width-ScreenX)/2, 
						(d3dwindm.Height-ScreenY)/2, 
						ScreenX, ScreenY, 0);
			d3dpp.BackBufferFormat = d3dwindm.Format;
		};

		d3dpp.Windowed = !isFullScreen;
		d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
				
		p_d3d_Device->Reset(&d3dpp); 
		SetDeviceParams ();
	};
};
break;

case WM_KEYDOWN:
{
	if(wParam==VK_ESCAPE)
	if(isFullScreen)
	{
		SetWindowLong (hWnd, GWL_STYLE, 
				GetWindowLong(hWnd, GWL_STYLE) | 
				WS_CAPTION | WS_SYSMENU);
		SetWindowPos (hWnd, 0, (d3dwindm.Width-ScreenX)/2, 
				(d3dwindm.Height-ScreenY)/2, 
				ScreenX, ScreenY, 0);
			
		ZeroMemory (&d3dpp, sizeof(d3dpp));
		d3dpp.BackBufferFormat = d3dwindm.Format;
		d3dpp.Windowed = true;
		d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

		p_d3d_Device->Reset(&d3dpp); 
		SetDeviceParams ();
		isFullScreen = false;
	};
};
break;

Здесь добавляются два обработчика - для нажатия левой кнопки мыши и для нажатия клавиши Escape на клавиатуре.

Если нажали, в оконном режиме, на левую кнопку мыши - то у нас появляется диалоговое окно для выбора, и затем устанавливаются выбранные параметры.

Ранее созданная нами переменная для хранения информации о параметрах видеорежима рабочего стола нужна нам при полноэкранном режиме. Точнее для переключения (при нажатии Escape) обратно в оконный режим.

Первоначально в полноэкранном режиме можно было самому выбрать в каой режим переключаться (использовалось диалоговое окно), но из-за одной проблемы (этот диалог иногда появлялся, а иногда нет, и покопавшись в документации и задав пару вопросов в форумах, оказалось, что в D3D8 при полноэкранном режиме нельзя использовать Windows GDI) пришлось от этого отказаться и просто возвращаться к оконному режиму, где заново можно выбрать режим. Так же работает и переключение с одного полноэкранного режима на другой, но для этого вам необходимо каким либо образом реализовать этот выбор у себя в программе.

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

На данный момент пока все...



Опубликовал admin
28 Окт, Четверг 2004г.



Программирование для чайников.