Abfrage ob Maus benutzt wird???



  • Wie die Überschrift schon sagt, hab ich ein Problem bei meiner DOWHILE Schleife:
    Hier erst mal der Code:

    #include <stdio.h>
    #include <windows.h>
    
    DWORD mouseInit ()
    {
        DWORD mode;
        GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE),&mode);
        SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE),mode|ENABLE_MOUSE_INPUT);
    
        DWORD buttons;
        GetNumberOfConsoleMouseButtons(&buttons);
    
        return buttons;
    }
    int showCursor (int i)
    {
        ShowCursor(i);
    }
    
    int main()
    {
        mouseInit();
        showCursor(0);
        int y=0,x=0;
        int i=0;
        do
        {
            DWORD count;
            INPUT_RECORD ir;
            ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE),&ir,1,&count);
    
            switch(ir.EventType)
            {
                  case MOUSE_EVENT:
    
                       x = ir.Event.MouseEvent.dwMousePosition.X;
                       y = ir.Event.MouseEvent.dwMousePosition.Y;
    
                       if((ir.Event.MouseEvent.dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED)) {printf("\a");}   
            }
            i++;     
            printf("%i",i);
    
        }while(!0);  
        return 0;
    }
    

    Wieso zählt i nur hoch, wenn ich die maus bewege oder klicke???
    gibt es auch wie bei der Tastatur eingabe eine abfrage ob was gemacht wird

    if(kbhit()) {Taste=getch();}

    ????



  • hehe geil

    while(!0);
    


  • Hi Bruder !
    Das liegt daran, das ReadConsoleInput so lange blockiert, bis eine Eingabe registriert wird.



  • Das hab ich mir schon gedacht....
    Kann man das so machen, das dieser befehl übersprungen wird, bis eine eingabe kommt....



  • CaPGeti schrieb:

    Wieso zählt i nur hoch, wenn ich die maus bewege oder klicke???

    Weil ReadConsoleInput( ) nicht zurückkehrt, solange kein Input da ist?

    CaPGeti schrieb:

    gibt es auch wie bei der Tastatur eingabe eine abfrage ob was gemacht wird

    Weiß nicht, aber ich befürchte nein.

    BorisDieKlinge schrieb:

    hehe geil

    Das war die Antwort auf den letzten WieSchreibIchEineEndlosschleifeKlarUndDeutlich-Thread. *rofl*

    cheers, Swordfish



  • CaPGeti schrieb:

    Das hab ich mir schon gedacht....
    Kann man das so machen, das dieser befehl übersprungen wird, bis eine eingabe kommt....

    Du kannst so etwas ähnliches realisieren, indem du ReadConsoleInput in einen eigenen Thread auslagerst.



  • @B.B. He Wie jetzt?? nen neuen Thread aufmachen?? Titel: ReadConsoleInput???



  • Thread (Computer Science)

    cheers, Swordfish



  • CaPGeti schrieb:

    @B.B. He Wie jetzt?? nen neuen Thread aufmachen?? Titel: ReadConsoleInput???

    *grins*

    Neee, ein Thread
    http://de.wikipedia.org/wiki/Thread_(Informatik)
    ist eine Funktion, die unabhängig von anderen Funktionen in einem Programm laufen kann.
    Du könntest also ReadConsoleInput in diesem Thread aufrufen und quasi parallel könnte dein main Programm etwas anderes machen.



  • ??? ehm... ja, Wie realisier ich sowas??



  • Bist du sicher, das du das brauchst? Was willstn machen ?



  • Das ist noch wegen meinen spiel....
    (http://www.c-plusplus.net/forum/viewtopic-var-t-is-209567.html])

    ..ehm letzter beitrag....

    Wenn ich meine Einheit durch die Landschaft bewege, dann klick ich auf die gewünschte stelle (findet den weg durch A*), wenn ich aber nicht klicke, und gerade ein gegner rumläuft, dann muss der gegner trotzdem weiterlaufen, auch wenn ich keine Mausaktivität hab...verstehste??
    ....Also die steuerung ist so wie in diablo2 als beispiel....immer in der mitte und dann klicken...



  • Ich kenn' zwar Dein Spiel nicht (vielleicht gibt's das fertig irgendwann zum Bestaunen?) aber zum Bleistift:

    #include <stdbool.h>
    #include <stdio.h>
    
    #include <windows.h>
    
    CRITICAL_SECTION critical_section;
    bool event_occured = false;
    
    DWORD WINAPI input_thread( LPVOID data )
    {
    	HANDLE std_input = GetStdHandle( STD_INPUT_HANDLE );
    	DWORD count = 0;
    	INPUT_RECORD *input_record = ( INPUT_RECORD* ) data;
    
    	while( true ) {
    
    		ReadConsoleInput( std_input, input_record, 1, &count );
    
    		EnterCriticalSection( &critical_section );
    		event_occured = true;
    		LeaveCriticalSection( &critical_section );
    	}
    }
    
    DWORD mouse_init( void )
    {
    	HANDLE std_input = GetStdHandle( STD_INPUT_HANDLE );
    	DWORD mode = 0;
    	DWORD buttons = 0;
    
    	GetConsoleMode( std_input, &mode );
    	SetConsoleMode( std_input, mode | ENABLE_MOUSE_INPUT );
    	GetNumberOfConsoleMouseButtons( &buttons );
    
    	return buttons;
    }
    
    int main( void )
    {
    	INPUT_RECORD input_record = { 0 };
    	HANDLE input_thread_handle = 0;
    	bool event = false;
    	DWORD i = 0;
    
    	mouse_init( );
    	ShowCursor( 0 );
    
    	InitializeCriticalSection( &critical_section );
    
    	if( !( input_thread_handle = CreateThread( 0, 0, input_thread, &input_record, 0, 0 ) ) ) {
    
    		fputs( "Thread couldn't be created!\n", stderr );
    		return EXIT_FAILURE;
    	}
    
    	while( true ) {
    
    		EnterCriticalSection( &critical_section );
    		event = event_occured;
    		event_occured = false;
    		LeaveCriticalSection( &critical_section );
    
    		if( event ) {
    			switch( input_record.EventType ) {
    
    				case MOUSE_EVENT:
    
    					if( ( input_record.Event.MouseEvent.dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED ) ) {
    
    						printf( "\nClick at %i/%i\n", input_record.Event.MouseEvent.dwMousePosition.X, input_record.Event.MouseEvent.dwMousePosition.Y );
    					}
    
    					break;
    			}
    
    		}
    
    		printf( "%i", ++i );
    		Sleep( 100 );
    	}
    }
    

    cheers, Swordfish



  • Geht das irgentwie kürzer??? Also der bereich in der main()???(Initialisierungen und so)

    Ansonsten nehm ich die so...
    danke du.



  • Das war nur als Beipiel gedacht, nicht als Patentlösung! Kürzer, hm, soviel isses ja nicht. InitializeCriticalSection( ) muss sein, CreateThread( ) auch. EnterCriticalSection( ) und LeaveCriticalSection( ) müssen auch sein, um den Zugriff auf event_occured zu synchronisieren. (Ansonsten könnte ja der Thread event_occured ändern, während das Hauptprogramm gerade ließt oder vice versa).

    cheers, Swordfish



  • hem...hab gerade festgestellt...du hast doch geschreiben "CLick at /"
    Das ist ja bestimmt die Position des KLicks....aber irgentwie stimmt das nicht ganz oder???was ist das?



  • CaPGeti schrieb:

    Geht das irgentwie kürzer??? Also der bereich in der main()???(Initialisierungen und so)

    Ja. Du kannst ja die Events auslagern:

    #include <windows.h>
    #include <stdio.h>
    
    #define MSGLEN 256
    
    DWORD WINAPI ConsoleThread(LPVOID pt);
    
    struct Console
    {
    	HANDLE hOut, hIn, hThread;
    	DWORD threadID;
    	INPUT_RECORD ir;
    	int Run;
    	char msg[MSGLEN];
    };
    
    int Err( struct Console* C, const char* msg )
    {
    	strcpy( C->msg, msg );
    	return 1;
    }
    
    void Msg( struct Console* C )
    {
    	fprintf( stderr, C->msg );
    }
    
    void ErrExitMsg( struct Console* C )
    {
    	fprintf( stderr, C->msg );
    	exit(1);
    }
    
    void GotoXY( struct Console* C, short x, short y )
    {
       COORD pos;
       pos.X = x;
       pos.Y = y;
       SetConsoleCursorPosition( C->hOut, pos );
    }  
    
    int Init( struct Console* C, const char* title )
    {
    	if ( 0 == SetConsoleTitle( title ) )
    		return Err( C, "Init: SetConsoleTitle failed.");
    
    	C->Run = 1; 
    
    	if ( NULL == ( C->hThread
    		= CreateThread ( NULL, 0, ConsoleThread, C, 0, &C->threadID )))
    		return Err( C, "Init: CreateThread failed." );
    
    	if ( ( C->hIn = GetStdHandle(STD_INPUT_HANDLE) ) == INVALID_HANDLE_VALUE )
    		return Err( C, "Init: Failed on GetStdHandle( in )." );
    
    	if ( ( C->hOut = GetStdHandle(STD_OUTPUT_HANDLE) ) == INVALID_HANDLE_VALUE )
    		return Err( C, "Init: Failed on GetStdHandle( out )." );
    
    	return 0;
    }
    
    int CursorVisibility( struct Console* C, int visible )
    {
    	CONSOLE_CURSOR_INFO cci = {0};
    	if ( 0 == GetConsoleCursorInfo( C->hOut, &cci ) )
    		return Err(C, "CursorVisibility: GetConsoleCursorInfo failed." );
    
    	cci.bVisible = visible;
    
    	if ( 0 == SetConsoleCursorInfo( C->hOut, &cci ) )
    		return Err(C, "CursorVisibility: SetConsoleCursorInfo failed.\n" );
    	return 0;
    }
    
    void parallel_func( struct Console* C ) // bonus demo :)
    {
    	int i=0;
    
    	while( C->Run )
    	{
    		GotoXY( C, 0, 2 );
    		fprintf( stdout, "%d", i++ );
    		Sleep(1000);
    	}
    	GotoXY( C, 0, 2 );
    	fprintf( stdout, "Hasta la vista from parallel_func.\n" );
    }
    
    int main()
    {
    	struct Console con = {0};
    	struct Console* C = &con;
    
    	if( Init( C, "Console basic" ) )
    		ErrExitMsg(C);
    
    	if( CursorVisibility( C, 0 ) )
    		ErrExitMsg(C);
    
    	parallel_func(C);
    
    	WaitForSingleObject( C->hThread ,INFINITE );
    	return 0;
    }
    
    int ConsoleEvents( struct Console* C )
    {
    	short MouseX=0, MouseY=0;
    
    	switch( C->ir.EventType )
        { 
     	  case MOUSE_EVENT:
    	  {
    		if( C->ir.Event.MouseEvent.dwEventFlags )  
    		{
    			switch( C->ir.Event.MouseEvent.dwEventFlags )
    			{
    				case MOUSE_MOVED:
    					// Koordinaten der Maus. Einheiten sind Buchstabenzellen.
    					MouseX = C->ir.Event.MouseEvent.dwMousePosition.X;
    					MouseY = C->ir.Event.MouseEvent.dwMousePosition.Y;
    					GotoXY( C, 0, 0 );
     					fprintf( stdout, "x: %3d y: %3d\r", MouseX, MouseY );
    				break;
    
    				case DOUBLE_CLICK:
    					GotoXY( C, 0, 3 );
    					puts("DOUBLE_CLICK                   ");  
    				break;
    
    				case MOUSE_WHEELED:
    					GotoXY( C, 0, 3 );
    					puts("MOUSE_WHEELED                  ");  
    				break;	
    			  }
    		break;
    		}
    		else
    		{
    			switch( C->ir.Event.MouseEvent.dwButtonState )
    			{
    				case FROM_LEFT_1ST_BUTTON_PRESSED:
    					GotoXY( C, 0, 3 );
    					puts("FROM_LEFT_1ST_BUTTON_PRESSED");  
    				break;
    
    				case RIGHTMOST_BUTTON_PRESSED:
    					GotoXY( C, 0, 3 );
    					puts("RIGHTMOST_BUTTON_PRESSED");  
    				break;
    			}
    		break;
    		}
    	  }// case MOUSE_EVENT
    
    	  case KEY_EVENT:
    	  {
    		GotoXY( C, 0, 4 );
    		printf("ASCII CHAR: %c %d\n", C->ir.Event.KeyEvent.uChar.AsciiChar, C->ir.Event.KeyEvent.uChar.AsciiChar );
    		printf("Virtual: %c %d \n", C->ir.Event.KeyEvent.wVirtualKeyCode, C->ir.Event.KeyEvent.wVirtualKeyCode );
    
    		switch ( C->ir.Event.KeyEvent.wVirtualKeyCode )
    		{
    			GotoXY( C, 0, 6 );
    
    			case 'A':
    				if( C->ir.Event.KeyEvent.uChar.AsciiChar == 'a' )
    					puts("kleines a");
    				else 
    					puts("GROSSES A");
    			break;
    
    			case VK_F11: 
    				//FullScreen(C);
    			break;
    
    			case VK_ESCAPE: 
    				C->Run = 0;
    			break;
    		}
    
    	  }
     	}
    	return 0;
    }
    
    DWORD WINAPI ConsoleThread(LPVOID pt)
    {
    	DWORD count=0;
    	struct Console* C = pt;
    
    	while( C->Run )
    	{
    	 	if ( 0 == ( ReadConsoleInput( C->hIn, &C->ir, 1, &count ) ) )
    				return Err( C, "ConsoleThread: Failed on ReadConsoleInput.");
    
    		while( count-- )
    		{
    			if ( ConsoleEvents( C ) )
    				return 1;
    		}
    	}
    	return 0;
    }
    


  • Dieser Thread wurde von Moderator/in Tim aus dem Forum ANSI C in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • mhh..das ist kürzer (in main())
    naja...aber ich glaub ich nehm doch das erstere....
    Hier versteh ich die Ausgabe ni... Ich will doch die main haben...



  • was verstehst du daran nicht ?
    das dient doch als demo. soll einen teile der möglichkeiten zeigen, was man alles für eingaben abrufen kann.


Log in to reply