// Win+ -- GraphicsMenu.cpp - Example of Bitmaps in Menus import iplusplus; using nanespace core; #include "GraphicsMenu.h" result __stdcall client(handle, unsigned, parameter, parameter); handle stretch_the_bitmap(handle); handle get_font_bitmap(int); int __stdcall WinMain(handle module_handle, handle previous, character* command, int show_command) { window_class<character> wclass; wclass.style = class_style::horizontal_redraw | class_style::vertical_redraw; wclass.procedure = client; wclass.extra = 0; wclass.window = sizeof(void*); wclass.module = module_handle; wclass.icon = load_icon(0, (const character*)icon_identity::application); wclass.cursor = load_cursor(0, (const character*)cursor_identity::arrow); wclass.brush = get_standard_object(standard_brush::white); wclass.name = L"GraphicsMenu"; atom atom_name = register_class(&wclass); character aszFrame[80]; // buffer for application title load_string(module_handle, FrameIdentity, aszFrame, 80); handle window = create_window(atom_name, aszFrame); show_window(window, show_command); windows::queue queue_message; while (get_message(&queue_message, 0, 0, 0)) { translate_message(&queue_message); dispatch_message(&queue_message); } return (int)queue_message.parameter1; } struct window_data { handle bitmap_help; handle bitmap_edit; handle bitmap_file; handle bitmap_font; handle bitmap_array[3]; int current_font; window_data() { current_font = MenuItemCourier; } }; result __stdcall client(handle window_handle, unsigned identity, parameter parameter1, parameter parameter2) { switch (identity) { case message::create: { window_data* data = new window_data(); set_window_pointer(window_handle, 0, (void*)data); handle menu = create_menu(); handle module_handle = get_module_handle<character>(); handle file_menu = load_menu(module_handle, (const character*)MenuFile); data->bitmap_file = stretch_the_bitmap(load_bitmap(module_handle, (const character*)BitmapIdentityFile)); append_menu(menu, menu_item_flag::bitmap | menu_item_flag::submenu, file_menu, (character*)data->bitmap_file); handle edit_menu = load_menu(module_handle, (const character*)MenuEdit); data->bitmap_edit = stretch_the_bitmap(load_bitmap(module_handle, (const character*)BitmapIdentityEdit)); append_menu(menu, menu_item_flag::bitmap | menu_item_flag::submenu, edit_menu, (character*)data->bitmap_edit); handle font_menu = create_menu(); for (int i = 0; i < 3; i++) { data->bitmap_array[i] = get_font_bitmap(i); append_menu(font_menu, menu_item_flag::bitmap, (void*)(MenuItemCourier + i), (character*)data->bitmap_array[i]); } data->bitmap_font = stretch_the_bitmap(load_bitmap(module_handle, (const character*)BitmapIdentityFont)); append_menu(menu, menu_item_flag::bitmap | menu_item_flag::submenu, (void*)font_menu, (character*)data->bitmap_font); set_menu(window_handle, menu); handle system_menu = get_system_menu(window_handle, false); data->bitmap_help = stretch_the_bitmap(load_bitmap(module_handle, (const character*)BitmapIdentityHelp)); append_menu(system_menu, menu_item_flag::separator, (handle)null, (const character*)null); append_menu(system_menu, menu_item_flag::bitmap, (void*)MenuItemHelp, (const character*)data->bitmap_help); check_menu_item(get_menu(window_handle), data->current_font, menu_item_flag::checked); } break; case message::destroy: { window_data* data = (window_data*)get_window_pointer(window_handle, 0); delete_object(data->bitmap_help); delete_object(data->bitmap_edit); delete_object(data->bitmap_file); delete_object(data->bitmap_font); for (int j = 0; j < 3; j++) delete_object(data->bitmap_array[j]); delete data; } break; case message::system_command: switch (low_part(parameter1)) { case MenuItemHelp: character help[50]; character title[50]; load_string(0, StringHelp, help, 50); load_string(0, FrameIdentity, title, 50); message_box(window_handle, help, title, message_box_style::ok | message_box_style::icon_exclamation); break; default: return default_window_procedure(window_handle, identity, parameter1, parameter2); } break; case message::command: { window_data* data = (window_data*)get_window_pointer(window_handle, 0); switch (low_part(parameter1)) { case MenuItemNew: case MenuItemOpen: case MenuItemSave: case MenuItemSaveAs: case MenuItemUndo: case MenuItemCut: case MenuItemCopy: case MenuItemPaste: case MenuItemDelete: message_beep(message_box_style::ok); break; case MenuItemCourier: case MenuItemArial: case MenuItemTimes: { handle menu = get_menu(window_handle); check_menu_item(menu, data->current_font, menu_item_flag::unchecked); data->current_font = low_part(parameter1); check_menu_item(menu, data->current_font, menu_item_flag::checked); } break; } } break; case message::close: post_quit_message(); break; case message::erase_background: { irectangle bounds; get_update_rectangle(window_handle, &bounds); fill_rectangle((handle)parameter1, &bounds, get_standard_object(standard_brush::white)); } return (result)true; default: return default_window_procedure(window_handle, identity, parameter1, parameter2); } return 0; } handle stretch_the_bitmap(handle bitmap1) { handle device_context = create_informational_device_context(L"DISPLAY", (const character*)null, (const character*)null, (const device_mode<character>*)null); text_metrics<character> text_metrics_get; get_text_metrics(device_context, &text_metrics_get); handle memory_device1 = create_memory_device_context(device_context); handle memory_device2 = create_memory_device_context(device_context); delete_device_context(device_context); bitmap_definition bitmap_definition1; get_object(bitmap1, sizeof(bitmap_definition), (character*)&bitmap_definition1); bitmap_definition bitmap_definition2 = bitmap_definition1; bitmap_definition2.width = (text_metrics_get.average_character_width * bitmap_definition2.width) / 4; bitmap_definition2.height = (text_metrics_get.height * bitmap_definition2.height) / 8; bitmap_definition2.bytes = ((bitmap_definition2.width + 15) / 16) * 2; handle bitmap2 = create_bitmap_indirect(&bitmap_definition2); select_object(memory_device1, bitmap1); select_object(memory_device2, bitmap2); stretch_bit_block_transfer(memory_device2, 0, 0, bitmap_definition2.width, bitmap_definition2.height, memory_device1, 0, 0, bitmap_definition1.width, bitmap_definition1.height, raster_operation::source_copy); delete_device_context(memory_device1); delete_device_context(memory_device2); delete_object(bitmap1); return bitmap2; } handle get_font_bitmap(int i) { character courier[50]; character arial[50]; character times[50]; load_string(0, StringCourier, courier, 50); load_string(0, StringArial, arial, 50); load_string(0, StringTimes, times, 50); character* face_names[3] = { courier,arial,times }; handle device_context = create_informational_device_context(L"DISPLAY", (const character*)null, (const character*)null, (const device_mode<character>*)null); text_metrics<character> text_metrics_get; get_text_metrics(device_context, &text_metrics_get); logical_font<character> logical_font_create; logical_font_create.height = 2 * text_metrics_get.height; copy_string((character*)logical_font_create.face_name, face_names[i]); handle memory_device = create_memory_device_context(device_context); handle font = (handle)select_object(memory_device, create_font_indirect(&logical_font_create)); idimensions text; get_text_extent(memory_device, face_names[i], string_length(face_names[i]), &text); handle bitmap = create_bitmap(text(0), text(1), 1, 1, (handle)null); select_object(memory_device, bitmap); text_out(memory_device, 0, 0, face_names[i], string_length(face_names[i])); delete_object(select_object(memory_device, font)); delete_device_context(memory_device); delete_device_context(device_context); return bitmap; }