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.
-
@@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.