It's a subtle point, but make sure hDC is a device context for one of your display devices, not the entire desktop. This might be the reason if you happen to have SetDeviceGammaRamp() returning FALSE and GetLastError() reporting ERROR_INVALID_PARAMETER. You can find display devices using EnumDisplayMonitors() and GetMonitorInfo().
Another interesting side effect is that sometimes it appears that the provided gamma ramp provided may be modified by SetDeviceGammaRamp(). This also appears to be device dependent. It's best to make a copy of the gamma ramp if you are setting it from a ramp that you're holding on to for a reference ramp or other needs.
Sample code:
D3DGAMMARAMP* g_pRamp = 0;
BOOL CALLBACK EnumMonitorProc( HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData )
{
MONITORINFOEX info;
info.cbSize = sizeof(info);
if ( GetMonitorInfo( hMonitor, (LPMONITORINFO)info ) == TRUE )
{
HDC hDC = CreateDC( _T("DISPLAY"), info.szDevice, 0, 0 );
if ( hDC != 0 )
{
D3DGAMMARAMP localRamp = *g_pRamp;
SetDeviceGammaRamp( hDC, &localRamp );
DeleteDC( hDC );
}
}
// Continue to next device
return TRUE;
}
void SetGammaRampAllDisplays( D3DGAMMARAMP* pRamp )
{
// Set the global ramp for the callback function
g_pRamp = pRamp;
EnumDisplayMonitors( 0, 0, EnumMonitorProc, 0 );
g_pRamp = 0;
}