Шаг 32 - Создаем внеэкранную (невидимую,OffScreen) поверхность

Здесь многое нам знакомо, создание поверхности, помещение BMP файла на поверхность и так далее. Нам нужно в ресурсы поместить еще одну картинку. Она уже будет в проекте. Давайте создавать поверхность. Мы создадим функцию CreateOffScreen1Surf, которая будет делать все сразу. Создавать поверхность, помещать на нее файл и так далее.

Visual Basic
Visual C++

Visual Basic

Рисунка у нас уже должно быть два в ресурсах.

32_1.gif (1092 b)

Описываем переменную поверхности.

Private OffSrc1 As DirectDrawSurface7

Создаем функцию.

Public Function CreateOffScreen1Surf() As Boolean
On Error GoTo Errors:
Dim offscr1 As DDSURFACEDESC2
offscr1.lFlags = DDSD_CAPS Or DDSD_HEIGHT Or DDSD_WIDTH
offscr1.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
offscr1.lHeight = 240    
offscr1.lWidth = 100    

	Set OffSrc1 = objDirectDraw.CreateSurface(offscr1)
 
	Dim r As RECT
	r.Top = 0
	r.Left = 0
	r.Right = 100
	r.Bottom = 240
	CreateOffScreen1Surf = ImageToSurface(OffSrc1, 102, r, 0, 0)
	Exit Function
Errors:
CreateOffScreen1Surf = False
End Function

Обратите внимание, что немного изменил ImageToSurface для учета растров разных размеров.

Public Function ImageToSurface(sr As DirectDrawSurface7, rID As Long, r As RECT, x As Integer, y As Integer) As Boolean
On Error GoTo Errors:

	DirectDraw.Picture1.Picture = LoadResPicture(rID, vbResBitmap)
    
	a = sr.GetDC
	hCompt = CreateCompatibleDC(a)
	SelectObject hCompt, DirectDraw.Picture1.Picture
	BitBlt a, r.Top, r.Left, r.Right, r.Bottom, hCompt, x, y, SRCCOPY

	sr.ReleaseDC (a)
	Debug.Print DirectDraw.Picture1.Image

	ImageToSurface = True
	Exit Function
Errors:
ImageToSurface = False
End Function

Ну и надо подправить вызов в ClearSurfSecond:

Public Function ClearSurfSecond() As Boolean
.......
Dim r As RECT
	r.Top = 0
	r.Left = 0
	r.Right = 640
	r.Bottom = 480
	ClearSurfSecond = ImageToSurface(SecondarySurf, 101, r, 0, 0)
.......
End Function

Инициализировать первую внеэкранную поверхность мы будем при загрузке формы.

Private Sub Form_Load()
............
If (DirectDrawClass.CreateOffScreen1Surf() = False) Then
End
End If

DirectDrawClass.Flips
End Sub

Visual C++

Рисунка у нас два в ресурсах.

32_2.gif (8876 b)

Объявляем переменную поверхности.

class CDirectDraw  
{
.......
	LPDIRECTDRAWSURFACE offscr1;
.......
};

Создаем функцию:

BOOL CDirectDraw::CreateOffScreen1Surf()
{
	DDSURFACEDESC offscr;
	memset(&offscr,0,sizeof(DDSURFACEDESC));
	offscr.dwSize = sizeof(DDSURFACEDESC);
	offscr.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
	offscr.ddsCaps.dwCaps  = DDSCAPS_OFFSCREENPLAIN;
	offscr.dwHeight = 240;
	offscr.dwWidth = 100;

	if (lpDD->CreateSurface(&offscr,&offscr1,NULL) !=DD_OK)
		return FALSE;

	CRect rect;
	rect.top =0;
	rect.bottom = 240;
	rect.left = 0;
	rect.right = 100;
	return ImageToSurface(offscr1,IDB_BITMAP2,rect,0,0);
}

Обратите внимание, что немного изменил ImageToSurface для учета растров разных размеров.

BOOL CDirectDraw::ImageToSurface(LPDIRECTDRAWSURFACE sr, long rID,CRect rect,int x,int y )
{
	HANDLE hBMP;
	HDC hdc;
	hBMP=LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(rID),
		IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
	if (hBMP == NULL) return FALSE;
	rezult = sr->GetDC(&hdc);
	if(rezult!=DD_OK) return FALSE;
	HDC hCompt = CreateCompatibleDC(hdc);
	SelectObject(hCompt,hBMP);
	BitBlt(hdc, rect.top  ,rect.left ,rect.right,
		rect.bottom, hCompt, 0, 0, SRCCOPY);
	sr->ReleaseDC(hdc);  
	return TRUE;
}

Ну и надо подправить вызов в ClearSurfSecond:

BOOL CDirectDraw::ClearSurfSecond()
{
//memset(&DdsdSecond,0,sizeof(DDSURFACEDESC));
//DdsdSecond.dwSize = sizeof(DDSURFACEDESC);
//if (SecondarySurf->Lock(NULL,&DdsdSecond,DDLOCK_WAIT |
//	DDLOCK_SURFACEMEMORYPTR,NULL)!=DD_OK) return FALSE;
//  char* buf = (char*)DdsdSecond.lpSurface;
//	memset(buf,0,(DdsdSecond.dwHeight * DdsdSecond.dwHeight)); 
//
//if (SecondarySurf->Unlock(NULL)!=DD_OK) return FALSE; 
     
	CRect rect;
	rect.top = 0;
	rect.left = 0;
	rect.right = 640;
	rect.bottom = 480;

	return ImageToSurface(SecondarySurf,IDB_BITMAP1,rect,0,0);
}

Инициализировать первую внеэкранную поверхность мы будем при загрузке диалога.

BOOL CDirectDlg::OnInitDialog()
{
	.....
	if (cDirecDraw.CreateOffScreen1Surf()!=TRUE)
	{
		return FALSE;
	}

	cDirecDraw.Flips(); 
	return TRUE;  // return TRUE  unless you set the focus to a control
}

Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 05.05.2002