Aktualisieren von ClistCtrl



  • Hallo alle zusammen

    ich habe folgendes Problem: ich hab eine Liste die ich mit Daten fühle. Danach führe ich mit Hilfe von CreateProcess ein Script auf mit denn Daten aus der Liste als Parameter, praktisch nach jeder Zeile wird ein neues Prozess aufgerufen. Nach jedem beendetem Prozess würde ich gerne in die Liste z.B Fertig schreiben. Leider geht es nicht. Das Hauptdialogfeld friert praktisch ein und erst wenn alle Prozesse fertig sind wird die entsprechende Spalte gefühlt. Ich habe schon mit Sleep(..) ausprobiert was leider nicht ging. UpdateData habe ich natürlich auch drin. Für Hilfe wäre ich sehr dankbar.

    Gruß Salfador



  • Hi,

    Du solltest dir ein HANDLE von
    jeden Prozess holen.
    In einer Schleife die gültigkeit überprüfen.
    Falls der Prozess bzw HANDLE nicht mehr
    gültig ist -> updaten.

    tomb



  • Hallo

    danke für die Anwort. Köntest du es mit dem Hänle etwas genauer erklären. Wie meinst du es Handle abfangen. Ich benutze voelgenden code(aus der MSDN):

    ZeroMemory( &si, sizeof(si) );
    				si.cb = sizeof(si);
    				ZeroMemory( &pi, sizeof(pi) );
    				if ( !CreateProcess(0,cPath,
    					NULL,             // Process handle not inheritable. 
    					NULL,             // Thread handle not inheritable. 
    					FALSE,            // Set handle inheritance to FALSE. 
    					0,                // No creation flags. 
    					NULL,             // Use parent's environment block. 
    					NULL,             // Use parent's starting directory. 
    					&si,              // Pointer to STARTUPINFO structure.
    					&pi ))
    				{
    					MessageBox("Konvertierung fehlgeschlagen","Error", MB_ICONERROR | MB_OK);
    				}
    
    				WaitForSingleObject( pi.hProcess, INFINITE );
    
    				// Close process and thread handles. 
    				CloseHandle( pi.hProcess );
    				CloseHandle( pi.hThread );
    

    Für eine Antwort wäre ich Dankbar.

    Gruß Salfador



  • Während deinem WaitForSingleObject blockierst du den Hauptthread deiner Anwendung, der auch z.B. für das das Verarbeiten von Nutzereingaben und das Neuzeichnen der Liste verantwortlich ist.

    Du kannst ein neuzeichnen mit UpdateWindow() erzwingen -
    allerdings "hängt" deine Anwendung immer noch.

    Die sauberste Lösung wäre sicherlich, das Processing in einen Worker-Thread zu legen, der den Hauptthread mittels PostMessage von seinen Fortschritten benachrichtigt. Ist aber möglicherwese etwas komplex für nen Einsteiger.

    Die nächstbeste Lösung wäre, sich einen Timer zu setzen, und den Handle z.B. aller 100 ms zu testen ohne zu warten ( WaitForSingleObject(pi.hProcess, 0) );

    Ist aber recht aufwendig, da man zwischen den Aufrufen eine Menge Status "aufbewahren" muß (z.B. zumindest den Prozeßhandle)

    Die am einfachsten zu implementierende, aber m.E. gefährlichste Lösung ist:

    DWORD waitState;
    while(1) // break on "Process terminated"
    {
      waitState = WaitForSingleObject(pi.hProcess, 100);
      if (ok != WAIT_TIMEOUT) 
        break;
      while (theApp.PumpMessage()); // theApp: see below
    }
    

    (theApp: meine CMyAp-Deklaration wird immer von einem extern CMyApp theApp gefolgt, so kann ich auf das Application-Object (was ja ein Singleton ist) immer nett zugreifen)

    PumpMessage dispatcht genau eine anstehende Windows message, und gibt false zurück, wenn keine mehr ansteht. Ist insofern ungünstig weil:
    a) ein "PumpMessage" nicht iun allen Umgebungen möglich/erlaubt ist, macht deine Lösung also weniger portabel
    b) Man bekommt (oft verwirrende) Reentrancy-Probleme.
    c) lokale message-Loops sind immer wieder ein Stolperstein


Anmelden zum Antworten