Wie kann man die aktuelle Einstellung der Hardwarebeschleunigung der Grafikkarte ermitteln bzw. ändern?
Leider gibt es dafür keine direkte API in Windows, offensichtlich macht das Kontrollfeld (in XP: Desktop -> Eigenschaften -> Einstellungen -> Erweitert -> Problembehandlung -> Hardwarebeschleunigung) des Explorers das auch direkt in der Registry (dort wird der Wert abgelegt). 

 Insofern muss man bei einer "nachgebauten" Lösung immer mit etwas "Raten" leben. 
Folgende Unit kann die aktuelle Einstellung ermitteln, setzen und eine Änderung auch direkt wirksam machen:
																	1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174:
  				 | 									unit UVHWAccel;
 
  interface
  function GetPrimaryDisplayKey(const ForceUpdate: Boolean = FALSE): AnsiString;
  function GetHardwareAccelerationLevel: Integer;
  function SetHardwareAccelerationLevel(const NewLevel: Integer): Boolean;
  function ForceUpdateDisplaySettings: Boolean;
  implementation
  uses   Windows, Registry, SysUtils;
  const   DISPLAY_DEVICE_PRIMARY_DEVICE = DWORD($00000004);
    REG_PATH_VIDEO = AnsiString('\HARDWARE\DEVICEMAP\VIDEO');   REG_KEY_VIDEO0 = AnsiString('\Device\Video0');   REG_PREFIX     = AnsiString('\REGISTRY\MACHINE');   REG_ACCEL_VAL  = AnsiString('Acceleration.Level');
    ENUM_CURRENT_SETTINGS = DWORD(-1);  type     TDisplayDevice = packed record     cb: DWORD;     DeviceName: array[0..31] of AnsiChar;     DeviceString: array[0..127] of AnsiChar;     StateFlags: DWORD;     DeviceID: array[0..127] of AnsiChar;     DeviceKey: array[0..127] of AnsiChar;   end;
  var   PrimaryDisplayKeyCached: AnsiString;
  function EnumDisplayDevices(Unused: Pointer; iDevNum: DWORD;   var lpDisplayDevice: TDisplayDevice; dwFlags: DWORD): BOOL;   stdcall; external user32 name 'EnumDisplayDevicesA';
  function GetPrimaryDisplayKey(const ForceUpdate: Boolean = FALSE): AnsiString;   var     DisplayDevice: TDisplayDevice;     iDevNum: DWORD;     Reg: TRegistry; begin   if ForceUpdate then     PrimaryDisplayKeyCached := '';   if (PrimaryDisplayKeyCached = '') then begin         DisplayDevice.cb := SizeOf(DisplayDevice);     iDevNum:= 0;         while (PrimaryDisplayKeyCached = '') and EnumDisplayDevices(NIL, iDevNum, DisplayDevice, 0) do begin       if (DisplayDevice.StateFlags and DISPLAY_DEVICE_PRIMARY_DEVICE) <> 0 then         PrimaryDisplayKeyCached := DisplayDevice.DeviceKey;               Inc(iDevNum);     end;         if (PrimaryDisplayKeyCached = '') then begin       Reg := TRegistry.Create(KEY_READ);       try         try           Reg.RootKey := HKEY_LOCAL_MACHINE;           if Reg.OpenKey(REG_PATH_VIDEO, FALSE) then             PrimaryDisplayKeyCached := Reg.ReadString(REG_KEY_VIDEO0);         finally           Reg.Free;         end;       except         PrimaryDisplayKeyCached := '';       end;     end;         if (UpperCase(Copy(PrimaryDisplayKeyCached, 1, Length(REG_PREFIX))) = REG_PREFIX) then       Delete(PrimaryDisplayKeyCached, 1, Length(REG_PREFIX));   end;   Result := PrimaryDisplayKeyCached; end;
  function GetHardwareAccelerationLevel: Integer;   var     Reg: TRegistry; begin   Result := -1;   if (PrimaryDisplayKeyCached = '') then     GetPrimaryDisplayKey;   if (PrimaryDisplayKeyCached <> '') then begin     Reg := TRegistry.Create(KEY_READ);     try       Reg.RootKey := HKEY_LOCAL_MACHINE;       if Reg.OpenKey(PrimaryDisplayKeyCached, FALSE) then begin         if Reg.ValueExists(REG_ACCEL_VAL) then           Result := Reg.ReadInteger(REG_ACCEL_VAL)         else           Result := 0;       end     finally       Reg.Free;     end;   end; end;
  function SetHardwareAccelerationLevel(const NewLevel: Integer): Boolean;   var     Reg: TRegistry; begin   Result := FALSE;   if (PrimaryDisplayKeyCached = '') then     GetPrimaryDisplayKey;   if (PrimaryDisplayKeyCached <> '') then begin     Reg := TRegistry.Create;     try       Reg.RootKey := HKEY_LOCAL_MACHINE;       if Reg.OpenKey(PrimaryDisplayKeyCached, FALSE) then begin         if (NewLevel = 0) then begin           Reg.DeleteValue(REG_ACCEL_VAL);           Result := TRUE;         end         else if (NewLevel in [1..5]) then begin           Reg.WriteInteger(REG_ACCEL_VAL, NewLevel);           Result := TRUE;         end;       end     finally       Reg.Free;     end;   end; end;
  function ForceUpdateDisplaySettings: Boolean;   var     DevMode: TDevMode; begin     Result := EnumDisplaySettings(NIL, ENUM_CURRENT_SETTINGS, DevMode);   if Result then         ChangeDisplaySettings(DevMode, CDS_RESET); end;
  initialization   PrimaryDisplayKeyCached := '';
  end.					 				 | 			
		
	  Anmerkungen:
