This lightweight library provides a simple, high-performance menu system for Windows console applications. It features a highly optimized rendering engine, customizable menus, keyboard and mouse navigation, and a clean abstraction layer.
0.9.4 STABLE
- Optimized Rendering Engine: A new partial redraw system dramatically improves performance by only updating changed elements, eliminating flickering on selection changes. 🚀
- Efficient Memory Management: The library now pre-allocates memory for menus and options more efficiently, reducing expensive
realloccalls and improving speed when adding options dynamically. - Robust Text Alignment: Added support for UTF-8 character counting, ensuring menu elements are perfectly centered and aligned, even with non-ASCII characters.
- Refactored Color API: The color management API has been modernized for better type safety and clarity.
- Improved Input Stability: Enhanced input handling to prevent missed or ghost inputs, especially on menu initialization.
- Windows-only implementation (uses Windows API)
- Customizable headers and footers
- Colorful menu options with highlighting (VT100 & Legacy)
- Keyboard navigation (arrow keys + Enter)
- Mouse navigation (toggleable)
- Advanced color customization with macros / RGB colors
- Double buffering for smooth, flicker-free rendering
- NEW: Optimized partial screen redraws for maximum performance
- NEW: UTF-8 support for accurate text alignment
- Dynamically centers the menu in the console
- Legacy console support (Windows 7/8 compatibility) with automatic VT100 detection
- Add
menu.handmenu.cto your project. - Include the header in your code:
#include "menu.h"
- Windows operating system (Windows 7+)
- C99 compatible compiler
- Standard Windows libraries
#include "menu.h" void menu_callback(MENU menu, dpointer data) { char* message = (char*)data; printf("Selected: %s\n", message); getchar(); } int main() { MENU main_menu = create_menu(); // Create menu items with associated data add_option(main_menu, create_menu_item("Option 1", menu_callback, "First option")); add_option(main_menu, create_menu_item("Option 2", menu_callback, "Second option")); add_option(main_menu, create_menu_item("Exit", menu_callback, "Exiting...")); change_header(main_menu, "MAIN MENU"); change_footer(main_menu, "Navigate with arrow keys or mouse"); // Enable mouse support toggle_mouse(main_menu); enable_menu(main_menu); // Use clear_menu() or clear_menus() if menus are no more need // clear_menus_and_exit(); return 0; }#include "menu.h" void callback(MENU menu, void* data) { printf("Callback executed!\n"); getchar(); // To close the menu after callback, you can call clear_menu() // clear_menu(menu); } int main() { // === Global Settings Configuration === // Create a new settings object to force legacy mode MENU_SETTINGS settings = create_new_settings(); settings.force_legacy_mode = 1; // Force legacy color system and rendering (e.g., for Win 7 or win 10 old consoles) set_default_menu_settings(settings); // --- VT100 Color Settings (WILL BE IGNORED in legacy mode) --- MENU_COLOR modern_colors = create_color_object(); modern_colors.headerColor = new_full_rgb_color(mrgb(255, 255, 255), mrgb(90, 0, 157)); // White on Purple modern_colors.footerColor = new_full_rgb_color(mrgb(255, 255, 255), mrgb(90, 0, 157)); modern_colors.optionColor = new_full_rgb_color(mrgb(0, 0, 0), mrgb(200, 200, 200)); // Black on Light Gray set_default_color_object(modern_colors); // --- Legacy Color Settings (WILL BE USED because of force_legacy_mode) --- LEGACY_MENU_COLOR legacy_colors = create_legacy_color_object(); legacy_colors.headerColor = BRIGHT_MAGENTA; legacy_colors.footerColor = BRIGHT_MAGENTA; legacy_colors.optionColor = HIGHLIGHT_COLOR; // White on Blue set_default_legacy_color_object(legacy_colors); // === Menu Creation === MENU menu = create_menu(); add_option(menu, create_menu_item("Options", callback, NULL)); add_option(menu, create_menu_item("Exit", callback, NULL)); enable_menu(menu); return 0; }MENU create_menu()Creates and returns a new menu object.void enable_menu(MENU menu)Activates and displays the menu, entering its main loop.void clear_menu(MENU menu)Frees all resources for a specific menu.void clear_menus()Destroys all created menus.void clear_menus_and_exit()Destroys all menus and exits the program with code 0.
MENU_ITEM create_menu_item(const char* text, __menu_callback callback, void* data)Creates a menu item with text, a callback function, and associated user data.void add_option(MENU menu, const MENU_ITEM item)Adds a menu item to a menu.void clear_option(MENU menu, MENU_ITEM option)Removes and frees a specific menu item from a menu.
void change_header(MENU menu, const char* text)Sets the menu header text.void change_footer(MENU menu, const char* text)Sets the menu footer text.void change_menu_policy(MENU menu, int header_policy, int footer_policy)Controls header/footer visibility (1 = show, 0 = hide).
void toggle_mouse(MENU menu)Toggles mouse input support for a specific menu.
MENU_SETTINGS create_new_settings()Creates a new settings object with default values.void set_menu_settings(MENU menu, MENU_SETTINGS settings)Applies custom settings to a specific menu.void set_default_menu_settings(MENU_SETTINGS settings)Sets the default settings for all newly created menus.
MENU_COLOR create_color_object()Creates a new color object with default colors.void set_color_object(MENU menu, MENU_COLOR color_object)Applies a color scheme to a specific menu.void set_default_color_object(MENU_COLOR color_object)Sets the default color scheme for new menus.
LEGACY_MENU_COLOR create_legacy_color_object()Creates a new legacy color object.void set_legacy_color_object(MENU menu, LEGACY_MENU_COLOR color_object)Applies a legacy color scheme to a specific menu.void set_default_legacy_color_object(LEGACY_MENU_COLOR color_object)Sets the default legacy color scheme for new menus.
MENU_RGB_COLOR mrgb(short r, short g, short b)Creates an RGB color structure.COLOR_OBJECT_PROPERTY new_rgb_color(int text_color, MENU_RGB_COLOR color)Returns a color property for either foreground (text_color = 1) or background (text_color = 0).COLOR_OBJECT_PROPERTY new_full_rgb_color(MENU_RGB_COLOR fg, MENU_RGB_COLOR bg)Returns a color property for a complete foreground and background pair.
Compile your application source file with menu.c:
gcc your_app.c menu.c -o your_app.exe-
API Changes in 0.9.4 STABLE The color management API has been refactored. Instead of passing char buffers, functions like
new_full_rgb_colornow return aCOLOR_OBJECT_PROPERTYstruct, which should be assigned directly (e.g.,my_colors.headerColor = new_full_rgb_color(...)). -
Memory Management - Use
clear_menu()to free a menu's resources if you need to close it from a callback.clear_menus_and_exit()is a convenient way to clean up before program termination.- The library now manages memory for options in blocks, making
add_optionmore efficient.
-
Performance - The new rendering engine is extremely fast and avoids redrawing the entire screen on simple updates like selection changes.
- Mouse input is well-optimized.
-
Compatibility - VT100 mode (with full RGB color) requires Windows 10/11.
- Legacy mode works on Windows 7 and newer.
- The library automatically detects VT100 support but can be overridden with
settings.force_legacy_mode = 1;. - It's good practice to define both a modern
MENU_COLORand aLEGACY_MENU_COLORscheme for your application to ensure it looks great on all target systems.
-
Error Handling - The library automatically handles console resizing and displays a user-friendly message if the window is too small, pausing until it's resized appropriately.
Contributions are welcome! Please submit pull requests or open issues on GitHub.