// compile with: x86_64-w64-mingw32-g++ d3d9Test.cpp #include #include static BOOL Monitorenumproc( HMONITOR hMonitor, HDC unnamedParam2, LPRECT bounds, LPARAM unnamedParam4 ) { MONITORINFOEX mi; mi.cbSize = sizeof(mi); if(GetMonitorInfo(hMonitor, &mi)) { printf("%p: %s\n", hMonitor, mi.szDevice); printf("%d, %d, %d, %d\n", bounds->left, bounds->top, bounds->right, bounds->bottom); } else { printf("GetMonitorInfo failed for %p\n", hMonitor); } return TRUE; } int main(int argc, char **argv) { HRESULT hr = E_FAIL; HMODULE libHandle = NULL; UINT m_uD3DAdapterCount = 0; HMONITOR *hMonitor = NULL; // Manually load the d3d9.dll library. libHandle = LoadLibrary("d3d9.dll"); if (libHandle != NULL) { // Define a function pointer to the Direct3DCreate9Ex function. typedef HRESULT (WINAPI *LPDIRECT3DCREATE9EX)(UINT, IDirect3D9Ex**); // Obtain the address of the Direct3DCreate9Ex function. LPDIRECT3DCREATE9EX Direct3DCreate9ExPtr = NULL; Direct3DCreate9ExPtr = (LPDIRECT3DCREATE9EX) GetProcAddress(libHandle, "Direct3DCreate9Ex"); if (Direct3DCreate9ExPtr != NULL) { // Direct3DCreate9Ex is supported. hr = S_OK; IDirect3D9Ex *pD3D = NULL; if (FAILED(hr = Direct3DCreate9ExPtr(D3D_SDK_VERSION, &pD3D))) { printf("Failed\n"); } else { m_uD3DAdapterCount = pD3D->GetAdapterCount(); hMonitor = (HMONITOR*) calloc(m_uD3DAdapterCount, sizeof(*hMonitor)); printf("\nD3D9 says you have %d adapter(s):\n", m_uD3DAdapterCount); for (UINT i = 0; i < m_uD3DAdapterCount; i++) { D3DADAPTER_IDENTIFIER9 id; pD3D->GetAdapterIdentifier(i, 0, &id); HMONITOR mon = pD3D->GetAdapterMonitor(i); printf(" - %s (%s) %p\n", id.DeviceName, id.Description, mon); } pD3D->Release(); } } else { // Direct3DCreate9Ex is not supported on this // operating system. hr = ERROR_NOT_SUPPORTED; printf("Not supported\n"); } // Free the library. FreeLibrary(libHandle); } printf("\nEnumDisplayDevices:\n"); UINT m_rgpDisplaysCount = 0; for (UINT uDevice = 0; true; uDevice++) { DISPLAY_DEVICE dd; ZeroMemory(&dd, sizeof(dd)); dd.cb = sizeof(dd); if (!EnumDisplayDevices(NULL, uDevice, &dd, 0)) break; // no more devices printf("- %d: %s", uDevice, dd.DeviceName); if (!(dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) { printf(" (not attached to desktop)\n"); continue; } if (dd.StateFlags & (DISPLAY_DEVICE_REMOTE | DISPLAY_DEVICE_MIRRORING_DRIVER)) { if (dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) { printf(" (mirroring driver)\n"); continue; // mirror devices are considered hidden and should // be excluded as display. Remembering that a // non-local device is present is sufficient for // now. } } m_rgpDisplaysCount++; printf(" (OK)\n"); } printf("\nEnumDisplayDevices says %d device(s) are OK\n\n", m_rgpDisplaysCount); // If DX reported adapters that m_rgpDisplays doesn't have, dotnet assumes it's due to mode change. if (m_uD3DAdapterCount > m_rgpDisplaysCount) { printf("DotNet assumes a mode change, which causes issues in rendering, when m_uD3DAdapterCount > m_rgpDisplaysCount (%d > %d)\n", m_uD3DAdapterCount, m_rgpDisplaysCount); printf("See https://github.com/dotnet/wpf/blob/c4e74175da6108104491e1ae64982444d7c8713d/src/Microsoft.DotNet.Wpf/src/WpfGfx/core/common/display.cpp#L1629\n"); } else { printf("DotNet should be happy\n"); } printf("\nEnumDisplayMonitors:\n"); BOOL ret = EnumDisplayMonitors(NULL, NULL, Monitorenumproc, NULL); if (!ret) printf("EnumDisplayMonitors ret: %d\n", ret); return hr; }