Intel 82852/82855 Notebookgrafik mit Multiscreen unter Vista

mm77

Cadet 2nd Year
Registriert
März 2008
Beiträge
17
Hallo,

leider gibt es für die älteren Notebook-Grafikchips von Intel nur eingeschränkte Unterstützung in Vista. In meinem Fall handelt es sich um einen 855 GM/GME - Chipsatz. Vista liefert zwar einen Treiber von Intel mit (Intel 82852/82855 GM/GME Graphics), aber dem fehlt eine wichtige Funktion, wenn man noch einen externen Bildschirm an sein Notebook gehängt hat. Man kann nicht einstellen, welches der primäre Bildschirm ist.

Nun habe ich rausgefunden, wie man das auch manuell durch eine Registry-Änderung hinkriegt, und das Ganze in ein Visual Basic Script gegossen. Ich hoffe, dass ich so Anderen, die den gleichen Chipsatz haben, helfen kann. Außerdem habe ich die Hoffnung, dass die Methode prinzipiell auch bei ähnlichen Chipsätzen von Intel funktioniert. Die Daten in der Registry sind übrigens auch denen des Treibers von Intel für Windows XP recht ähnlich. Vielleicht lässt sich sogar der Dual Display Clone (gleiches Bild auf beiden Bildschirmen) durch Abgucken der Einstellungen von XP zum Laufen bringen. Wegen des Umschaltens auf den TV-Ausgang könnte man auch noch gucken. Es folgt der Visual Basic Script - Code mit Doku am Anfang:

Code:
' THIS SCRIPT IS EXPEREMENTAL. USE IT AT YOUR OWN RISK AND
' MAKE SURE THAT YOU UNDERSTAND WHAT IT DOES AND THAT YOU ARE
' ABLE TO RECOVER YOUR COMPUTER IN CASE OF A BREAKDOWN (FOR
' EXAMPLE A BLANK SCREEN)!


' This script chooses a screen as primary screen on Windows Vista
' with the Intel 82852/82855 GM/GME graphics driver (included in Vista)
' when you have an Intel 855GM/GME-chipset in your notebook.
' This is not natively supported by the driver in a way that
' can be used by normal users. I suppose that the driver doesn't
' offer the interfaces that are used by the Vista user interface
' to do this task. The driver is also not shipped with a special
' tool to change the primary screen. It seems that there are no
' other drivers available for Vista.
'
' The script also adjusts the screen resolution for the new primary
' screen.
'
' It is written in Visual Basic Script. It only works if scripting
' is not disabled on your Windows - system.
'
' The primary screen is chosen by changing the value of
'   HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\
'   Services\ialm\Device0\Display1_UID1
' in the registry. The following values are used:
'   internal screen as primary: 00 00 04 04
'   external screen as primary: 00 00 00 01
' It is possible that these values won't work for you. They
' could instead result in a blank screen. It is at least no bad
' idea to find out the current value in your registry. It is
' also recommended to make the first test with the /test - parameter.
' It is possible that this script also works with similar chipsets
' from Intel and that only the registry value is different.
'
' The script uses the file ResSwitch.exe which has to be in the
' same directory as this script. ResSwitch.exe is part of
' the small freeware tool QRes which can be downloaded here:
' http://www.naughter.com/qres.html
'
' This script is meant to be saved in a file called
' setPrimaryScreen.vbs. Make sure that no line breaks
' are added.
'
' The necessary command line - parameters are displayed when starting the
' script. It can also be started by a shortcut on your desktop.
' The script needs privileges to change the registry value mentioned
' above. The easiest way to achieve this is to run it as administrator.
' A shortcut could have the following target:
' %SYSTEMROOT%\system32\wscript.exe %SYSTEMROOT%\setPrimaryScreen.vbs ...
' If you do it this way (with wscript.exe) you are able to run it as
' administrator, but you will have to copy ResSwitch.exe to
' %SYSTEMROOT%\system32\
'
' Note: The error codes given back by the registry manipulation -
' operations that this script uses are not always helpful.


' used registry values (REG_BINARY), could be different for your computer:
Dim internalScreenRegistryValue, externalScreenRegistryValue
internalScreenRegistryValue = Array(0,0,4,4)  ' in regedit: 00 00 04 04
externalScreenRegistryValue = Array(0,0,0,1)  ' in regedit: 00 00 00 01
' be careful when copying values from regedit, I am not 100% sure,
' but I think that the hex-numbers in regedit (groups of two digits)
' have to be converted to integers which can be done with windows-
' calculator by converting from hex to dec


' ------- Don't change the following unless you are able to -------
' ------------ write scripts with Visual Basic Script! ------------



Dim errorCode

' validation of user input:
Dim usageMessage
usageMessage =_
        "Please use this script in the following format:"&vbNewLine&_
        "     "&WScript.ScriptName&" primaryScreen width height "&_
        "[/test]"&vbNewLine&_
        vbNewLine&_
        "primaryScreen has to be replaced by internal or external. "&_
        "width and height are the resolution for the primary "&_
        "screen. The parameter /test is optional. If it is used "&_
        "the script tries to change the registry value back to it's "&_
        "original value at the end (after 15 seconds)."&vbNewLine&_
        vbNewLine&_
        "Examples:"&vbNewLine&_
        "     "&WScript.ScriptName&" external 1280 1024"&vbNewLine&_
        "     "&WScript.ScriptName&" internal 1024 768"&vbNewLine&_
        "     "&WScript.ScriptName&" internal 1024 768 /test"&vbNewLine&_
        vbNewLine&_
        "The script has done nothing. Please start it again."
If  ( WScript.Arguments.Count < 3 ) Then
   WScript.Echo(usageMessage)
   WScript.Quit(-1)
Else
   If  ( _
           Wscript.Arguments(0) <> "external" _
           And _
           Wscript.Arguments(0) <> "internal" _
       ) _
       Or _
       ( Not isNumeric(Wscript.Arguments(1)) ) _
       Or _
       ( Not isNumeric(Wscript.Arguments(2)) ) Then
      WScript.Echo(usageMessage)
      WScript.Quit(-1)
   End If
End If

' check if ResSwitch.exe is present:
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FileExists("ResSwitch.exe") Then
   WScript.Echo(_
       "The file ResSwitch.exe is not present in the directory where this "&_
       "script is located. ResSwitch.exe is part of the "&_
       "small freeware tool QRes. You can download it here:"&vbNewLine&_
       "     http://www.naughter.com/qres.html"&vbNewLine&vbNewLine&_
       "The script is aborted. Nothing was changed.")
   WScript.Quit(-1)
End If

Dim testMode
testMode = false
If WScript.Arguments.Count > 3 Then
   If Wscript.Arguments(3) = "/test" Then
      testMode = true
   End If
End If

' choose code that will be set in registry
' depending on the selected primaryScreen:
Dim displayCode
If Wscript.Arguments(0) = "external" Then
   displayCode = externalScreenRegistryValue
Else
   If Wscript.Arguments(0) = "internal" Then
      displayCode = internalScreenRegistryValue
   End If
End If

' if test-parameter given, save current registry value:
If testMode Then
   Dim originalDisplayCode
   errorCode = getRegValue(originalDisplayCode)
   if errorCode <> 0 Then
      WScript.Echo("The current registry value couldn't be read for "&_
                   "later restoring (necessary for test-mode). "&_
                   "The error code is "&CStr(errorCode)&". You can try "&_
                   "to google for WbemErrorEnum and look the error code "&_
                   "up. The script is aborted. Nothing was changed.")
      WScript.Quit(-1)
   End If
End If

' set value in registry to change primary screen:
errorCode = setRegValue(displayCode)
if errorCode <> 0 Then
   Dim errorMsg
   errorMsg =_
         "An error occured during changing the registry value. "&_
         "The error code is " & CStr(errorCode) & ". You can try to "&_
         "google for WbemErrorEnum and look the error code up. "&_
         "The script is aborted. It is not 100% sure if the registry "&_
         "is unchanged. Possible changes are not applied until "&_
         "display settings like resolution are changed or the "&_
         "computer is restarted."
   If testMode Then
      errorMsg = errorMsg &_
         " The original registry value was "&_
         regValueToStr(originalDisplayCode)&". "&_
         "You can use regedit to verify that the registry value is still "&_
         "the original value and change it manually if it is not. "&_
         "You will find it here: HKEY_LOCAL_MACHINE\SYSTEM\"&_
         "CurrentControlSet\Services\ialm\Device0\Display1_UID1"
   End If
   WScript.Echo(errorMsg)
   WScript.Quit(-1)
End If

' change resolution (this will also apply registry changes):
errorCode = changeScreenResolution(Wscript.Arguments(1),Wscript.Arguments(2))
if errorCode <> 0 Then
   WScript.Echo("An error occured during changing the resolution. "&_
                "The error code returned by ResSwitch.exe is " &_
                CStr(errorCode) &_
                ". The registry value was changed, but this change isn't "&_
                "applied until display settings like resolution are "&_
                "changed or the computer is restarted. If the script "&_
                "was started in test-mode the registry value will be "&_
                "changed back to the original value.")
End If

