struct D3DDevice; struct DisplayMode; struct DisplayDriver { DisplayDriver* Next; GUID Guid; char* Description; D3DDevice* D3DDeviceList; DisplayMode* DisplayModeList; }; struct D3DDevice { D3DDevice* Next; GUID Guid; char* Name; BOOL IsHW; }; struct DisplayMode { DisplayMode* Next; int Width; int Height; int Depth; }; DisplayDriver* DisplayDriverList; LPDIRECTDRAW7 pDirectDraw; LPDIRECT3D7 pDirect3D; HRESULT CALLBACK EnumDisplayDrivers( GUID FAR* pGuid, LPSTR DriverDescription, LPSTR DriverName, LPVOID Context, HMONITOR HMonitor ); HRESULT CALLBACK EnumDisplayModes( LPDDSURFACEDESC2 pDDSD, LPVOID Context ); HRESULT CALLBACK EnumDevices( LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 pD3DDD, LPVOID Context ); void ReleaseLists(); BOOL EnumerateDirectX( HWND hWnd ) { ReleaseLists(); DirectDrawEnumerateEx(( LPDDENUMCALLBACKEX )EnumDisplayDrivers, NULL, DDENUM_ATTACHEDSECONDARYDEVICES | DDENUM_DETACHEDSECONDARYDEVICES | DDENUM_NONDISPLAYDEVICES ); for( DisplayDriver* TheDD = DisplayDriverList; TheDD; TheDD = TheDD->Next ) { DirectDrawCreateEx( &( TheDD->Guid ), ( void** ) &pDirectDraw, IID_IDirectDraw7, NULL ); pDirectDraw->SetCooperativeLevel( hWnd, DDSCL_NORMAL ); pDirectDraw->EnumDisplayModes( 0, NULL, &( TheDD->DisplayModeList ), ( LPDDENUMMODESCALLBACK2 )EnumDisplayModes ); pDirectDraw->QueryInterface( IID_IDirect3D7, ( void** ) &pDirect3D ); pDirect3D->EnumDevices(( LPD3DENUMDEVICESCALLBACK7 )EnumDevices, &( TheDD->D3DDeviceList )); DXRELEASE( pDirect3D ); DXRELEASE( pDirectDraw ); } return TRUE; } HRESULT CALLBACK EnumDisplayDrivers( GUID FAR* pGuid, LPSTR DriverDescription, LPSTR DriverName, LPVOID Context, HMONITOR HMonitor ) { DisplayDriver* NewDD = new DisplayDriver; if( NewDD ) { ZeroMemory( NewDD, sizeof( DisplayDriver )); if( pGuid ) CopyMemory( &( NewDD->Guid ), pGuid, sizeof( GUID )); NewDD->Description = new char[strlen( DriverDescription ) + 1]; if( NewDD->Description ) { strcpy( NewDD->Description, DriverDescription ); } NewDD->DisplayModeList = NULL; NewDD->D3DDeviceList = NULL; NewDD->Next = NULL; } if( !DisplayDriverList ) DisplayDriverList = NewDD; else { for( DisplayDriver* TheDD = DisplayDriverList; TheDD->Next; TheDD = TheDD->Next ) ; TheDD->Next = NewDD; } return DDENUMRET_OK; } HRESULT CALLBACK EnumDisplayModes( LPDDSURFACEDESC2 pDDSD, LPVOID Context ) { DisplayMode** DMList = ( DisplayMode** )Context; DisplayMode* NewDM = new DisplayMode; if( NewDM ) { NewDM->Width = pDDSD->dwWidth; NewDM->Height = pDDSD->dwHeight; NewDM->Depth = pDDSD->ddpfPixelFormat.dwRGBBitCount; NewDM->Next = NULL; } if( !( *DMList )) *DMList = NewDM; else { for( DisplayMode* TheDM = *DMList; TheDM->Next; TheDM = TheDM->Next ) ; TheDM->Next = NewDM; } return DDENUMRET_OK; } HRESULT CALLBACK EnumDevices( LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 pD3DDD, LPVOID Context ) { D3DDevice** DevList = ( D3DDevice** )Context; D3DDevice* NewDev = new D3DDevice; if( NewDev ) { CopyMemory( &( NewDev->Guid ), &( pD3DDD->deviceGUID ), sizeof( GUID )); NewDev->Name = new char[strlen( DeviceName ) + 1]; if( NewDev->Name ) { strcpy( NewDev->Name, DeviceName ); } NewDev->IsHW = pD3DDD->dwDevCaps & D3DDEVCAPS_HWRASTERIZATION; NewDev->Next = NULL; } if( !( *DevList )) *DevList = NewDev; else { for( D3DDevice* TheDev = *DevList; TheDev->Next; TheDev = TheDev->Next ) ; TheDev->Next = NewDev; } return DDENUMRET_OK; } void ReleaseLists() { if( DisplayDriverList ) { DisplayDriver* TheDD, * NextDD; for( TheDD = DisplayDriverList; TheDD; TheDD = NextDD ) { NextDD = TheDD->Next; if( TheDD->Description ) delete TheDD->Description; if( TheDD->DisplayModeList ) { DisplayMode* TheDM, * NextDM; for( TheDM = TheDD->DisplayModeList; TheDM; TheDM = NextDM ) { NextDM = TheDM->Next; delete TheDM; } } if( TheDD->D3DDeviceList ) { D3DDevice* TheDev, * NextDev; for( TheDev = TheDD->D3DDeviceList; TheDev; TheDev = NextDev ) { NextDev = TheDev->Next; if( TheDev->Name ) delete TheDev->Name; delete TheDev; } } delete TheDD; } DisplayDriverList = NULL; } }