Statusmeldung von Durchlauf einer Schleife

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Panik
Beiträge: 9
Registriert: 21.03.2007 20:18

Statusmeldung von Durchlauf einer Schleife

Beitrag von Panik »

Hallo!

Ich habe mir seit kurzem Purebasic geleistet und versuche bei meinem ersten Programm das umzusetzen, was ich mir schon als HTA und vbs erstellt habe.
Ich scheitere aber bei dem Purebasiccode an einer Sache:
Ich lasse ein externes Programm mittels Sendkeys die Bilder eines Ordner bearbeiten. Dazu wird eine Schleife durchlaufen.
Nun wollte ich im Hauptprogramm irgendwie eine Anzeige in der Statuszeile haben, welche mir anzeigt, bei welchem Bild das Purebasicprogramm ist - also der aktuelle Schleifenstand.
Es scheitert irgendwie daran, das die Anzeige sich nicht aktualisieren kann.
(in vbs habe ich das mit einem zeitlich begrenzten msgbox-popub gemacht. Das ist ja in Purebasic nicht drin - oder ?)

Hat jemand einen Tip ?

Panik

Code: Alles auswählen

;Entrauscher für schlechte Fotos (z.B. digitalisierte Unterwasserbilder von Einwegkameras )
;Programm nach Sendkeys-Abschnitt von Panik programmiert
;
; German forum:
; Author: Danilo
; Date: 07. April 2003
; OS: Windows
; Demo: No
; Posted 07 April 2003 by Danilo on german forum
;SendKeys(handel,Window$,Keys$) 
;Handel ......... ist ein Handel zu einen Fenster bekommst du wenn du das Fenster erzeugst. 
;Window$ ........ Ist der Name des Fesnters, wenn du den Handel nicht kennst. In dem Fall gibt man dan Handel = 0 an. 
;Keys$ .......... Sind die Tasten die du schicken möchtest, wobei du Sondertasten in {} Einschliest (zb. {CONTROLDOWN}) 

