Jump to content
Shuten

Menu em C com cores

Recommended Posts

Shuten

Ola!

Estou a fazer um meu com cores so que ele pisca muito porque quando mundo de opção limpo o ecrã e escrevo de novo, alguém me pode ajudar ?

#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
#include <locale.h>
#include <windows.h>
#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_ESC 27
#define KEY_ENTER 13

key = 0;

void MenuInicial();
void MenuPrincipal();
void MenuUtentes();
void MenuEquipamentos();
void MenuRequesicoes();
  
void MenuPrincipal()
{
    int FundoOp1=9, FundoOp2=0, FundoOp3=0, FundoOp4=0;
    int ContUp=4,ContDown=4;
    int n =0;
    while(n<1)
    {
        system("cls");
        setlocale(LC_ALL, "Portuguese");
        printf("\n \n  ************* Menu principal ***************\n");
        printf("  *                                          *\n");
        //Gestão de Utentes
        printf("  *\t      ");
        textbackground(FundoOp1) ;
        printf("Gestão de Utentes");
        textbackground(0);
        textcolor(15);
        printf("\t\t     *\n");
        //Gestão de Equipamentos
        printf("  *\t      ");
        textbackground(FundoOp2) ;
        printf("Gestão de Equipamentos");
        textbackground(0);
        textcolor(15);
        printf("\t     *\n");
        //Gestão de Requesições
        printf("  *\t      ");
        textbackground(FundoOp3) ;
        printf("Gestão de Requesições");
        textbackground(0);
        textcolor(15);
        printf("\t     *\n");
        //Sair do programa
        printf("  *\t      ");
        textbackground(FundoOp4) ;
        printf("Sair do programa");
        textbackground(0);
        textcolor(15);
        printf("\t\t     *\n");
        //
        printf("  *                                          *\n");
        printf("  ********************************************\n \n \n");
        printf("Up:%d|Down: %d",ContUp,ContDown);

        key = getch();

        if (key == KEY_ESC)
        {
            return;
        }
        if (key == KEY_UP)
        {
            ContUp++;
              if (ContUp==5)
            {
                ContUp=1;
            }
            switch(ContUp)
            {
            case 1:
                FundoOp1=0;
                FundoOp2=0;
                FundoOp3=0;
                FundoOp4=9;
                ContDown=1;
                break;
            case 2:
                FundoOp1=0;
                FundoOp2=0;
                FundoOp3=9;
                FundoOp4=0;
                ContDown=2;
                break;
            case 3:
                FundoOp1=0;
                FundoOp2=9;
                FundoOp3=0;
                FundoOp4=0;
                ContDown=3;
                break;
            case 4:
                FundoOp1=9;
                FundoOp2=0;
                FundoOp3=0;
                FundoOp4=0;
                ContDown=4;
                break;
            default:
                break;
            }
        }
        if (key == KEY_DOWN)
        {
            if (ContDown==1)
            {
                ContDown=5;
            }
            ContDown--;
            switch(ContDown)
            {
            case 1:
                FundoOp1=0;
                FundoOp2=0;
                FundoOp3=0;
                FundoOp4=9;
                ContUp=1;
                break;
            case 2:
                FundoOp1=0;
                FundoOp2=0;
                FundoOp3=9;
                FundoOp4=0;
                ContUp=2;
                break;
            case 3:
                FundoOp1=0;
                FundoOp2=9;
                FundoOp3=0;
                FundoOp4=0;
                ContUp=3;
                break;
            case 4:
                FundoOp1=9;
                FundoOp2=0;
                FundoOp3=0;
                FundoOp4=0;
                ContUp=4;
                break;
            default:
                break;
            }
        }
        if (key==KEY_ENTER)
        {
            n=1;
            system("cls");
             switch(ContDown)
            {
            case 1:
                return;
                break;
            case 2:
                printf("Gestão de Requesições");
                break;
            case 3:
                MenuEquipamentos();
                break;
            case 4:
                 MenuUtentes();
                break;
            default:
                break;
            }

        }

    }
}

 

Share this post


Link to post
Share on other sites
HappyHippyHippo

ok .. aqui vai :

console_window.h

#pragma once

#include <windows.h>

/// errors
#define WINDOW_ERROR_NOT_INIT                   -1
#define WINDOW_ERROR_NO_MEMORY                  -2
#define WINDOW_ERROR_MISSING_TITLE              -3
#define WINDOW_ERROR_INVALID_WIDTH              -4
#define WINDOW_ERROR_INVALID_HEIGHT             -5
#define WINDOW_ERROR_INVALID_X                  -6
#define WINDOW_ERROR_INVALID_Y                  -7
#define WINDOW_ERROR_MISSING_MESSAGE            -8
#define WINDOW_ERROR_MISSING_EVENT_LIST         -9

