Pseudo GUI in C++ ohne ImprovedConsole



  • Hallo,
    weiß jemand wie man in C++ ohne IC(und ohne andere externe Produkte) aber mit der WIN32-API eine Pseudo-GUI(also "GUI" in der konsole) realisieren könnte? Habs schon oft versucht, hat aber nie geklappt.



  • In der Console selber gehen keiner Bilder.
    Aber mit der Conioex.h + conioex.c ohne winapi kann man so sachen basteln die wie ein BIOS aussehen.
    Halt farbe verwenden... Und direkt zeilen anspringen.
    Da du WinAPI ansprichst sollte egal sein das es nur für windows geht...



  • Klar, mir ist es egal, da ich windows verwende und ich ja nur hobbyprogger bin. Ich hab schon etwas erfahrung mit der "WINAPI-Konsolenabteilung". Ich hab schon ne kleine Klasse für professionelle Mausbedienbare Menüs geschrieben. Eine Kostprobe?

    #ifndef __CONMENU_H__
    #define __CONMENU_H__
    
    #include <windows.h>
    #include <iostream>
    #include <cstdio>
    #include <string>
    
    enum ConsoleColor
    {
    	CC_BLACK        = 0,
    	CC_DARKRED      = FOREGROUND_RED,
    	CC_DARKGREEN    = FOREGROUND_GREEN,
    	CC_DARKBLUE     = FOREGROUND_BLUE,
    	CC_OCHER        = FOREGROUND_RED | FOREGROUND_GREEN,
    	CC_VIOLET       = FOREGROUND_RED | FOREGROUND_BLUE,
    	CC_TURQUOISE    = FOREGROUND_GREEN | FOREGROUND_BLUE,
    	CC_GREY         = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
    
    	CC_DARKGREY     = FOREGROUND_INTENSITY | CC_BLACK,
    	CC_RED          = FOREGROUND_INTENSITY | CC_DARKRED,
    	CC_GREEN        = FOREGROUND_INTENSITY | CC_DARKGREEN,
    	CC_BLUE         = FOREGROUND_INTENSITY | CC_DARKBLUE,
    	CC_YELLOW       = FOREGROUND_INTENSITY | CC_OCHER,
    	CC_PINK         = FOREGROUND_INTENSITY | CC_VIOLET,
    	CC_LIGHTBLUE    = FOREGROUND_INTENSITY | CC_TURQUOISE,
    	CC_WHITE        = FOREGROUND_INTENSITY | CC_GREY
    };
    
    class ConsoleMenu
    {
    private:
    	std::string *_menupoints;
    	int _count, _selected;
    	// Initialisiert die Maus und gibt die Anzahl der Maustasten zurück 
    	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; 
    	} 
    	// Zeigt oder versteckt den Mauscursor 
    	void showCursor (bool show = true) 
    	{
    		ShowCursor(show); 
    	}
    
    	//lösche Bildschirm
    	void cls(HANDLE hConsole)
    	{   
    		COORD coordScreen = { 0, 0 }; /* here's where we'll home the cursor */
    		BOOL bSuccess;
    		DWORD cCharsWritten;
    		CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */
    		DWORD dwConSize; /* number of character cells in the current buffer */ 
    		/* get the number of character cells in the current buffer */
    		bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
    		dwConSize = csbi.dwSize.X * csbi.dwSize.Y;   
    		/* fill the entire screen with blanks */   
    		bSuccess = FillConsoleOutputCharacter(hConsole, ' ', dwConSize, coordScreen, &cCharsWritten);
    		bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
    		/* now set the buffer's attributes accordingly */
    		bSuccess = FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten);
    		/* put the cursor at (0, 0) */
    		bSuccess = SetConsoleCursorPosition(hConsole, coordScreen);
    		return; 
    	} 
    public:
    
    	ConsoleMenu(std::string menupoints[], unsigned int count)
    	{
    		_count = 0;
    		_selected = 0;
    		mouseInit();
    		showCursor();
    		if(count <= 10)
    		{
    			_count = count;
    			_menupoints = new std::string[count];
    			for(int i = 0; i < _count; i++)
    			{
    				_menupoints[i] = menupoints[i];
    			}
    		}
    	}
    	~ConsoleMenu()
    	{
    		showCursor(false);
    		delete[] _menupoints;
    	}
    
    	int ShowMenu(int x, int y, WORD color)
    	{
    		cls(GetStdHandle(STD_OUTPUT_HANDLE));
    		showCursor(false);
    		int i;
    		bool running = true;
    		while(1)
    		{
    			for(i = 0; i < _count; i++)
    			{
    				COORD tmp;
    				tmp.X = x;
    				tmp.Y = y+i;
    				SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), tmp);
    				if(i == _selected)
    				{
    					SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color | BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_GREEN);
    					std::cout << (i+1 <= 9  ? i+1: 0)  << " ";
    					SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_GREEN);
    					std::cout << _menupoints[i] << std::endl;
    					SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN);
    				}
    				else
    				{
    					SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
    					std::cout << (i+1 <= 9 ? i+1 : 0)  << " ";
    					SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN);
    					std::cout << _menupoints[i] << std::endl;
    				}
    			}
    
    			DWORD j; 
    			INPUT_RECORD ir; 
    			ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE),&ir,1,&j); 
    
    			switch(ir.EventType) 
    			{ 
    			case KEY_EVENT:
    				if(ir.Event.KeyEvent.bKeyDown)
    				{
    					if(ir.Event.KeyEvent.wVirtualScanCode  == 28 )
    					{
    						SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN);
    						cls(GetStdHandle(STD_OUTPUT_HANDLE));
    						if(_selected+1 <= 9)
    						{
    							showCursor(true);
    							cls(GetStdHandle(STD_OUTPUT_HANDLE));
    							return _selected + 1;
    						}
    						else
    						{
    							showCursor(true);
    							cls(GetStdHandle(STD_OUTPUT_HANDLE));
    							return 0;
    						}
    					}
    					else if(ir.Event.KeyEvent.wVirtualScanCode == 72 && _selected > 0)
    						_selected--;
    					else if(ir.Event.KeyEvent.wVirtualScanCode == 80 && _selected < _count - 1)
    						_selected++;
    					else if(ir.Event.KeyEvent.wVirtualKeyCode == '1' && _count >= 1)
    					{
    						showCursor(true);
    						cls(GetStdHandle(STD_OUTPUT_HANDLE));
    						return 1;
    					}
    					else if(ir.Event.KeyEvent.wVirtualKeyCode == '2' && _count >= 2)
    					{
    						showCursor(true);
    						cls(GetStdHandle(STD_OUTPUT_HANDLE));
    						return 2;
    					}
    					else if(ir.Event.KeyEvent.wVirtualKeyCode == '3' && _count >= 3)
    					{
    						showCursor(true);
    						cls(GetStdHandle(STD_OUTPUT_HANDLE));
    						return 3;
    					}
    					else if(ir.Event.KeyEvent.wVirtualKeyCode == '4' && _count >= 4)
    					{
    						showCursor(true);
    						cls(GetStdHandle(STD_OUTPUT_HANDLE));
    						return 4;
    					}
    					else if(ir.Event.KeyEvent.wVirtualKeyCode == '5' && _count >= 5)
    					{
    						showCursor(true);
    						cls(GetStdHandle(STD_OUTPUT_HANDLE));
    						return 5;
    					}
    					else if(ir.Event.KeyEvent.wVirtualKeyCode == '6' && _count >= 6)
    					{
    						showCursor(true);
    						cls(GetStdHandle(STD_OUTPUT_HANDLE));
    						return 6;
    					}
    					else if(ir.Event.KeyEvent.wVirtualKeyCode == '7' && _count >= 7)
    					{
    						showCursor(true);
    						cls(GetStdHandle(STD_OUTPUT_HANDLE));
    						return 7;
    					}
    					else if(ir.Event.KeyEvent.wVirtualKeyCode == '8' && _count >= 8)
    					{
    						showCursor(true);
    						cls(GetStdHandle(STD_OUTPUT_HANDLE));
    						return 8;
    					}
    					else if(ir.Event.KeyEvent.wVirtualKeyCode == '9' && _count >= 9)
    					{
    						showCursor(true);
    						cls(GetStdHandle(STD_OUTPUT_HANDLE));
    						return 9;
    					}
    					else if(ir.Event.KeyEvent.wVirtualKeyCode == '0' && _count >= 10)
    					{
    						showCursor(true);
    						cls(GetStdHandle(STD_OUTPUT_HANDLE));
    						return 0;
    					}
    					else if(ir.Event.KeyEvent.wVirtualScanCode == 1)
    					{
    						showCursor(true);
    						cls(GetStdHandle(STD_OUTPUT_HANDLE));
    						return -1;
    					}
    				}	
    
    				break;
    
                case MOUSE_EVENT:
    
    				if(ir.Event.MouseEvent.dwMousePosition.Y >= y && ir.Event.MouseEvent.dwMousePosition.Y  < y+_count)
    					_selected = ir.Event.MouseEvent.dwMousePosition.Y - y;
    				if(ir.Event.MouseEvent.dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED)
    				{
    					showCursor(true);
    					cls(GetStdHandle(STD_OUTPUT_HANDLE));
    					if(_selected == 9)
    						return 0;
    					return _selected+1;
    				}
    				break;
    			}
    		}
    		return -2;
    	}
    };
    
    #endif
    

    Stellt euch vor, es funktioniert! 😃

    Ich wollte aber mal ne richtige Menüleiste wie in edit.com. Sowas wollte ich machen. Bei mir gibt es aber kein conioex.h. Ich hätte VC++ 2008 EE und VC++ 6.0 AE im Angebot(VC 2008 wäre mir lieber). Ich wollte hauptsächich maal Fragen ob jemand Beispielcode für ne Menüleiste hat. Ich meine nur wie soll man das Menü einblenden und wieder ausblenden. Das abfangen des Klicks mit der Maus wäre nicht das Problem. Eher die wiederherstellung des "Dokuments". Wer möchte schon das Menü in seinem "Dokument" haben?



  • Wozu conioex.h?
    Du hast doch schon SetConsoleCursorPosition zum Cursor setzen und die Farbe ändern kannst du auch. Mehr brauchst du eigentlich nicht.

    Für das Menu kannst du ja erstmal dein Dokument "zeichen" und dann das Menu darüber malen. Weiss jetzt nicht genau was deine Frage ist.

    Was mir spontan auffällt:

    ir.Event.KeyEvent.wVirtualKeyCode == '3' && _count >= 3
    

    Das hast du ja quasi 10 mal, das geht sicher auch besser als 10x if 😉



  • Wozu conioex.h?
    Du hast doch schon SetConsoleCursorPosition zum Cursor setzen und die Farbe ändern kannst du auch. Mehr brauchst du eigentlich nicht.

    Für das Menu kannst du ja erstmal dein Dokument "zeichen" und dann das Menu darüber malen. Weiss jetzt nicht genau was deine Frage ist.

    Was mir spontan auffällt:

    C/C++ Code:
    ir.Event.KeyEvent.wVirtualKeyCode == '3' && _count >= 3

    Das hast du ja quasi 10 mal, das geht sicher auch besser als 10x if

    Meine Frage konkret: Wie Bildschirm in Buffer sichern? Das meine ich(z.B. für "Dialogfelder"). Das mit dem Menü war bloß ein Beispiel. Aber wenn ich ein mehrseitiges Dokument habe, müsste ich wieder raufscrollen zum Menü, und selbst wenn das automatischpassiert müsste ich wieder runterscrollen zu meiner Stelle im Dokument. Außerdem ist in deinem Vorsclag auch ein kleiner Fehler. Wenn ich eine Statusleiste implementieren(ist das richtig geschrieben 😃 ) möchte dann würde die bei langen textdateien
    int i = 0;
    while(i < 1000)
    {
    cout << "sehr ";
    i++;
    }
    weit runterrücken. Das meine ich. Wie Scrollleisten machen?


Anmelden zum Antworten