📄 windraw2.cpp
字号:
if (pDrawCreate == NULL || pDrawEnum == NULL) {
/* ... */
ReleaseDirectDraw (ppDirectDraw, NULL, phDirectDraw);
return E_NOINTERFACE;
}
/* create a DirectDraw display provider for this device,
* using the fancy multimon-aware version, if it exists: */
if (pDrawEnumEx)
*ppDirectDraw = DirectDrawCreateFromDeviceEx (lpszDevice, pDrawCreate, pDrawEnumEx);
else
*ppDirectDraw = DirectDrawCreateFromDevice (lpszDevice, pDrawCreate, pDrawEnum);
if (*ppDirectDraw == NULL)
{
ReleaseDirectDraw (ppDirectDraw, NULL, phDirectDraw);
return E_NOINTERFACE;
}
return NOERROR;
}
/*
* Called to release any DirectDraw provider we previously loaded.
* We may be called at any time especially when something goes
* horribly wrong and when we need to clean up before returning
* so we can't guarantee that all state variables are consistent
* so free only those really allocated. This should only be called
* once all the reference counts have been released.
*/
void ReleaseDirectDraw (LPDIRECTDRAW *ppDirectDraw, LPDIRECTDRAW2 *ppDirectDraw2, HINSTANCE *phDirectDraw)
{
/* release any DirectDraw provider interface: */
if (ppDirectDraw && *ppDirectDraw) {
IDirectDraw_Release (*ppDirectDraw);
*ppDirectDraw = NULL;
}
if (ppDirectDraw2 && *ppDirectDraw2)
{
(*ppDirectDraw2)->Release();
*ppDirectDraw2 = NULL;
}
/* decrement module load count: */
if (*phDirectDraw) {
FreeLibrary (*phDirectDraw);
*phDirectDraw = NULL;
}
}
#if 0
/*
* Are we running on Direct Draw version 1? We need to find out as
* we rely on specific bug fixes in DirectDraw 2 for fullscreen playback. To
* find out, we simply see if it supports IDirectDraw2. Only version 2 and
* higher support this.
*/
BOOL IsDirectDrawVersion1 (LPDIRECTDRAW pDirectDraw)
{
IDirectDraw2 *p;
HRESULT hr;
/* check if DirectDraw is available: */
if (pDirectDraw == NULL)
return FALSE;
/* query and release interface: */
p = NULL;
hr = IDirectDraw_QueryInterface(pDirectDraw, IID_IDirectDraw2, (void *)&p);
if (p)
IDirectDraw2_Release (p);
/* returns TRUE, if !IDrectDraw2; FALSE otherwise */
return hr != NOERROR;
}
#endif
/***************************************
*
* Routines for using GDI on a multimonitor system
*
*/
/*
* Get display DC.
* Use:
* HDC GetDisplayDC (LPSTR lpszDevice)
* Input:
* lpszDevice - device name to use (in a multimonitor system)
* Returns:
* NULL, if error; !NULL - display device DC.
*/
static HDC GetDisplayDC (LPSTR lpszDevice)
{
HDC hdcDisplay;
/* get a DC on the right monitor - it's ugly, but this is the way
* you have to do it */
if (lpszDevice == NULL || lstrcmpiA (lpszDevice, "DISPLAY") == 0)
hdcDisplay = CreateDCA ("DISPLAY", NULL, NULL, NULL);
else
hdcDisplay = CreateDCA (NULL, lpszDevice, NULL, NULL);
return hdcDisplay;
}
/*
* Get pixel format for a given device context.
* Use:
* HRESULT GetDeviceFormat (HDC hDC, LPBMI lpbmi);
* Input:
* hDC - device context to query
* lpbmi - pointer to a bitmapinfo structure to initialize
* Returns:
* NOERROR, if success, E_FAIL otherwise.
*/
static HRESULT GetDeviceFormat (HDC hDC, LPBMI lpbmi)
{
HBITMAP hBM;
/* initialize the bitmapinfo structure: */
memset (lpbmi, 0, sizeof (BMI));
lpbmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
lpbmi->bmiHeader.biBitCount = 0;
/* retrieve display format parameters: */
hBM = CreateCompatibleBitmap (hDC,1,1);
GetDIBits (hDC,hBM,0,1,NULL, (BITMAPINFO *)& (lpbmi->bmiHeader),DIB_RGB_COLORS);
/* this call will get the color table or the proper bitfields */
GetDIBits (hDC,hBM,0,1,NULL, (BITMAPINFO *)& (lpbmi->bmiHeader),DIB_RGB_COLORS);
DeleteObject (hBM);
/* check the validity of the format & exit: */
return CheckBitmap ((BITMAPINFO *)& (lpbmi->bmiHeader))? NOERROR: E_FAIL;
}
/*
* Retrieves display pixel format. This is normally called
* when we receive WM_DEVMODECHANGED device change messages.
*
* The optional szDevice parameter tells us which monitor we are interested
* in for a multi monitor system.
*
* The calling program mush use global syncronization objects to prevent
* re-entering this code.
*/
static HRESULT GetDisplayFormat (LPBMI lpbmi, LPSTR lpszDevice)
{
HDC hdcDisplay;
HRESULT hr;
/* get a DC of a given monitor: */
if ((hdcDisplay = GetDisplayDC (lpszDevice)) == NULL)
return E_FAIL;
/* retrieve display format parameters: */
hr = GetDeviceFormat (hdcDisplay, lpbmi);
/* delete hdcDisplay & exit: */
DeleteDC (hdcDisplay);
return hr;
}
/*
* Generates the "standard" WinDraw palette.
* Since we will have to deal with multiple datatypes, each having
* its own combination of colors, what we really need is some "uniform"
* palette, we could use to render all these objects with minimum loss
* of quality.
* This function generates so-called 6x6x6-color palette that contains
* all possible combinations of 6 uniformly-displaced values for each
* color component (R, G, and B). To avoid interference with Windows
* system palette (first and last 10 entries in the palette), we will
* insert our colors in 10..225 range, and mark them as non-collapsable
* in hope to boost the performance (ideally, this should prevent GDI
* from compressing the palette, and eliminate extra mapping).
*/
static HRESULT CreateDefaultPalette (LPPALETTEENTRY lppe,
int *pnLoColor, int *pnHiColor, LPSTR lpszDevice)
{
HDC hdc;
HRESULT hr = E_FAIL;
unsigned int i, r, g, b;
/* get a DC of a given monitor: */
if ((hdc = GetDisplayDC (lpszDevice)) != NULL) {
/* apparently some displays have odd numbers of system colors: */
if (GetDeviceCaps (hdc, NUMRESERVED) == 20) {
/* retrieve system colors: */
memset (lppe, 0, 256 * sizeof (RGBQUAD));
GetSystemPaletteEntries (hdc, 0, 10, lppe);
GetSystemPaletteEntries (hdc, 246, 10, lppe + 246);
/* generate 6x6x6 (~2.58 bits/channel) palette: */
i = 10;
for (b = 0; b <= 0xFF; b += 0x33)
for (g = 0; g <= 0xFF; g += 0x33)
for (r = 0; r <= 0xFF; r += 0x33) {
/* create a palette entry: */
lppe [i].peGreen = g;
lppe [i].peBlue = b;
lppe [i].peRed = r;
lppe [i].peFlags = PC_NOCOLLAPSE; /* !!! */
i ++;
}
/* store the range of our colors: */
*pnLoColor = 10;
*pnHiColor = i;
hr = NOERROR;
}
DeleteDC (hdc);
}
return hr;
}
char*
CollectDDInfo(LPWINDRAW lpwd, LPDIRECTDRAWSURFACE lpSurface, char *pFunction, char* pSeparator)
{
char* pszDDInfo = NULL;
CHXString pDDInfo;
char szTemp[MAX_DISPLAY_NAME]; /* Flawfinder: ignore */
char szTmp[MAX_DISPLAY_NAME]; /* Flawfinder: ignore */
// write date and time of log
SYSTEMTIME time;
memset(&time, 0, sizeof(time));
GetSystemTime(&time);
GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, &time, "ddd',' MMM dd yyyy, ", szTmp, sizeof(szTmp));
SafeSprintf(szTemp, MAX_DISPLAY_NAME, "\nLog Entry: %s", szTmp);
pDDInfo = szTemp;
GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &time, "hh:mm:ss tt", szTmp, sizeof(szTmp));
SafeSprintf(szTemp, MAX_DISPLAY_NAME, "%s%s", szTmp, pSeparator);
pDDInfo += szTemp;
// write systime members
SafeSprintf(szTemp, MAX_DISPLAY_NAME, "Systime: %d %d %d %d %d %d %d %d%s",
time.wYear, time.wMonth, time.wDayOfWeek, time.wDay,
time.wHour, time.wMinute, time.wSecond, time.wMilliseconds, pSeparator);
pDDInfo += szTemp;
// write function that caused fault
SafeSprintf(szTemp, MAX_DISPLAY_NAME, "Function: %s%s", pFunction, pSeparator);
pDDInfo += szTemp;
// write OS version
OSVERSIONINFO ver;
memset(&ver, 0, sizeof(ver));
ver.dwOSVersionInfoSize = sizeof(ver);
GetVersionEx(&ver);
SafeSprintf(szTemp, MAX_DISPLAY_NAME,
"OS MajorVersion: %ld MinorVersion: %ld BuildNum: %ld PlatformId: %ld Build: %s%s",
ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, ver.dwPlatformId, ver.szCSDVersion, pSeparator);
pDDInfo += szTemp;
// write processor info
SYSTEM_INFO sysinfo;
memset(&sysinfo, 0, sizeof(sysinfo));
GetSystemInfo(&sysinfo);
SafeSprintf(szTemp, MAX_DISPLAY_NAME, "Processor Type: %ld Level: %ld Revision: %ld Count: %ld%s",
sysinfo.dwProcessorType,
sysinfo.wProcessorLevel,
sysinfo.wProcessorRevision,
sysinfo.dwNumberOfProcessors,
pSeparator);
pDDInfo += szTemp;
// write DD version
TCHAR szVersion[256] = __TEXT("\0"); /* Flawfinder: ignore */
HKEY hKey = 0;
RegOpenKeyEx(HKEY_LOCAL_MACHINE,
__TEXT("Software\\Microsoft\\DirectX"),
0, KEY_READ, &hKey);
if (hKey)
{
DWORD dwType = REG_SZ;
DWORD dwSize = sizeof(szVersion);
RegQueryValueEx(hKey, __TEXT("Version"), NULL, &dwType, (BYTE*)szVersion, &dwSize);
RegCloseKey(hKey);
}
SafeSprintf(szTemp, MAX_DISPLAY_NAME, "DirectDraw Version %s%s", szVersion, pSeparator);
pDDInfo += szTemp;
if (lpSurface)
{
// Get DD4* from the surface
void* pVoid = NULL;
IDirectDrawSurface2* lpSurface2 = NULL;
#if DIRECTDRAW_VERSION > 0x0500
IDirectDraw4* pDD4 = NULL;
IDirectDraw* pDD = NULL;
#endif //DIRECTDRAW_VERSION > 0x0500
DDDEVICEIDENTIFIER ddID;
memset(&ddID, 0, sizeof(ddID));
lpSurface->QueryInterface(IID_IDirectDrawSurface2, (void**)&lpSurface2);
if (lpSurface2)
{
lpSurface2->GetDDInterface(&pVoid);
lpSurface2->Release();
}
#if DIRECTDRAW_VERSION > 0x0500
if (pVoid)
((IUnknown*)pVoid)->QueryInterface(IID_IDirectDraw, (void**)&pDD);
if (pDD)
{
pDD->QueryInterface(IID_IDirectDraw4, (void **)&pDD4);
pDD->Release();
}
// Query for the driver descripton
if (pDD4)
{
pDD4->GetDeviceIdentifier(&ddID, DDGDI_GETHOSTIDENTIFIER);
pDD4->Release();
}
// DD4 not supportted (probably NT4)...use more drastic measures
else
#endif //DIRECTDRAW_VERSION > 0x0500
{
// Check if we are runnning NT
OSVERSIONINFO osVersion;
memset(&osVersion,0, sizeof(OSVERSIONINFO));
osVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&osVersion) && osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
char szChipType[MAXCHIPTYPE]; /* Flawfinder: ignore */
// Try to get WinNT device information
GetWinNTDeviceID (&ddID, szChipType);
}
}
// write DD driver
unsigned short data4 = ddID.guidDeviceIdentifier.Data4[0]<<8 |
ddID.guidDeviceIdentifier.Data4[1];
unsigned long data5 = ddID.guidDeviceIdentifier.Data4[2]<<24 |
ddID.guidDeviceIdentifier.Data4[3]<<16 |
ddID.guidDeviceIdentifier.Data4[4]<<8 |
ddID.guidDeviceIdentifier.Data4[5];
unsigned short data6 = ddID.guidDeviceIdentifier.Data4[6]<<8 |
ddID.guidDeviceIdentifier.Data4[7];
SafeSprintf(szTemp, MAX_DISPLAY_NAME,
"DirectDraw Driver: %s VendorID: %ld GUID {""%lx-%x-%x-%x-%lx%x""}%s",
ddID.szDescription,
ddID.dwVendorId,
ddID.guidDeviceIdentifier.Data1,
ddID.guidDeviceIdentifier.Data2,
ddID.guidDeviceIdentifier.Data3,
data4,
data5,
data6,
pSeparator);
pDDInfo += szTemp;
// write display properties
DDSURFACEDESC ddsd;
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
lpSurface->GetSurfaceDesc(&ddsd);
char fourCC[5] = {(char)(ddsd.ddpfPixelFormat.dwFourCC & 0x000000FF), /* Flawfinder: ignore */
((char)(ddsd.ddpfPixelFormat.dwFourCC & 0x0000FF00)>>8),
((char)(ddsd.ddpfPixelFormat.dwFourCC & 0x00FF0000)>>16),
(char)(ddsd.ddpfPixelFormat.dwFourCC>>24),
'\0'};
SafeSprintf(szTemp, MAX_DISPLAY_NAME,
"DisplayMode: %s %s BackBuffers: %ld Width: %ld Height: %ld%s",
(ddsd.ddsCaps.dwCaps & DDSCAPS_OVERLAY) ? "Overlay" : "Offscreen",
fourCC,
(ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) ? ddsd.dwBackBufferCount : 0,
ddsd.dwWidth,
ddsd.dwHeight,
pSeparator);
pDDInfo += szTemp;
}
BMI bmi;
memset(&bmi, 0, sizeof(bmi));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -