656 lines
21 KiB
C++
656 lines
21 KiB
C++
|
/****************************************************************************
|
||
|
*
|
||
|
* File: testdd.cpp
|
||
|
* Project: DxDiag (DirectX Diagnostic Tool)
|
||
|
* Author: Mike Anderson (manders@microsoft.com)
|
||
|
* Purpose: Test DirectDraw functionality on this machine
|
||
|
*
|
||
|
* (C) Copyright 1998 Microsoft Corp. All rights reserved.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
#include <Windows.h>
|
||
|
#define DIRECTDRAW_VERSION 5 // run on DX5 and later versions
|
||
|
#include <ddraw.h>
|
||
|
#include "reginfo.h"
|
||
|
#include "sysinfo.h"
|
||
|
#include "dispinfo.h"
|
||
|
#include "testdd.h"
|
||
|
#include "resource.h"
|
||
|
|
||
|
#ifndef ReleasePpo
|
||
|
#define ReleasePpo(ppo) \
|
||
|
if (*(ppo) != NULL) \
|
||
|
{ \
|
||
|
(*(ppo))->Release(); \
|
||
|
*(ppo) = NULL; \
|
||
|
} \
|
||
|
else (VOID)0
|
||
|
#endif
|
||
|
|
||
|
enum TESTID
|
||
|
{
|
||
|
TESTID_LOAD_DDRAW_DLL= 1,
|
||
|
TESTID_GET_DIRECTDRAWCREATE,
|
||
|
TESTID_DIRECTDRAWCREATE,
|
||
|
TESTID_GETCAPS,
|
||
|
TESTID_USER_VERIFY_RECTANGLES,
|
||
|
TESTID_USER_VERIFY_WINDOW_BOUNCE,
|
||
|
TESTID_USER_VERIFY_FULLSCREEN_BOUNCE,
|
||
|
TESTID_SETCOOPERATIVELEVEL_NORMAL,
|
||
|
TESTID_CREATEPRIMARYSURFACE,
|
||
|
TESTID_GETPRIMARYSURFACEDESC,
|
||
|
TESTID_COLORFILL_BLT_TO_PRIMARY,
|
||
|
TESTID_CREATE_OFFSCREENPLAIN_SURFACE,
|
||
|
TESTID_COLORFILL_BLT_TO_OFFSCREENPLAIN,
|
||
|
TESTID_BLT_OFFSCREENPLAIN_TO_FRONT,
|
||
|
TESTID_CREATE_TEST_WINDOW,
|
||
|
TESTID_SETCOOPERATIVELEVEL_FULLSCREEN,
|
||
|
TESTID_SETDISPLAYMODE,
|
||
|
TESTID_CREATEPRIMARYSURFACE_FLIP_ONEBACK,
|
||
|
TESTID_GETATTACHEDSURFACE,
|
||
|
TESTID_COLORFILL_TO_BACKBUFFER,
|
||
|
TESTID_FLIP,
|
||
|
};
|
||
|
|
||
|
typedef HRESULT (WINAPI* LPDIRECTDRAWCREATE)(GUID FAR *lpGUID,
|
||
|
LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter);
|
||
|
|
||
|
|
||
|
BOOL BTranslateError(HRESULT hr, TCHAR* psz, BOOL bEnglish = FALSE); // from main.cpp (yuck)
|
||
|
|
||
|
|
||
|
static HRESULT TestPrimary(HWND hwndMain, LPDIRECTDRAW pdd, LONG* piStepThatFailed);
|
||
|
static HRESULT TestPrimaryBlt(HWND hwndMain, LPDIRECTDRAW pdd, LONG* piStepThatFailed);
|
||
|
static HRESULT TestFullscreen(HWND hwndMain, LPDIRECTDRAW pdd, LONG* piStepThatFailed);
|
||
|
static HRESULT CreateTestWindow(HWND hwndMain, HWND* phwnd);
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* TestDD
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
VOID TestDD(HWND hwndMain, DisplayInfo* pDisplayInfo)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
TCHAR szPath[MAX_PATH];
|
||
|
HINSTANCE hInstDDraw = NULL;
|
||
|
LPDIRECTDRAWCREATE pDDCreate;
|
||
|
LPDIRECTDRAW pdd = NULL;
|
||
|
TCHAR sz[300];
|
||
|
TCHAR szTitle[100];
|
||
|
|
||
|
LoadString(NULL, IDS_STARTDDTEST, sz, 300);
|
||
|
LoadString(NULL, IDS_APPFULLNAME, szTitle, 100);
|
||
|
|
||
|
if (IDNO == MessageBox(hwndMain, sz, szTitle, MB_YESNO))
|
||
|
return;
|
||
|
|
||
|
// Remove info from any previous test:
|
||
|
ZeroMemory(&pDisplayInfo->m_testResultDD, sizeof(TestResult));
|
||
|
|
||
|
pDisplayInfo->m_testResultDD.m_bStarted = TRUE;
|
||
|
|
||
|
// Load ddraw.dll
|
||
|
GetSystemDirectory(szPath, MAX_PATH);
|
||
|
lstrcat(szPath, TEXT("\\ddraw.dll"));
|
||
|
hInstDDraw = LoadLibrary(szPath);
|
||
|
if (hInstDDraw == NULL)
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_LOAD_DDRAW_DLL;
|
||
|
pDisplayInfo->m_testResultDD.m_hr = DDERR_NOTFOUND;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
|
||
|
// Get DirectDrawCreate entry point
|
||
|
pDDCreate = (LPDIRECTDRAWCREATE)GetProcAddress(hInstDDraw, "DirectDrawCreate");
|
||
|
if (pDDCreate == NULL)
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_GET_DIRECTDRAWCREATE;
|
||
|
pDisplayInfo->m_testResultDD.m_hr = DDERR_NOTFOUND;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
|
||
|
// Call DirectDrawCreate
|
||
|
if (FAILED(hr = pDDCreate(&pDisplayInfo->m_guid, &pdd, NULL)))
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_DIRECTDRAWCREATE;
|
||
|
pDisplayInfo->m_testResultDD.m_hr = hr;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
|
||
|
// Get DirectDraw caps
|
||
|
DDCAPS ddcaps;
|
||
|
DDCAPS ddcaps2;
|
||
|
ddcaps.dwSize = sizeof(ddcaps);
|
||
|
ddcaps2.dwSize = sizeof(ddcaps2);
|
||
|
if (FAILED(hr = pdd->GetCaps(&ddcaps, &ddcaps2)))
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_GETCAPS;
|
||
|
pDisplayInfo->m_testResultDD.m_hr = hr;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
ReleasePpo(&pdd);
|
||
|
|
||
|
if (!pDisplayInfo->m_bCanRenderWindow)
|
||
|
{
|
||
|
LoadString(NULL, IDS_SKIPWINDOWED, sz, 300);
|
||
|
MessageBox(hwndMain, sz, szTitle, MB_OK);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// First test
|
||
|
LoadString(NULL, IDS_DDTEST1, sz, 300);
|
||
|
if (IDCANCEL == MessageBox(hwndMain, sz, szTitle, MB_OKCANCEL))
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_bCancelled = TRUE;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
if (FAILED(hr = pDDCreate(&pDisplayInfo->m_guid, &pdd, NULL)))
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_DIRECTDRAWCREATE;
|
||
|
pDisplayInfo->m_testResultDD.m_hr = hr;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
if (FAILED(hr = TestPrimary(hwndMain, pdd, &pDisplayInfo->m_testResultDD.m_iStepThatFailed)))
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_hr = hr;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
ReleasePpo(&pdd);
|
||
|
LoadString(NULL, IDS_CONFIRMDDTEST1, sz, 300);
|
||
|
if (IDNO == MessageBox(hwndMain, sz, szTitle, MB_YESNO))
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_USER_VERIFY_RECTANGLES;
|
||
|
pDisplayInfo->m_testResultDD.m_hr = S_OK;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
|
||
|
// Second test
|
||
|
LoadString(NULL, IDS_DDTEST2, sz, 300);
|
||
|
if (IDCANCEL == MessageBox(hwndMain, sz, szTitle, MB_OKCANCEL))
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_bCancelled = TRUE;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
if (FAILED(hr = pDDCreate(&pDisplayInfo->m_guid, &pdd, NULL)))
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_DIRECTDRAWCREATE;
|
||
|
pDisplayInfo->m_testResultDD.m_hr = hr;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
if (FAILED(hr = TestPrimaryBlt(hwndMain, pdd, &pDisplayInfo->m_testResultDD.m_iStepThatFailed)))
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_hr = hr;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
ReleasePpo(&pdd);
|
||
|
LoadString(NULL, IDS_CONFIRMDDTEST2, sz, 300);
|
||
|
if (IDNO == MessageBox(hwndMain, sz, szTitle, MB_YESNO))
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_USER_VERIFY_WINDOW_BOUNCE;
|
||
|
pDisplayInfo->m_testResultDD.m_hr = S_OK;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Third test
|
||
|
LoadString(NULL, IDS_DDTEST3, sz, 300);
|
||
|
if (IDCANCEL == MessageBox(hwndMain, sz, szTitle, MB_OKCANCEL))
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_bCancelled = TRUE;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
if (FAILED(hr = pDDCreate(&pDisplayInfo->m_guid, &pdd, NULL)))
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_DIRECTDRAWCREATE;
|
||
|
pDisplayInfo->m_testResultDD.m_hr = hr;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
POINT ptMouse;
|
||
|
GetCursorPos(&ptMouse);
|
||
|
if (FAILED(hr = TestFullscreen(hwndMain, pdd, &pDisplayInfo->m_testResultDD.m_iStepThatFailed)))
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_hr = hr;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
SetCursorPos( ptMouse.x, ptMouse.y );
|
||
|
ReleasePpo(&pdd);
|
||
|
LoadString(NULL, IDS_CONFIRMDDTEST3, sz, 300);
|
||
|
if (IDNO == MessageBox(hwndMain, sz, szTitle, MB_YESNO))
|
||
|
{
|
||
|
pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_USER_VERIFY_FULLSCREEN_BOUNCE;
|
||
|
pDisplayInfo->m_testResultDD.m_hr = S_OK;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
|
||
|
LoadString(NULL, IDS_ENDDDTESTS, sz, 300);
|
||
|
MessageBox(hwndMain, sz, szTitle, MB_OK);
|
||
|
|
||
|
LEnd:
|
||
|
ReleasePpo(&pdd);
|
||
|
if (hInstDDraw != NULL)
|
||
|
FreeLibrary(hInstDDraw);
|
||
|
if (pDisplayInfo->m_testResultDD.m_bCancelled)
|
||
|
{
|
||
|
LoadString(NULL, IDS_TESTSCANCELLED, sz, 300);
|
||
|
lstrcpy(pDisplayInfo->m_testResultDD.m_szDescription, sz);
|
||
|
|
||
|
LoadString(NULL, IDS_TESTSCANCELLED_ENGLISH, sz, 300);
|
||
|
lstrcpy(pDisplayInfo->m_testResultDD.m_szDescription, sz);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (pDisplayInfo->m_testResultDD.m_iStepThatFailed == 0)
|
||
|
{
|
||
|
LoadString(NULL, IDS_TESTSSUCCESSFUL, sz, 300);
|
||
|
lstrcpy(pDisplayInfo->m_testResultDD.m_szDescription, sz);
|
||
|
|
||
|
LoadString(NULL, IDS_TESTSSUCCESSFUL_ENGLISH, sz, 300);
|
||
|
lstrcpy(pDisplayInfo->m_testResultDD.m_szDescriptionEnglish, sz);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TCHAR szDesc[200];
|
||
|
TCHAR szError[200];
|
||
|
if (0 == LoadString(NULL, IDS_FIRSTDDTESTERROR + pDisplayInfo->m_testResultDD.m_iStepThatFailed - 1,
|
||
|
szDesc, 200))
|
||
|
{
|
||
|
LoadString(NULL, IDS_UNKNOWNERROR, sz, 300);
|
||
|
lstrcpy(szDesc, sz);
|
||
|
}
|
||
|
LoadString(NULL, IDS_FAILUREFMT, sz, 300);
|
||
|
BTranslateError(pDisplayInfo->m_testResultDD.m_hr, szError);
|
||
|
wsprintf(pDisplayInfo->m_testResultDD.m_szDescription, sz,
|
||
|
pDisplayInfo->m_testResultDD.m_iStepThatFailed,
|
||
|
szDesc, pDisplayInfo->m_testResultDD.m_hr, szError);
|
||
|
|
||
|
// Nonlocalized version:
|
||
|
if (0 == LoadString(NULL, IDS_FIRSTDDTESTERROR_ENGLISH + pDisplayInfo->m_testResultDD.m_iStepThatFailed - 1,
|
||
|
szDesc, 200))
|
||
|
{
|
||
|
LoadString(NULL, IDS_UNKNOWNERROR_ENGLISH, sz, 300);
|
||
|
lstrcpy(szDesc, sz);
|
||
|
}
|
||
|
LoadString(NULL, IDS_FAILUREFMT_ENGLISH, sz, 300);
|
||
|
BTranslateError(pDisplayInfo->m_testResultDD.m_hr, szError, TRUE);
|
||
|
wsprintf(pDisplayInfo->m_testResultDD.m_szDescriptionEnglish, sz,
|
||
|
pDisplayInfo->m_testResultDD.m_iStepThatFailed,
|
||
|
szDesc, pDisplayInfo->m_testResultDD.m_hr, szError);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* TestPrimary
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
HRESULT TestPrimary(HWND hwndMain, LPDIRECTDRAW pdd, LONG* piStepThatFailed)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
DDSURFACEDESC ddsd;
|
||
|
LPDIRECTDRAWSURFACE pdds = NULL;
|
||
|
RECT rc;
|
||
|
|
||
|
if (FAILED(hr = pdd->SetCooperativeLevel(NULL, DDSCL_NORMAL)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_SETCOOPERATIVELEVEL_NORMAL;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
|
||
|
ZeroMemory(&ddsd, sizeof(ddsd));
|
||
|
ddsd.dwSize = sizeof(ddsd);
|
||
|
ddsd.dwFlags = DDSD_CAPS;
|
||
|
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||
|
if (FAILED(hr = pdd->CreateSurface(&ddsd, &pdds, NULL)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_CREATEPRIMARYSURFACE;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
||
|
if (FAILED(hr = pdds->GetSurfaceDesc(&ddsd)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_GETPRIMARYSURFACEDESC;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
SetRect(&rc, 0, 0, ddsd.dwWidth, ddsd.dwHeight);
|
||
|
InflateRect(&rc, -64, -64);
|
||
|
|
||
|
DDBLTFX ddbltfx;
|
||
|
ZeroMemory(&ddbltfx, sizeof(ddbltfx));
|
||
|
ddbltfx.dwSize = sizeof(ddbltfx);
|
||
|
while (rc.right > rc.left + 2 && rc.bottom > rc.top + 2)
|
||
|
{
|
||
|
ddbltfx.dwFillColor = ~ddbltfx.dwFillColor;
|
||
|
if (FAILED(hr = pdds->Blt(&rc, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_COLORFILL_BLT_TO_PRIMARY;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
InflateRect(&rc, -4, -4);
|
||
|
}
|
||
|
|
||
|
// Give the user a moment to verify the test pattern
|
||
|
Sleep(2000);
|
||
|
|
||
|
// Clean up affected screen area in case this display isn't part of the desktop:
|
||
|
ddbltfx.dwFillColor = 0;
|
||
|
if (FAILED(hr = pdds->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_COLORFILL_BLT_TO_PRIMARY;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
|
||
|
LEnd:
|
||
|
ReleasePpo(&pdds);
|
||
|
InvalidateRect(NULL, NULL, FALSE); // repaint desktop
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* TestPrimaryBlt
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
HRESULT TestPrimaryBlt(HWND hwndMain, LPDIRECTDRAW pdd, LONG* piStepThatFailed)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
DDSURFACEDESC ddsd;
|
||
|
LPDIRECTDRAWSURFACE pddsFront = NULL;
|
||
|
LPDIRECTDRAWSURFACE pddsBack = NULL;
|
||
|
RECT rc;
|
||
|
RECT rcDest;
|
||
|
RECT rcScreen;
|
||
|
DDBLTFX ddbltfx;
|
||
|
INT i;
|
||
|
LONG xv = 1;
|
||
|
LONG yv = 2;
|
||
|
|
||
|
if (FAILED(hr = pdd->SetCooperativeLevel(NULL, DDSCL_NORMAL)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_SETCOOPERATIVELEVEL_NORMAL;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
|
||
|
ZeroMemory(&ddsd, sizeof(ddsd));
|
||
|
ddsd.dwSize = sizeof(ddsd);
|
||
|
ddsd.dwFlags = DDSD_CAPS;
|
||
|
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||
|
if (FAILED(hr = pdd->CreateSurface(&ddsd, &pddsFront, NULL)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_CREATEPRIMARYSURFACE;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
|
||
|
if (FAILED(hr = pddsFront->GetSurfaceDesc(&ddsd)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_GETPRIMARYSURFACEDESC;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
SetRect(&rcScreen, 0, 0, ddsd.dwWidth, ddsd.dwHeight);
|
||
|
|
||
|
ZeroMemory(&ddsd, sizeof(ddsd));
|
||
|
ddsd.dwSize = sizeof(ddsd);
|
||
|
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
||
|
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
|
||
|
ddsd.dwWidth = 200;
|
||
|
ddsd.dwHeight = 200;
|
||
|
if (FAILED(hr = pdd->CreateSurface(&ddsd, &pddsBack, NULL)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_CREATE_OFFSCREENPLAIN_SURFACE;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
|
||
|
SetRect(&rc, 0, 0, 32, 32);
|
||
|
OffsetRect(&rc, 10, 35);
|
||
|
|
||
|
ZeroMemory(&ddbltfx, sizeof(ddbltfx));
|
||
|
ddbltfx.dwSize = sizeof(ddbltfx);
|
||
|
for (i = 0; i < 200; i++)
|
||
|
{
|
||
|
ddbltfx.dwFillColor = 0;
|
||
|
if (FAILED(hr = pddsBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_COLORFILL_BLT_TO_OFFSCREENPLAIN;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
OffsetRect(&rc, xv, yv);
|
||
|
if (rc.left < 2 && xv < 0 || rc.right > 198 && xv > 0)
|
||
|
xv = -xv;
|
||
|
if (rc.top < 2 && yv < 0 || rc.bottom > 198 && yv > 0)
|
||
|
yv = -yv;
|
||
|
ddbltfx.dwFillColor = 0xffffffff;
|
||
|
if (FAILED(hr = pddsBack->Blt(&rc, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_COLORFILL_BLT_TO_OFFSCREENPLAIN;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
SetRect(&rcDest, 0, 0, 200, 200);
|
||
|
OffsetRect(&rcDest, (rcScreen.right - 200) / 2, (rcScreen.bottom - 200) / 2);
|
||
|
if (FAILED(hr = pddsFront->Blt(&rcDest, pddsBack, NULL, DDBLT_WAIT, NULL)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_BLT_OFFSCREENPLAIN_TO_FRONT;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
Sleep(2);
|
||
|
}
|
||
|
|
||
|
// Clean up affected screen area in case this display isn't part of the desktop:
|
||
|
ddbltfx.dwFillColor = 0;
|
||
|
if (FAILED(hr = pddsFront->Blt(&rc, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_COLORFILL_BLT_TO_PRIMARY;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
|
||
|
LEnd:
|
||
|
InvalidateRect(NULL, NULL, FALSE); // repaint desktop
|
||
|
ReleasePpo(&pddsBack);
|
||
|
ReleasePpo(&pddsFront);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* TestFullscreen
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
HRESULT TestFullscreen(HWND hwndMain, LPDIRECTDRAW pdd, LONG* piStepThatFailed)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
HWND hwnd = NULL;
|
||
|
DDSURFACEDESC ddsd;
|
||
|
LPDIRECTDRAWSURFACE pddsFront = NULL;
|
||
|
LPDIRECTDRAWSURFACE pddsBack = NULL;
|
||
|
RECT rc;
|
||
|
RECT rcScreen;
|
||
|
DDBLTFX ddbltfx;
|
||
|
BOOL bDisplayModeSet = FALSE;
|
||
|
INT i;
|
||
|
LONG xv = 1;
|
||
|
LONG yv = 2;
|
||
|
|
||
|
ShowCursor(FALSE);
|
||
|
|
||
|
if (FAILED(hr = CreateTestWindow(hwndMain, &hwnd)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_CREATE_TEST_WINDOW;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
|
||
|
if (FAILED(hr = pdd->SetCooperativeLevel(hwnd,
|
||
|
DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_SETCOOPERATIVELEVEL_FULLSCREEN;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
|
||
|
if (FAILED(hr = pdd->SetDisplayMode(640, 480, 16)))
|
||
|
{
|
||
|
TCHAR szMessage[300];
|
||
|
TCHAR szTitle[100];
|
||
|
pdd->SetCooperativeLevel(hwnd, DDSCL_NORMAL);
|
||
|
SendMessage(hwnd, WM_CLOSE, 0, 0);
|
||
|
LoadString(NULL, IDS_SETDISPLAYMODEFAILED, szMessage, 300);
|
||
|
LoadString(NULL, IDS_APPFULLNAME, szTitle, 100);
|
||
|
MessageBox(hwndMain, szMessage, szTitle, MB_OK);
|
||
|
*piStepThatFailed = TESTID_SETDISPLAYMODE;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
bDisplayModeSet = TRUE;
|
||
|
|
||
|
ZeroMemory(&ddsd, sizeof(ddsd));
|
||
|
ddsd.dwSize = sizeof(ddsd);
|
||
|
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
|
||
|
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
|
||
|
ddsd.dwBackBufferCount = 1;
|
||
|
if (FAILED(hr = pdd->CreateSurface(&ddsd, &pddsFront, NULL)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_CREATEPRIMARYSURFACE_FLIP_ONEBACK;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
|
||
|
if (FAILED(hr = pddsFront->GetSurfaceDesc(&ddsd)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_GETPRIMARYSURFACEDESC;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
SetRect(&rcScreen, 0, 0, ddsd.dwWidth, ddsd.dwHeight);
|
||
|
|
||
|
ZeroMemory(&ddbltfx, sizeof(ddbltfx));
|
||
|
ddbltfx.dwSize = sizeof(ddbltfx);
|
||
|
|
||
|
DDSCAPS ddscaps;
|
||
|
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
|
||
|
if (FAILED(hr = pddsFront->GetAttachedSurface(&ddscaps, &pddsBack)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_GETATTACHEDSURFACE;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
|
||
|
SetRect(&rc, 0, 0, 32, 32);
|
||
|
OffsetRect(&rc, 10, 35);
|
||
|
|
||
|
ZeroMemory(&ddbltfx, sizeof(ddbltfx));
|
||
|
ddbltfx.dwSize = sizeof(ddbltfx);
|
||
|
for (i = 0; i < 200; i++)
|
||
|
{
|
||
|
ddbltfx.dwFillColor = 0;
|
||
|
if (FAILED(hr = pddsBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_COLORFILL_TO_BACKBUFFER;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
OffsetRect(&rc, xv, yv);
|
||
|
if (rc.left < 2 && xv < 0 || rc.right > 198 && xv > 0)
|
||
|
xv = -xv;
|
||
|
if (rc.top < 2 && yv < 0 || rc.bottom > 198 && yv > 0)
|
||
|
yv = -yv;
|
||
|
OffsetRect(&rc, (rcScreen.right - 200) / 2, (rcScreen.bottom - 200) / 2);
|
||
|
ddbltfx.dwFillColor = 0xffffffff;
|
||
|
if (FAILED(hr = pddsBack->Blt(&rc, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_COLORFILL_TO_BACKBUFFER;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
OffsetRect(&rc, -(rcScreen.right - 200) / 2, -(rcScreen.bottom - 200) / 2);
|
||
|
if (FAILED(hr = pddsFront->Flip(NULL, DDFLIP_WAIT)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_FLIP;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
Sleep(2);
|
||
|
}
|
||
|
|
||
|
ddbltfx.dwFillColor = 0;
|
||
|
if (FAILED(hr = pddsFront->Blt(&rc, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_COLORFILL_BLT_TO_PRIMARY;
|
||
|
goto LEnd;
|
||
|
}
|
||
|
|
||
|
LEnd:
|
||
|
ShowCursor(TRUE);
|
||
|
ReleasePpo(&pddsBack);
|
||
|
ReleasePpo(&pddsFront);
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
// Something has already failed, so report that failure
|
||
|
// rather than any failure of SetCooperativeLevel
|
||
|
pdd->SetCooperativeLevel(hwnd, DDSCL_NORMAL);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (FAILED(hr = pdd->SetCooperativeLevel(hwnd, DDSCL_NORMAL)))
|
||
|
{
|
||
|
*piStepThatFailed = TESTID_SETCOOPERATIVELEVEL_NORMAL;
|
||
|
}
|
||
|
}
|
||
|
if (hwnd != NULL)
|
||
|
SendMessage(hwnd, WM_CLOSE, 0, 0);
|
||
|
if (bDisplayModeSet)
|
||
|
{
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
// Something has already failed, so report that failure
|
||
|
// rather than any failure of RestoreDisplayMode
|
||
|
pdd->RestoreDisplayMode();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Nothing has failed yet, so report any failure of RestoreDisplayMode
|
||
|
if (FAILED(hr = pdd->RestoreDisplayMode()))
|
||
|
return hr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* CreateTestWindow
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
HRESULT CreateTestWindow(HWND hwndMain, HWND* phwnd)
|
||
|
{
|
||
|
static BOOL bClassRegistered = FALSE;
|
||
|
WNDCLASS wndClass;
|
||
|
TCHAR* pszClass = TEXT("DxDiag Test Window"); // Don't need to localize
|
||
|
HINSTANCE hInst = (HINSTANCE)GetWindowLongPtr(hwndMain, GWLP_HINSTANCE);
|
||
|
TCHAR szTitle[200];
|
||
|
|
||
|
if (!bClassRegistered)
|
||
|
{
|
||
|
ZeroMemory(&wndClass, sizeof(wndClass));
|
||
|
wndClass.style = CS_HREDRAW | CS_VREDRAW;
|
||
|
wndClass.lpfnWndProc = DefWindowProc;
|
||
|
wndClass.cbClsExtra = 0;
|
||
|
wndClass.cbWndExtra = 0;
|
||
|
wndClass.hInstance = hInst;
|
||
|
wndClass.hIcon = NULL;
|
||
|
wndClass.hCursor = NULL;
|
||
|
wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
|
||
|
wndClass.lpszMenuName = NULL;
|
||
|
wndClass.lpszClassName = pszClass;
|
||
|
if (NULL == RegisterClass(&wndClass))
|
||
|
return E_FAIL;
|
||
|
bClassRegistered = TRUE;
|
||
|
}
|
||
|
|
||
|
LoadString(NULL, IDS_APPFULLNAME, szTitle, 200);
|
||
|
*phwnd = CreateWindow(pszClass, szTitle, WS_OVERLAPPED,
|
||
|
0, 0, 0, 0, hwndMain, NULL, hInst, NULL);
|
||
|
if (*phwnd == NULL)
|
||
|
return E_FAIL;
|
||
|
|
||
|
ShowWindow(*phwnd, SW_SHOW);
|
||
|
|
||
|
return S_OK;
|
||
|
}
|