# [C/C++] zwei sachen gleichzeitig laufen lassen



## Tobias K. (1. September 2002)

moin


gleich zur frage:
wie kann ich in einer konsolen anwendung eine uhr z.b. unten rechts ständig laufen lassen, wenn ich gleichzeitig noch was anderes mit dem programm mach? das es geht weiss ich aber ich hab keinen plan wie!


mfg
umbrasaxum


----------



## goela (1. September 2002)

Entweder Du verwendest einen Timer oder einen Thread!


----------



## Tobias K. (1. September 2002)

und wie mach ich das?
hast du da mal ein beispiel?


mfg umbrasaxum


----------



## goela (1. September 2002)

Dazu müsste ich aber etwas genauer über Deine Consolen-Anwendung wissen.

Visual Studio? Borland oder GNU?
Rein in C oder C++ ohne irgendwelche Bibliotheken (MFC, .NET etc.)


----------



## Tobias K. (1. September 2002)

ok dann mal ein paar infos:
visual studio 6
win 98/2000 (falls das ne rolle spielt)
wär schön wenn es reines c/c++ wär


----------



## goela (2. September 2002)

So hab Dir ein Beispiel gemacht, dass rechts Oben eine Uhr anzeigt und gleichzeitig einen Buchstaben auf dem Bildschirm herumhüpfen lässt!

Hier der Code und als ZIP das ganze Projekt!

```
// ConsoleThread.cpp : Defines the entry point for the console application.
//
// WICHTIGE EINSTELLUNGEN IM PROJEKT
// KEINE PRECOMPILED HEADER
// MULTITHREADED APPLIKATION

#include <windows.h>
#include <process.h>    /* _beginthread, _endthread */
#include <time.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

void CheckKey( void *dummy );
void Time(void *dummy);
void BouncingLetter(void *dummy);

/* GetRandom returns a random integer between min and max. */
#define GetRandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))

BOOL repeat = TRUE;     /* Global repeat flag and video variable */
HANDLE hStdOut;         /* Handle for console window */
CONSOLE_SCREEN_BUFFER_INFO csbi;    /* Console information structure */

void main()
{
    DWORD   result;

    // Bildschirm's Zeilen und Spalten info holen
    hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
    GetConsoleScreenBufferInfo( hStdOut, &csbi );

    /* Launch CheckKey thread to check for terminating keystroke. */
    _beginthread( CheckKey, 0, NULL );
    _beginthread( BouncingLetter, 0, NULL  );
    _beginthread( Time, 0, NULL  );

    COORD position;
    position.X = 28;
    position.Y = 12;

    /* Loop solange bis CheckKey programm abbricht */
    while( repeat )
    {
        WriteConsoleOutputCharacter(hStdOut, "Druecke Taste fuer Programmende", 31, position, &result );
        Sleep( 1000L );
    }

} // void main()

/////////////////////////////////////////////////////////////////////////////

// Thread für warten auf Tastenende!
void CheckKey( void *dummy )
{
    _getch();
    repeat = 0;    /* _endthread implied */

}

/////////////////////////////////////////////////////////////////////////////

// Thread-Funktion für Zeitausgabe
void Time(void *dummy)
{
    COORD position;
    DWORD   result;
    char szBuffer[200];

    time_t ltime;
    struct tm *today;

    // Position für Zeit:
    position.X = 60;
    position.Y = 1;

    // Threadschleife
    while( repeat )
    {
        time( &ltime );
        today = localtime( &ltime );
        strftime(szBuffer, 200, "Zeit: %H:%M:%S", today );
        WriteConsoleOutputCharacter(hStdOut, szBuffer, strlen(szBuffer), position, &result );
        Sleep( 1000L );
    }

    // Thread terminieren
    _endthread();

} // void Time(void *dummy)

/////////////////////////////////////////////////////////////////////////////

// Hüpfendes Zeichen
void BouncingLetter(void *dummy)
{
    DWORD   result;
    COORD   oldcoord, newcoord;
    char    blankcell = 0x20;
    BOOL    first = TRUE;

    srand( _threadid );
    newcoord.X = GetRandom( 0, csbi.dwSize.X - 1 );
    newcoord.Y = GetRandom( 0, csbi.dwSize.Y - 1 );

    // Threadschleife
    while( repeat )
    {
        // Pause zwischen den Loops
        Sleep( 100L );

       // Zuerst letzte Position löschen, dann neuen Text schreiben
       if( first )
           first = FALSE;
       else
           WriteConsoleOutputCharacter( hStdOut, &blankcell, 1, oldcoord, &result );
        
       WriteConsoleOutputCharacter( hStdOut, "0", 1, newcoord, &result );

       // Neue Position setzen
       oldcoord.X = newcoord.X;
       oldcoord.Y = newcoord.Y;
       newcoord.X += GetRandom( -1, 1 );
       newcoord.Y += GetRandom( -1, 1 );

       // Bildschirmgrenzen prüfen
       if( newcoord.X < 0 )
           newcoord.X = 1;
       else if( newcoord.X == csbi.dwSize.X )
           newcoord.X = csbi.dwSize.X - 2;
       else if( newcoord.Y < 0 )
           newcoord.Y = 1;
       else if( newcoord.Y == csbi.dwSize.Y )
           newcoord.Y = csbi.dwSize.Y - 2;
       else
           continue;

    } // while( repeat )

    // Thread beenden
    _endthread();

} // void BouncingText(void *dummy)
```


----------



## Tobias K. (2. September 2002)

moin

ja genau sowas hab ich gesucht! danke


mfg
umbrasaxum


----------

