// win+ -- clover.cpp -- Clover Drawing Program using Regions import iplusplus; using nanespace core; import std.core; #define two_pi (2.0 * 3.14159) result __stdcall client(handle, unsigned, parameter, parameter); int __stdcall WinMain(handle module_handle, handle previous, character* command, int show_command) { window_classwclass; 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"Clover"; atom atom_name = register_class(&wclass); handle window = create_window(atom_name, L"Draw a Clover"); show_window(window, show_command); 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 clipping_region; int width_of_client, height_of_client; }; 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); } break; case message::destroy: { window_data* data = (window_data*)get_window_pointer(window_handle, 0); delete_object(data->clipping_region); delete data; } break; case message::size: { window_data* data = (window_data*)get_window_pointer(window_handle, 0); data->width_of_client = low_part(parameter2); data->height_of_client = high_part(parameter2); if (data->clipping_region) delete_object(data->clipping_region); handle region_array[6]; region_array[0] = create_elliptic_region(0, data->height_of_client / 3, data->width_of_client / 2, 2 * data->height_of_client / 3); region_array[1] = create_elliptic_region(data->width_of_client / 2, data->height_of_client / 3, data->width_of_client, 2 * data->height_of_client / 3); region_array[2] = create_elliptic_region(data->width_of_client / 3, 0, 2 * data->width_of_client / 3, data->height_of_client / 2); region_array[3] = create_elliptic_region(data->width_of_client / 3, data->height_of_client / 2, 2 * data->width_of_client / 3, data->height_of_client); region_array[4] = create_rectangular_region(0, 0, 1, 1); region_array[5] = create_rectangular_region(0, 0, 1, 1); data->clipping_region = create_rectangular_region(0, 0, 1, 1); combine_region(region_array[4], region_array[0], region_array[1], region_combine:: _or ); combine_region(region_array[5], region_array[2], region_array[3], region_combine:: _or ); combine_region(data->clipping_region, region_array[4], region_array[5], region_combine::exclusive_or); for (int i = 0; i < 6; i++) delete_object(region_array[i]); } break; case message::paint: { window_data* data = (window_data*)get_window_pointer(window_handle, 0); paint paint_structure; handle device_context = begin_paint(window_handle, &paint_structure); set_viewport_origin(device_context, data->width_of_client / 2, data->height_of_client / 2); select_clipping_region(device_context, data->clipping_region); double radius = sqrt(data->width_of_client * data->width_of_client / 2.0 + data->height_of_client * data->height_of_client / 2.0); for (double Angle = 0; Angle < two_pi; Angle += two_pi / 360) { move_to(device_context, 0, 0); draw_line_to(device_context, (int)(radius * cos(Angle) + 0.5), (int)(-radius * sin(Angle) + 0.5)); } end_paint(window_handle, &paint_structure); } break; case message::close: post_quit_message(); break; default: return default_window_procedure(window_handle, identity, parameter1, parameter2); } return 0; }