ReadProgramString

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
HeX0R
Beiträge: 2958
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: ReadProgramString

Beitrag von HeX0R »

Das liegt an der Windows-Eventverarbeitung!
Wenn Du ClearGadgetItems() aufrufst, wird das erst in die Windows Messagequeue gelegt und erst dann komplett ausgeführt, nachdem (mehrmals) per WaitWindowEvent() diese Events auch abgeholt und verarbeitet wurden.
Du aber springst direkt danach zu Deinem ExifTool und keine weiteren Events werden abgeholt.
Die Holzhackermethode wäre, nach dem ClearGadgetItems() eine stumpfsinnige While WindowEvent() : Wend Zeile einzufügen.
Besser wäre aber natürlich das Ganze anders umzusetzen.

Bei Windowsanwendungen ist das A und O ständig alle Events abzuholen und natürlich auch zu verarbeiten.
Alles was das ausbremst muss dann ausgelagert oder anders konzipiert werden.
Benutzeravatar
dibro
Beiträge: 143
Registriert: 11.03.2006 12:52
Computerausstattung: Win 10 64 bit
Wohnort: Solingen

Re: ReadProgramString

Beitrag von dibro »

Danke, habe ich sofort ausprobiert,
While WindowEvent() : Wend
und es läuft.
Sieht jedenfalls viel besser aus, als vorher. Holzhacker ist mir egal :mrgreen:
Ich hatte schon mit delay() und 2 x löschen versucht, was nichts brachte.
Wenn das compiliert ist, sieht das eh keiner mehr.
Viele Grüße und schönes Wochenende
Dieter
Gruß aus Solingen, PB 6.0 Win 10 Pro
Benutzeravatar
mk-soft
Beiträge: 3700
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: ReadProgramString

Beitrag von mk-soft »

RunProgram in einem Thread auslagern.

Siehe Example 2
Link: Mini Thread Control
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
dibro
Beiträge: 143
Registriert: 11.03.2006 12:52
Computerausstattung: Win 10 64 bit
Wohnort: Solingen

Re: ReadProgramString

Beitrag von dibro »

@ mk-soft
danke für die Hinweise und die Beispiele.
Wie irgendwo erwähnt, habe ich seit mehr als 10 Jahre nicht mehr programmiert und bin jetzt nur wieder dazu gekommen, weil die GoPro Kamera die falsche Zeit hatte und ich die verschiedenen Videos nicht ordenlich sortieren kann. Deshalb hole ich das Erstelldatum der Kamera nach "vorne" um es manipulieren zu können. Ich habe aber vieles vergessen und bin gewisserweise wieder ein Anfänger.
Die Beispiele habe ich ausprobiert und ich schaue nach einiger Zeit auch leidlich durch. Jetzt kommt meine Frage:
Warum muss ich das so aufwändig machen? OK das mit dem While WindowEvent() : Wend ist irgendwie nicht elegant, obwohl es funktioniert.
Wenn ich aber die Procedur ExifRun(...) als Thread aufrufe, funktioniert das auch ohne While WindowEvent() : Wend, ist aber total einfach.
Oder ist das eine blöde Frage?
Das Exiftool beendet ja von alleine, wahrscheinlich auch wenn ich viele Dateien ändern will, habe ich aber noch nicht probiert. Da will ich erst mal Sicherheitskopien der Videos machen. Vielleicht muss ich dann auch ein delay einfügen oder warten, bis das Tool fertig ist.

