📄 windraw2.cpp
字号:
/* force ANSI, we assume it: */ pDrawEnum = (PDRAWENUM) GetProcAddress (*phDirectDraw, "DirectDrawEnumerateA"); pDrawEnumEx = (LPDIRECTDRAWENUMERATEEXA)GetProcAddress (*phDirectDraw, "DirectDrawEnumerateExA"); /* we don't need DirectDrawEnumerateEx, that's just for multimon stuff: */ 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)); GetDisplayFormat(&bmi, NULL); // write monitor properties
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -