note description: "EiffelVision screen, implementation interface." legal: "See notice at end of class." status: "See notice at end of class." date: "$Date$" revision: "$Revision$" class EV_SCREEN_IMP inherit EV_SCREEN_I redefine interface, virtual_width, virtual_height, virtual_x, virtual_y, monitor_count, monitor_area_from_position, monitor_area_from_window, working_area_from_position, working_area_from_window, refresh_graphics_context, widget_at_mouse_pointer end EV_DRAWABLE_IMP redefine interface, destroy, make end WEL_INPUT_EVENT export {NONE} all end WEL_UNIT_CONVERSION rename horizontal_resolution as wel_horizontal_resolution, vertical_resolution as wel_vertical_resolution export {NONE} all end create make feature -- Initialization old_make (an_interface: attached like interface) -- Create `Current', a screen object. do assign_interface (an_interface) end make -- Initialize `Current' do create dc dc.get Precursor end feature -- Access dc: WEL_SCREEN_DC -- DC for drawing. feature -- Status report destroyed: BOOLEAN -- Is `Current' destroyed? do Result := not dc.exists end pointer_position: EV_COORDINATE -- Position of the screen pointer. local wel_point: WEL_POINT do wel_point := reusable_wel_point wel_point.set_cursor_position create Result.set (wel_point.x, wel_point.y) end widget_at_mouse_pointer: detachable EV_WIDGET -- local wel_point: WEL_POINT do wel_point := reusable_wel_point wel_point.set_cursor_position Result := widget_at_position (wel_point.x, wel_point.y) end widget_at_position (x, y: INTEGER): detachable EV_WIDGET -- Widget at position (`x', `y') if any. local l_window: detachable WEL_WINDOW wel_point: WEL_POINT widget_imp: detachable EV_WIDGET_IMP internal_combo_box: detachable EV_INTERNAL_COMBO_BOX_IMP internal_combo_field: detachable EV_INTERNAL_COMBO_FIELD_IMP do -- Assign the cursor position to `wel_point'. wel_point := reusable_wel_point wel_point.set_x_y (x, y) -- Retrieve WEL_WINDOW at `wel_point'. l_window := wel_point.window_at -- If there is a window at `wel_point'. widget_imp ?= l_window if widget_imp /= Void then -- Result is interface of `widget_imp'. Result := widget_imp.interface else -- Combo boxes must be handled as a special case, as -- they are comprised of two widgets. internal_combo_box ?= l_window if internal_combo_box /= Void then Result := internal_combo_box.parent.interface else internal_combo_field ?= l_window if internal_combo_field /= Void then Result := internal_combo_field.parent.interface end end end end monitor_area_from_position (a_x, a_y: INTEGER): EV_RECTANGLE -- local l_wel_mon: POINTER l_mon_info: WEL_MONITOR_INFO l_rect: WEL_RECT l_success: BOOLEAN do create l_rect.make (a_x, a_y, a_x, a_y) l_wel_mon := {WEL_API}.monitor_from_rect (l_rect.item, monitor_defaulttonearest) create l_mon_info.make l_success := {WEL_API}.get_monitor_info (l_wel_mon, l_mon_info.item) if l_success then l_rect := l_mon_info.monitor_area create Result.make (l_rect.x, l_rect.y, l_rect.width, l_rect.height) else -- Use fallback implementation to return the primary monitor. Result := Precursor (a_x, a_y) end end monitor_area_from_window (a_window: EV_WINDOW): EV_RECTANGLE -- local l_wel_mon: POINTER l_mon_info: WEL_MONITOR_INFO l_window_imp: detachable EV_WINDOW_IMP l_rect: WEL_RECT l_success: BOOLEAN do l_window_imp ?= a_window.implementation check l_window_imp_attached: l_window_imp /= Void then end -- Use window handle if displayed, otherwise use coordinates from window. if a_window.is_displayed then l_wel_mon := {WEL_API}.monitor_from_window (l_window_imp.wel_item, monitor_defaulttonearest) else create l_rect.make (l_window_imp.x_position, l_window_imp.y_position, l_window_imp.x_position + l_window_imp.width, l_window_imp.y_position + l_window_imp.height) l_wel_mon := {WEL_API}.monitor_from_rect (l_rect.item, monitor_defaulttonearest) end create l_mon_info.make l_success := {WEL_API}.get_monitor_info (l_wel_mon, l_mon_info.item) if l_success then l_rect := l_mon_info.monitor_area create Result.make (l_rect.x, l_rect.y, l_rect.width, l_rect.height) else -- Use fallback implementation to return the primary monitor. Result := Precursor (a_window) end end working_area_from_position (a_x, a_y: INTEGER): EV_RECTANGLE -- local l_wel_mon: POINTER l_mon_info: WEL_MONITOR_INFO l_rect: WEL_RECT l_success: BOOLEAN do create l_rect.make (a_x, a_y, a_x, a_y) l_wel_mon := {WEL_API}.monitor_from_rect (l_rect.item, monitor_defaulttonearest) create l_mon_info.make l_success := {WEL_API}.get_monitor_info (l_wel_mon, l_mon_info.item) if l_success then l_rect := l_mon_info.working_area create Result.make (l_rect.x, l_rect.y, l_rect.width, l_rect.height) else -- Use fallback implementation to return the primary monitor. Result := Precursor (a_x, a_y) end end working_area_from_window (a_window: EV_WINDOW): EV_RECTANGLE -- local l_wel_mon: POINTER l_mon_info: WEL_MONITOR_INFO l_window_imp: detachable EV_WINDOW_IMP l_rect: WEL_RECT l_success: BOOLEAN do l_window_imp ?= a_window.implementation check l_window_imp_attached: l_window_imp /= Void then end -- Use window handle if displayed, otherwise use coordinates from window. if a_window.is_displayed then l_wel_mon := {WEL_API}.monitor_from_window (l_window_imp.wel_item, monitor_defaulttonearest) else create l_rect.make (l_window_imp.x_position, l_window_imp.y_position, l_window_imp.x_position + l_window_imp.width, l_window_imp.y_position + l_window_imp.height) l_wel_mon := {WEL_API}.monitor_from_rect (l_rect.item, monitor_defaulttonearest) end create l_mon_info.make l_success := {WEL_API}.get_monitor_info (l_wel_mon, l_mon_info.item) if l_success then l_rect := l_mon_info.working_area create Result.make (l_rect.x, l_rect.y, l_rect.width, l_rect.height) else -- Use fallback implementation to return the primary monitor. Result := Precursor (a_window) end end monitor_defaulttonull: INTEGER = 0 monitor_defaulttoprimary: INTEGER = 1 monitor_defaulttonearest: INTEGER = 2 -- Win32 API Monitor default return constant values. feature -- Basic operation set_pointer_position (x, y: INTEGER) -- do cwin_set_cursor_position (x, y) end set_default_colors -- Set foreground and background color to their default values. local a_default_colors: EV_STOCK_COLORS do create a_default_colors set_background_color (a_default_colors.default_background_color) set_foreground_color (a_default_colors.default_foreground_color) end fake_pointer_button_press (a_button: INTEGER) -- Simulate the user pressing a `a_button' -- on the pointing device. do inspect a_button when 1 then send_mouse_left_button_down when 2 then send_mouse_right_button_down when 3 then send_mouse_middle_button_down end end fake_pointer_button_release (a_button: INTEGER) -- Simulate the user releasing a `a_button' -- on the pointing device. do inspect a_button when 1 then send_mouse_left_button_up when 2 then send_mouse_right_button_up when 3 then send_mouse_middle_button_up end end fake_pointer_wheel_up -- Simulate the user rotating the mouse wheel up. do send_mouse_wheel_up end fake_pointer_wheel_down -- Simulate the user rotating the mouse wheel down. do send_mouse_wheel_down end fake_key_press (a_key: EV_KEY) -- Simulate the user pressing `a_key'. local vk_code: INTEGER do vk_code := Key_conversion.key_code_to_wel(a_key.code) send_keyboard_key_down (vk_code) end fake_key_release (a_key: EV_KEY) -- Simulate the user releasing `a_key'. local vk_code: INTEGER do vk_code := Key_conversion.key_code_to_wel(a_key.code) send_keyboard_key_up (vk_code) end feature -- Measurement width: INTEGER -- Width of `Current'. do Result := dc.width end height: INTEGER -- Height of `Current'. do Result := dc.height end virtual_width: INTEGER -- Virtual width of `Current' do Result := system_metrics_constants.virtual_screen_width end virtual_height: INTEGER -- Virtual height of `Current' do Result := system_metrics_constants.virtual_screen_height end virtual_x: INTEGER -- X position of virtual screen in main display coordinates do Result := system_metrics_constants.virtual_screen_x end virtual_y: INTEGER -- Y position of virtual screen in main display coordinates do Result := system_metrics_constants.virtual_screen_y end monitor_count: INTEGER -- Number of monitors used for displaying the screen. do Result := system_metrics_constants.monitor_count end vertical_resolution: INTEGER -- Number of pixels per inch along screen height. do Result := get_device_caps (dc.item, logical_pixels_y) end horizontal_resolution: INTEGER -- Number of pixels per inch along screen width. do Result := get_device_caps (dc.item, logical_pixels_x) end redraw -- Force screen to redraw itself. do {WEL_WINDOW}.cwin_invalidate_rect (default_pointer, default_pointer, False) end feature -- Status setting destroy -- Destroy actual object. do dc.release Precursor {EV_DRAWABLE_IMP} end feature -- Implementation refresh_graphics_context -- do -- Reacquire the dc and reset any set values. dc.release dc.get set_drawing_mode (drawing_mode) if dashed_line_style then enable_dashed_line_style else disable_dashed_line_style end if background_color_internal /= Void then set_background_color (background_color) end if foreground_color_internal /= Void then set_foreground_color (foreground_color) end end interface: detachable EV_SCREEN note option: stable attribute end feature {NONE} -- Constants System_metrics_constants: WEL_SYSTEM_METRICS -- System metrics constants. once create Result end Key_conversion: EV_WEL_KEY_CONVERSION -- Key conversion routines. once create Result end feature {NONE} -- Implementation reusable_wel_point: WEL_POINT -- Reusable wel point object to avoid creating a new object for temporary use. once create Result.make (0, 0) end invariant dc_not_void: dc /= Void note copyright: "Copyright (c) 1984-2018, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end