' if test-parameter given, change registry value back to original value
' and apply it by changing screen resolution again after 15 seconds:
If testMode Then
   WScript.sleep(15000)
   errorCode = setRegValue(originalDisplayCode)
   If errorCode <> 0 Then
      WScript.Echo(_
          "An error occured during changing the registry value "&_
          "back to the original value. I am very sorry. "&_
          "The error code is " & CStr(errorCode) & ". You can try to "&_
          "google for WbemErrorEnum and look the error code up. "&_
          "The original registry value was "&_
          regValueToStr(originalDisplayCode)&". You "&_
          "can use regedit to change the registry value back "&_
          "to the original value. "&_
          "You will find it here: HKEY_LOCAL_MACHINE\SYSTEM\"&_
          "CurrentControlSet\Services\ialm\Device0\Display1_UID1")
      WScript.Quit(-1)
   End If
   errorCode = changeScreenResolution(_
                      Wscript.Arguments(1),Wscript.Arguments(2))
   If errorCode <> 0 Then
      WScript.Echo(_
          "An error occured during changing the resolution. "&_
          "The error code returned by ResSwitch.exe is "&CStr(errorCode)&_
          ". The registry value was changed back to it's original value, "&_
          "but this change isn't applied until display settings like "&_
          "resolution are changed or the computer is restarted.")
      WScript.Quit(-1)
   End If
   WScript.Echo("The registry value was changed back to it's original "&_
                "value.")
End If


' ------- subroutines with the most important code: -------

' changes screen resolution, width and height have to be numeric,
' function returns an error code, 0 means success
Function changeScreenResolution (width, height)
   ' starts ResSwitch.exe as new process and waits for it to finish
   Set oShell = CreateObject("WScript.Shell")
   changeScreenResolution = oShell.run (_
                               "ResSwitch.exe /WIDTH:" & CInt(width) &_
                                            " /HEIGHT:" & CInt(height) &_
                                            " /RESET", 0, true)
End Function

' reads value of HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\
' Services\ialm\Device0\Display1_UID1 from registry and stores
' it in parameter value, value is of type uint8 value[] (REG_BINARY-
' representation), function returns an error code, 0 means success
Function getRegValue(ByRef value)
   Const HKEY_LOCAL_MACHINE = &H80000002
   Set objRegistry = GetObject("Winmgmts:root\default:StdRegProv")
   getRegValue = objRegistry.GetBinaryValue(_
                    HKEY_LOCAL_MACHINE,_
                    "SYSTEM\CurrentControlSet\Services\ialm\Device0",_
                    "Display1_UID1",_
                    value)
End Function

' sets HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\
' Services\ialm\Device0\Display1_UID1 to value,
' value is of type uint8 value[] (REG_BINARY-representation),
' function returns an error code, 0 means success
Function setRegValue(value)
   Const HKEY_LOCAL_MACHINE = &H80000002
   Set objRegistry = GetObject("Winmgmts:root\default:StdRegProv")
   setRegValue = objRegistry.SetBinaryValue(_
                    HKEY_LOCAL_MACHINE,_
                    "SYSTEM\CurrentControlSet\Services\ialm\Device0",_
                    "Display1_UID1",_
                    value)
End Function

' gets parameter value of type uint8 value[] representing value in registry,
' returns a string that represents the value as hex-numbers,
' the string-representation should be the same as REG_BINARY in regedit
Function regValueToStr(value)
   Dim result
   Dim currentByte
   result = ""
   For i=0 To UBound(value)
      currentByte = CStr(Hex(value(i)))
      If value(i) < 17 Then
         currentByte = "0" & currentByte
      End If
      result = result & " " & currentByte
   Next
   result = LTrim(result)
   regValueToStr = result
End Function

Wenn das beim jeweiligen Chipsatz nicht funktioniert, kann man auch folgende Methode ausprobieren:

Umschalten von externem auf internes Display:
1. Rechner runterfahren
2. Kabel zum externen Display entfernen
3. Rechner neu hochfahren

Umschalten von internem auf externes Display:
1. in Geräte-Manager gehen
2. Treiber aktualisieren bei der Grafikkarte wählen
3. über manuelle Wahl des Treibers aus der Liste verfügbarer Treiber den bisherigen Treiber neu installieren
4. Rechner neu starten

Wenn das klappt, kann man auch davon ausgehend versuchen herauszufinden, was sich bei dem jeweiligen Chipsatz in der Registry ändert, wenn man zwischen den beiden Displays umschaltet. Das kann man ganz gut machen, indem man in regedit den Schlüssel HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ialm als txt-Datei exportiert, einmal mit dem internen Display als primärem Display und einmal mit dem externen Display als primärem Display. Mit einem Vergleichstool für Textdateien kann man dann recht schnell die Unterschiede sehen. Ich habe dafür die Vergleichsfunktion des Programms Eclipse genommen, aber es gibt solche Tools auch als stand-alone (z.B. http://winmerge.org/ [selbst nicht ausprobiert], weitere: http://en.wikipedia.org/wiki/Comparison_of_file_comparison_tools).

Bei mir fand ich heraus, dass sich der Wert von HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ialm\Device0\Display1_UID1 unterscheidet. Bei internem Display als primärem Display ist es 00 00 04 04, bei externem Display als primärem Display 00 00 00 01.

Ich bin gespannt, bei welchen Chipsätzen die von mir gefundenen Registrywerte funtionieren. Wenn jemand weitere Werte rausfindet, bitte posten!
 
Zuletzt bearbeitet: (Tippfehler)
Zurück
Oben