Bild in Hintergrund/Vordergrund

  • Hallo,
    ich habe mehrere Bilder in meinem Script, die auch übereinander angezeigt werden sollen (z. B. ein Telefon was auf einem Tisch steht).
    Wie ist es mir nun möglich, dass diese Bilder beim Scriptaufruf auch korrekt angezeigt werden? Habe schon gelesen, dass man dass untere Bild mit GUICtrlSetState(-1, $gui_disable) disablen soll und die Bilder die nach vorn sollen, einen Parameter mit auf den Weg geben: $GUI_ONTOP
    Hat aber leider nicht den gewünschten Efekt :(

  • Hättest du ein Script, hätte ich dir auch dabei spezifisch helfen können ( denk in zukunft bitte dran ). Aber ich habe trotzdem ein kleines Script geschrieben, bei dem sich zwei Bilder überlappen:

    [autoit]

    GUICreate("Bild GUI", 500, 500)
    GUICtrlCreatePic(@ScriptDir & "\Bild_1.bmp", 0, 0, 200, 100)
    GUICtrlCreatePic(@ScriptDir & "\Bild_2.bmp", 100, 40, 230, 300)
    GUISetState()
    Do
    Until GUIGetMsg() = -3

    [/autoit]

    ich hoffe das hilft dir, ansonsten: Code posten + Frage stellen

    mfg
    hauke96

  • Hilft mir leider nicht. Habe mal paar Screenshots hochgeladen. Auf dem ersten Bild sieht man wie es nach dem Ladevorgang des Grundrisses und der Objekte aussieht. Das Bild wird erst erstellt (siehe Code Zeile 101) und dann die Objekte (Zeile 111 und 114). Die Objekte kann man da aber noch nicht sehen. Nimmt man jetzt z. B. einen weiteren Tisch und wischt mit diesem über die Objekte, werden sie sichtbar. Den gleichen Effekt hat auch, wenn man das Fenster kurz minimiert und wieder aufruft. Dann sind die Objekte auch ÜBER dem Grundriss.

    Spoiler anzeigen
    [autoit]

    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GUIListBox.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #include <array.au3>
    #include <Misc.au3>
    #include <file.au3>
    #include <ListViewConstants.au3>

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

    Global $objektepfad = @ScriptDir & "\Objekte\"
    dim $aObjekte[9] = ["Tisch waagerecht", "Tisch senkrecht", "PC", "Telefon", "Bodendose", "LAN-Buchse", "Label", "GAA", "KAD"]
    dim $positionen[1][5]
    dim $positionenBackup[1][5] ;Hier wird beim Laden des Skriptes der Inhalt der .ini reingeschrieben und nicht verändert.
    global $positionenspeicher = @scriptdir & "\positionen.ini" ;Sollen Änderungen nicht gespeichert werden, wird der Inhalt aus dem Backuparray geschrieben.
    $hWnd = GUICreate("Drag/Drop Controls", 1400, 900)
    $Objekte = GUICtrlCreateGroup("Objekte verwalten", 1230, 116, 150, 320)
    $List1 = GUICtrlCreateList("", 1240, 146, 130, 240)
    $Button1 = GUICtrlCreateButton("Hinzufügen", 1240, 396, 130, 25, $WS_GROUP)
    $GSladen = GUICtrlCreateButton("Laden", 1248, 64, 115, 25, $WS_GROUP)
    $geschaeftstellen = GUICtrlCreateGroup("Geschäftsstelle auswählen", 1232, 5, 150, 100)
    $grundrissgroup = GUICtrlCreateGroup("Grundriss", 5, 5, 1220, 890)
    $listegeschaeftsstellen = GUICtrlCreateCombo("GS auswählen", 1248, 32, 113, 25)
    GUICtrlSetData($listegeschaeftsstellen, "Auswahl1|Auswahl2", "Drucker auswählen")
    guictrlsetstate($List1, $GUI_DISABLE)
    guictrlsetstate($Button1, $GUI_DISABLE)
    GUISetState(@SW_SHOW)

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

    for $c = 0 to ubound($aObjekte) - 1
    GUICtrlSetData($List1, $aObjekte[$c] & "|") ;Inhalt für Dropdownbox aus Array wird hierein geschrieben
    Next

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

    GUISetState()
    $vUser32Dll = DllOpen("user32.dll")
    While True
    $msg = GUIGetMsg()
    Switch $msg
    Case $GUI_EVENT_CLOSE
    $GSauswahl = GUICtrlRead($listegeschaeftsstellen)
    $msg = MsgBox(4, "Änderungen speichern", "Sollen die Änderungen gespeichert werden?")
    if $msg = 7 Then
    for $c = 0 to ubound($positionenbackup) - 1 ;Änderungen nicht speichern: Backuparray wird in .ini geschrieben
    IniWrite(@ScriptDir & "\" & $GSauswahl & ".ini", $positionenbackup[$c][1], $positionenbackup[$c][0], $positionenbackup[$c][2] & ":" & $positionenbackup[$c][3] & ":" & $positionenbackup[$c][4])
    Next
    else
    for $c = 0 to ubound($positionen) - 1 ;Änderungen speichern: Normales Array wird in .ini geschrieben
    IniWrite(@ScriptDir & "\" & $GSauswahl & ".ini", $positionen[$c][1], $positionen[$c][0], $positionen[$c][2] & ":" & $positionen[$c][3] & ":" & $positionen[$c][4])
    Next
    EndIf
    DllClose($vUser32Dll)
    Exit
    Case $GUI_EVENT_PRIMARYDOWN ;Wenn linke Maustaste gedrückt wird...
    $aMousePos = GUIGetCursorInfo($hWnd)
    If $aMousePos[4] Then
    $iControl = $aMousePos[4]
    $aPos = ControlGetPos($hWnd, "", $iControl)
    $iDist_X = $aMousePos[0] - $aPos[0] ;Wenn man verschiebt, wird dort gegriffen, wo man klickt
    $iDist_Y = $aMousePos[1] - $aPos[1]
    While _IsPressed("01", $vUser32Dll)
    $aMousePos = GUIGetCursorInfo($hWnd)
    if $aMousePos[0] < 1230 then ;damit man alles was rechts ist in der groupbox nicht verschieben kann
    ControlMove($hWnd, "", $iControl, $aMousePos[0] - $iDist_X, $aMousePos[1] - $iDist_Y) ; Bewegt das Control zu der Position wo sich der Mauszeiger befindet
    Sleep(10)
    $controlPos = ControlGetPos($hWnd, "", $aMousePos[4]);<<<<<<<weitermachen
    for $b = 0 to ubound($positionen) - 1

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

    $AktID = _ArraySearch($positionen, $aMousePos[4], 0, 0, 0, 0, 1, 0) ;Schaut an welcher Position die aktuelle ID (Worüber sich der Mauszeiger befindet) im Array steht
    if not @error Then
    $positionen[$AktID][2] = $controlPos[0] ;Es wird nach der aktuellen ID gesucht.(worüber sich der Mauszeiger befindet).
    $positionen[$AktID][3] = $controlPos[1] ;Dann werden die Koordinaten des Controls (nicht des Mauszeigers) gelesen und in das Array geschrieben
    EndIf
    Next
    EndIf
    WEnd
    EndIf
    Case $Button1
    $ausgewaehlt = GUICtrlRead($List1)
    if $ausgewaehlt = "Label" Then
    $positionen[ubound($positionen) - 1][4] = InputBox("Beschriftung des Labels", "Bitte geben Sie den Inhalt des Labels ein:")
    $positionen[ubound($positionen) - 1][0] = GUICtrlCreateLabel($positionen[ubound($positionen) - 1][4], 1110, 20, 50, 15) ;Erstellt ein Label mit der vorherig ausgewählten Beschriftung
    GUICtrlSetBkColor(-1, 0xFFFFFF) ;Setzt Hintergrundfarbe des Labels auf weiß
    Else
    $positionen[ubound($positionen) - 1][0] = GUICtrlCreatePic($objektepfad & $ausgewaehlt & ".jpg", 1100, 20, 0, 0, $GUI_ONTOP) ;Bild wird erstellt, wenn nicht "Label" ausgewählt wurde. Die ID wird ins Array geschrieben
    EndIf
    $positionen[ubound($positionen) - 1][1] = $ausgewaehlt ;Name des Controls was erstellt wurde wird in Array geschrieben
    ReDim $positionen[UBound($positionen)+1][5] ;Neue Dimensionierung des Array, weil ein Eintrag hinzugekommen ist
    Case $GUI_EVENT_SECONDARYUP ;Wenn Rechtsklick
    $aMousePos = GUIGetCursorInfo($hWnd)
    if $aMousePos[0] < 1230 then ;damit man alles was rechts ist in der groupbox nicht löschen kann
    $PosDelete = _ArraySearch($positionen, $aMousePos[4], 0, 0, 0, 0, 1, 0) ;Schaut an welcher Stelle im Array sich die ID befindet
    if not @error Then ;Wurde die ID gefunden, dann...
    GUICtrlDelete($aMousePos[4]) ;1...wird das Control mit der entsprechenden ID gelöscht
    _ArrayDelete($positionen, $PosDelete) ;2...wird der Eintrag aus Array gelöscht
    sleep(100)
    EndIf
    EndIf
    case $GSladen ;Wird der "Laden"-Button gedrück
    $GSauswahl = GUICtrlRead($listegeschaeftsstellen) ;Aktiviert Liste und Button, dass man diese benutzen kann (zuvor waren sie ausgegraut)
    guictrlsetstate($List1, $GUI_ENABLE)
    guictrlsetstate($Button1, $GUI_ENABLE)
    $grundriss = GUICtrlCreatePic(@ScriptDir & "\Grundrisse\" & $GSauswahl & ".jpg", 20, 25, 0, 0) ;Erstellt Bild des Grundrisses
    GUICtrlSetState(-1, $gui_disable) ;Und soll diesen eigentlich disablen, funktioniert aber noch nicht. Bild muss in Hintergrund!
    for $d = 0 to ubound($aObjekte) - 1 ;Anhand der Objekte aus dem Array $aObjects werden die Werte aus den jeweiligen Sektionen gelesen
    $section = IniReadSection (@ScriptDir & "\" & $GSauswahl & ".ini", $aObjekte[$d]) ;Hier werden die Positionen aus der .ini gelesen und in $positionen
    for $e = 1 to ubound($section) - 1 ;gespeichert, wo später vll. noch Objekte hinzukommen
    $coords = stringsplit($section[$e][1], ":") ;Der Wert aus .ini wird in 3 Teile gesplittet:
    $xcoord = $coords[1] ;1: X-Koordinate
    $ycoord = $coords[2] ;2: Y-Koordinate
    $labeltext = $coords[3] ;3: Inhalt des Labels
    if $aObjekte[$d] = "Label" Then ;Erstellt Label bzw...
    $positionen[ubound($positionen)- 1][0] = GUICtrlCreateLabel($labeltext, $xcoord, $ycoord, 50, 15)
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    Else
    $positionen[ubound($positionen) - 1][0] = GUICtrlCreatePic ($objektepfad & $aObjekte[$d] & ".jpg", $xcoord, $ycoord, 0, 0, $GUI_ONTOP) ;...Bilder an der Position, die aus .ini ausgelesen wurde
    EndIf ;ID's der Conrols werden in Array geschrieben
    $positionen[ubound($positionen)- 1][1] = $aObjekte[$d] ;Objektname, Koordinaten, Labeltext werden ebenfals ins Array geschrieben
    $positionen[ubound($positionen)- 1][2] = $xcoord
    $positionen[ubound($positionen)- 1][3] = $ycoord
    $positionen[ubound($positionen)- 1][4] = $labeltext
    ReDim $positionen[UBound($positionen)+1][5] ;Redimnesioniert, da es pro Eintrag größer wird, das Array
    Next
    Next
    for $f = 0 to ubound($positionen) - 1 ;Erstellt das Backuparray mit identischen Inhalten aus $positionen
    $positionenbackup[$f][0] = $positionen[$f][0] ;Hat man Änderungen vorgenommen, können diese verworfen werden, indem die Inhalte
    $positionenbackup[$f][1] = $positionen[$f][1] ;aus dem backuparray in die .ini geschrieben werden
    $positionenbackup[$f][2] = $positionen[$f][2]
    $positionenbackup[$f][3] = $positionen[$f][3]
    $positionenbackup[$f][4] = $positionen[$f][4]
    ReDim $positionenbackup[UBound($positionenbackup)+1][5]
    Next
    FileDelete(@ScriptDir & "\" & $GSauswahl & ".ini") ;.ini muss nach jedem Einlesen in das Array gelöscht werden. Behält man die .ini bei,
    EndSwitch ;kann es bei Änderungen zu Geistereinträgen kommen
    WEnd

    [/autoit]
  • Problem in diesem Fall ist dein unsauberer Programmierstil.
    Jedes mal wenn auf den GSladen Button gedrückt wird erstellst du einige neue Controls.
    Erstell die Controls die du benötigst am anfang und setz die Bilder dann mit Guictrlsetdata.
    Dann kannst du sie auch am besten in der richtigen Reihenfolge erstellen, was in deinem Fall ja wichtig ist da manche Bilder im Vordergrund und einige im Hintergrund sein sollen.

  • Unsauber? Ich dachte gerade so wie ichs gelöst habe ist es am besten. Wenn ich später Räume mit den Objekten ausstatte, komme da vll. 40, 50 Objekte in einen Raum. Ich muss dann also min 50 Objekte vorher im Code erstellen und dann später die Bilder zuordnen? Den Weg finde ich persönlich ziemlich unsauber. Zwar würde das dann mein Problem lösen, aber überzeugen tut mich das nicht. Kann ich nicht auch ein Conrol erstellen (im Nachhinein) und dann dieses mit guictrlsetdata das bild zuweisen? Ist dann eine Mischung aus deinem und meinem und ich habe dieses ganze Codeplammflet nicht.

  • Naja Problem finde ich halt, dass "unendlich" Controls erstellt werden.
    Drückt ein User 10 mal auf den Button haste da schon mehrere hundert Controls.
    Das ist es was ich unsauber finde und ich denke die meisten werden mir da zustimmen.

    Natürlich kannst du deine vorgeschlagene Mischung verwenden. Ich würde das so machen:
    Einmal das $grundriss Control, das würde ich am Anfang erstellen (und falls nicht benötigt vorrübergehend ausblenden)
    Und einmal ein Array mit den "dynamischen" Controls wie dus ja eh schon hast.
    ABER: dann auch immer die veralteten Controls mit Guictrldelete löschen.

    Wenn du mir Bilder und aktuellen Quellcode postest überarbeit ichs vllt kurz so wie ich mein
    (Natürlich nur als Alternativvorschlag, in erster Linie muss ein Script natürlich funktionieren^^ )

  • Bei 10 Mal drücken mehrere hundert Controls? Wo das denn? Die Controls werden mit Position und Namen sowie ID ja in das Array geschrieben und da gibt es keine paar Hundert. Oder was übersehe ich? Meine Controls erstelle ich ja mit:

    Spoiler anzeigen
    [autoit]

    Case $Button1
    $ausgewaehlt = GUICtrlRead($List1)
    if $ausgewaehlt = "Label" Then
    $positionen[ubound($positionen) - 1][4] = InputBox("Beschriftung des Labels", "Bitte geben Sie den Inhalt des Labels ein:")
    $positionen[ubound($positionen) - 1][0] = GUICtrlCreateLabel($positionen[ubound($positionen) - 1][4], 1110, 20, 50, 15) ;Erstellt ein Label mit der vorherig ausgewählten Beschriftung
    GUICtrlSetBkColor(-1, 0xFFFFFF) ;Setzt Hintergrundfarbe des Labels auf weiß
    Else
    $positionen[ubound($positionen) - 1][0] = GUICtrlCreatePic($objektepfad & $ausgewaehlt & ".jpg", 1100, 20, 0, 0, $GUI_ONTOP) ;Bild wird erstellt, wenn nicht "Label" ausgewählt wurde. Die ID wird ins Array geschrieben
    EndIf
    $positionen[ubound($positionen) - 1][1] = $ausgewaehlt ;Name des Controls was erstellt wurde wird in Array geschrieben
    ReDim $positionen[UBound($positionen)+1][5]

    [/autoit]

    Ok, kannst gerne mal reinschauen. Hier alle aktuellen Datien als Anhang.

  • Ahh jetz check ich erst richtig wie das alles läuft. Im Drüberschauen geht das einfach nicht so gut, deswegen isses gerade bei etwas größeren Scripten gut diese lauffähig zu posten ;)

    Also Problem ist das beim GSladen der Grundriss immer im Vordergrund ist, sehe ich das richtig?
    Wenn ja wäre die Lösung wie bereits gesagt das Control erst zu erstellen und dann das Bild zu setzen (nachdem alle anderen Bilder erstellt wurden)
    also in Zeile 102 einfach so:

    [autoit]

    $grundriss = GUICtrlCreatePic("", 20, 25, 0, 0)

    [/autoit]


    Und dann am ende des Cases (also Beispielsweise zwischen For Schleife und FileDelete Zeile 133) das einfügen:

    [autoit]

    GUICtrlSetImage($grundriss, @ScriptDir & "\Grundrisse\" & $GSauswahl & ".jpg")

    [/autoit]


    Dann denke ich wird es so erstellt wie du willst.

    2 Probleme die ich auch noch sehe ist dass:
    1. Beim verschieben eines Objektes im Hintergrund die Bilder die darüberliegen mitverschoben werden ( also die Überlagerungen)
    Auch das dürfte sich lösen lassen indem du einfach das bild nochmal mit SetImage setzt
    2. Sich auch andere Controls verschieben lassen, ist zwar lustig aber wohl kaum gewünscht^^

    GSladen kann man ja nicht öfters aufrufen weil du beim ersten Aufruf disables, das hatte ich überlesen
    Also: Ich nehme alles zurück was ich vorhin sagte: Es ist schön sauber ^^
    Nur halt nicht unbedingt gleich verständlich wenn man nur Quellcode und wenig Zeit hat, aber da kannst du nix dafür ;)

    Ich hoffe jetz konnt ich dir vernünftiger weiterhelfen als vorhin

  • Also Problem ist das beim GSladen der Grundriss immer im Vordergrund ist, sehe ich das richtig?

    Genau, das war mein Problem!

    Dann denke ich wird es so erstellt wie du willst.

    Jop, nach dienem Vorschlag wirds jetzt so erstellt, wie ich möchte. Finds zwar etwas unverständlich, da der Grundriss (das Bild von diesem) ja immernoch NACH den anderen Controls erstellt wird...

    Beim verschieben eines Objektes im Hintergrund die Bilder die darüberliegen mitverschoben werden ( also die Überlagerungen)
    Auch das dürfte sich lösen lassen indem du einfach das bild nochmal mit SetImage setzt

    Ja, das ist aber nicht weiter tragisch, da Grundriss oder das Groupcontrol gar nicht verschoben werden sollen

    Sich auch andere Controls verschieben lassen, ist zwar lustig aber wohl kaum gewünscht

    Ne, ist nicht gewünscht :P Habe ich auch teilweise schon versucht zu unterbinden mit

    [autoit]

    if $aMousePos[0] < 1230 then

    [/autoit]


    Funktioniert aber nur mit den Controls rechts. Wenn man sie allerdings aus der Ecke rauszieht über eine bestimmte Position hinaus, werden die auch verschoben. Weiß noch nicht genau wie ich das löse... Vll. so, dass die ID's halt nicht verschoben werden können...

    Es ist schön sauber

    Danke :D

    Ich hoffe jetz konnt ich dir vernünftiger weiterhelfen als vorhin

    Das konntest du, vielen Dank dass du dir dafür Zeit genommen hast :love:

  • Zitat

    Funktioniert aber nur mit den Controls rechts. Wenn man sie allerdings aus der Ecke rauszieht über eine bestimmte Position hinaus, werden die auch verschoben. Weiß noch nicht genau wie ich das löse... Vll. so, dass die ID's halt nicht verschoben werden können...


    Du hast doch eh alle ID's die verschiebbar sein sollen in dem Array $positionen oder?
    Versuchs mal indem du das:

    [autoit]

    If $aMousePos[4] Then

    [/autoit]


    durch das ersetzt:

    [autoit]

    If _ArraySearch($positionen, $aMousePos[4], 0, 0, 0, 0, 1,0)<>-1 Then

    [/autoit]
  • War gerade auf einem anderen Lösungsweg, deiner ist aber einfacher :) Wollte die IDs der Controls die nicht verschiebbar sein sollen, in ein extra Array scheiben. Warum einfach wenns auch kompliziert geht :whistling:

    Edit: Sehe gerade, dass das nächste Problem aufgetaucht ist: Wenn ich das GUI minimiere, den Grundriss vorher schon geladen habe, verschwindet das Bild, wenn ich es wiederaufrufe. Die Objekte sind aber noch da.

    Einmal editiert, zuletzt von Scritch (7. Juli 2011 um 11:01)