#include "../tdkpin_window_messages.h" #include Win16FarPtr g_object_windows_application; HINSTANCE16 g_win16_previous_instance; HINSTANCE16 g_win16_instance; uint16_t g_win16_show_command; Win16FarPtr g_win16_message_box; Win16FarPtr g_object_windows_dispatch_proc; uint16_t g_object_windows_thunk_code_selector; Win16FarPtr g_object_windows_free_thunk; Win16FarPtr g_object_windows_message_hook; Win16FarPtr g_object_windows_creating_object; static HWND16 g_dialog_item; static uint16_t g_dlg_code; static HWND16 g_focus; static HWND16 g_parent; static unsigned g_parent_calls; static HWND16 g_lookup_window; static Win16FarPtr g_window_object; static Win16FarPtr g_child_object; static Win16FarPtr g_called_proc; static Win16FarPtr g_called_object; static ObjectWindowsMessage *g_called_message; static uint16_t g_window_word; HWND16 GetDlgItem16(HWND16 dialog, INT16 control_id) { assert(dialog == 0x77); (void)control_id; return g_dialog_item; } LRESULT16 SendMessage16( HWND16 window, UINT16 message, WPARAM16 wparam, LPARAM16 lparam) { assert(window == g_dialog_item && message == 0x87); assert(wparam == 0 && lparam == 0); return g_dlg_code; } HWND16 GetFocus16(void) { return g_focus; } HWND16 GetParent16(HWND16 window) { assert(window == g_focus); g_parent_calls++; return g_parent; } BOOL16 IsWindow16(HWND16 window) { g_lookup_window = window; return window != 0; } int32_t GetWindowLong16(HWND16 window, INT16 index) { assert(window != 0 && index == -4); return (int32_t)win16_make_far_pointer(0x6000, 0x0100); } Win16Handle GetProp16(HWND16 window, Win16FarPtr name) { Win16FarPtr object = window == 0x55 ? g_child_object : 0; return win16_far_offset(name) == 0x067a ? win16_far_selector(object) : win16_far_offset(object); } uint16_t GetWindowWord16(HWND16 window, INT16 index) { assert(window != 0 && index == -12); return g_window_word; } void win16_call_object_event_handler( Win16FarPtr procedure, Win16FarPtr object, Win16FarPtr event) { g_called_proc = procedure; g_called_object = object; g_called_message = (ObjectWindowsMessage *)(uintptr_t)event; } void win16_call_object_message_handler( Win16FarPtr procedure, Win16FarPtr object, ObjectWindowsMessage *message) { g_called_proc = procedure; g_called_object = object; g_called_message = message; } void win16_call_object_message_hook( Win16FarPtr procedure, Win16FarPtr object, Win16FarPtr handler, HWND16 window, UINT16 message, WPARAM16 wparam, LPARAM16 lparam) { (void)procedure; (void)object; (void)handler; (void)window; (void)message; (void)wparam; (void)lparam; assert(false); } static void write_far(uint16_t offset, Win16FarPtr pointer) { win16_write_u16( win16_dgroup_pointer(offset), 0, win16_far_offset(pointer)); win16_write_u16( win16_dgroup_pointer((uint16_t)(offset + 2)), 0, win16_far_selector(pointer)); } static void write_dispatch_table( uint16_t vmt, uint16_t table, uint16_t id, Win16FarPtr handler) { win16_write_u16(win16_dgroup_pointer((uint16_t)(vmt + 4)), 0, table); win16_write_u16(win16_dgroup_pointer(table), 0, 0); win16_write_u16(win16_dgroup_pointer((uint16_t)(table + 2)), 0, 0xffff); win16_write_u16(win16_dgroup_pointer((uint16_t)(table + 4)), 0, 0xffff); win16_write_u16(win16_dgroup_pointer((uint16_t)(table + 6)), 0, 1); win16_write_u16(win16_dgroup_pointer((uint16_t)(table + 8)), 0, id); write_far((uint16_t)(table + 10), handler); } static void reset_call(void) { g_called_proc = 0; g_called_object = 0; g_called_message = 0; g_dialog_item = 0; g_dlg_code = 0; g_focus = 0; g_parent = 0; g_parent_calls = 0; } int main(void) { static uint8_t dgroup[0x1000]; static uint8_t code[0x200]; static uint8_t stack[0x100]; static uint8_t window_bytes[64]; static uint8_t child_bytes[64]; win16_reset_segment_bindings(); win16_bind_segment(0x5000, dgroup, sizeof(dgroup), true); win16_set_dgroup_selector(0x5000); win16_bind_segment(0x6000, code, sizeof(code), false); win16_bind_segment(0x7000, window_bytes, sizeof(window_bytes), true); win16_bind_segment(0x7100, child_bytes, sizeof(child_bytes), true); win16_bind_segment(0x7200, stack, sizeof(stack), true); g_window_object = win16_make_far_pointer(0x7000, 2); g_child_object = win16_make_far_pointer(0x7100, 2); uint16_t window_vmt = 0x0100; uint16_t child_vmt = 0x0200; win16_write_u16(g_window_object, 0, window_vmt); win16_write_u16(g_child_object, 0, child_vmt); win16_write_u16(g_window_object, 4, 0x77); Win16FarPtr menu_handler = win16_make_far_pointer(0x6100, 0x1000); Win16FarPtr control_handler = win16_make_far_pointer(0x6100, 0x2000); Win16FarPtr notify_handler = win16_make_far_pointer(0x6100, 0x3000); Win16FarPtr default_handler = win16_make_far_pointer(0x6100, 0x4000); Win16FarPtr default_control = win16_make_far_pointer(0x6100, 0x5000); write_dispatch_table(window_vmt, 0x0300, 0x8005, control_handler); write_dispatch_table(child_vmt, 0x0340, 0xa010, menu_handler); /* Parent table supplies the notification id as a second node. */ win16_write_u16(win16_dgroup_pointer(0x0340), 0, 0x0380); win16_write_u16(win16_dgroup_pointer(0x0380), 0, 0); win16_write_u16(win16_dgroup_pointer(0x0382), 0, 0xffff); win16_write_u16(win16_dgroup_pointer(0x0384), 0, 0xffff); win16_write_u16(win16_dgroup_pointer(0x0386), 0, 1); win16_write_u16(win16_dgroup_pointer(0x0388), 0, 0x9002); write_far(0x038a, notify_handler); write_far((uint16_t)(window_vmt + 0x0c), default_handler); write_far((uint16_t)(window_vmt + 0x14), default_control); write_far((uint16_t)(window_vmt + 0x10), default_handler); write_far((uint16_t)(child_vmt + 0x10), default_handler); write_far((uint16_t)(child_vmt + 0x18), default_handler); write_far((uint16_t)(child_vmt + 0x14), default_control); ObjectWindowsMessage *message = (ObjectWindowsMessage *)&stack[16]; Win16FarPtr message_far = win16_make_far_pointer(0x7200, 16); (void)message_far; reset_call(); *message = (ObjectWindowsMessage){.wparam = 0x0010, .lparam = 0}; g_focus = 0x66; g_parent = 0x55; object_windows_wm_command(g_window_object, message); assert(g_parent_calls == 1 && g_lookup_window == 0x55); assert(g_called_proc == menu_handler && g_called_object == g_child_object); reset_call(); *message = (ObjectWindowsMessage){.wparam = 0x6000, .lparam = 0}; object_windows_wm_command(g_window_object, message); assert(g_called_proc == default_handler && g_called_object == g_window_object); reset_call(); *message = (ObjectWindowsMessage){ .wparam = 0x0100, .lparam = (LPARAM16)0x00020055u, }; g_dialog_item = 0x55; object_windows_wm_command(g_window_object, message); assert(g_called_proc == notify_handler && g_called_object == g_child_object); reset_call(); *message = (ObjectWindowsMessage){.wparam = 5, .lparam = 0x66}; object_windows_wm_command(g_window_object, message); assert(g_called_proc == control_handler && g_called_object == g_window_object); reset_call(); *message = (ObjectWindowsMessage){.wparam = 0x1000, .lparam = 0x66}; object_windows_wm_command(g_window_object, message); assert(g_called_proc == default_control && g_called_object == g_window_object); reset_call(); win16_write_u8(win16_far_add_offset(g_window_object, 0x16), 1); *message = (ObjectWindowsMessage){.wparam = 0x0100, .lparam = 0}; g_dialog_item = 0x55; g_dlg_code = 0x30; object_windows_wm_command(g_window_object, message); assert((uint16_t)message->lparam == 0x55); assert(g_called_proc == default_handler); assert(g_called_object == g_child_object); reset_call(); *message = (ObjectWindowsMessage){.wparam = 2, .lparam = 0}; object_windows_route_scroll_notification(g_window_object, message); assert(g_called_proc == default_handler); reset_call(); *message = (ObjectWindowsMessage){ .wparam = 2, .lparam = (LPARAM16)0x00550000u, }; object_windows_route_scroll_notification(g_window_object, message); assert(g_called_proc == notify_handler && g_called_object == g_child_object); reset_call(); *message = (ObjectWindowsMessage){ .wparam = 2, .lparam = (LPARAM16)0x00660000u, }; g_window_word = 5; object_windows_route_scroll_notification(g_window_object, message); assert(g_called_proc == control_handler && g_called_object == g_window_object); reset_call(); *message = (ObjectWindowsMessage){ .wparam = 2, .lparam = (LPARAM16)0x00660000u, }; g_window_word = 0x1000; object_windows_route_scroll_notification(g_window_object, message); assert(g_called_proc == default_control && g_called_object == g_window_object); reset_call(); *message = (ObjectWindowsMessage){ .window = 0x77, .wparam = 0x0010, }; object_windows_route_command_target(g_window_object, message); assert(g_called_proc == default_handler && g_called_object == g_window_object); win16_write_u16(g_window_object, 6, win16_far_offset(g_child_object)); win16_write_u16(g_window_object, 8, win16_far_selector(g_child_object)); message->window = 0x66; object_windows_route_command_target(g_window_object, message); assert(g_called_proc == menu_handler && g_called_object == g_child_object); win16_write_u16(g_window_object, 6, 0); win16_write_u16(g_window_object, 8, 0); message->window = 0x55; object_windows_route_command_target(g_window_object, message); assert(g_called_proc == menu_handler && g_called_object == g_child_object); reset_call(); *message = (ObjectWindowsMessage){.message = 0x0111, .wparam = 5}; object_windows_forward_event_to_parent(g_window_object, message); assert(g_called_proc == 0); win16_write_u16(g_window_object, 6, win16_far_offset(g_child_object)); win16_write_u16(g_window_object, 8, win16_far_selector(g_child_object)); object_windows_forward_event_to_parent(g_window_object, message); assert(g_called_proc == default_control && g_called_object == g_child_object); reset_call(); *message = (ObjectWindowsMessage){.message = 2}; g_window_word = 5; object_windows_forward_event_to_parent(g_window_object, message); assert(g_called_proc == default_control && g_called_object == g_child_object); return 0; }