Endlosschleife mit Ende... (Großes Problem)



  • Hallo!
    Ich habe ein großes Problem!
    Ich würde gerne ein paar Zeilen Code über den Menüeintrag Start ausführen!
    Dieser Code soll in einer Endlosschleife so lange ausgeführt werden, bis der Menüeintrag Stop gewählt wird!
    Zeitgleich soll in dem Hauptfenster (es gibt nur eins) Text immer wieder aktualisiert werden.

    int WINAPI WinMain(HINSTANCE hInstance,        // Handle der Instanz
                       HINSTANCE hPrevInstance,
                       LPSTR     lpCmdLine,        // Kommandozeile
                       int       nCmdShow)         // Art der Anzeige
    {
        MSG msg;                          // Zum Speichern einer Meldung
    
        hInst = hInstance;                // An globale Variable zuweisen
    
        if(!InitApplication())            // Fenster registrieren 
          return (FALSE);              
    
        if(!InitInstance(nCmdShow))       // Das Hauptfenster erzeugen
           return (FALSE);
    
        // Meldungen auslesen und weiterleiten, solange keine 
        // WM_QUIT Meldung kommt.
        while(GetMessage(&msg,NULL,0,0))
        {
           TranslateMessage(&msg);        // Übersetzt virtual key codes.
           DispatchMessage(&msg);         // Meldung an das Fenster weitergeben.
        }
        return (msg.wParam);    // Den Wert von PostQuitMessage zurückgeben.
    }
    
    /////////////////////////////////////////////////////////////////////////
    //  Funktion: InitApplication()
    //
    //  Zweck:    Initialisert die Daten des Fensters und registriert diese
    //            Fensterklasse
    //            Diese Funktion füllt eine Datenstruktur vom Typ WNDCLASSE
    //            und ruft RegisterClass() auf.
    //
    BOOL InitApplication()
    {
        WNDCLASSEX  wc; 
    
        // Die Struktur mit Werten füllen, die das Hauptfenster beschreibt.
        wc.cbSize         = sizeof(WNDCLASSEX);                  // Anzahl Bytes dieser Struktur.
        wc.style          = CS_HREDRAW | CS_VREDRAW;             // Fensterstile
        wc.lpfnWndProc    = (WNDPROC)WndProc;                    // Fensterprozedur
        wc.cbClsExtra     = 0;
        wc.cbWndExtra     = 0;
        wc.hInstance      = hInst;                               // Handle dieser Instanz
        wc.hIcon          = LoadIcon( NULL, IDI_HAND);			 // Standard-Icon
        wc.hCursor        = LoadCursor( NULL, IDC_ARROW);        // Standard-Cursor Pfeil
        wc.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH); // Hintergrund der Client Area
        wc.lpszMenuName   = MAKEINTRESOURCE(IDR_MENU);                                // Menue-Name (hier keins)
        wc.lpszClassName  = szAppName;                           // Name dieser Fensterklasse
        wc.hIconSm        = LoadIcon( NULL, IDI_HAND);			 // Standard-Icon (klein)
    
        // Die Fensterklasse registrieren und "erfolgreich" oder "fehler" zurückgeben.
        return RegisterClassEx(&wc);    
    }
    
    /////////////////////////////////////////////////////////////////////////
    //   Funktion: InitInstance(int)
    //
    //   Zweck:    Das Hauptfenster erzeugen und anzeigen.
    //
    BOOL InitInstance(int nCmdShow)
    {
       HWND hWnd;
    
       hWnd = CreateWindowEx( 
    
    						WS_EX_TOPMOST,
    						szAppName,           // Name der Fensterklasse
                            szTitle,             // Titel des Fensters
                            WS_OVERLAPPEDWINDOW, // Fensterstil
                                                 // Lage des Fensters:
                            0,					 // x-Koordinate
                            0,                   // y-Koordinate
                            200,				 // Fensterbreite
                            300,                 // Fensterhoehe
                            NULL,                // Handle: Elternfenster
                            NULL,                // Handle: Menue
                            hInst,               // Handle des Programms
                            NULL);               // Zeiger auf zusätzliche Daten
                                                 // für WM_CREATE
       if (!hWnd) 
          return (FALSE);
    
       ShowWindow(hWnd, nCmdShow);				 // Fenster anzeigen.
       UpdateWindow(hWnd);						 // Eine WM_PAINT-Meldung senden.
    
       return (TRUE);
    }
    

    Soweit ist ja alles ok! In der WinMain werden die Messages in der while-Schleife abgearbeitet. (So habe ich das zumindest verstanden...)

    Hier werden nun die Meldungen verarbeitet. Unter Anderem existiert noch ein Menü:

    ///////////////////////////////////////////////////////////////////////////
    //  Funktion:  WndProc(HWND, unsigned, WORD, LONG)
    //
    //  Zweck:     Meldungen verarbeiten.
    //
    //  Meldungen: WM_PAINT   - Fensterinhalt zeichnen
    //             WM_DESTROY - WM_QUIT Meldung in die Warteschlange einfügen
    //             WM_LBUTTONDOWN - Auf Linke Maustaste reagieren
    //             . . .
    //
    LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
       PAINTSTRUCT ps;
       HDC  hdc;
       RECT rect;
    
       switch (message)
       {
    	case WM_COMMAND:
    		switch(LOWORD(wParam))
    		{
    			case ID_FILE_START:
                               HIER SOLL DIE ENDLOSSCHLEIFE GESTARTET WERDEN
    			break;
    
    			case ID_FILE_STOP:
    			HIER SOLL DIE ENDLOSSCHLEIFE BEENDET WERDEN
    			break;
    
    			case ID_CONFIG_PIXELCHECK:
    					break;
    
    			case ID_CONFIG_STATISTIC:
    
    				break;
    
    			case ID_ABOUT_INFO:
    				DialogBox(hInst, MAKEINTRESOURCE(IDD_INFO),hWnd, (DLGPROC)DlgProcInfo);
    				break;
    
    			case ID_FILE_EXIT:
    				DestroyWindow(hWnd);
    		}
    
         case WM_PAINT:
    
    			hdc = BeginPaint( hWnd, &ps);
     			GetClientRect(hWnd, &rect);
    			DrawText(hdc, statisticTab[i].text, -1, &rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);			
    			EndPaint( hWnd, &ps);
    
             break;
    
          case WM_DESTROY:
             PostQuitMessage(0);
             break;
    
          default:
             return DefWindowProc(hWnd, message, wParam, lParam);
       }
       return 0;
    }
    

    So, wenn ich nun an den oben genannten Stellen den Code in der Endlosschleife starte, habe ich ja das Problem, dass ich aus der Endlosschleife keine Messages mehr heraus bekomme geschweige diese abegearbeitet werden! Somit ist ein Beenden nicht möglich! Was noch viel wichtiger ist... Im Hauptfenster wird der Text nicht mehr aktualisiert. Kann somit nicht mehr die Schleifendurchläufe zählen und im Hauptfenster ausgeben!

    Ich befürchte, dass ich hier ein ganz banales Problem habe. Ehrlich gesagt sind es meine ersten Versuche mit C++ und der WinAPI... Bin sonst "nur" C und die Konsole gewöhnt. Anscheinend habe ich beim OOP so einige Denkfehler!

    Wäre für Hilfe sehr dankbar!

    mfg,

    gammla



  • ganz oben in der Datei unterhalb der includ verzeichnisse setzt u ne variable

    BOOL m_bWhile = FALSE;
    

    dann

    case ID_FILE_START:
    {
       m_bWhile = TRUE;
       do
         {
          //mach was
         }while(m_bWhile);
    }
    break;
    
    case ID_FILE_STOP:
    {
       m_bWhile = FALSE;
    }break;
    

    habs jetzt nicht getestet aber so sollte es funzen



  • Was du suchst ist Multithreading. Google dich schlau.

    http://msdn2.microsoft.com/en-us/library/ms684254.aspx



  • @@rT!f@Ct
    Auf diese Weise habe ich es schon versucht. Das Problem ist, dass während der Schleifenabarbeitung keine Messages von der WinMain verarbeitet werden. Zumindest nicht zuverlässig! Meine Client Area ist in dieser Situation nicht Aktuell! Nehmen wir an, wir zählen eine Variable i mit jedem Schleifendurchlauf hoch und wollen den Inhalt der Variablen in der Client-Area anzeigen. Das Problem in dieser Situation ist, dass die WinMain die Messages nicht abarbeitet und somit nicht die Client-Area aktualisiert... Korrigiert mich, wenn ich da falsch liege... Hat bei mir so nicht wirklich funktioniert.

    @tenchou
    Das ist natürlich ein harter Brocken für einen Anfänger... Da sage ich nur: "Ran ans Werk!"

    Falls euch noch Tips einfallen, bitte posten! Multithreading scheint wirklich hart zu sein....

    mfg,

    Gammla



  • Guck Dir mal die "ProcessMessage-Funktion" an. Dann geht es sicherlich auch ohne Threads.



  • mach es in einem thread

    wieder ganz oben deklaration

    BOOL m_bWhile = FALSE;
    static	UINT thrFunc(LPVOID pParam);
    void Schleife(HWND);
    

    dann erstellst du die funktion

    UINT thrFunc (LPVOID pParam)
    {
       Schleife((HWND)pParam );
    
       return 0;
    }
    
    void Schleife (HWND hWnd)
    {
       m_bWhile = TRUE;
       do
         {
          //mach was
         }while(m_bWhile);
    }
    
    ....
    
    case ID_FILE_START:
    {
        AfxBeginThread(thrFunc,hWnd);//Starte den Thread
    }
    break;
    
    case ID_FILE_STOP:
    {
       m_bWhile = FALSE;
    }break;
    


  • Danke!
    Die ProcessMessages Funktion reicht vollkommen für mich aus und erfüllt genau das, was ich brauche!

    Nochmal danke an alle!

    Werde mich natürlich in naher Zukunft auch um das Thema Multithreading kümmern!

    Wobei ich den Code von @rT!f@Ct auch noch mal probieren werde!!!

    mfg,

    gammla



  • Also ich hätte einen Timer (WM_TIMER) vorgeschlagen, ist meistens das einfachste.
    Threads würde ich solange nicht verwenden wie es nicht nötig ist.


Anmelden zum Antworten