- Die Identifikation des primären Display-Devices erfolgt im Wesentlichen über die Funktion EnumDisplayDevices, die mittlerweile auch den Registrierungsschlüssel des entsprechenden Gerätes liefert (seit wann, weiß ich leider nicht). Wenn das primäre Device nicht auf diesem Wege ermittelt werden kann, wird manuell unter \\HKLM\HARDWARE\DEVICEMAP\VIDEO\Device\Video0 in der Registrierung gesucht, was aber leider nicht immer funktioniert, da es von dem Treiber abhängt, wie das Device dort eingetragen wird. Es ist also prinzipiell möglich, dass die Funktionen der Unit nicht genutzt werden können, weil der Registrierungs-Schlüssel des primären Devices nicht gefunden wurde.
 - Bisher getestet unter Win XP prof sp3, weitere Testergebnisse sind willkommen
 
Benutzung:
		                    
            
                        Delphi-Quelltext                    
           	 															1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
  				 | 									uses   ..., UVHWAccel;
    var     i: Integer; begin   i := GetHardwareAccelerationLevel;   if (i >= 0) then     ShowMessage(IntToStr(i))   else     ShowMessage('Fehler!'); end;
  begin   if SetHardwareAccelerationLevel(0) then     ForceUpdateDisplaySettings   else     ShowMessage('Fehler!');					 				 | 			
		
	  
Im Anhang befindet sich eine Demo-Anwendung mit Quelltext.
Als kleine Spezial-Zugabe hängt auch noch ein Kommandozeilenutility (mit Quelltext) dran, so dass man die Funktionalität direkt fertig gekapselt nutzen kann. 
Warum braucht man das überhaupt? 
Leider kommt es unter bestimmten Umständen zu einer Fehlersituation bei Fernwartungs-Programmen (z.B. NetOp, VNC, etc.) und Java-Anwendungen: der Inhalt eines Java-Fensters wird in der Fernwartung nicht angezeigt (leer oder schwarz), da die Java-Laufzeitumgebung irgendwelche Probleme mit dem Grafiktreiber hat (die Details führen hier wirklich zu weit, da schieben sich auch die Beteiligten gegenseitig den Schwarzen Peter zu, die (vor allem Onboard-)Treiber-Hersteller sagen, dass Java-Framework ist "kaputt", die Java-Leute sagen, der Treiber ist "kaputt", *seufz*). Wenn man dann die Hardwarebeschleunigung runterdreht, so dass die DD-Funktionen von Java nicht mehr verwendet werden, ist der Inhalt der Java-Fenster wieder in der Fernwartung sichtbar. 

 
There are 10 types of people - those who understand binary and those who don´t.