1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. veronesi

Beiträge von veronesi

  • DLLs sind kompliziert...

    • veronesi
    • 27. Mai 2010 um 16:26

    Also auf das wäre ich jetzt nie gekommen!
    Woher hast Du das? Diese MSDN Dokus verstehe ich nicht!

    Nun zeige ich mit _ArrayDisplay($Ret) das ganze Array an.
    Jedoch kann ich damit nichts anfangen! Egal auf welchem Bildschirm der Mauszeiger sich befindet, ich bekomme für [0] und [2] immer die gleichen Werte. Für [1] bekomme ich immer einen anderen Wert, der ist jedoch auch unterschiedlich, wenn ich die Maus nicht bewege!

    Was könnte dies nun sein?

    Zudem steht in der MSDN Doku man müsse "MONITOR_DEFAULTTONEAREST" nehmen. Ich habe einfach mal angenommen, das ist 0 (deshalb die 0 am Ende des DllCalls)

  • DLLs sind kompliziert...

    • veronesi
    • 27. Mai 2010 um 16:17

    Vielen Dank Euch beiden!
    Es funktioniert beides!

    Da die Funktion jedoch einen "Point Structure" erwartet, bevorzuge ich die Variante von Progandy, weil "bloss" ein Parameter für diesen Point übergeben wird. Aber das von Marthog geht trotzdem auch!

    Interessanterweise habe ich gemerkt, dass ich nur mein "ptr" in "uint64" ändern muss, dann läuft es!

    Spoiler anzeigen
    [autoit]

    Local $Struct, $ptrStruct, $Ret

    [/autoit] [autoit][/autoit] [autoit]

    $Struct = DllStructCreate("long;long")
    DllStructSetData($Struct, 1, MouseGetPos(0))
    DllStructSetData($Struct, 2, MouseGetPos(1))
    $ptrStruct = DllStructGetPtr($Struct)

    [/autoit] [autoit][/autoit] [autoit]

    $Ret = DllCall("User32.dll", "handle", "MonitorFromPoint", "uint64", $ptrStruct, "dword", 0)

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0,"",$Ret)

    [/autoit]

    Gut, die MessageBox liefert ein Leerstring zurück, doch ich denke, dass kann die gar nicht anzeigen - ein Handle!

    Nun geht's aber weiter! Wie könnte ich mit diesem Handle auf den Monitor die korrekte Monitornummer herausfinden?

  • DLLs sind kompliziert...

    • veronesi
    • 27. Mai 2010 um 15:42
    Zitat von Cartan12

    Edit: und zwar genau beim DllCall aufruf...

    Ja, es stürzt beim DllCall Aufruf ab!
    Aber weshalb?
    Vermutlich steuere ich die Funktion falsch an!

    Aber wie wäre es korrekt?

  • DLLs sind kompliziert...

    • veronesi
    • 27. Mai 2010 um 15:41
    Zitat von Ubuntu

    Dafür müsstest du die Auflösungen aller Bildschirme kennen

    Die kenne ich!
    Siehe meine Scripte im gerade editierten Post vorher!

  • DLLs sind kompliziert...

    • veronesi
    • 27. Mai 2010 um 15:37

    Hallo Ubuntu,

    vielen Dank.
    Doch dies funktioniert doch "nur" bei max. 2 Monitoren! Oder?
    Ich habe hier 8 Monitore gleichzeitig....

    Ich möchte schlussendlich herausfinden, auf welchem Bildschirm die Maus ist. Dann könnte ich mit der folgenden Funktion alle geöffneten Fenster auf dem Monitor anordnen, wo die Maus ist!
    _TileWindows()

    Spoiler anzeigen
    [autoit]

    #include-once
    #include "Func_GetMonitorInfo.au3"
    #include "Func_GetMouseInfo.au3"

    [/autoit] [autoit][/autoit] [autoit]

    Func _TileWindows()
    ;Tile Windows on that screen where the mouse is!
    ;Call: _TileWindows()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $MonNr, $Left, $Top, $Right, $Bottom, $tStruct, $Rect, $aTmp[32][32]
    $MonNr = _GetMouseInfo()
    $aTmp = _GetMonitorInfo()

    [/autoit] [autoit][/autoit] [autoit]

    $Left = $aTmp[$MonNr][2]
    $Top = $aTmp[$MonNr][3]
    $Right = $aTmp[$MonNr][0]
    $Bottom = $aTmp[$MonNr][1]

    [/autoit] [autoit][/autoit] [autoit]

    $tStruct = DllStructCreate("int[4]") ;4 points of values that are integers
    DllStructSetData($tStruct, 1, $Left, 1)
    DllStructSetData($tStruct, 1, $Top, 2)
    DllStructSetData($tStruct, 1, $Right, 3)
    DllStructSetData($tStruct, 1, $Bottom, 4)
    $Rect = DllStructGetPtr($tStruct) ;Now $rect holds our left/top/right/bottom values in a type of array basically

    [/autoit] [autoit][/autoit] [autoit]

    DllCall("user32.dll", "int", "TileWindows", "int", 0, "int", 0, "Ptr", $Rect, "int", 0, "int", 0)
    EndFunc

    [/autoit]


    _GetMonitorInfo()
    (Leider stimmen hier die Monitor-Nummern nicht mit den Nummern von Windows überein. Das wäre eigentlich schon alles was ich bräuchte! Wenn diese Funktion die korrekten
    Monitor-Nummern - so wie Windows sie vergibt - zurückgeben würde, dann wäre alles o.k.)

    Spoiler anzeigen
    [autoit]

    #include-once

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetMonitorInfo()
    ;Returns some informations about your screens
    ;Call: _GetMonitorInfo()
    ;Return: Array With
    ;[0][0] Nr of Monitors
    ;[1][0] X Resolution of Monitor 1
    ;[1][1] Y Resolution of Monitor 1
    ;[1][2] X Position of Monitor 1
    ;[1][3] Y Position of Monitor 1

    [/autoit] [autoit][/autoit] [autoit]

    ;[2][0] X Resolution of Monitor 2
    ;[2][1] Y Resolution of Monitor 2
    ;[2][2] X Position of Monitor 2
    ;[2][3] Y Position of Monitor 2
    ;......

    [/autoit] [autoit][/autoit] [autoit]

    Local $NrOfMonitors, $ResolutionX[32], $ResolutionY[32], $PositionX[32], $PositionY[32], $Ret
    Local $cbMonitorEnumProc = DllCallbackRegister("MonitorEnumProc", "ubyte", "ptr;ptr;ptr;int")

    [/autoit] [autoit][/autoit] [autoit]

    If @error Then Return SetError(1, 0, False)
    Local $strctCount = DllStructCreate("uint Count;uint Width[12];uint Height[12];int left[12];int top[12]")
    If @error Then Return SetError(2, @error, False)
    Local $iCount

    [/autoit] [autoit][/autoit] [autoit]

    DllStructSetData($strctCount, "Count", 0)

    [/autoit] [autoit][/autoit] [autoit]

    $Ret = DllCall("User32.dll", "ubyte","EnumDisplayMonitors","ptr", 0,"ptr", 0, "ptr", DllCallbackGetPtr($cbMonitorEnumProc), "ptr", DllStructGetPtr($strctCount))
    If @error Or $Ret[0] = 0 Then Return SetError(3, @error, False)

    [/autoit] [autoit][/autoit] [autoit]

    DllCallbackFree($cbMonitorEnumProc)

    [/autoit] [autoit][/autoit] [autoit]

    $iCount = Int(DllStructGetData($strctCount, "Count"))

    [/autoit] [autoit][/autoit] [autoit]

    Local $aMonitors[$iCount+1][4] = [[$iCount]]

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $iCount
    $aMonitors[$i][0] = Int(DllStructGetData($strctCount, "Width",$i))
    $aMonitors[$i][1] = Int(DllStructGetData($strctCount, "Height",$i))
    $aMonitors[$i][2] = Int(DllStructGetData($strctCount, "left",$i))
    $aMonitors[$i][3] = Int(DllStructGetData($strctCount, "top",$i))
    Next

    [/autoit] [autoit][/autoit] [autoit]

    $strctCount = 0
    Return $aMonitors
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func MonitorEnumProc($hMonitor, $hdcMonitor, $lprcMonitor, $dwData)
    Local $strctRECT = DllStructCreate("long left;long top;long right;long bottom", $lprcMonitor)
    Local $strctCount = DllStructCreate("uint Count;uint Width[12];uint Height[12];int left[12];int top[12]", $dwData)
    Local $iNumber = DllStructGetData($strctCount, "Count")
    Local $Height = Int(DllStructGetData($strctRECT, "bottom"))-Int(DllStructGetData($strctRECT, "top"))
    Local $Width = Int(DllStructGetData($strctRECT, "right"))-Int(DllStructGetData($strctRECT, "left"))

    [/autoit] [autoit][/autoit] [autoit]

    DllStructSetData($strctCount, "Width", $Width, $iNumber+1)
    DllStructSetData($strctCount, "Height", $Height, $iNumber+1)
    DllStructSetData($strctCount, "left", Int(DllStructGetData($strctRECT, "left")), $iNumber+1)
    DllStructSetData($strctCount, "top", Int(DllStructGetData($strctRECT, "top")), $iNumber+1)
    DllStructSetData($strctCount, "Count", $iNumber+1)
    Return True
    EndFunc

    [/autoit]


    _GetMouseInfo()

    Spoiler anzeigen
    [autoit]

    #include-once
    #include "Func_GetMonitorInfo.au3"
    Func _GetMouseInfo()
    ;Returns the screen number on which the actual mouse cursor is
    ;Call: _GetMouseInfo()

    Local $aTmp[32][32], $MousePos, $NrOfScreens, $i
    $MousePos = MouseGetPos()
    $aTmp = _GetMonitorInfo()
    If @error <> 0 Then Return 1 ;If any error found Return Screen Number 1
    $NrOfScreens = $aTmp[0][0]
    For $i = 1 To $NrOfScreens
    If $MousePos[0] >= $aTmp[$i][2] AND ($MousePos[0] <= $aTmp[$i][2] + $aTmp[$i][0]) AND $MousePos[1] >= $aTmp[$i][3] AND ($MousePos[1] <= $aTmp[$i][3] + $aTmp[$i][1]) Then Return $i
    ;Checks on which Screen the Mousecursor is
    Next
    EndFunc

    [/autoit]


    Trotzdem danke!

  • DLLs sind kompliziert...

    • veronesi
    • 27. Mai 2010 um 14:43

    ... zumindestens für mich!

    Vielleicht kann mir ja jemand dabei helfen:
    Ich stehe mit den DLLs etwas auf Kriegsfuss.
    Das liegt vielleicht auch daran, dass ich eigentlich kein Programmierer bin und das ziemlich kompliziert finde!

    Ich möchte mit der Funktion MonitorFromPoint aus der User32.dll ein handle zurückbekommen, welches sich auf den Monitor bezieht, wo sich die Maus gerade befindet.
    Dann möchte ich damit die Monitornummer zurückbekommen, auf welchem sich die Maus gerade befindet.

    Angefangen habe ich damit:

    [autoit]

    Local $Struct, $ptrStruct, $Ret

    [/autoit][autoit][/autoit][autoit]

    $Struct = DllStructCreate("long;long")
    DllStructSetData($Struct, 1, MouseGetPos(0))
    DllStructSetData($Struct, 2, MouseGetPos(1))
    $ptrStruct = DllStructGetPtr($Struct)

    [/autoit][autoit][/autoit][autoit]

    $Ret = DllCall("User32.dll", "handle", "MonitorFromPoint", "ptr", $ptrStruct, "dword", 0)
    MsgBox(0,"",$Ret)

    [/autoit]

    Doch leider stürzt mir bei der zweitletzten Zeile AutoIt ab. Was könnte der Fehler in dieser Zeile sein?
    Die Dokumentation zu dieser Funktion in der User32.dll findet ihr hier

    Und wie könnte ich danach mit diesem Handle weiterarbeiten, wenn es mal läuft?

    Für Ideen wäre ich dankbar!
    Gruss
    Veronesi

  • Problem mit Windows7

    • veronesi
    • 27. Mai 2010 um 10:07

    Umgehen kannst Du das nicht, ohne die UAC zu deaktivieren.
    Sämtliche Scripts halten dann an.

    Windows erstellt dann nämlich quasi eine Bildschirmkopie, legt diese auf einen weiteren (virtuellen) Bildschirm und blendet die UAC Meldung ein.

    Aber du kannst ein

    [autoit]

    #RequireAdmin

    [/autoit]


    einfügen. Damit kommt die UAC Meldung nur einmal beim starten.

    Ich habe z.B. ein Script, welches 52 Kundenspezifische Applikationen automatisiert installiert. Früher musste man 52x die UAC bestätigen.
    Nun nur noch einmal, danach läuft alles automatisch.

    Mit

    [autoit]

    RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System","ConsentPromptBehaviorAdmin","REG_DWORD",0) ; Temporary disable UAC from Vista/Win7 for Installers!

    [/autoit]


    kannst Du die UAC Meldung temporär abschalten. Das geht aber nur, wenn du lokaler Admin bist.

    Mit

    [autoit]

    If @OSVersion = "WIN_VISTA" Then RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System","ConsentPromptBehaviorAdmin","REG_DWORD",2) ; Enable UAC
    If @OSVersion = "WIN_7" Then RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System","ConsentPromptBehaviorAdmin","REG_DWORD",5) ; Enable UAC

    [/autoit]


    kannst Du die UAC Meldungen wieder einschalten.

    Alternativ kannst Du die AutoIt EXE auch bei den geplanten Tasks einfügen. Diese laufen ohne UAC Meldung automatisch durch....

  • WinGettitle

    • veronesi
    • 26. Mai 2010 um 15:36

    Hier eine mögliche Lösung.
    Vielleicht nicht ganz so elegant, aber es funktioniert!

    Spoiler anzeigen
    [autoit]

    Local $Title = "", $LastTitle = "", $Found, $Line = ""
    Local $File = @ScriptDir & "\Title.txt", $hFile

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While Sleep(100)
    $Title = WinGetTitle("[Active]")

    [/autoit] [autoit][/autoit] [autoit]

    If $Title <> $LastTitle Then ;Search only in file when window title has changed!
    $LastTitle = $Title
    $hFile = FileOpen($File,0)
    $Found = False

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $Line = FileReadLine($hFile)
    If @error <> 0 Then ExitLoop ;OEF is reached
    If $Line = $Title Then
    $Found = True
    ExitLoop
    EndIf
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    FileClose($hFile)

    [/autoit] [autoit][/autoit] [autoit]

    If Not $Found Then ;Line not found, write it!
    $hFile = FileOpen($File,2) ;Write only the last window title!
    FileWriteLine($hFile,$Title)
    FileClose($hFile)
    EndIf
    EndIf
    WEnd

    [/autoit]

    Natürlich könnte man das Ganze noch kürzen, weil ja im Textfile nur immer einer Zeile drinnen steht.
    Also könnte man diese While Schlaufe auch noch streichen.....

    Aber vielleicht willst du ja auch alle Fenster nacheinander drinnen haben.....
    Dann müsste man FileOpen($File,2) durch FileOpen($File,1) ersetzen!

  • WinGettitle

    • veronesi
    • 26. Mai 2010 um 15:17

    Nein, den Titel musst du natürlich schon auslesen.
    Das hast du ja schon.

    Aber anstatt den Titel nun einfach in die Textdatei reinzuschreiben, überprüfst du zuerst, ob dieser Titel nicht schon drin steht.

  • WinGettitle

    • veronesi
    • 26. Mai 2010 um 15:07

    Dann musst Du doch nur einfach bevor Du den Fenstertitel in die Textdatei schreibst, überprüfen, ob dieser Text schon drinnen steht.
    Z.B. mit FileReadLine (natürlich in einer Schlaufe um alle Linien überprüfen zu können).

    Gruss
    Veronesi

  • Bildschirmnummer gemäss "Windows Identify" bestimmen.

    • veronesi
    • 26. Mai 2010 um 07:19

    Hoi name22,

    nein, @DesktopWidth und @DesktopHeight zeigt nur die Auflösung des primären Monitors an.
    Ich habe aber hier 8 Monitore gleichzeitig.....

    Das _WinApi_EnumDisplayDevices sieht interessant aus, jedoch habe ich noch nicht gefunden, wie oder ob ich überhaupt die Bildschirmnummer herausfinden kann!
    Aber ist mal ein Anfang!

    Kennt sich jemand mit EnumDisplayDevices etwas aus?

    Edit:
    Auch bei den _WinAPI_GetSystemMetrics habe ich nichts gefunden. (MSDN)

    Es müsste ja nicht zwingend eine fertige Funktion sein. Wenn jemand eine DLL kennt, mit welcher man bei Multimonitor Systemen an die Informationen kommt, dann nur her damit :)

  • Bildschirmnummer gemäss "Windows Identify" bestimmen.

    • veronesi
    • 25. Mai 2010 um 21:50

    Hallo zusammen,

    das nachfolgende Script taucht immer wieder in diversen Foren auf - es ist also nicht von mir ;)

    Spoiler anzeigen
    [autoit]

    #include-once

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetMonitorInfo()
    ;Returns some informations about your screens
    ;Call: _GetMonitorInfo()
    ;Return: Array With
    ;[0][0] Nr of Monitors
    ;[1][0] X Resolution of Monitor 1
    ;[1][1] Y Resolution of Monitor 1
    ;[1][2] X Position of Monitor 1
    ;[1][3] Y Position of Monitor 1

    [/autoit] [autoit][/autoit] [autoit]

    ;[2][0] X Resolution of Monitor 2
    ;[2][1] Y Resolution of Monitor 2
    ;[2][2] X Position of Monitor 2
    ;[2][3] Y Position of Monitor 2
    ;......

    Local $NrOfMonitors, $ResolutionX[32], $ResolutionY[32], $PositionX[32], $PositionY[32], $Ret
    Local $cbMonitorEnumProc = DllCallbackRegister("MonitorEnumProc", "ubyte", "ptr;ptr;ptr;int")

    [/autoit] [autoit][/autoit] [autoit]

    If @error Then Return SetError(1, 0, False)
    Local $strctCount = DllStructCreate("uint Count;uint Width[12];uint Height[12];int left[12];int top[12]")
    If @error Then Return SetError(2, @error, False)
    Local $iCount

    DllStructSetData($strctCount, "Count", 0)

    $Ret = DllCall("User32.dll", "ubyte","EnumDisplayMonitors","ptr", 0,"ptr", 0, "ptr", DllCallbackGetPtr($cbMonitorEnumProc), "ptr", DllStructGetPtr($strctCount))
    If @error Or $Ret[0] = 0 Then Return SetError(3, @error, False)

    DllCallbackFree($cbMonitorEnumProc)

    $iCount = Int(DllStructGetData($strctCount, "Count"))

    Local $aMonitors[$iCount+1][4] = [[$iCount]]

    For $i = 1 To $iCount
    $aMonitors[$i][0] = Int(DllStructGetData($strctCount, "Width",$i))
    $aMonitors[$i][1] = Int(DllStructGetData($strctCount, "Height",$i))
    $aMonitors[$i][2] = Int(DllStructGetData($strctCount, "left",$i))
    $aMonitors[$i][3] = Int(DllStructGetData($strctCount, "top",$i))
    Next
    $strctCount = 0
    Return $aMonitors
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func MonitorEnumProc($hMonitor, $hdcMonitor, $lprcMonitor, $dwData)
    Local $strctRECT = DllStructCreate("long left;long top;long right;long bottom", $lprcMonitor)
    Local $strctCount = DllStructCreate("uint Count;uint Width[12];uint Height[12];int left[12];int top[12]", $dwData)
    Local $iNumber = DllStructGetData($strctCount, "Count")
    Local $Height = Int(DllStructGetData($strctRECT, "bottom"))-Int(DllStructGetData($strctRECT, "top"))
    Local $Width = Int(DllStructGetData($strctRECT, "right"))-Int(DllStructGetData($strctRECT, "left"))

    DllStructSetData($strctCount, "Width", $Width, $iNumber+1)
    DllStructSetData($strctCount, "Height", $Height, $iNumber+1)
    DllStructSetData($strctCount, "left", Int(DllStructGetData($strctRECT, "left")), $iNumber+1)
    DllStructSetData($strctCount, "top", Int(DllStructGetData($strctRECT, "top")), $iNumber+1)
    DllStructSetData($strctCount, "Count", $iNumber+1)
    Return True
    EndFunc

    [/autoit]

    Es gibt die Anzahl der Monitore, deren Auflöung und Position zurück.
    Das funktioniert auch wunderbar!

    Bisher habe ich jedoch immer gedacht, dass wenn ich $aMonitors[1][0] verwende, die X-Auflösung des 1. Monitors erhalte.
    Dies stimmte auch bis jetzt. Nun habe ich jedoch einen neuen Grafikkarten - Treiber installiert. Jetzt stimmt diese Nummer nicht mehr mit dem überein, was Windows bestimmt.

    Mit anderen Worten: Gehe ich in die Systemsteuerung und drücke bei den Monitoren auf "Identify / Identifizieren" dann werden mir ja die Monitornummer auf jedem Bildschirm kurz eingeblendet.
    Und genau diese Nummern möchte ich eigentlich mit AutoIt auslesen.

    Bei gewissen Grafikkarten / Treibern stimmen die Nummern (zufälligerweise ?) überein. Aber nicht immer!

    Kann man die Nummern auch über eine DLL bestimmen?

    Grüsse
    Veronesi

  • Desktopauflösung ändern (wieder offen wegen Problems)

    • veronesi
    • 12. Mai 2010 um 20:43

    Versuch mal dieses Script hier.
    Es kann zwar die Auflösung von mehreren Monitoren setzen, doch das spielt ja keine Rolle!

    Gruss
    Veronesi

    Spoiler anzeigen
    [autoit]

    #include-once

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ; Function Name: _ChangeScreenRes()
    ; Description: Changes the current screen geometry, colour and refresh rate.
    ; Version: 1.0.0.0
    ; Parameter(s): $i_DisplayNum - Display to change, starting at 1
    ; $i_Width - Width of the desktop screen in pixels. (horizontal resolution)
    ; $i_Height - Height of the desktop screen in pixels. (vertical resolution)
    ; $i_BitsPP - Depth of the desktop screen in bits per pixel.
    ; $i_RefreshRate - Refresh rate of the desktop screen in hertz.
    ; Requirement(s): AutoIt Beta > 3.1
    ; Return Value(s): On Success - Screen is adjusted, @ERROR = 0
    ; On Failure - sets @ERROR = 1
    ; Forum(s):
    ; Author(s): Original code - psandu.ro, PartyPooper
    ; Modifications - bobchernow
    ;===============================================================================
    Func _ChangeScreenRes($i_DisplayNum = 1, $i_Width = @DesktopWidth, $i_Height = @DesktopHeight, $i_BitsPP = @DesktopDepth, $i_RefreshRate = @DesktopRefresh)
    Local Const $DM_PELSWIDTH = 0x00080000
    Local Const $DM_PELSHEIGHT = 0x00100000
    Local Const $DM_BITSPERPEL = 0x00040000
    Local Const $DM_DISPLAYFREQUENCY = 0x00400000
    Local Const $CDS_TEST = 0x00000002
    Local Const $CDS_UPDATEREGISTRY = 0x00000001
    Local Const $DISP_CHANGE_RESTART = 1
    Local Const $DISP_CHANGE_SUCCESSFUL = 0
    Local Const $HWND_BROADCAST = 0xffff
    Local Const $WM_DISPLAYCHANGE = 0x007E
    If $i_Width = "" Or $i_Width = -1 Then $i_Width = @DesktopWidth; default to current setting
    If $i_Height = "" Or $i_Height = -1 Then $i_Height = @DesktopHeight; default to current setting
    If $i_BitsPP = "" Or $i_BitsPP = -1 Then $i_BitsPP = @DesktopDepth; default to current setting
    If $i_RefreshRate = "" Or $i_RefreshRate = -1 Then $i_RefreshRate = @DesktopRefresh; default to current setting
    Local $DEVMODE = DllStructCreate("byte[32];int[10];byte[32];int[6]")
    Local $s_Display

    [/autoit] [autoit][/autoit] [autoit]

    $s_Display = "\\.\Display" & $i_DisplayNum

    [/autoit] [autoit][/autoit] [autoit]

    Local $B = DllCall("user32.dll", "int", "EnumDisplaySettings", "ptr", 0, "int", 0, "ptr", DllStructGetPtr($DEVMODE))

    [/autoit] [autoit][/autoit] [autoit]

    If @error Then
    $B = 0
    SetError(1)
    Return $B
    Else
    $B = $B[0]
    EndIf
    If $B <> 0 Then
    DllStructSetData($DEVMODE, 2, BitOR($DM_PELSWIDTH, $DM_PELSHEIGHT, $DM_BITSPERPEL, $DM_DISPLAYFREQUENCY), 5)
    DllStructSetData($DEVMODE, 4, $i_Width, 2)
    DllStructSetData($DEVMODE, 4, $i_Height, 3)
    DllStructSetData($DEVMODE, 4, $i_BitsPP, 1)
    DllStructSetData($DEVMODE, 4, $i_RefreshRate, 5)

    [/autoit] [autoit][/autoit] [autoit]

    $B = DllCall("user32.dll", "int", "ChangeDisplaySettingsEx","str", $s_Display, "ptr", DllStructGetPtr($DEVMODE), "hwnd", 0, "dword", $CDS_TEST, "lparam", 0)
    If @error Then
    $B = -1
    Else
    $B = $B[0]
    EndIf
    Select
    Case $B = $DISP_CHANGE_RESTART
    $DEVMODE = ""
    Return 2
    Case $B = $DISP_CHANGE_SUCCESSFUL
    DllCall("user32.dll", "int", "ChangeDisplaySettingsEx","str", $s_Display, "ptr", DllStructGetPtr($DEVMODE), "hwnd", 0, "dword", $CDS_UPDATEREGISTRY, "lparam", 0)
    ;~ DllCall("user32.dll", "int", "SendMessage", "hwnd", $HWND_BROADCAST, "int", $WM_DISPLAYCHANGE, _
    ;~ "int", $i_BitsPP, "int", $i_Height * 2 ^ 16 + $i_Width)
    $DEVMODE = ""
    Return 1
    Case Else
    $DEVMODE = ""
    SetError(1)
    Return $B
    EndSelect
    EndIf
    EndFunc;==>_ChangeScreenRes

    [/autoit]
  • Standard Audiogerät setzen (Win XP + Win 7)

    • veronesi
    • 1. Mai 2010 um 14:14

    So, ich konnte nun auch 42 unterschiedlichen Windows 7 Rechnern nachschauen ;)

    Doch leider gibt's diesen Schlüssel auf keinem System. Und wenn ich den erstelle, reagiert der PC nicht auf diesen Schlüssel..

    Klappt das bei Euch?

    Spoiler anzeigen
    [autoit]

    Dim $RegKey = "HKEY_CURRENT_USER\Software\Microsoft\Multimedia\Sound Mapper" ;Registry Key
    Dim $ActualSettings, $OutputDevice1, $OutputDevice2

    [/autoit] [autoit][/autoit] [autoit]

    If Not FileExists(@ScriptDir & "\Swap_AudioOutput_Settings.ini") Then ;Create default INI file if no file found!
    IniWrite(@ScriptDir & "\Swap_AudioOutput_Settings.ini","Audio Output","OutputDevice1","Realtek HD Audio output")
    IniWrite(@ScriptDir & "\Swap_AudioOutput_Settings.ini","Audio Output","OutputDevice2","Realtek HD Audio output")
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $OutputDevice1 = IniRead(@ScriptDir & "\Swap_AudioOutput_Settings.ini","Audio Output","OutputDevice1","Realtek HD Audio output") ;Load Device
    $OutputDevice2 = IniRead(@ScriptDir & "\Swap_AudioOutput_Settings.ini","Audio Output","OutputDevice2","Realtek HD Audio output")

    [/autoit] [autoit][/autoit] [autoit]

    $ActualSettings = RegRead($RegKey, "Playback") ;Get actual Output-Device

    [/autoit] [autoit][/autoit] [autoit]

    If $ActualSettings = $OutputDevice1 Then
    RegWrite($RegKey, "Playback", "REG_SZ", $OutputDevice2)
    Else
    RegWrite($RegKey, "Playback", "REG_SZ", $OutputDevice1)
    EndIf
    Exit

    [/autoit]

    Vielleicht geht's ja bei Euch auch nicht?
    Natürlich müsst ihr die Werte bei OutputDevice1 und OutputDevice2 anpassen auf die Namen, welche bei Euch stehen!

    Danke + Grüsse
    Veronesi

  • Standard Audiogerät setzen (Win XP + Win 7)

    • veronesi
    • 29. April 2010 um 07:12

    Ach ja? Das ist aber interessant!

    Bei uns (Win 7 Business, 64-bit) gibt's den nicht.
    Aber ich kann mal versuchen, ob's läuft, wenn man den erstellt!

    Danke + Grüsse
    Veronesi

  • Standard Audiogerät setzen (Win XP + Win 7)

    • veronesi
    • 28. April 2010 um 11:15

    Hallo SchrotterCh,

    danke für die Antwort.
    Doch "gegooglet" habe ich schon sehr viel darüber.

    Gut ich habe vergessen zu erwähnen, dass ich es nicht über Makros (also Systemsteuerung automatisch öffnen, mit Pfeiltasten zu Sounds und Multimedia fahren, Enter drücken......) machen möchte!

    Das ganze ist dann System und Sprachabhängig. Und genau das möchte ich vermeiden. Es gibt doch bestimmt einen DLL Aufruf oder ähnliches.
    Zudem sind bei gewissen PCs die Berechtigungen eingeschränkt, so dass sie die Systemsteuerung nicht öffnen können. Sie hätten zwar die Berechtigung um z.B. das Audio zu ändern, kommen aber ohne Systemsteuerung fast nicht ran!

    Trotzdem danke!
    Gruss

  • Standard Audiogerät setzen (Win XP + Win 7)

    • veronesi
    • 28. April 2010 um 10:18

    Hat keiner eine Antwort?
    Oder zumindest einen Lösungsansatz?

    Vielleicht fällt dem einen oder anderen noch was ein!

    Grüsse
    Veronesi

  • Standard Audiogerät setzen (Win XP + Win 7)

    • veronesi
    • 27. April 2010 um 11:08

    Hallo zusammen,
    wie in der Überschrift erwähnt, möchte ich das Standard Audioausgabegerät für Windows XP und Windows 7 setzen können.
    Dabei muss ich nicht zwingend die verfügbaren Geräte auslesen können, sondern ich setze dafür einfach 2-3 Konstanten. Das reicht für meine Zwecke!

    Unter XP konnte man mit dem Registry Schlüssel HKEY_CURRENT_USER\Software\Microsoft\Multimedia\Sound Mapper\Playback das Standardgerät setzen.
    Doch unter Windows 7 gibt es den Schlüssel nicht mehr.

    Weiss jemand, wie man das machen könnte?

    Ach ja: das Ausgabegerät sollte dann nicht nur für das AutoIt skript geändert sein, sondern für alle Windows Programme!

    Grüsse
    Veronesi

  • Aufnahme mit _BASS_Record

    • veronesi
    • 24. April 2010 um 20:23

    Hallo Eukalyptus,

    vielen herzlichen Dank! Es funktioniert wie immer super!
    Den Befehl _BASS_ChannelSetAttribute habe ich wirklich übersehen. Hab ihn echt nicht gefunden!

    Nochmals Dankeschön!

    Gruss
    Veronesi

  • Aufnahme mit _BASS_Record

    • veronesi
    • 24. April 2010 um 14:10

    Und weiter geht's mit Aufnahmeproblemen :)

    Anbei mein zusammengekürztes Teil-Script, damit man mit möglichst wenig Code mein Problem analysieren kann:

    Spoiler anzeigen
    [autoit]

    #include "Include\Bass.au3"
    #include "Include\BassConstants.au3"
    #include "Include\BassEnc.au3"
    Dim $File = @TempDir & "\1kHz.wav"

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0,"",CheckAudio(50))

    [/autoit] [autoit][/autoit] [autoit]

    Exit

    [/autoit] [autoit][/autoit] [autoit]

    Func CheckAudio($Tolerance) ;Check for Audio
    Local $hRecord, $hMusic, $iFreqOut, $iFreqIn, $TimerAudio

    [/autoit] [autoit][/autoit] [autoit]

    FileInstall("Include\1kHz.wav", @TempDir & "\1kHz.wav", 1)
    FileInstall("Include\bass.dll", @TempDir & "\bass.dll", 1)
    FileInstall("Include\basscb.dll", @TempDir & "\basscb.dll", 1)
    FileInstall("Include\bassenc.dll", @TempDir & "\bassenc.dll", 1)

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_STARTUP(@TempDir & "\BASS.dll") ;Open Bass.DLL.
    _BASS_Init(0, 1, 44100, 0, "") ;Initalize bass.
    If @error Then
    Return -1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_RecordInit(0)
    If @error Or _BASS_RecordGetDevice() > 10 Or _BASS_RecordGetDevice() < 0 Then
    Return -2
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_RecordSetInput(0, $BASS_INPUT_ON, -1)
    $hRecord = _BASS_RecordStart(44100, 2, 0)
    $hMusic = _BASS_StreamCreateFile(False, $File, 0, 0, 0) ;Set handle for 1kHz. Music File

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_ChannelPlay($hMusic, 1) ;Play 1kHz. Music-File
    $TimerAudio = TimerInit()
    While _BASS_ChannelIsActive($hMusic) = $BASS_ACTIVE_PLAYING ;While playing get frequency of Line-Out and Line-In
    $iFreqOut = GetFreq($hMusic)
    $iFreqIn = GetFreq($hRecord)
    ;~ ToolTip("Frequenz Out: " & $iFreqOut & @LF & "Frequenz In: " & $iFreqIn)
    If TimerDiff($TimerAudio) > 1500 Then ExitLoop
    Sleep(50)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Free()
    _BASS_RecordFree()

    [/autoit] [autoit][/autoit] [autoit]

    If $iFreqOut + $Tolerance > $iFreqIn And $iFreqOut - $Tolerance < $iFreqIn And $iFreqOut < 1100 And $iFreqOut > 900 Then ;If both frequencies are +/- the same and the Output frequency is +/- 1kHz. then it's OK!
    Return 1
    ElseIf $iFreqOut > 1100 Or $iFreqOut < 900 Then
    Return -3
    Else
    Return -4
    EndIf
    EndFunc ;==>CheckAudio

    [/autoit] [autoit][/autoit] [autoit]

    Func GetFreq($hHandle)
    Local $TmpData = 0, $TmpNr = 0, $fft = 0
    Local $fftstruct = DllStructCreate("float[4096]")
    _BASS_ChannelGetData($hHandle, DllStructGetPtr($fftstruct), $BASS_DATA_FFT8192)
    For $i = 0 To 4095
    $TmpData = Round(DllStructGetData($fftstruct, 1, $i + 1) * 100)
    If $TmpData > 0.2 And $fft < $TmpData Then ;Bestimme den Ort des Maximalwerts der FFT Analyse
    $fft = $TmpData
    $TmpNr = $i + 1
    EndIf
    Next
    Return Round(22000 / 4096 * $TmpNr) ;Max 22kHz.
    EndFunc ;==>GetFreq

    [/autoit]

    Damit kann ich (erfolgreich) ein 1kHz. File abspielen, es gleichzeitig "aufnehmen" und die Ein- und Ausgangsfrequenz analysieren.

    Nun sollte ich das noch erweitern können. Und zwar möchte ich beim Empfangen den linken und rechten Kanal getrennt analysieren können.

    Ich habe schon einiges getestet, doch leider bin ich nicht so recht weiter gekommen :(
    Besten Dank schon jetzt für Eure Hilfe !

    Grüsse
    Veronesi

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™