📄 mouse.cpp
字号:
static HRESULT
InitFail(HWND hWnd, HRESULT hRet, LPCTSTR szError)
{
ReleaseAllObjects();
DestroyWindow(hWnd);
return hRet;
}
//-----------------------------------------------------------------------------
// Name: ReleaseAllObjects()
// Desc: Finished with all objects we use; release them
//-----------------------------------------------------------------------------
static void
ReleaseAllObjects(void)
{
if (g_pDDSOverlay != NULL)
{
// Use UpdateOverlay() with the DDOVER_HIDE flag to remove an overlay
// from the display.
g_pDDSOverlay->UpdateOverlay(NULL, g_pDDSPrimary, NULL, DDOVER_HIDE, NULL);
g_pDDSOverlay->Release();
g_pDDSOverlay = NULL;
}
if (g_pDDSPrimary != NULL)
{
g_pDDSPrimary->Release();
g_pDDSPrimary = NULL;
}
if (g_pDD != NULL)
{
g_pDD->Release();
g_pDD = NULL;
}
}
//-----------------------------------------------------------------------------
// Name: LoadCursorImages()
// Desc: Load the bug resource images into our various flipping surfaces.
//-----------------------------------------------------------------------------
static HRESULT
LoadCursorImages()
{
// HRESULT hRet;
// int CallCount = 0;
// Put the first bug image onto the first buffer of our complex surface.
if (!LoadImageOntoSurface(g_pDDSOverlay, CursorImg))
return (E_FAIL);
// Use the enumeration attachment function to load the other images.
// hRet = g_pDDSOverlay->EnumAttachedSurfaces((LPVOID)&CallCount,EnumSurfacesCallback);
return (DD_OK);
}
//-----------------------------------------------------------------------------
// Function: LoadImageOnToSurface
// Description:
// Loads a resource based bitmap image onto a DirectDraw surface. Can
// covert the bitmap to all RGB formats, plus a couple YUV formats.
//-----------------------------------------------------------------------------
static BOOL
LoadImageOntoSurface(LPDIRECTDRAWSURFACE4 lpdds, LPCTSTR lpstrResID)
{
HBITMAP hbm = NULL;
HDC hdcImage = NULL;
HDC hdcSurf = NULL;
BOOL bRetVal = FALSE;
HRESULT ddrval;
DDSURFACEDESC2 ddsd;
if (!lpdds) return FALSE;
//
// get surface size and format.
//
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
ddrval = lpdds->GetSurfaceDesc(&ddsd);
if (FAILED(ddrval))
goto Exit;
// Load the bitmap resource. We'll use LoadImage() since it'll scale the
// image to fit our surface, and maintain the color information in the
// bitmap.
hbm = (HBITMAP)LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_MOUSE));
if (hbm == NULL)
{
DWORD Errors=GetLastError();
goto Exit;
}
// If our surface is a FOURCC YUV format, we need to do a little work to convert
// our RGB resource bitmap into the appropriate YUV format.
if (ddsd.ddpfPixelFormat.dwFlags == DDPF_FOURCC)
{
if (!CopyBitmapToYUVSurface(lpdds, hbm))
goto Exit;
}
else //Looks like we're just using a standard RGB surface format, let GDI do the work.
{
// Create a DC and associate the bitmap with it.
hdcImage = CreateCompatibleDC(NULL);
SelectObject(hdcImage, hbm);
ddrval = lpdds->GetDC(&hdcSurf);
if (FAILED(ddrval))
goto Exit;
if (BitBlt(hdcSurf, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, 0, 0, SRCCOPY) == FALSE)
goto Exit;
}
bRetVal = TRUE;
Exit:
if (hdcSurf)
lpdds->ReleaseDC(hdcSurf);
if (hdcImage)
DeleteDC(hdcImage);
if (hbm)
DeleteObject(hbm);
return bRetVal;
}
//-----------------------------------------------------------------------------
// Function: CopyBitmapToYUVSurface
// Description:
// Copies an RGB GDI bitmap to a YUV surface. Both bitmap and surface
// must be a multiple of 2 pixels in width for the supported YUV formats.
// The following formats are supported:
// YUYV
// UYVY
//
// The "YUYV" YUV pixel format looks like this:
// As a series of BYTES: [Y0][U][Y1][V] (reverse it for a DWORD)
//
// The "UYVY" YUV pixel format looks like this:
// As a series of BYTES: [U][Y0][V][Y1] (reverse it for a DWORD)
//
// As you can see, both formats pack two pixels into a single DWORD. The
// pixels share U and V components and have separate Y components.
//
// Returns: TRUE if successful, otherwise FALSE.
//-----------------------------------------------------------------------------
static BOOL
CopyBitmapToYUVSurface(LPDIRECTDRAWSURFACE4 lpDDSurf, HBITMAP hbm)
{
HDC hdcImage;
HRESULT ddrval;
DDSURFACEDESC2 ddsd;
DWORD x, y, dwWidth, dwHeight;
LONG lPitch;
LPBYTE pSurf;
DWORD dwBytesInRow;
COLORREF color;
BYTE R,G,B, Y0,Y1,U,V;
BOOL bRet = FALSE;
if (hbm == NULL || lpDDSurf == NULL)
return FALSE;
//
// select bitmap into a memoryDC so we can use it.
//
hdcImage = CreateCompatibleDC(NULL);
SelectObject(hdcImage, hbm);
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
// Lock down the surface so we can modify it's contents.
ddrval=lpDDSurf->Lock( NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT, NULL);
if (FAILED(ddrval))
goto CleanUp;
dwWidth=ddsd.dwWidth;
dwHeight=ddsd.dwHeight;
lPitch=ddsd.lPitch;
pSurf=(LPBYTE)ddsd.lpSurface;
dwBytesInRow=ddsd.dwWidth*2;
// Go through the image 2 pixels at a time and convert to YUV
for(y=0; y<dwHeight; y++)
{
for(x=0; x<dwWidth; x+=2)
{
// The equations for color conversion used here, probably aren't
// exact, but they seem to do an OK job.
color=GetPixel(hdcImage, x,y);
R=GetRValue(color);
G=GetGValue(color);
B=GetBValue(color);
Y0= (BYTE)(0.29*R + 0.59*G + 0.14*B);
U= (BYTE)(128.0 - 0.14*R - 0.29*G + 0.43*B);
color=GetPixel(hdcImage, x+1,y);
R=GetRValue(color);
G=GetGValue(color);
B=GetBValue(color);
Y1= (BYTE)(0.29*R + 0.57*G + 0.14*B);
V= (BYTE)(128.0 + 0.36*R - 0.29*G - 0.07*B);
switch (ddsd.ddpfPixelFormat.dwFourCC)
{
case MAKEFOURCC('Y','U','Y','V'):
*(pSurf++) = Y0;
*(pSurf++) = U;
*(pSurf++) = Y1;
*(pSurf++) = V;
break;
case MAKEFOURCC('U','Y','V','Y'):
*(pSurf++) = U;
*(pSurf++) = Y0;
*(pSurf++) = V;
*(pSurf++) = Y1;
break;
}
}
pSurf+=(lPitch-dwBytesInRow);
}
lpDDSurf->Unlock(NULL);
CleanUp:
if(hdcImage)
DeleteDC(hdcImage);
return TRUE;
}
//-----------------------------------------------------------------------------
// Name: MoveMouse()
// Desc: Called on the timer, this function moves the overlay around the
// screen, periodically calling flip to animate the mosquito.
//-----------------------------------------------------------------------------
static void
MoveMouse(int xPos,int yPos)
{
HRESULT hRet;
// DWORD dwXAligned;
// Add the current velocity vectors to the position.
g_nOverlayXPos = xPos;
g_nOverlayYPos = yPos;
// Check to see if this new position puts the overlay off the edge of the screen.
// SetOverlayPosition() won't like that.
// Have we gone off the left edge?
if (g_nOverlayXPos < 0) {
g_nOverlayXPos = 0;
// g_nOverlayXVel = RANDOM_VELOCITY();
}
// Have we gone off the right edge?
/*
if ((g_nOverlayXPos+g_nOverlayWidth) > GetSystemMetrics(SM_CXSCREEN)){
g_nOverlayXPos = GetSystemMetrics(SM_CXSCREEN) - g_nOverlayWidth;
g_nOverlayXVel = -RANDOM_VELOCITY();
}
*/
// Have we gone off the top edge?
if (g_nOverlayYPos < 0) {
g_nOverlayYPos = 0;
// g_nOverlayYVel = RANDOM_VELOCITY();
}
// Have we gone off the bottom edge?
/*
if ( (g_nOverlayYPos+g_nOverlayHeight) > GetSystemMetrics(SM_CYSCREEN)) {
g_nOverlayYPos = GetSystemMetrics(SM_CYSCREEN) - g_nOverlayHeight;
g_nOverlayYVel = -RANDOM_VELOCITY();
}
// We need to check for any alignment restrictions on the X position.
if (g_dwOverlayXPositionAlignment)
dwXAligned = g_nOverlayXPos - g_nOverlayXPos % g_dwOverlayXPositionAlignment;
else
dwXAligned = g_nOverlayXPos;
*/
// Set the overlay to it's new position.
hRet = g_pDDSOverlay->SetOverlayPosition(g_nOverlayXPos, g_nOverlayYPos);
if (hRet == DDERR_SURFACELOST)
{
if (FAILED(RestoreAllSurfaces()))
return;
}
if (!LoadImageOntoSurface(g_pDDSOverlay, CursorImg))
return ;
// Flip.
/*
while (TRUE)
{
hRet = g_pDDSOverlay->Flip(NULL, 0);
if (hRet == DD_OK)
break;
if (hRet == DDERR_SURFACELOST)
{
hRet = RestoreAllSurfaces();
if (hRet != DD_OK)
break;
}
if (hRet != DDERR_WASSTILLDRAWING)
break;
}
*/
}
//-----------------------------------------------------------------------------
// Name: RestoreAllSurfaces
// Desc: Called in case we lose our surface's vram.
//-----------------------------------------------------------------------------
static HRESULT
RestoreAllSurfaces()
{
HRESULT hRet;
// Try Restoring the primary surface.
hRet = g_pDDSPrimary->Restore();
if (hRet != DD_OK)
return hRet;
// Try Restoring the overlay surface.
hRet = g_pDDSOverlay->Restore();
if (hRet != DD_OK)
return hRet;
// Reload the images.
hRet = LoadCursorImages();
if (hRet != DD_OK)
return hRet;
// Show the overlay.
hRet = g_pDDSOverlay->UpdateOverlay(&rs, g_pDDSPrimary, &rd, DDOVER_SHOW, NULL);
return hRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -