Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1

    Colori caratteri in c++

    Ciao io mi chiamo Roberto!!!! Piacere di conoscervi

    Io Studio per perito Informatica e programmiamo in c++, devo consegnare una relazione importante al prof!!! volevo saper qual'è l'istruzione che mi permette di cambiare il colore dei caratteri in uotput!!!

    Io conosco l'istruzione system("COLOR 1B"); che mi cambia il colore dello sfondo e i caratteri!!! ma se volessi colorare una parola di un colore e il resto in un altro colore!!!è possibile????

    Ringrazio chiunque mi dia una mano!!!!!

  2. #2
    Invece di usare il comando COLOR del prompt dei comandi tramite la system usa la apposita API di Windows SetConsoleTextAttribute.
    Esempio:
    codice:
    #include <iostream>
    #include <windows.h>
    using namespace std;
    
    int main()
    {
        HANDLE hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
        if(hStdOut==NULL)
        {
            cerr<<"Impossibile ottenere un handle alla console.";
            return 1;
        }
        cout<<"Questo testo ha le impostazioni di default."<<endl;
        cout<<"Anche questo, ma da qui in poi ";
        SetConsoleTextAttribute(hStdOut,FOREGROUND_RED|FOREGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_INTENSITY);
        cout<<" tutto viene scritto in viola su sfondo verde chiaro."<<endl;
        SetConsoleTextAttribute(hStdOut,FOREGROUND_RED|FOREGROUND_BLUE_|FOREGROUND_GREEN);
        cout<<"Ora tutto e' normale."<<endl;
        return 0;
    }
    Tieni conto che il colore viene specificato come combinazione di costanti rosso-verde-blu-intensità riferite a primo piano o a sfondo. Ad esempio per ottenere un giallo scuro in primo piano e un viola chiaro di sfondo dovrai specificare
    codice:
    FOREGROUND_RED|FOREGROUND_GREEN|BACKGROUND_RED|BACKGROUND_BLUE|BACKGROUND_INTENSITY
    dal momento che il giallo è la somma di rosso e verde e il viola chiaro è somma di rosso e blu e "intensità".
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    salve,
    anche a me serve dare messaggi di diverso colore
    ed ho scritto questa funzione pen non stare a fare or su or:
    codice:
    // questi son i colori da usare nella funzione.
    // i colori con la L son luminosi, gli altri son scuri.
    enum Colors {
         Black, Blue, Green, Aqua, Red, Purple, Brown, LGray,
         Gray, LBlue, LGreen, LAqua, LRed, LPurple, LYellow, White
    };
    
    // i colori possibili son 16
    // quindi ci son 256 possibili combinazioni
    // la funzione si chiama così
    //      color( colore_testo, colore_sfondo);
    //      oppure
    //      color ( colore_testo)
    //      in questo caso lo sfondo sarà nero
    bool color(Colors Text, Colors Background = Black ){
         HANDLE hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
         if(hStdOut==NULL){
            cerr<<"Impossibile ottenere un handle alla console.\n";
            return false;
         }
         SetConsoleTextAttribute(hStdOut, Text | (16*Background));
         return true;
    }
    cmq,
    la mia domanda è un altra:

    se io volessi stampare una stringa colorata e poi ripristinare il precedente colore come faccio?

    dovrei:
    - salvarmi il colore attuale
    - cambiare colore
    - stampare la stringa
    - ripristinare il colore precedente

    oppure esiste una funzione che mi permetta di stampare un tot di caratteri con un determinato colore senza cambiare il colore per il testo successivo?

    se non esistesse
    son costretto a salvarmi il colore attuale,
    pensavo tra le funzioni disponibili a ReadConsoleOutput o ReadConsoleOutputAttribute.

    mi pare che la più appropriata sia ReadConsoleOutputAttribute
    ho provato a fare:
    codice:
        HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
        WORD attributo_attuale =0;
        COORD bufferCoord = {0, 0};
        DWORD j=0;
        ReadConsoleOutputAttribute(hConsole, &attributo_attuale, 1, bufferCoord, &j)
    e funziona, in attributo_attuale mi salva l'attibuto del primo carattere della console cioè quello in posizione {0, 0}.
    Il mio problema sta nel fatto che, mi servirebbe sapere quello dell'ultimo carattere stampato..
    come faccio ad avere le sue coordinate?

    questa è stato un tentativo,
    son solo pochi giorni che lavoro con windows.h,
    magari mi sto complicando la vita :master:
    quindi son ben accetti consigli :P
    Grazie a tutti
    Saluti
    Stefano

  4. #4
    Originariamente inviato da Stefano_1986_
    dovrei:
    - salvarmi il colore attuale
    - cambiare colore
    - stampare la stringa
    - ripristinare il colore precedente
    Sì.
    Per quanto riguarda il salvataggio del colore attuale, nella sezione Remarks della guida della funzione SetConsoleTextAttribute c'è scritto:
    To determine the current color attributes of a screen buffer, call the GetConsoleScreenBufferInfo function.
    ; quindi...
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    cavolo, mi è proprio sfuggito...
    ho scritto questo:
    codice:
    int GetCurrentColor(){
        HANDLE hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
        if( hStdOut==NULL ){
            cerr<<"Impossibile ottenere un handle alla console.\n";
            return 7; // colore standard del dos: testo grigio chiaro e sfondo nero
        }
        CONSOLE_SCREEN_BUFFER_INFO x;
        if( GetConsoleScreenBufferInfo(hStdOut, &x) == 0 ){
            cerr<<"GetConsoleScreenBufferInfo fallita.\n";
            return 7;
        }
        return x.wAttributes;
    }
    funziona!
    qualche suggerimento per migliorarlo?

    altra domanda:
    come cambio il colore di sfondo senza cambiare il colore del carattere?
    conosco system("COLOR XY");
    ma cambia entrambi.
    Grazie

  6. #6
    Originariamente inviato da Stefano_1986_
    cavolo, mi è proprio sfuggito...
    ho scritto questo:
    codice:
    int GetCurrentColor(){
        HANDLE hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
        if( hStdOut==NULL ){
            cerr<<"Impossibile ottenere un handle alla console.\n";
            return 7; // colore standard del dos: testo grigio chiaro e sfondo nero
        }
        CONSOLE_SCREEN_BUFFER_INFO x;
        if( GetConsoleScreenBufferInfo(hStdOut, &x) == 0 ){
            cerr<<"GetConsoleScreenBufferInfo fallita.\n";
            return 7;
        }
        return x.wAttributes;
    }
    funziona!
    qualche suggerimento per migliorarlo?
    Non mi pare che ci siano margini di miglioramento... fa già il suo lavoro egregiamente.
    L'unica cosa che ti potrei suggerire è di raggruppare tutte queste funzioni in una classe che richiamerà GetStdHandle solo al momento della costruzione.
    altra domanda:
    come cambio il colore di sfondo senza cambiare il colore del carattere?
    Ti basta ottenere gli attributi correnti, effettuarne l'AND con tutti gli attributi di sfondo (in modo da eliminare gli attributi del colore di primo piano), effettuarne l'OR con i nuovi attributi di primo piano e richiamare SetConsoleTextAttribute con questo nuovo valore.
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Originariamente inviato da MItaly
    Ti basta ottenere gli attributi correnti, effettuarne l'AND con tutti gli attributi di sfondo (in modo da eliminare gli attributi del colore di primo piano), effettuarne l'OR con i nuovi attributi di primo piano e richiamare SetConsoleTextAttribute con questo nuovo valore.
    Scusa, colpa mia... mi son espresso male...
    Vorrei poter cambiare lo sfondo dell'intera console, non lo sfondo del testo.
    Grazie

  8. #8
    Ci sarebbe questa funzione, ma ha lo stesso difetto dell'istruzione COLOR del prompt dei comandi; volendo preservare il colore di primo piano puoi provare a lavorare con la ReadConsoleOutputAttribute e la WriteConsoleOutputAttribute; con la prima andrai a leggere gli attributi di colore di tutti i caratteri della schermata, li modificherai come meglio credi con un semplice ciclo for e li applicherai con la seconda funzione indicata.
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Ciau, grazie ancora x le informazioni,
    ho provato ed ho scritto questo:
    codice:
    bool inverticolori(){
    	DWORD dim = 80*300; // dimensione della console 80 colonne, 300 righe
    	WORD attributo_attuale[dim];
        HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
        COORD bufferCoord = {0, 0};
        DWORD j=0;
        ReadConsoleOutputAttribute(hConsole, attributo_attuale, dim, bufferCoord, &j);
        for(int i=0; i<dim; i++){
                int k = attributo_attuale[i];
                attributo_attuale[i] = (16*(k%16)) +(k/16); 
        }
        WriteConsoleOutputAttribute( hConsole, attributo_attuale, dim, bufferCoord, &j);
    }
    non ho messo i controlli, ma è solo una prova,
    così com'è inverte i colori
    esempio
    sfondo nero e scritta grigia ---> sfondo grigio e testo nero

    se non si vuole invertire, ma si vuole fare qualche altra modifica basta cambiare "(16*(k%16)) +(k/16)".


    poi ho scritto anche
    codice:
    void Colorout(char* s, Colors Text, Colors Background=Black){
        HANDLE hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
        CONSOLE_SCREEN_BUFFER_INFO x;
        GetConsoleScreenBufferInfo(hStdOut, &x);
    
        SetConsoleTextAttribute(hStdOut, Text | (16*Background));
        cout<<s;
        SetConsoleTextAttribute(hStdOut, x.wAttributes);
    }
    che stampa una stringa colorata e poi ripristina il colore precedente, anche qui bisogna aggiungere i controlli errori.

    che dici? sembra tutto ok?

  10. #10
    Mi pare tutto OK, personalmente invece di
    codice:
                attributo_attuale[i] = (16*(k%16)) +(k/16);
    e
    codice:
        SetConsoleTextAttribute(hStdOut, Text | (16*Background));
    avrei scritto
    codice:
                attributo_attuale[i] = ((k & 0xf)<<4) | (k>>4);
    e
    codice:
        SetConsoleTextAttribute(hStdOut, (Text & 0xf) | (Background<<4));
    , dal momento che, oltre ad essere più efficiente, se si lavora con flag a bitmask è molto più corretto e chiaro usare gli operatori booleani e gli shift.
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.