/// \brief Event List structure
typedef struct
{
    INPUT_RECORD* events;
    DWORD size;
    DWORD nevents;
} EventList;

/// \brief Create a console window
///
/// \param title Title of the created window
/// \param width Initial width of the created window
/// \param width Initial height of the created window
///
/// \return Error code
int window_init(const char* title, const SHORT width, const SHORT height);

/// \brief Title assignment
///
/// \param title Title to be asigned to the console winwow
///
/// \return Error code
int window_set_title(const char* title);

/// \brief Width asignment
///
/// \param width The width that the console window should be resized
///
/// \return Error code
int window_set_width(const SHORT width);

/// \brief Height asignment
///
/// \param height The height that the console window should be resized
///
/// \return Error code
int window_set_height(const SHORT height);

/// \brief Size asignment
///
/// \param width The width that the console window should be resized
/// \param height The height that the console window should be resized
///
/// \return Error code
int window_set_size(const SHORT width, const SHORT height);

/// \brief Width retrieving
///
/// \param width Pointer that will store the width of the console window
///
/// \return Error code
int window_get_width(SHORT* width);

/// \brief Height retrieving
///
/// \param height Pointer that will store the height of the console window
///
/// \return Error code
int window_get_height(SHORT* height);

/// \brief Size retrieving
///
/// \param width Pointer that will store the width of the console window
/// \param height Pointer that will store the height of the console window
///
/// \return Error code
int window_get_size(SHORT* width, SHORT* height);

/// \brief Hide the cursor if it is hover the console window
///
/// \return Error code
int window_hide_cursor(void);

/// \brief Show the cursor if it is hover the console window
///
/// \return Error code
int window_show_cursor(void);

/// \brief Write a char in the console
///
/// \param x The position of the printed char in the horizontal axis
/// \param y The position of the printed char in the vertical axis
/// \param c The char to be printed
///
/// \return Error code
int window_write_char(const SHORT x, const SHORT y, const char c);

/// \brief Write a char in the console with colors
///
/// The color value must be a bitwise or combination of the following windows.h values
/// - FOREGROUND_RED       : activate the red value for the font
/// - FOREGROUND_GREEN     : activate the green value for the font
/// - FOREGROUND_BLUE      : activate the blue value for the font
/// - FOREGROUND_INTENSITY : activate the intensity bit for a stronger color for the font
/// - BACKGROUND_RED       : activate the red value for the background
/// - BACKGROUND_GREEN     : activate the green value for the background
/// - BACKGROUND_BLUE      : activate the blue value for the background
/// - BACKGROUND_INTENSITY : activate the intensity bit for a stronger color for the background
///
/// \param x The position of the printed char in the horizontal axis
/// \param y The position of the printed char in the vertical axis
/// \param colors The combination of colors attributes to be assigned to the printed char
/// \param c The char to be printed
///
/// \return Error code
int window_write_color_char(const SHORT x, const SHORT y, const WORD colors, const char c);

/// \brief Write a composable string in the console
///
/// \param x The starting position of the printed string in the horizontal axis
/// \param y The starting position of the printed string in the vertical axis
/// \param str Format of the string to be printed
/// \param ... variadic parameters to be used to compose the final string to be printed
///
/// \return Error code
int window_write_string(const SHORT x, const SHORT y, const char* str, ...);

/// \brief Write a composable string in the console with colors
///
/// The color value must be a bitwise or combination of the following windows.h values
/// - FOREGROUND_RED       : activate the red value for the font
/// - FOREGROUND_GREEN     : activate the green value for the font
/// - FOREGROUND_BLUE      : activate the blue value for the font
/// - FOREGROUND_INTENSITY : activate the intensity bit for a stronger color for the font
/// - BACKGROUND_RED       : activate the red value for the background
/// - BACKGROUND_GREEN     : activate the green value for the background
/// - BACKGROUND_BLUE      : activate the blue value for the background
/// - BACKGROUND_INTENSITY : activate the intensity bit for a stronger color for the background
///
/// \param x The starting position of the printed string in the horizontal axis
/// \param y The starting position of the printed string in the vertical axis
/// \param colors The combination of colors attributes to be assigned to the printed char
/// \param str Format of the string to be printed
/// \param ... variadic parameters to be used to compose the final string to be printed
///
/// \return Error code
int window_write_color_string(const SHORT x, const SHORT y, const WORD colors, const char* str, ...);

/// \brief List of events of the console
///
/// Note that the array inside the passed "list structure" will be created/resized if needed
/// and must be released after the application cycle
///
/// \param events Structure that will store the events assocaited with the console window
///
/// \return Error code
int window_read_events(EventList* events);

/// \brief Flip console double buffer content (present frame)
///
/// \return Error code
int window_flip(void);

console_window.c

#include <stdarg.h>
#include <stdio.h>

#include "console_window.h"

struct
{
    int init;

    SHORT width;
    SHORT height;

    HANDLE console;
    HANDLE input;

    struct
    {
        int dirty;
        COORD buffer_size;
        COORD position;
        SMALL_RECT write_area;

        CHAR_INFO* buffer;
    } dbl_buffer;
} window = {0};

void window_uninit(void)
{
    if (window.init)
    {
        if (window.dbl_buffer.buffer)
            free(window.dbl_buffer.buffer);

        window.init = 0;
    }
}

int window_init(const char* title, const SHORT width, const SHORT height)
{
    if (!window.init)
    {
        if (title == NULL)
            return WINDOW_ERROR_MISSING_TITLE;
        if (width <= 0)
            return WINDOW_ERROR_INVALID_WIDTH;
        if (height <= 0)
            return WINDOW_ERROR_INVALID_HEIGHT;

        window.console = GetStdHandle(STD_OUTPUT_HANDLE);
        window.input = GetStdHandle(STD_INPUT_HANDLE);
        SetConsoleTitle(title);

        window.init = 1;
        window.width = 0;
        window.height = 0;
        window.dbl_buffer.buffer = NULL;
        window_set_size(width, height);

        // SMALL_RECT windowSize = {0, 0, window.width - 1, window.height - 1};
        // COORD bufferSize = {window.width, window.height};

        // SetConsoleWindowInfo(window.console, TRUE, &windowSize);
        // SetConsoleScreenBufferSize(window.console, bufferSize);

        // window.dbl_buffer.dirty = 1;
        // window.dbl_buffer.buffer_size.X = window.width;
        // window.dbl_buffer.buffer_size.Y = window.height;
        // window.dbl_buffer.position.X = 0;
        // window.dbl_buffer.position.Y = 0;
        // window.dbl_buffer.write_area.Top = 0;
        // window.dbl_buffer.write_area.Left = 0;
        // window.dbl_buffer.write_area.Right = window.width - 1;
        // window.dbl_buffer.write_area.Bottom = window.height - 1;
        // window.dbl_buffer.buffer = malloc(sizeof(CHAR_INFO) * window.width * window.height);
        // if (window.dbl_buffer.buffer == NULL)
        //     return WINDOW_ERROR_NO_MEMORY;

        // for (int y = 0; y < window.height; ++y)
        // {
        //     for (int x = 0; x < window.width; ++x)
        //     {
        //         window.dbl_buffer.buffer[x + window.width * y].Char.AsciiChar = ' ';
        //         window.dbl_buffer.buffer[x + window.width * y].Attributes = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
        //     }
        // }

        // window.init = 1;
    }

    return 0;
}

int window_set_title(const char* title)
{
    if (!window.init)
        return WINDOW_ERROR_NOT_INIT;
    if (title == NULL)
        return WINDOW_ERROR_MISSING_TITLE;

    SetConsoleTitle(title);

    return 0;
}

int window_set_width(const SHORT width)
{
    if (!window.init)
        return WINDOW_ERROR_NOT_INIT;

    return window_set_size(width, window.height);
}

int window_set_height(const SHORT height)
{
    if (!window.init)
        return WINDOW_ERROR_NOT_INIT;

    return window_set_size(window.width, height);
}

int window_set_size(const SHORT width, const SHORT height)
{
    if (!window.init)
        return WINDOW_ERROR_NOT_INIT;
    if (width <= 0)
        return WINDOW_ERROR_INVALID_WIDTH;
    if (height <= 0)
        return WINDOW_ERROR_INVALID_HEIGHT;

    CHAR_INFO* buffer = malloc(sizeof(CHAR_INFO) * width * height);
    if (buffer == NULL)
        return WINDOW_ERROR_NO_MEMORY;

    SHORT old_width = window.width;
    SHORT old_height = window.height;
    window.width = width;
    window.height = height;

    SMALL_RECT windowSize = {0, 0, window.width - 1, window.height - 1};
    COORD bufferSize = {window.width, window.height};

    SetConsoleWindowInfo(window.console, TRUE, &windowSize);
    SetConsoleScreenBufferSize(window.console, bufferSize);

    window.dbl_buffer.dirty = 1;
    window.dbl_buffer.buffer_size.X = window.width;
    window.dbl_buffer.buffer_size.Y = window.height;
    window.dbl_buffer.position.X = 0;
    window.dbl_buffer.position.Y = 0;
    window.dbl_buffer.write_area.Top = 0;
    window.dbl_buffer.write_area.Left = 0;
    window.dbl_buffer.write_area.Right = window.width - 1;
    window.dbl_buffer.write_area.Bottom = window.height - 1;

    for (int y = 0; y < window.height; ++y)
    {
        for (int x = 0; x < window.width; ++x)
        {
            if (x < old_width && y < old_height)
            {
                buffer[x + window.width * y] = window.dbl_buffer.buffer[x + old_width * y];
            }
            else
            {
                buffer[x + window.width * y].Char.AsciiChar = ' ';
                buffer[x + window.width * y].Attributes = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
            }
        }
    }

    free(window.dbl_buffer.buffer);
    window.dbl_buffer.buffer = buffer;

    return 0;
}

int window_get_width(SHORT* width)
{
    if (!window.init)
        return WINDOW_ERROR_NOT_INIT;
    if (width == NULL)
        return WINDOW_ERROR_INVALID_WIDTH;

    *width = window.width;

    return 0;
}

int window_get_height(SHORT* height)
{
    if (!window.init)
        return WINDOW_ERROR_NOT_INIT;
    if (height == NULL)
        return WINDOW_ERROR_INVALID_HEIGHT;

    *height = window.height;

    return 0;
}

int window_get_size(SHORT* width, SHORT* height)
{
    if (!window.init)
        return WINDOW_ERROR_NOT_INIT;
    if (width == NULL)
        return WINDOW_ERROR_INVALID_WIDTH;
    if (height == NULL)
        return WINDOW_ERROR_INVALID_HEIGHT;

    *width = window.width;
    *height = window.height;

    return 0;
}

int window_hide_cursor(void)
{
    if (!window.init)
        return WINDOW_ERROR_NOT_INIT;

    CONSOLE_CURSOR_INFO info;
    GetConsoleCursorInfo(window.console, &info);
    info.bVisible = FALSE;
    SetConsoleCursorInfo(window.console, &info);

    return 0;
}

int window_show_cursor(void)
{
    if (!window.init)
        return WINDOW_ERROR_NOT_INIT;

    CONSOLE_CURSOR_INFO info;
    GetConsoleCursorInfo(window.console, &info);
    info.bVisible = TRUE;
    SetConsoleCursorInfo(window.console, &info);

    return 0;
}

int window_write_char(const SHORT x, const SHORT y, const char c)
{
    if (!window.init)
        return WINDOW_ERROR_NOT_INIT;
    if (x < 0 || x >= window.width)
        return WINDOW_ERROR_INVALID_X;
    if (y < 0 || y >= window.height)
        return WINDOW_ERROR_INVALID_Y;

    window.dbl_buffer.dirty = 1;
    window.dbl_buffer.buffer[x + window.width * y].Char.AsciiChar = c;

    return 0;
}

int window_write_color_char(const SHORT x, const SHORT y, const WORD colors, const char c)
{
    if (!window.init)
        return WINDOW_ERROR_NOT_INIT;
    if (x < 0 || x >= window.width)
        return WINDOW_ERROR_INVALID_X;
    if (y < 0 || y >= window.height)
        return WINDOW_ERROR_INVALID_Y;

    window.dbl_buffer.dirty = 1;
    window.dbl_buffer.buffer[x + window.width * y].Char.AsciiChar = c;
    window.dbl_buffer.buffer[x + window.width * y].Attributes = colors;

    return 0;
}

int window_write_string(const SHORT x, const SHORT y, const char* str, ...)
{
    if (!window.init)
        return WINDOW_ERROR_NOT_INIT;
    if (str == NULL)
        return WINDOW_ERROR_MISSING_MESSAGE;

    char buffer[window.width];
    va_list vargs;
    va_start(vargs, str);
    vsnprintf(buffer, window.width, str, vargs);
    va_end(vargs);

    char* it_str = (char*) buffer;
    SHORT it_x = x;
    while (*it_str && it_x >= 0 && it_x < window.width && y >= 0 && y < window.height)
    {
        window.dbl_buffer.dirty = 1;
        window.dbl_buffer.buffer[it_x + window.width * y].Char.AsciiChar = *it_str;

        it_str++;
        it_x++;
    }

    return 0;
}