; SendKeys procedure by PB -- do whatever you want with it. :) 
; Syntax: r=SendKeys(handle,window$,keys$) ; r = 0 for failure. 
; Specify either a handle or window$ title to type to, but not both! 
; You cannot type curly braces { } as part of the keystrokes, sorry! 
; 
Procedure SendKeys(handle,window$,keys$) 
If window$<>"" : handle=FindWindow_(0,window$) : EndIf ; Use window$ instead of handle. 
   If IsWindow_(handle)=0 ; Does the target window actually exist? 
      ProcedureReturn 0 ; Nope, so report 0 for failure to type. 
   Else 
   ; This block gives the target window the focus before typing. 
   thread1=GetWindowThreadProcessId_(GetForegroundWindow_(),0) 
   thread2=GetWindowThreadProcessId_(handle,0) 
   If thread1<>thread2 : AttachThreadInput_(thread1,thread2,#True) : EndIf 
      SetForegroundWindow_(handle) ; Target window now has the focus for typing. 
      Delay(125) ; 1/8 second pause before typing, to prevent fast CPU problems. 
      ; Now the actual typing starts. 
      For r=1 To Len(keys$) 
          vk$=Mid(keys$,r,1) 
          If vk$="{" ; Special key found. 
             s=FindString(keys$,"}",r+1)-(r+1) ; Get length of special key. 
             s$=Mid(keys$,r+1,s) ; Get special key name. 
             Select s$ ; Get virtual key code of special key. 
                Case "ALTDOWN" : keybd_event_(#VK_MENU,0,0,0) ; Hold ALT down. 
                Case "ALTUP" : keybd_event_(#VK_MENU,0,#KEYEVENTF_KEYUP,0) ; Release ALT. 
                Case "BACKSPACE" : vk=#VK_BACK 
                Case "CONTROLDOWN" : keybd_event_(#VK_CONTROL,0,0,0) ; Hold CONTROL down. 
                Case "CONTROLUP" : keybd_event_(#VK_CONTROL,0,#KEYEVENTF_KEYUP,0) ; Release CONTROL. 
                Case "DELETE" : vk=#VK_DELETE 
                Case "DOWN" : vk=#VK_DOWN 
                Case "END" : vk=#VK_END 
                Case "ENTER" : vk=#VK_RETURN 
                Case "F1" : vk=#VK_F1 
                Case "F2" : vk=#VK_F2 
                Case "F3" : vk=#VK_F3 
                Case "F4" : vk=#VK_F4 
                Case "F5" : vk=#VK_F5 
                Case "F6" : vk=#VK_F6 
                Case "F7" : vk=#VK_F7 
                Case "F8" : vk=#VK_F8 
                Case "F9" : vk=#VK_F9 
                Case "F10" : vk=#VK_F10 
                Case "F11" : vk=#VK_F11 
                Case "F12" : vk=#VK_F12 
                Case "ESCAPE" : vk=#VK_ESCAPE 
                Case "HOME" : vk=#VK_HOME 
                Case "INSERT" : vk=#VK_INSERT 
                Case "LEFT" : vk=#VK_LEFT 
                Case "PAGEDOWN" : vk=#VK_NEXT 
                Case "PAGEUP" : vk=#VK_PRIOR 
                Case "PRINTSCREEN" : vk=#VK_SNAPSHOT 
                Case "RETURN" : vk=#VK_RETURN 
                Case "RIGHT" : vk=#VK_RIGHT 
                Case "SHIFTDOWN" : shifted=1 : keybd_event_(#VK_SHIFT,0,0,0) ; Hold SHIFT down. 
                Case "SHIFTUP" : shifted=0 : keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) ; Release SHIFT. 
                Case "TAB" : vk=#VK_TAB 
                Case "UP" : vk=#VK_UP 
             EndSelect 
             If Left(s$,3)<>"ALT" And Left(s$,7)<>"CONTROL" And Left(s$,5)<>"SHIFT" 
                keybd_event_(vk,0,0,0) : keybd_event_(vk,0,#KEYEVENTF_KEYUP,0) ; Press the special key. 
             EndIf 
             r=r+s+1 ; Continue getting the keystrokes that follow the special key. 
          Else 
             vk=VkKeyScanEx_(Asc(vk$),GetKeyboardLayout_(0)) ; Normal key found. 
             If vk>304 And shifted=0 : keybd_event_(#VK_SHIFT,0,0,0) : EndIf ; Due to shifted character. 
             keybd_event_(vk,0,0,0) : keybd_event_(vk,0,#KEYEVENTF_KEYUP,0) ; Press the normal key. 
             If vk>304 And shifted=0 : keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) : EndIf ; Due to shifted character. 
          EndIf 
      Next 
      If thread1<>thread2 : AttachThreadInput_(thread1,thread2,#False) : EndIf ; Finished typing to target window! 
      keybd_event_(#VK_MENU,0,#KEYEVENTF_KEYUP,0) ; Release ALT key if user forgot. 
      keybd_event_(#VK_CONTROL,0,#KEYEVENTF_KEYUP,0) ; Release CONTROL key if user forgot. 
      keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) ; Release SHIFT key if user forgot. 
      ProcedureReturn 1 ; Report successful typing! :) 
   EndIf 
EndProcedure 
;
If OpenWindow(0,100,100,500,400,"Entrauscher.exe (c.) by pm",#PB_Window_SystemMenu)

  If CreateGadgetList(WindowID(0))  
    ButtonGadget      (1,20,20,100,20,"Quellordner")
    ButtonGadget      (2,160,20,100,20,"Zielordner")
    StringGadget      (3,20, 60, 400, 20, "")
    SetGadgetText     (3,quellpfad$)
    ListViewGadget    (4,20, 100, 400, 190)     
    ButtonGadget      (5,300,20,100,20,"Übernehmen")    
  EndIf
  
  If CreateStatusBar(0, WindowID(0))    
    AddStatusBarField(500)
  EndIf
  
  
    NewList MyList.s()
    zaehl.l = 0
  
Repeat
  EventID = WaitWindowEvent()
    
    If EventID = #PB_Event_CloseWindow 
      Quit = 1
    EndIf
        
    If EventID = #PB_Event_Gadget
    
      If EventGadget()=1      
        InitialPath$ = ""
        Path$ = PathRequester("Bitte wählen Sie einen Quellordner aus", InitialPath$)
        If Path$
          quellpfad$ = Path$ 
          TextGadget(8, 20,  310, 400, 30, "Quellordner : " + Chr(10) + quellpfad$)
          SetGadgetText     (3, quellpfad$)          
          
          ClearGadgetItemList(4)         
          If ExamineDirectory(0, GetGadgetText(3), "*.jpg")
            While NextDirectoryEntry(0)
              FileName$ = ""                         
              If DirectoryEntryType(0) = #PB_DirectoryEntry_File
                FileName$ = FileName$ + DirectoryEntryName(0)
              EndIf          
              AddGadgetItem(4, -1, FileName$) 
              AddElement(MyList())
              MyList() = FileName$                       
            Wend
            FinishDirectory(0)        
                        
          Else
            MessageRequester("Fehler","Folgendes Verzeichnis konnte nicht gelesen werden : "+GetGadgetText(3),0)
          EndIf           
          
        Else
          MessageRequester("Information", "Die Auswahl wurde abgebrochen.", 0) 
        EndIf      
      EndIf      
      
      If EventGadget()=2   
        InitialPath$ = ""
        Path$ = PathRequester("Bitte wählen Sie einen Zielordner aus", InitialPath$)
        If Path$
           zielpfad$ = Path$
           TextGadget(9, 20,  350, 400, 30, "Zielordner : " + Chr(10) + zielpfad$)       
        Else
          MessageRequester("Information", "Die Auswahl wurde abgebrochen.", 0) 
        EndIf       
      EndIf       
       
      If EventGadget()=5        
        ForEach MyList()
          zaehl = zaehl + 1          
          StatusBarText(0, 0, "Datei " + Str(zaehl), #PB_StatusBar_Raised)
          w$="Entrauscher.exe (c.) by pm"
          Delay(1000) : SendKeys(0,w$,"")                                
          bildpfad$ = quellpfad$+MyList()          
          tempbild1$ = "C:\Programme\FixFoto\noiseware\nce_temp.jpg"
          tempbild2$ = "C:\Programme\FixFoto\noiseware\nce_temp_filtered.jpg"
          DeleteFile(tempbild2$)
          CopyFile(bildpfad$, tempbild1$)          
          RunProgram("C:\Programme\FixFoto\noiseware\Noiseware.exe " , #DQUOTE$ + tempbild1$ + #DQUOTE$ ,"",0) 
          w$="About Noiseware"
          Delay(1000) : SendKeys(0,w$,"{TAB}")
          Delay(1000) : SendKeys(0,w$,"{ENTER}")         
          w$="Aktion"
          Delay(1000) : SendKeys(0,w$,"") 
          If zaehl = 1
          ; unbedingt in den Noiseware Speicherotionen die Dateisuffixangaben auf "_filtered" einstellen
          MessageRequester("Aktion","Stellen Sie jetzt individuelle Filterfunktionen ein und klicken danach auf OK !",4096) 
          Else
          EndIf
          w$="nce_temp.jpg - Noiseware Community Edition"
          Delay(1000) : SendKeys(0,w$,"{CONTROLDOWN}{ENTER}")
          w$="nce_temp.jpg - Noiseware Community Edition"
          Delay(3000) : SendKeys(0,w$,"{CONTROLDOWN}s") 
          w$="Save As"
          Delay(1000) : SendKeys(0,w$,"{CONTROLDOWN}{ENTER}") 
          w$="nce_temp.jpg - Noiseware Community Edition"         
          Delay(2000) : SendKeys(0,w$,"{ALTDOWN}{F4}")          
          CopyFile(tempbild2$,zielpfad$+(Left(MyList(),Len(MyList())-4))+".jpg")    
        Next
      EndIf             

    EndIf
    
  Until Quit=1
  
EndIf

End
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

statusbar oder ähnliches wird nur upgedated, wenn auch ein event und eine eventbearbeitung in der hauptschleife stattfindet....

bezogen auf dein programm:
den schleifendurchlauf für die abarbeitung solltest du nicht in einer
abgeschlossenen For/Next haben, sondern in die Hauptschleife integrieren.

probier einfach mal dein

Code: Alles auswählen

ForEach
;...
Next
durch

Code: Alles auswählen

If NextElement
;...
EndIf
zu ersetzen.

PS:
nunja...
natürlich auch noch aus der direkten reaktion auf den button rausnehmen,
der sollte nur ein laufflag setzen, dass du dann auch wieder löschen solltest,
wenn die arbeit erledigt ist.

in PB musst du halt die Events direkt checken, PB ist Prozedural, nicht ObjektOrientiert...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3873
Registriert: 13.09.2004 17:48
Kontaktdaten:

Beitrag von bobobo »

Für "nurAnguckSachen" kann man die Zeile

Code: Alles auswählen

while windowevent():wend
hinter die gerade upgedateten Gadgets schreiben welches dann
erst aktualisiert werden bevor es weiter im Programm geht.

Solches aber bitte nie (!) in einer Schleife die auf Events reagieren soll
eintragen.

und ne temporäre messagebox kann man wie folgt machen

Code: Alles auswählen

Global tid
Enumeration
#win0
#win1
#but
EndEnumeration

Procedure meldung()

  OpenWindow(#win1,0,0,400,400,"gna",#PB_Window_ScreenCentered)
  CreateGadgetList(WindowID(#win1))
  TextGadget(0,0,0,400,400,"hallo.. ich bin eine ziemlich hässliche Meldung")
  DisableWindow(#win1,1)
  Repeat
  ResizeWindow(#win1,WindowX(#win1)-1,#PB_Ignore,#PB_Ignore,#PB_Ignore)
  Until tid=0
  CloseWindow(#win1)
EndProcedure

Procedure piep()
  If tid=0
    tid=CreateThread(@meldung(),0)
    Delay(1000)
    tid=0
  EndIf
EndProcedure
    

OpenWindow(#win0,0,0,100,100,"hihi",#PB_Window_SystemMenu    )
CreateGadgetList(WindowID(#win0))
ButtonGadget(#But,0,0,30,30,"piep")
Repeat
Event = WaitWindowEvent() ; This line waits until an event is received from Windows
  
  WindowID = EventWindow() ; The Window where the event is generated, can be used in the gadget procedures
  
  GadgetID = EventGadget() ; Is it a gadget event?
  
  EventType = EventType() ; The event type
  
  ;You can place code here, and use the result as parameters for the procedures
  
  If Event = #PB_Event_Gadget
    
    If GadgetID = #But
    CreateThread(@piep(),0)
      
    EndIf
    
  EndIf

Until Event=#PB_Event_CloseWindow

‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> Solches aber bitte nie (!) in einer Schleife die auf Events reagieren soll eintragen.
ja genau, nie na niemals nicht!


> und ne temporäre messagebox kann man wie folgt machen
oder so wie von netmaestro im englischen vorgeschlagen:
http://www.purebasic.fr/english/viewtop ... 325#187325
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Panik
Beiträge: 9
Registriert: 21.03.2007 20:18

Beitrag von Panik »

Hallo !

Danke für die Antworten.
Leider habe ich sie nicht fruchtbringend hinbekommen.

Die verschwindende Messagebox ist gut, nur leider kriegt man sie nicht so richtig permanent in den Vordergrund (SystemModal).
Zudem scheinen die Proceduren Einfluss auf die normalen Messageboxen zu haben, die im Fall des Falles auch nicht in den Vordergrund kommen und gar nicht mehr auf eine Quittierung warten.

Mit if nextelement und andere Schleifen klappen auch nicht so.

Nun habe ich , wie empfohlen alles in Proceduren ausgelagert und baue für die Statusmeldung zum Schleifenbeginn ein neues Fenster am Rand auf.Am Schleifenende wird es geschlossen.
So klappt es einigermaßen, auch wenn es vielleicht ne Krücke ist. ;-)

Also bis zur nächsten Frage ...

Ciao
Panik
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

>> nur leider kriegt man sie nicht so richtig permanent in den Vordergrund (SystemModal).
Flag: #MB_SYSTEMMODAL übergeben!

Ansonsten kannste Dir noch folgendes Beispiel im engl. Forum ansehen:
http://www.purebasic.fr/english/viewtopic.php?t=26363
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten