einfaches thread



  • void CdokdokDlg::OnBnClickedButton1()
    {
    	// TODO: Fügen Sie hier Ihren Kontrollbehandlungscode für die Benachrichtigung ein.
    	long i=0;
    	long r=0;
    	do
    	{
    		i++;
    		if(i == 1000000)
    		{
    			r++;
    			i =0;
    		}
    	}while(r<1000000);
    	MessageBox("dokdok");
    }
    

    versuch das mal unter einem knopf im dialod zu starten denn versuch das fenster zu minmiren und maxmieren oder verschieben.
    eben man kann nicht sehen was im dialod ist von knopfe oder controls



  • ich muß hier ein thread erzeugen....

    wie geht es hier im beispiel?



  • Wenn du "im Dialog sitzt", kann der nur eine Methode gleichzeitig verarbeiten. Also solange der in dieser Schleife ist, werden keine Nachrichten ausgwertet, die der Dialog bekommt.
    Das Verhalten was du möchstest geht nur, wenn du den Dialog von "außen" verschiebst, also aus einem anderen Fenster heraus oder du benutzt keine Schleife, sondern die Methode OnIdle oder den WM_TIMER. Das sind wieder Nachrichten die wie jede andere auch verarbeitet werden(Besonderheiten siehe MSDN).



  • ich habe das timerbeispiel einmal geschaut
    mmm ich denke drin war was ich suche. die aktuellezeit hat erschien während ich mit dem dialog was anders tue..

    ich denke ich muß zurück zu dem timer beispiel.

    die funktion OnIdle ist mir komplitziert..kann sein weil in sams in verbindung mit zeichnen und farben kam..

    kannst du siese funktion OnIdle in meinem beispiel einsetzen...wenn ja wäre ich dankbar.... 😃



  • In der MSDN findest du was:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_cwinapp.3a3a.onidle.asp

    Dieses Bsp ist denke ich einleuchtend (Quelle: msdn)

    // In this example, four idle loop tasks are given various 
    // opportunities to run:
    // Task1 is always given a chance to run during idle time, provided
    //   that no message has queued up while the framework was processing
    //   its own idle loop tasks (at lCount levels 0 and 1).
    // Task2 is given a chance to run only if Task1 has already run,
    //   provided that no message has queued up while Task1 was running.
    // Task3 and Task4 are given a chance to run only if both Task1 and
    //   Task2 have already run, and no message has queued up in the mean
    //   time.  If Task3 gets its chance to run, then Task4 always gets
    //   a chance to run immediately after Task3.
    
    BOOL CMyApp::OnIdle(LONG lCount)
    {
       // In this example, as in most applications, you should let the
       // base class CWinApp::OnIdle complete its processing before you
       // attempt any additional idle loop processing.
       if (CWinApp::OnIdle(lCount))
          return TRUE;   
    
       // The base class CWinApp::OnIdle reserves the lCount values 0 
       // and 1 for the framework's own idle processing.   If you wish to
       // share idle processing time at a peer level with the framework,
       // then replace the above if-statement with a straight call to
       // CWinApp::OnIdle; and then add a case statement for lCount value
       // 0 and/or 1. Study the base class implementation first to 
       // understand how your idle loop tasks will compete with the 
       // framework's idle loop processing.
    
       switch (lCount)
       {
          case 2:
             Task1();
             return TRUE; // next time give Task2 a chance
          case 3:
             Task2();
             return TRUE; // next time give Task3 and Task4 a chance
          case 4:
             Task3();
             Task4();
             return FALSE; // cycle through the idle loop tasks again
       }
       return FALSE;
    }
    

    Grüße Raphael



  • ich habe versucht etwas zu verstehen von OnIdle......no chance..
    ich bin doch kein profi .

    wie rufe ich task1 und task2 ..

    kannst du mein beispiel einsetzen

    wäre nett wenn ja



  • Das taskt1, tastk2 ist nur ein Bsp

    long lNumber = 1; // unsere Zahl (hab ich jetzt global definiert, kannst aber auch einfach eine Membervariable deiner CWinApp Klasse nehmen)
    BOOL CMyApp::OnIdle(LONG lCount) 
    { 
       lNumber++; // Zahl um eins erhöhen
       if (lNumber == 1000000) // lNumber ist jetzt genau eine Milllionen
       {
           // tue etwas
       }
       if (lNumber < 1000000)
           return TRUE; // OnIdle soll wieder ausgeführt werden
       else
           return FALSE; // wir brauchen kein OnIdle mehr
    }
    

    Müsste so funktionieren. Da ich OnIdle noch nie verwendet habe (da ich lieber mit Threads arbeite), weiß ich nicht, in welchen Abständen OnIdle normalerweiße aufgerufen wird (hab keine Erfahrung damit). Musst du halt mal ausprobieren.



  • OnIdle wird dann aufgerufen, wenn das Fenster gerade nichts zu tun hat.
    Wenns ne ca. konstante Zeit sein soll dann WM_TIMER aufrufen, wobei man auch hier beachten muss, dass diese Nachricht geringe Priorität hat und daher bei der Zeitangabe ein "MINDESTENS so lange warten" gilt. Dürfte aber für dieses Problem vollkommen ausreichen



  • sorry rapha

    ich verstehe nicht.
    warum rufe ich OnIdle denn wenn von 1 bis 1000 000 wird nicht gemacht ausser flase zurück geben.

    ich sage dir meine frage nochmal.

    ich habe ein dialog mit einem knopf . wenn ich den knopf klicken startet eine schelife oder process die zählt von 1 bis 10000000 für 1000 000 mal.

    ich will daß mein dialog wärend des prossezes kann man andere knopf deucken oder das fenster verschieben.

    ich habe seit gestern rumpropiert leider kein erfolg.



  • dokdok schrieb:

    warum rufe ich OnIdle denn wenn von 1 bis 1000 000 wird nicht gemacht ausser flase zurück geben.

    Aus der MSDN:

    OnIdle performs some processing and returns a nonzero value to indicate it should be called again to do further processing.
    Eventually, OnIdle finishes processing all its idle tasks and returns 0. This tells the message loop to stop calling OnIdle until the next message is received from the message queue, at which point the idle cycle restarts with the argument set to 0.

    dokdok schrieb:

    ich sage dir meine frage nochmal.
    ich habe ein dialog mit einem knopf . wenn ich den knopf klicken startet eine schelife oder process die zählt von 1 bis 10000000 für 1000 000 mal.
    ich will daß mein dialog wärend des prossezes kann man andere knopf deucken oder das fenster verschieben.
    ich habe seit gestern rumpropiert leider kein erfolg.

    Wenn du in einer Schleife von 1 bis 1000000 zählst, wird die Nachrichtenschleife blockiert.
    Dies kannst du umgehen, wenn du z.b.

    1. einen extra Thread verwendest
    2. einen Timer verwendest
    3. OnIdle verwendest

    Nimm doch einfach einen Thread:
    Definier ne Funktion, die zählt:

    UINT CountThread( LPVOID pParam )
    {
    	for (long l=0; l<1000000; l++)
    	{
    		// tue etwas
    	}
    	return 0;
    }
    

    und ruf diese in einem anderen Thread auf, wenn man auf den Button klickt

    AfxBeginThread(CountThread, NULL);
    


  • Ich rate vom Thread ab, weil er doch sein Fenster beeinflussen will. Dann schiebt er von nem anderen Thread aus, muss aufpassen das sich nichts ins Gehege kommt usw.
    WM_TIMER benutzen und gut, wie ich schon weiter oben geschrieben habe



  • error C2665: 'AfxBeginThread': Durch keine der 2 Überladungen kann Parameter 1 vom Typ 'UINT' konvertiert werden



  • Parameter 1 ist falsch, es muss der Funktionszeiger auf die Threadfunktion sein.
    Poste mal deinen Code



  • void CProgressControlDlg::OnBnClickedButton1()
    {
       LPVOID pParam;
       AfxBeginThread(CountThread(pParam) ,NULL);
    }
    
    UINT CProgressControlDlg::CountThread( LPVOID pParam ) 
    { 
        for (long l=0; l<1000000; l++) 
        { 
            // tue etwas 
        } 
        return 0; 
    }
    


  • dokdok schrieb:

    void CProgressControlDlg::OnBnClickedButton1()
    {
    LPVOID pParam;
    AfxBeginThread(CountThread(pParam) ,NULL);
    }

    Das muss

    void CProgressControlDlg::OnBnClickedButton1()
    {
       LPVOID pParam;
       AfxBeginThread(CountThread ,NULL);
    }
    

    heißen, denn CountThread(pParam) ruft die Funktion auf und gibt den rückgabewert an AfxBeginThread weiter (was dann ein UINT ist).

    dokdok schrieb:

    UINT CProgressControlDlg::CountThread( LPVOID pParam )
    {
    for (long l=0; l<1000000; l++)
    {
    // tue etwas
    }
    return 0;
    }

    Das Funktioniert nur, wenn du CountThread in der Klasse CProgressControlDlg (mit static) statisch machst. Oder du definierst CountThread als globale Funktion.



  • ich sags doch lass die Finger von Threads :p
    😉 😉 😉

    der timer reicht hier vollkommen aus



  • oohhhhhhhhhhhhhhhhhhhhhhhhhhhhh

    es funktioniert

    ich danke euch alle.

    zitat

    ich freue mich... 🤡



  • hi pellaeon

    kannst du mir ein beispiel mit dem timer schicken.. neugirig

    wäre sehr nett.

    mit dem thread hat funktioniert dank rapha.



  • Wenn du Timer verwenden willst, mach einfach eine Behandlungsroutine für die WM_TIMER Nachricht:

    long l = 1; // unsre globale Zählervariable (besser du verwendest eine Membervariable in CProgressControlDlg
    void CProgressControlDlg::OnTimer(UINT nIDEvent) 
    {
    	l++;
    	if (l == 1000000)
    	{
    		// l ist 1000000
    		// tue was
    		KillTimer(0 /* unsere TimerID */); // Timer stoppen
    	}
    
    	CDialog::OnTimer(nIDEvent);
    }
    

    Und dann kannst du, wenn man auf den Button klickt, den Timer aufrufen

    SetTimer(0, // die id unseres Timers (frei wählbar)
             10, // mit welchen Abständen OnTimer aufgerufen werden soll (hier alle 10 Millisekunden)
             NULL // reserviert, muss immer 0 sein
    	 );
    


  • hätt ich nicht besser machen können 🤡


Anmelden zum Antworten