Dateien per Kontextmenü in eine Liste überführen

  • Hallo Ihr Lieben,

    ich habe einmal wieder ein Problem :) Mal wieder etwas spezielles.

    Zur Vorgeschichte:
    Ich habe ein Kontexteintrag in Windows erstellt, dass bei jeder Datei den Kontexteintrag "Datei hinzu" anzeigt.
    Wenn man da drauf klickt, öffnet sich mein Programm und der Dateipfad wird ja per Kommandozeile übertragen.

    Diese kann ich ja schnell abfangen;

    [autoit]


    If $CmdLine[0] > 0 Then
    MsgBox(0,"ausgabe",$CmdLine[1])
    EndIf

    [/autoit]

    Soweit ja kein Problem :) Nun habe ich eine Liste in meiner GUI erstellt ("$mylist = GUICtrlCreateList").
    Diese soll nun meinen Dateinamen beinhalten. Auch kein Problem:

    [autoit]


    If $CmdLine[0] > 0 Then
    GUICtrlSetData($mylist, $CmdLine[1] &"|")
    EndIf

    [/autoit]

    Nun will ich aber eine zweite Datei per Kontextmenü einfügen!

    Probleme: Es öffnet sich ein zweites Fenster. Sprich 2x mein Programm. Unerwünscht!
    Lösung: Kann man mit _Sinlgeton verhindern.

    Leider weiß ich nun nicht, wie ich eine Datei im Hauptfenster eintragen und diese
    auch noch in der Liste eintragen kann. ;(

    [autoit]


    If _Singleton("Dateien",1) = 0 Then
    WinActivate("Form1")

    If $CmdLine[0] > 0 Then
    MsgBox(0,"ausgabe",$CmdLine[1])
    GUICtrlSetData($mylist, $CmdLine[1] &"|")
    EndIf

    Exit
    EndIf

    [/autoit]

    Setze ich diesen Code vor dem "GUISetState(@SW_SHOW)" wird zwar die Datei angezeigt, aber nicht im Hauptfenster hinzugefügt.
    Logisch, weil der ja gar nicht weißt, dass noch eine Liste im anderen Fenster existiert. Kann man die Liste global setzen oder gibt es eine andere Möglichkeit?

    Hoffe es ist soweit verständlich. Vielen Dank schon einmal im Voraus.

    Die Anna :*

    "Wo kämen wir hin, wenn jeder sagte wo kämen wir hin, und niemand ginge, um zu sehen, wohin wir kämen, wenn wir gingen..." :wacko:

    Einmal editiert, zuletzt von AnnaM (27. Mai 2011 um 21:54)

  • Das selbe Problem hab ich auch erkannt bei mir, aber für mich ist es nicht zwingend erforderlich auf eine Instanz zu bestehen, da ohnehin keine GUI genutzt werden soll.
    Nun zu dir:

    1. dieses _singleton würde ich ganz an den Anfang setzwen, noch bevor irgendwelche GUI Elemente erstellt werden, denn du willst die 2. Instanz ja sofort beenden und garnie benutzen.
    2. guictrlsetdata in der 2. Instanz kann nicht funktionieren, weil du die Instanz sofort beendest

    Du musst also in dieser _singleton Abfrage eine Übergabe an die 1. Instanz relaisieren. Dafür gibt es viele Möglichkeiten, eine wäre über die control Funktionen, also controlsettext(), controlsend() usw. Dafür musst du dir einmalig mit Au3info die Daten deines Scriptes auslesen, also Fenstertitel, ControlID / Instanz / Class welches beeinflusst werden soll usw.

    Eine andere Möglichkeit wäre die Übergabe über eine Temp Datei. Dazu müsstest du in der Hauptschleife deines Scriptes immer prüfen lassen ob eine neue Datei mit einem von dir definierten Namen im Scriptdir erstellt wurde und diese dann auslesen lassen. In der singleton Bedingung erstellt deine 2. Instanz dann solch eine Datei mit dem Inhalt von cmdline[1]. Die erste Instanz liest die Datei aus wenn sie gefunden wird und löscht diese im Anschluss wieder.

    Eine dritte Möglichkeit wäre noch eine TCP Verbindung zwischen beiden Scripten, wobei Instanz 1 den Server darstellt und prüft ob sich eine Client Instanz verbindet. Hier kannst du dann ebenfalls cmdline[1] aus der 2. Instanz an die 1. senden.

    EDIT: Ausserdem sollte singleton doch ungleich null sein wenn eine andere instanz existiert, also eher so:

    [autoit]


    If _Singleton("Dateien",1) <> 0 Then
    datenuebergabe() ; je nachdem wie du das relisieren willst siehe oben
    exit
    endif

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

    2 Mal editiert, zuletzt von misterspeed (26. Mai 2011 um 19:59)

  • Danke schon einmal für deine Antwort.

    Aber ich glaube mit ControlSend kann ich nicht in eine Liste (GUICtrlCreateList) schreiben, oder?
    Möglichkeit 2 und 3 sind ganz schön komplex nur für eine Übergabe eines Pfades :)
    Möglichkeit 2 wäre ein Überlegung wert.

    Ansonsten gibt es keine Möglichkeit mehr? Würde das ja gerne mit ControlSend machen.
    Aber das kenne ich nur mit einer Inputbox und ähnliches.

    Die Anna :*

    "Wo kämen wir hin, wenn jeder sagte wo kämen wir hin, und niemand ginge, um zu sehen, wohin wir kämen, wenn wir gingen..." :wacko:

  • Ob die control Funktionen auch für List Objekte geeignet sind weiss ich nicht, sollte aber eigtl auch gehen. Die einfachste Variante ist wohl die Temp-Datei. Aufwand ist da auch nahe null, einfach ein filewrite(...) in die _singleton Bedingung und in der Hauptschleife dann

    [autoit]


    while 1
    ;... gui gedöns sofern du nicht den on event mode benutzt
    if fileexists(...) then
    fileread(...)
    guictrlsetdata(...)
    filedelete(...)
    endif
    wend

    [/autoit]

    Es gäbe btw noch eine vierte Möglichkeit über stdout / stdin oder irgendwelche pipes... einfach mal nach Komunikation zwischen 2 scripten suchen, da findest du einige Varianten.

  • Ich würde es gerne mit StdinWrite & StdinWrite machen.
    Aber es klappt ja mal gar nicht. Keine Ahnung wie man das macht.

    Die Anna :*

    "Wo kämen wir hin, wenn jeder sagte wo kämen wir hin, und niemand ginge, um zu sehen, wohin wir kämen, wenn wir gingen..." :wacko:

  • Ich habe schon viele Beiträge von dir mir angesehen:
    [ offen ] _WinAPI_PostMessage + string

    Aber ich kapier nicht, wie ich das mit ein uns dem selben Fenster machen soll.
    Mein Programm wird ja aufgerufen und festgestellt, dass es offen ist und dann wieder geschlossen.
    Und genau in dieser Zeit muss ich ja den pfad speichern oder verschicken.

    Die Anna :*

    "Wo kämen wir hin, wenn jeder sagte wo kämen wir hin, und niemand ginge, um zu sehen, wohin wir kämen, wenn wir gingen..." :wacko:

  • Ja, danke :) Hab ich gemerkt

    Aber ich bin wohl zu blöd um es bei mir einzubauen.

    Das ist mein Code bis jetzt:

    Spoiler anzeigen
    [autoit]


    #include <ButtonConstants.au3>
    #include <ComboConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GUIListBox.au3>
    #include <GuiStatusBar.au3>
    #include <ProgressConstants.au3>
    #include <WindowsConstants.au3>
    #include <File.au3>
    #include <INet.au3>
    #include <Misc.au3>

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

    If _Singleton("load",1) = 0 Then

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

    MsgBox(0,"","Mehrfach-Aufruf")
    Exit

    EndIf

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

    #Region ### START Koda GUI section ### Form=
    $Form = GUICreate("load", 458, 360, -1, -1)

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

    $myList = GUICtrlCreateList("", 8, 8, 249, 266, BitOR($GUI_SS_DEFAULT_LIST,$LBS_NOSEL,$WS_HSCROLL))
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

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

    If $CmdLine[0] > 0 Then
    GUICtrlSetData($mylist, $CmdLine[1]&"|")
    EndIf

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

    While True

    $msg = GUIGetMsg($Form)
    Select

    Case $msg = $GUI_EVENT_CLOSE
    Exit
    EndSelect

    WEnd

    [/autoit]

    Also, wenn ich eine Datei im Kontextmenü auf hinzufügen klicke, gehts super.
    Bei der nächsten Datei, also wenn das Fenster noch offen ist, gehts nicht mehr.. logisch.

    Nur ich checks nicht, wie man das Beispiel von dir - was echt das tut was ich will - auf meinen Fall übertragen kann.
    Könntest du mir helfen das umzuschreiben? Ich will ja die Dateinamen in diese Liste bekommen :(
    Das ist nur ein String, der ankommt. Z.B: "C:/test.txt" Hilfe ;(

    Die Anna :*

    "Wo kämen wir hin, wenn jeder sagte wo kämen wir hin, und niemand ginge, um zu sehen, wohin wir kämen, wenn wir gingen..." :wacko:

    Einmal editiert, zuletzt von AnnaM (27. Mai 2011 um 08:13)

  • Ich hab das Beispiel mal etwas zusammengekürzt.

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

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

    Global $aGlobalArray, $hWnd_AutoIt, $iGlobalShowArray = 0, $sUniqueID = "E15FF08B-84AC-472A-89BF-5F92DB683165" ; Declare Variables.

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

    If Not _Singleton($sUniqueID, 1) Then
    If Not WinWait($sUniqueID, "", 10) Then Exit MsgBox(0, '', "Fehler beim warten") ; Auf das Autoit-Fenster warten.
    Local $hTarget = HWnd(ControlGetText($sUniqueID, "", "Edit1")) ; Das Handle aus dem Editfenster auslesen und
    WM_COPYDATA_SENDDATA($hTarget, "test") ; string "test" senden
    Exit
    EndIf

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

    Global $g = GUICreate("test")

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

    Global $lblData = GUICtrlCreateLabel("", 10, 10, 100, 40)

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

    GUISetState()

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

    ; Jetzt bereit zum Daten empfangen
    GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA") ; Nachricht zum empfangen aktivieren
    ; GUI handle veröffentlichen im Editfenster des versteckten AutoIt-Fensters
    AutoItWinSetTitle("-"&$sUniqueID&"-")
    ControlSetText("-"&$sUniqueID&"-", "", "Edit1", $g)
    AutoItWinSetTitle($sUniqueID)
    ; Ende handle veröffentlichen

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

    While GUIGetMsg()<>-3
    WEnd

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

    Func WM_COPYDATA_SENDDATA($hHandle, $sString)
    Local $aReturn, $tParam, $tData
    $tData = DllStructCreate("wchar[" & StringLen($sString) + 1 & "]")
    DllStructSetData($tData, 1, $sString)
    $tParam = DllStructCreate("ulong_ptr;dword;ptr")
    DllStructSetData($tParam, 1, 0)
    DllStructSetData($tParam, 2, DllStructGetSize($tData))
    DllStructSetData($tParam, 3, DllStructGetPtr($tData))
    $aReturn = DllCall("user32.dll", "int", "SendMessageW", "hwnd", $hHandle, "uint", $WM_COPYDATA, "hwnd", 0, "ptr", DllStructGetPtr($tParam))
    If (@error) Or ($aReturn[0] = -1) Then Return 0
    Return 1
    EndFunc ;==>WM_COPYDATA_SENDDATA

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

    Func WM_COPYDATA($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $aArray, $tData, $tParam, $sString
    $tParam = DllStructCreate("ulong_ptr;dword;ptr", $ilParam)
    $tData = DllStructCreate("wchar[" & DllStructGetData($tParam, 2) / 2 & "]", DllStructGetData($tParam, 3))
    $sString = DllStructGetData($tData, 1)

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

    ; Daten setzen
    GUICtrlSetData($lblData, $sString)

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

    EndFunc ;==>WM_COPYDATA

    [/autoit]
  • So kanns doch nicht funktionieren!??! ohje.. was ist denn die Variable $g?
    Muss ich nicht dauernd im Hauptfenster in der Schleife abfragen, ob etwas reingekommen ist?

    Spoiler anzeigen
    [autoit]


    #include <ButtonConstants.au3>
    #include <ComboConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GUIListBox.au3>
    #include <GuiStatusBar.au3>
    #include <ProgressConstants.au3>
    #include <WindowsConstants.au3>
    #include <File.au3>
    #include <INet.au3>
    #include <Misc.au3>

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

    Global $aGlobalArray, $hWnd_AutoIt, $iGlobalShowArray = 0, $sUniqueID = "load" ; Declare Variables.

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

    If Not _Singleton($sUniqueID, 1) Then

    MsgBox(0,"","Mehrfach-Aufruf")
    If Not WinWait($sUniqueID, "", 10) Then Exit MsgBox(0, '', "Fehler beim warten")
    Local $hTarget = HWnd(ControlGetText($sUniqueID, "", "ListBox1")) ; ListBox wird hier angesprochen
    WM_COPYDATA_SENDDATA($hTarget, "test") ; string "test" senden
    Exit
    EndIf

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

    #Region ### START Koda GUI section ### Form=
    Global $Form = GUICreate("load", 458, 360, -1, -1)
    Global $myList = GUICtrlCreateList("", 8, 8, 249, 266, BitOR($GUI_SS_DEFAULT_LIST,$LBS_NOSEL,$WS_HSCROLL))
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

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

    If $CmdLine[0] > 0 Then
    GUICtrlSetData($mylist, $CmdLine[1]&"|")
    EndIf

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

    MsgBox(0,"","unten")

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

    ; Jetzt bereit zum Daten empfangen
    GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA")
    AutoItWinSetTitle("-"&$sUniqueID&"-")
    ControlSetText("-"&$sUniqueID&"-", "", "ListBox1", $g) ; was soll das $g sein? Ist das nicht der neue Text? 8|
    AutoItWinSetTitle($sUniqueID)
    ; Ende handle veröffentlichen

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

    While True

    $msg = GUIGetMsg($Form)
    Select

    Case $msg = $GUI_EVENT_CLOSE
    _close()
    EndSelect


    WEnd

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

    Func WM_COPYDATA_SENDDATA($hHandle, $sString)
    Local $aReturn, $tParam, $tData
    $tData = DllStructCreate("wchar[" & StringLen($sString) + 1 & "]")
    DllStructSetData($tData, 1, $sString)
    $tParam = DllStructCreate("ulong_ptr;dword;ptr")
    DllStructSetData($tParam, 1, 0)
    DllStructSetData($tParam, 2, DllStructGetSize($tData))
    DllStructSetData($tParam, 3, DllStructGetPtr($tData))
    $aReturn = DllCall("user32.dll", "int", "SendMessageW", "hwnd", $hHandle, "uint", $WM_COPYDATA, "hwnd", 0, "ptr", DllStructGetPtr($tParam))
    If (@error) Or ($aReturn[0] = -1) Then Return 0
    Return 1
    EndFunc ;==>WM_COPYDATA_SENDDATA

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

    Func WM_COPYDATA($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $aArray, $tData, $tParam, $sString
    $tParam = DllStructCreate("ulong_ptr;dword;ptr", $ilParam)
    $tData = DllStructCreate("wchar[" & DllStructGetData($tParam, 2) / 2 & "]", DllStructGetData($tParam, 3))
    $sString = DllStructGetData($tData, 1)

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

    ; Daten setzen
    GUICtrlSetData($mylist, $sString)

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

    EndFunc ;==>WM_COPYDATA

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

    ;(

    Die Anna :*

    "Wo kämen wir hin, wenn jeder sagte wo kämen wir hin, und niemand ginge, um zu sehen, wohin wir kämen, wenn wir gingen..." :wacko:

  • $g ist das handle der GUI, also bei dir $Form. Und in der Schleife musst du doch nicht abfragen, ob was neues dazukommt wenn du es nur anzeigen willst. Wenn du Daten bekommst, wird die Funktion WM_COPYDATA automatisch (wegen GUIRegisterMsg) aufgerufen und dort schreibst du den Wert dann in die Listview.

    Und du musst natürlcih anpassen, was gesendet werden soll bei WM_COPYDATA_SENDDATA(..., "hier dein Wert zum senden")

  • Hallo Progandy,

    vielen Dank, dass du mir so viel noch hilfst. Ist ja nicht selbstverständlich.
    Funktioniert nun super. Egal, was ich reinziehe, wird in der Liste angezeigt :)

    Vielen Dank nochmals,

    Die Anna :*

    "Wo kämen wir hin, wenn jeder sagte wo kämen wir hin, und niemand ginge, um zu sehen, wohin wir kämen, wenn wir gingen..." :wacko:

    Einmal editiert, zuletzt von AnnaM (27. Mai 2011 um 21:53)