Code: Alles auswählen

    Case #Exif_Button ; Exif Datum nach Filedatum verschieben
        ClearGadgetItems(#Exif_Text) 
        While WindowEvent() : Wend
        If GetGadgetState(#Combogadget_Datei) = 0 : Datei$ = "G*.MP4" : EndIf 
        If GetGadgetState(#Combogadget_Datei) = 1 : Datei$ =  "*.MP4" : EndIf 
        If GetGadgetState(#Combogadget_Datei) = 2 : Datei$ =  "*.MOV" : EndIf 
        Pfad_File$ = Option$+Arbeitsverzeichnis$+Datei$ 
        ExifTool_Pfad$ = ExifPfad$ + "Exiftool.exe"   
        ExifRun(ExifTool_Pfad$, Pfad_File$, Arbeitsverzeichnis$, Flags) 
        AddGadgetItem(#Exif_Text,-1,Ausgabetext$+#NewLine)
    EndSelect 
Vielen Dank fürs Kümmern
Gruß
Dieter
Update 2.11.2022 Es läuft so natürlich nicht, als Anfänger hatte ich die vorige Datei im Compiler stehen gelassen und da konnte ich ändern was ich wollte. Ganz schön .... :? Alles wieder wie zuvor
Zuletzt geändert von dibro am 02.11.2022 19:34, insgesamt 2-mal geändert.
Gruß aus Solingen, PB 6.0 Win 10 Pro
Benutzeravatar
mk-soft
Beiträge: 3700
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: ReadProgramString

Beitrag von mk-soft »

Schau dir bitte alle Bespiele ...

Ein Thread läuft asynchron vom Hauptprogramm. Somit kannst du nicht einfach nach dem Aufruf das Ergebnis ausgeben, sondern muss auf die Fertigmeldung vom Thread warten (PostEvent)
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
HeX0R
Beiträge: 2958
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: ReadProgramString

Beitrag von HeX0R »

Das Problem mit While WindowEvent() : Wend ist, dass hiermit die Events "verbrannt" werden.
Da sie außerhalb der Main Event-Schleife läuft, würde Dein Programm nicht mitbekommen, wenn währenddessen z.B. der User Dein Programm beenden möchte (gut, mittlerweile gibt es BindEvents, damit kann man das Problem sogar umgehen).
Du bastelst hier ja offensichtlich ein Programm nur für Dich selbst, von daher würde ich sagen, lass das mit den Threads und nimm die Verbrennungsmethode.
Du solltest die ganzen Hinweise nur nicht völlig ignorieren, vielleicht machst Du ja auch mal ein Programm für andere User, spätestens dann musst Du aufpassen, wie Du die Dinge angehst.

In der PB IDE gibt es übrigens auch an mehreren Stellen diesen "Kniff".
Aber hier ist das eher dadurch entstanden, dass die IDE über die Jahre zu einem wahren Biest gewachsen ist, und irgendwann kommt man gar nicht mehr umhin (falls man nicht alles neu konzipieren möchte), solche "Krücken" zu benutzen.
Axolotl
Beiträge: 148
Registriert: 31.12.2008 16:34

Re: ReadProgramString

Beitrag von Axolotl »

Moin dibro,

ich kannte das exiftool bisher nicht, allerdings wurde ich neugierig und habe mal ein Testprogram gebaut.
Den Programmcode findest du im englischen Forum: Test_ExifTool

Für die Programmausführung von ExifTool verwende ich einen Thread und lasse alle Aufgaben durch ExifTool erledigen......
Die o.g. Beispiele zum Thema Thread sind perfekt und plattformunabhängig nutzbar.
Unter Windows ist der Zugriff auf die GUI wohl nicht ganz so sensibel wie unter Linux od.MacOS, deshalb findest du im Code auch die direkten Zugriffe auf Gadgets aus dem Thread heraus.
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Benutzeravatar
dibro
Beiträge: 143
Registriert: 11.03.2006 12:52
Computerausstattung: Win 10 64 bit
Wohnort: Solingen

Re: ReadProgramString

Beitrag von dibro »

@mk-soft
Da habe ich Mist gebaut, der Code stand noch im Compieler und da konnte ich ändern, was ich wollte, jetzt kümmere ich mich mal um den Thread.
@HeX0R
Die Bastelei ist zwar für mich privat, aber ich lasse das nicht so stehen, jetzt will ich es wissen - das mit dem Thread, das habe ich auch früher nie gebraucht. Für Rentner auf jeden Fall besser als Kreuzworträtseln.

@Axolotl
danke für den Link, da kann ich mir schön abgucken, wie so etwas gemacht wird. Wenn ich es schaffe und fertig bin, melde ich mich wieder.

Update 3.11.2022: Tolles Tool, kann eigenltlich alles was ich brauche, Time- und Date-Shift etc.
Da brauche ich nur wenige Kommandos ändern. :allright:
Da kann ich mein Progrämmle getrost einstampfen.
Schön ist auch der ExifTool-Help-Text, den ich mir in den Editor kopiert habe, jetzt kann ich auch schön die Kommandos mit F3 suchen, die ich brauche.
In der Kommandozeilenversion vom ExifTool ist das alles nicht so einfach zu finden.
Ich werde trotzdem das TestTool in ein eigenes Tool für mich umbauen.
Nur so zum Spaß und um zu lernen. Ich hoffe, du hast nichts dagegen Axolotl.
Vielen Dank und viele Grüße
Dieter
Gruß aus Solingen, PB 6.0 Win 10 Pro
Benutzeravatar
dibro
Beiträge: 143
Registriert: 11.03.2006 12:52
Computerausstattung: Win 10 64 bit
Wohnort: Solingen

Re: ReadProgramString

Beitrag von dibro »

Hi zusammen,
nachdem ich mein Prog auf einen Thread umgestellt habe, ist das Problem mit While WindowEvent() : Wend noch immer nicht gelöst.

Code: Alles auswählen

;MEXDatum Modifiziere EXif DaTum von Video-Dateien mit EXiftool  


;exiftool.exe "-filemodifydate<createdate"  "-filecreatedate<createdate" *.MP4 =>> Zeiten kopieren
;exiftool.exe "-filemodifydate<createdate"  "-filecreatedate<createdate"  G*.MP4
;-------------------------------------------------------------------------------------------------------

EnableExplicit



#Mainwindow = 1

Enumeration Gadgets 
  #Button_Pfad_Wahl                     ; Pfadwahl 
  #Button_Start_Datumsaenderung         ; Start Zeit ändern 
  #Button_Ende_Prgr                     ; Programmende 
  #Button_Exif_Start                    ; Start ExifTool
  #Button_Exif_Verzeichnis_suchen       ; Verzeichnis mit dem ExifTool
  #combogadg_DaT_Art                    ; Erstell- /  Änderungddatum
  #combogadg_DaT_Std                    ; Anzahl Stundenverschiebung 
  #Combogadget_Datei_Wildcards          ; Dateiart Wildcards  einstellen G*.MP4 / *.MP4 / *.* 
  #EDGadget_Text_Ausgabe                ; Anzeige Exifverzeichnis 
  #TxtGadg_Std_Korr                     ; Anzeige der Stundenkorrektur
  #Textgadget_Arbeistsverzeichnis       ; Zeigt den Pfad an 
  #TxtGadget_Zeit                       ; Zeigt die aktuelle Dateizeit 
  #TextGadget_Exif_Pfad                 ; Anzeige ExifPfad 
  #ProzessbarGadget
  #CheckboxSticky
EndEnumeration

  
                 
 Enumeration #PB_Event_FirstCustomValue
    #EventBeginProcessing
    #EventProcessingFinished
 EndEnumeration


  #TxtRunProgLaufzeit      =  "Laufzeit "
  #TxtZeiteinheit$         =  " ms"
  #TxtRunPrgOK$            =  "OK"
  #TxtRunPrgError$         =  "Fehlercode: "
  #TxtRunPrgFATAL$         =  "Fataler Fehler "
  #TxtProg_nicht_gefunden$  = "Programm nicht gefunden: "
  #NewLine=#CRLF$          ;Windows neue Zeile


  Structure Pfade
    Exif_Pfad$                    ; Pfad zum ExifTool einschließlich #EXIF_Executable$
    EXIF_Executable$              ; "ExifTool.exe"
    Exif_Kommando$                ; Exiftool Parameter
    Arbeitsverzeichnis$           ; Arbeitsverzeichnnis mit den Dateien
    Datei_Parameter$              ; Wildcards G*.MP4, *.MP4, *.MOV
    WatchDogTime.i                ; check on working tool 
  EndStructure
  
  
  Global Parameter.Pfade
  

  
Global datum$ = FormatDate("%dd.%mm.%yyyy.%hh:%mm:%ss",Date())
Global datums_flag = #PB_Date_Created
Global shift_hour_flag = 0  ; Stundendifferenz (-2)-(-1)- 0 - (+1) -(+2)
Global Ausgabetext$         ; "Datenausgabe"
Global Top = 5 
Global Hoehe = 30
Global Neu = 1
Global Ende, i, fertig


Procedure InitParameter()

  Protected Pfad$, ArbVerz$, Wildcards$, State.i, Watch.i, Thr.i, Abbr.i
  
  Pfad$ = GetGadgetText(#TextGadget_Exif_Pfad)

  ArbVerz$ = GetGadgetText(#Textgadget_Arbeistsverzeichnis)
  
  State = GetGadgetState(#Combogadget_Datei_Wildcards)
  If State = 0 : Wildcards$ = "G*.MP4" : EndIf
  If State = 1 : Wildcards$ = "*.MP4"  : EndIf
  If State = 2 : Wildcards$ = "*.MOV"  : EndIf

 
  ;init Struct 
   With Parameter      
     \Exif_Pfad$          = Pfad$ 
     \EXIF_Executable$    = "ExifTool.exe"
     \Exif_Kommando$      = " -filemodifydate<createdate" + " -filecreatedate<createdate "
     \Datei_Parameter$    = Wildcards$
     \Arbeitsverzeichnis$ = ArbVerz$
     EndWith 
EndProcedure

  

;-------------------------------

Procedure.s ExifRun(*Parameter)
  
  Protected Exitcode, NoErrText
  Protected NewErrorText$, AllErrorText$ =""
  Protected start = ElapsedMilliseconds()
  Protected Program.i
  Protected path$, Cmd$, WorkDir$, WildCard$ 
  Protected Flags =#PB_Program_Open | #PB_Program_Read | #PB_Program_Error | #PB_Program_Hide ;| #PB_Program_Wait
  
  With Parameter
    path$      = \Exif_Pfad$ + \EXIF_Executable$
    Cmd$       = \Exif_Kommando$  
    WorkDir$   = \Arbeitsverzeichnis$
    WildCard$ = \Datei_Parameter$            
  EndWith 
  
  cmd$ = Cmd$ + WorkDir$ + WildCard$
  
 
  Program = RunProgram(path$, Cmd$, WorkDir$, Flags)
   fertig = PostEvent(#EventBeginProcessing)

   If Program    
    While ProgramRunning(Program) 
      If AvailableProgramOutput(Program)                  
        Ausgabetext$ = WildCard$ +" "+ ReadProgramString(Program) + #NewLine 
      EndIf
        NewErrorText$=ReadProgramError(Program) 
      While NewErrorText$<>""
        NoErrText+1
        AllErrorText$ + Str(NoErrText)+":"+NewErrorText$+#NewLine
        NewErrorText$=ReadProgramError(Program) 
      Wend 
      i = i+2 : SetGadgetState   (#ProzessbarGadget, i) : Delay(40)
      If i => 100 : i= 0 : EndIf
    Wend
    Ausgabetext$+" "+#TxtRunProgLaufzeit+":"+Str(ElapsedMilliseconds()-start)+#TxtZeiteinheit$+#NewLine  
    If ElapsedMilliseconds()-start    
      Exitcode=ProgramExitCode(Program)
      If Exitcode<>0
        If 0=Exitcode 
          Ausgabetext$+#TxtRunPrgOK$ 
        Else   
          Ausgabetext$ + #TxtRunPrgError$ + Str(Exitcode) + #NewLine
          Ausgabetext$ + AllErrorText$ 
        EndIf 
      EndIf

    Else 
      If 0<>IsProgram(Program) 
        KillProgram(Program)
        CloseProgram(Program)
       Ausgabetext$ = Ausgabetext$ +" " + #NewLine +AllErrorText$ +" " 
      EndIf 
    EndIf 
    fertig = PostEvent(#EventProcessingFinished)
     i = 0
     SetGadgetState   (#ProzessbarGadget, i)
     ProcedureReturn Ausgabetext$
     CloseProgram(Program)
  Else
    MessageRequester(#TxtRunPrgFATAL$,#TxtProg_nicht_gefunden$+" "+ path$) 
  EndIf
  
EndProcedure



Procedure AendereDatum()
   
  Protected Zeit$, Pfad$
  Protected ArbVerz$, Para$
  Protected DatumsWert.i, DW_neu.i, gefunden.i
  
  With Parameter
    ArbVerz$ = \Arbeitsverzeichnis$
    Para$    = \Datei_Parameter$
  EndWith 
  
  gefunden = ExamineDirectory(#PB_Any,ArbVerz$,Para$) 

  If gefunden 
    While NextDirectoryEntry(gefunden) 
      If DirectoryEntryType(gefunden) = #PB_DirectoryEntry_File
          Para$ = DirectoryEntryName(gefunden) 
          If FileSize(Pfad$) =  FileSize(Para$)
            Para$ = ArbVerz$ + Para$ 
            DatumsWert = GetFileDate(Para$,datums_flag)                      
            Zeit$ = FormatDate("%dd.%mm.%yyyy:%hh.%ii",Datumswert)              
            DW_neu = AddDate(DatumsWert,#PB_Date_Hour,shift_hour_flag)        
            Zeit$ = FormatDate("%dd.%mm.%yyyy:%hh.%ii",DW_neu)               
            DW_neu = DatumsWert + (3600 * shift_hour_flag)                   
            Zeit$ = FormatDate("%dd.%mm.%yyyy:%hh.%ii",DW_neu)               
            SetFileDate(Para$,datums_flag,ParseDate("%dd.%mm.%yyyy:%hh.%ii",zeit$))
            SetGadgetText(#TxtGadget_Zeit, Zeit$)                              
            Ausgabetext$ = Para$ + " " + Zeit$
            AddGadgetItem(#EDGadget_Text_Ausgabe, -1, Ausgabetext$) ; +#NewLine
          Else
            Ausgabetext$ = "keine Datei gefunden"
            AddGadgetItem(#EDGadget_Text_Ausgabe, -1, Ausgabetext$ + #NewLine)
          EndIf
      EndIf
    Wend
    FinishDirectory(gefunden)
  Else 
    Ausgabetext$  = "Datei nicht gefunden, Arbeitsverzeichnis gesetzt?"
    AddGadgetItem(#EDGadget_Text_Ausgabe, -1, Ausgabetext$ + #NewLine)
 EndIf

EndProcedure
;  Erstellt eine Preference-Datei namens MEXDatum.pref  ------------------------------
  If OpenPreferences("MEXDatum.pref")
    PreferenceGroup("Global")
    With Parameter          ; initialisiere
      \Exif_Pfad$ = ReadPreferenceString("Exif_Pfad$","")
      \Arbeitsverzeichnis$ = ReadPreferenceString("Arbeitsverzeichnis$","")
      \Datei_Parameter$ = ReadPreferenceString("Datei_Parameter$","")
    EndWith
    ClosePreferences()
  Else
    CreatePreferences("MEXDatum.pref")
    ClosePreferences()
  EndIf  
    
; ----------------------------------

;--- Window 
  OpenWindow(#Mainwindow,             0,0,500,420,"MEXDatum = Modifiziere EXif-Datum mit dem Exiftool von Phil Harvey",
             #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  
  StickyWindow(#Mainwindow,#True)
  TextGadget(#TxtGadg_Std_Korr,     10,Top+10,180,20,"Datum lesen, Zeit ändern",#PB_Text_Center) : Top =Top + 30
  ComboBoxGadget(#combogadg_DaT_Art,10,Top,180,30) : Top = Top + 40
  AddGadgetItem(#combogadg_DaT_Art,0,"Zeit -2 Std")
  AddGadgetItem(#combogadg_DaT_Art,1,"Zeit -1 Std")
  AddGadgetItem(#combogadg_DaT_Art,2,"Datum +/-0 Std")
  AddGadgetItem(#combogadg_DaT_Art,3,"Zeit +1 Std")
  AddGadgetItem(#combogadg_DaT_Art,4,"Zeit +2 Std")
  SetGadgetState(#combogadg_DaT_Art,2) 
  If #combogadg_DaT_Art = 2 
    GadgetToolTip(#combogadg_DaT_Art, "das Datum wird nicht verändert")
  EndIf
;   keine Korrektur, nicht verändert, es wird nur die Zeit ausgelesen
  
  ComboBoxGadget(#combogadg_DaT_Std,10,Top,180,30)    : Top = Top + 40                          
  AddGadgetItem(#combogadg_DaT_Std,0,"Setzen: Datum erstellt")
  AddGadgetItem(#combogadg_DaT_Std,1,"Setzen: Datum geändert")
  SetGadgetState(#combogadg_DaT_Std,0)
  GadgetToolTip(#combogadg_DaT_Std,"Wählt welches Datum korrigiert werden soll")
  TextGadget(#TxtGadget_Zeit,         10,Top,180,30,datum$,#PB_Text_Border|#PB_Text_Center) : Top = Top + 40
  
  ButtonGadget(#Button_Pfad_Wahl,          10,Top,180,30,"Setzen: Arbeitsverzeichnis",#PB_Text_Center) : Top = Top + 40
  TextGadget  (#Textgadget_Arbeistsverzeichnis,           10,Top,180,35,"",#PB_Text_Border|#PB_Text_Center) : Top = Top + 45 ; zeigt den Pfad  
  SetGadgetText(#Textgadget_Arbeistsverzeichnis,Parameter\Arbeitsverzeichnis$)
  GadgetToolTip(#Button_Pfad_Wahl,"Wählt dasArbeitsverzeichnis mit den Dateien")
  
  ComboBoxGadget(#Combogadget_Datei_Wildcards,10, Top, 180, Hoehe) : Top = Top+40
  AddGadgetItem(#Combogadget_Datei_Wildcards,0,"Gopro: G* . MP4")
  AddGadgetItem(#Combogadget_Datei_Wildcards,1,"Video:  * . MP4")
  AddGadgetItem(#Combogadget_Datei_Wildcards,2,"Video:  * . MOV")

  SetGadgetState(#Combogadget_Datei_Wildcards,0)
  
  ButtonGadget(#Button_Exif_Verzeichnis_suchen,   10,Top,180,30,"Setzen: Exifverzeichnis",#PB_Text_Center) : Top = Top + 40
  GadgetToolTip(#Button_Exif_Verzeichnis_suchen, "Stellt das Verzeichnis mit dem ExifTool ein") 
  
  TextGadget(#TextGadget_Exif_Pfad,       10,Top,180,30,"",#PB_Text_Border|#PB_Text_Center) : Top = Top + 65 ; zeigt den Pfad  
  SetGadgetText(#TextGadget_Exif_Pfad,Parameter\Exif_Pfad$)
  
  
  ButtonGadget(#Button_Start_Datumsaenderung,       10, Top, 120, 30,"Start: Zeit",#PB_Text_Center) ; #Button_Start_Datumsaenderung,5,200,60,30
  GadgetToolTip(#Button_Start_Datumsaenderung, "startet einen Durchlauf, kann auch mehrfach betätigt werden") 
  ButtonGadget(#Button_Exif_Start,        270,Top,120,30,"Exiftool",#PB_Text_Center) ; #Button_Start_Datumsaenderung,5,200,60,30
  GadgetToolTip(#Button_Exif_Start, "startet das ExifTool") 

  ButtonGadget(#Button_Ende_Prgr,        140,Top,120,30,"Ende",#PB_Text_Center) ;#Button_Ende_Prgr,135,200,60,30,
  SetGadgetColor(#Button_Ende_Prgr, #PB_Gadget_FrontColor, $0000FF)
  GadgetToolTip(#Button_Ende_Prgr, "beendet das Programm") 

  ProgressBarGadget(#ProzessbarGadget,  10, Top -15, 480,  8, 0, 100)
  CheckBoxGadget(#CheckboxSticky, 400, Top , 100, 20, "Fenster oben")
  SetGadgetState(#CheckboxSticky,1)
  If #CheckboxSticky = 1 : StickyWindow(#Mainwindow,#True) : EndIf 
  
  EditorGadget(#EDGadget_Text_Ausgabe,          205,8,285, 355,#PB_Editor_ReadOnly|#PB_Editor_WordWrap)
  Ausgabetext$ = " Das ExifTool von von Phil Harvey muss auf dem Rechner installiert sein " + #NewLine +
                 " ------------------------------------------"                   + #NewLine +
                 " 1. Pfade setzen "        + #NewLine +
                 " 2. Dateiart wählen "     + #NewLine +
                 " 3. ExifTool starten "    + #NewLine +
                 " 4. Zeitänderung wählen " + #NewLine +
                 " 5. Zeit starten "        + #NewLine +
                 " 6. Freuen "              + #NewLine +
                 "------------------------------------------"                   + #NewLine +
                 " Das Programm speichert die aktuellen Einstellungen in einer MEXDatum.pref " + #NewLine +
                 " Die Funktionen Start und ExifTool können mehrfach aufgerufen werden " + #NewLine +
                 " Der Button ExifTool setzt die Änderungen Im FileDate wieder zurück auf das Erstelldatum der Kamera."
 
  If Neu 
        SetGadgetText(#EDGadget_Text_Ausgabe,Ausgabetext$)
     Neu = 0
  EndIf 
  StartDrawing(WindowOutput(#Mainwindow)) ;Rahmen zeichnen
          DrawingMode(#PB_2DDrawing_Outlined)
          Box(                      5, 5, 190, 360, RGB(255, 0, 0) ) 
          Box(                    202, 5, 290, 360, RGB(255, 0, 0))
  StopDrawing()
 

;--- Main -------------
Repeat
  Select WaitWindowEvent()      ;auf Ereignis im Window warten
    Case #PB_Event_CloseWindow  ;Fenster schließen
      Ende=1
  ;-TODO Warum funktioniert die Checkbox nicht???
    Case   #CheckboxSticky                              
      If   #PB_Checkbox_Checked
        StickyWindow(#Mainwindow,1)
      Else  
        StickyWindow(#Mainwindow,0)
      EndIf
    Case #PB_Event_Gadget ; Ende-Taste drücken
      Select EventGadget()
    Case #Button_Ende_Prgr
      Ende=1
  ;- Arbeitsordner wählen    
    Case #Button_Pfad_Wahl 
      With Parameter
      \Arbeitsverzeichnis$=PathRequester("Arbeitsordner wählen",\Arbeitsverzeichnis$)
      SetGadgetText(#Textgadget_Arbeistsverzeichnis,\Arbeitsverzeichnis$)
      InitParameter()
      EndWith
  ;- Exif-Pfad auswählen  
    Case #Button_Exif_Verzeichnis_suchen                    
      With Parameter
     \Exif_Pfad$= PathRequester("ExifTool Pfad wählen", \Exif_Pfad$)
      SetGadgetText(#TextGadget_Exif_Pfad,\Exif_Pfad$)
      InitParameter()
    EndWith
 ;- FileDate wählen
    Case #combogadg_DaT_Std                         
      Select GetGadgetState(#combogadg_DaT_Std)
       Case 0 : datums_flag = #PB_Date_Created:   ; gibt das Erstellungsdatum der Datei zurück
       Case 1 : datums_flag = #PB_Date_Modified:  ; gibt das Änderungsdatum der Datei zurück
      EndSelect
 ;- Stunden +/- wählen
    Case #combogadg_DaT_Art                         
      Select GetGadgetState(#combogadg_DaT_Art)   ; das Datum korrigiert werden soll
        Case 0 : shift_hour_flag =  -2
        Case 1 : shift_hour_flag =  -1
        Case 2 : shift_hour_flag =   0
        Case 3 : shift_hour_flag =   1
        Case 4 : shift_hour_flag =   2  
      EndSelect
  ;- Parameter wählen   
    Case #Combogadget_Datei_Wildcards       ; Auswählen welche Dateien korrigiert werden sollen
      With Parameter            
      Select GetGadgetState(#Combogadget_Datei_Wildcards)
        Case 0 : \Datei_Parameter$ =  "G*.MP4"
        Case 1 : \Datei_Parameter$ =  "*.MP4"
        Case 2 : \Datei_Parameter$ =  "*.MOV"
   
      EndSelect 
    EndWith 
    InitParameter()
  Case #PB_Event_CloseWindow :  End
    
 ;- Start Datumsänderung            
    Case #Button_Start_Datumsaenderung ; Zeitänderung starten
        ClearGadgetItems(#EDGadget_Text_Ausgabe) 
        AendereDatum()
        
;- ExifTool Start        
    Case #Button_Exif_Start ; Exif Datum nach Filedatum verschieben
      ClearGadgetItems(#EDGadget_Text_Ausgabe)
;-TODO Warum funktioniert CleargadgetItems hier nur mit der nächsten Zeile      
      While WindowEvent() : Wend 

      With Parameter
        If GetGadgetState(#Combogadget_Datei_Wildcards) = 0 : \Datei_Parameter$ = "G*.MP4" : EndIf 
        If GetGadgetState(#Combogadget_Datei_Wildcards) = 1 : \Datei_Parameter$ =  "*.MP4" : EndIf 
        If GetGadgetState(#Combogadget_Datei_Wildcards) = 2 : \Datei_Parameter$ =  "*.MOV" : EndIf
        If GetGadgetState(#Combogadget_Datei_Wildcards) = 2 : \Datei_Parameter$ =  "*.*"   : EndIf

      EndWith 
      InitParameter()
      ExifRun(@Parameter)             ;  CreateThread
      AddGadgetItem(#EDGadget_Text_Ausgabe,-1,Ausgabetext$+#NewLine)
      SetGadgetState(#combogadg_DaT_Art,2)       ;TODO diese 2 Zeilen entfallen, wenn die Zeit 
      shift_hour_flag = 0                        ;unmittelbar nach dem ExiTool korrigiert werden soll
      AendereDatum()       ; ruft anschließEnd das Programm Ändere Datum auf
 
    EndSelect
    
  EndSelect
Until Ende

;-Preferenzdatei schreiben
  OpenPreferences("MEXDatum.pref")
  PreferenceGroup("Global")
  With Parameter
    WritePreferenceString("Exif_Pfad$",         \Exif_Pfad$)
    WritePreferenceString("Exif_Executable$",   \EXIF_Executable$)
    WritePreferenceString("Exif_Kommando$",     \Exif_Kommando$)
    WritePreferenceString("Arbeitsverzeichnis$",\Arbeitsverzeichnis$)
    WritePreferenceString("Datei_Parameter$",   \Datei_Parameter$)
  EndWith
  ClosePreferences()
  
  End


  
Warum wird das Editorgadget durch Drücken der Buttons #Button_Start_Datumsaenderung Zeile 369 gelöscht, aber nicht bei #Button_Exif_Start Zeile 374. Ich habe alles versucht aber ohne While WindowEvent() : Wend geht es nicht.
Außerdem bekomme ich das #CheckboxSticky-Gadget Zeile 315 nicht ans laufen. Was ist da falsch?
Ich weiß nicht mehr weiter - wer kann mir da helfen.
Vielen Dank und schönes Wochenende
Dieter
Gruß aus Solingen, PB 6.0 Win 10 Pro
Benutzeravatar
Macros
Beiträge: 1314
Registriert: 23.12.2005 15:00
Wohnort: Olching(bei FFB)
Kontaktdaten:

Re: ReadProgramString

Beitrag von Macros »

Hallo Dieter,

das lässt sich beides leicht erklären:

Das Editorgadget wird gelöscht. Du siehst es jedoch nicht.
Das WaitWindowEvent() bzw. WindowEvent() erzählt deinem Programm nicht nur was auf dem Fenster passiert ist (damit du er später durch das Select verarbeiten kannst) es fängt auch ein paar dieser Ereignisse ab und kümmert sich darum. Dazu gehört das Fenster neu zu zeichnen.

Weil in Fall von #Button_Exif_Start dein Programm erst mal anderweitig beschäftigt ist dauert es, bis es wieder in den Rundlauf der Prgrammschleife kommt und das Fenster neuzeichnet. Durch das While WindowEvent() : Wend erledigt es davor alle neuzeichnen Aufgaben.

Das ist allerdings eine schlechte Lösung weil:
  • Wenn der Anwender etwas auf deinem Fenster macht während das While WindowEvent() : Wend läuft verwirfst du es und das Programm reagiert nicht darauf. Falls du in Zukunft einen Button zum Abbrechen einbauen willst klappt das so also nicht.
  • Wenn danach das Fenster neugezeichnet werden muss (das kann aus vielen Gründen passieren, manchmal nur, wenn man ein Fenster darüberschiebt) und dein Programm schon beim Starten vom Exiftool angekommen ist, dann tut es das nicht.
Die Lösung für solche Dinge sind Threads. Dein Hauptprogramm macht weiter in der Fensterschleife und dein Thread kümmert sich um das Exiftool. Schau es dir in der Hilfe und mit ein paar Beispielen mal an, dadurch, dass du ExifRun() als Prozedur hast, hast du gute Voraussetzungen.
Oh nun lese ich gerade du sagst du hättest schon einen Thread. Hast du nicht. Dazu musst du schon die Funktion CreateThread verwenden. Wie gesagt, dafür gibt es viele Beispiele. Schau ein paar an und versuche sie nachzuvollziehen und experimentiere damit die Beispiele zu ändern.

Nochmal kurz zum Code vom #CheckboxSticky-Gadget

Code: Alles auswählen

Case   #CheckboxSticky                              
      If   #PB_Checkbox_Checked
        StickyWindow(#Mainwindow,1)
      Else  
        StickyWindow(#Mainwindow,0)
      EndIf
Wenn du überlegst, was #PB_Checkbox_Checked ist, wird dir der Fehler klar.Die Konstante hat immer den Wert 1 und somit landest du immer im ersten Fall vom If. Du musst den Status abfragen.

Code: Alles auswählen

If GetGadgetState(#CheckboxSticky)=#PB_Checkbox_Checked
Allerdings weil das Gadget so schön den Status mit 0 und 1 zurückgibt kannst du einen Trick verwenden und deinen Code sehr viel kürzer machen.
(Das geht nur solange du das Gadget nicht mit dem #PB_CheckBox_ThreeState Flag verwendest, was du ja nicht tust)

Code: Alles auswählen

Case   #CheckboxSticky                              
      StickyWindow(#Mainwindow, GetGadgetState(#CheckboxSticky) )
Bild
Antworten