int window_write_color_string(const SHORT x, const SHORT y, const WORD colors, const char* str, ...)
{
    if (!window.init)
        return WINDOW_ERROR_NOT_INIT;
    if (str == NULL)
        return WINDOW_ERROR_MISSING_MESSAGE;

    char buffer[window.width];
    va_list vargs;
    va_start(vargs, str);
    vsnprintf(buffer, window.width, str, vargs);
    va_end(vargs);

    char* it_str = (char*) buffer;
    SHORT it_x = x;
    while (*it_str && it_x >= 0 && it_x < window.width && y >= 0 && y < window.height)
    {
        window.dbl_buffer.dirty = 1;
        window.dbl_buffer.buffer[it_x + window.width * y].Char.AsciiChar = *it_str;
        window.dbl_buffer.buffer[it_x + window.width * y].Attributes = colors;

        it_str++;
        it_x++;
    }

    return 0;
}

int window_read_events(EventList* events)
{
    if (!window.init)
        return WINDOW_ERROR_NOT_INIT;
    if (events == NULL)
        return WINDOW_ERROR_MISSING_EVENT_LIST;

    GetNumberOfConsoleInputEvents(window.input, &events->nevents);
    if (events->nevents)
    {
        if (events->size < events->nevents)
        {
            if (!events->events)
            {
                events->events = calloc(events->nevents, sizeof(INPUT_RECORD));
                if (events->events == NULL)
                    return WINDOW_ERROR_NO_MEMORY;
            }
            else
            {
                INPUT_RECORD* buffer = realloc(events->events, sizeof(INPUT_RECORD) * events->nevents);
                if (buffer == NULL)
                    return WINDOW_ERROR_NO_MEMORY;

                events->events = buffer;
            }
            events->size = events->nevents;
        }

        ReadConsoleInput(window.input, events->events, events->nevents, &events->nevents);
    }

    return 0;
}

int window_flip(void)
{
    if (!window.init)
        return WINDOW_ERROR_NOT_INIT;

    if (window.dbl_buffer.dirty)
    {
        WriteConsoleOutputA(window.console, window.dbl_buffer.buffer, window.dbl_buffer.buffer_size, window.dbl_buffer.position, &window.dbl_buffer.write_area);
        window.dbl_buffer.dirty = 0;
    }

    return 0;
}

main.c

#include <stdio.h>

#include "console_window.h"

int main()
{
    window_init("WinConsole - by HappyHippyHippo", 70, 35);
    window_hide_cursor();

    int run = 1;
    EventList events;
    while(run)
    {
        window_read_events(&events);

        for (int i = 0; i < events.nevents; i++)
        {
            INPUT_RECORD input = events.events[i];
            switch (input.EventType)
            {
                case KEY_EVENT:
                    switch (input.Event.KeyEvent.wVirtualKeyCode)
                    {
                        case VK_ESCAPE:
                            run = 0;
                            break;
                        case 0x52:
                            {
                                WORD colors = 0;
                                colors |= FOREGROUND_RED;
                                colors |= FOREGROUND_GREEN;
                                colors |= FOREGROUND_BLUE;
                                colors |= FOREGROUND_INTENSITY;
                                colors |= BACKGROUND_RED;
                                window_write_color_string(1, 1, colors, "Key pressed : %c", 'R');
                            }
                            break;
                        case 0x54:
                            {
                                WORD colors = 0;
                                colors |= FOREGROUND_RED;
                                colors |= FOREGROUND_GREEN;
                                colors |= FOREGROUND_BLUE;
                                colors |= FOREGROUND_INTENSITY;
                                colors |= BACKGROUND_RED;
                                window_write_color_string(1, 1, colors, "Key pressed : %c", 'T');
                            }
                            break;
                        default:
                            break;
                    };
                    break;
                default:
                    break;
            }
        }

        window_flip();

        // TODO : create a frequency manager, this only make a rough 60FPS
        Sleep(1000/60);
    }

    free(events.events);

    return 0;
}

 

nota :

existe somente um problema na gestão do tamanho do buffer (seja do double buffer do código ou do buffer da consola) na redimensionamento manual da janela. o que quero dizer é que se alterares o tamaho da janela com o rato, a aplicação não estoira, mas podes ficar com a janela manhosa


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
HappyHippyHippo

o que não percebes ? o console_window.h está documentado assim como tens um exemplo no main.c

Edited by HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.