How to make EV_COMBO_BOX release focus?

50 views
Skip to first unread message

Thomas Beale

unread,
Dec 2, 2024, 2:25:24 PM12/2/24
to Eiffel Users
I have a piece of code that associates some actions with an EV_COMBO_BOX, such that typing a string (a search key) and hitting return should run a search on an EV_RICH_TEXT control; if the key is found, the control gains focus, and the matching text is highlighted. The code is as follows.

make
do
-- create controls
create ev_root_container
create ev_search_combo

-- connect controls
ev_root_container.extend (ev_search_combo)

-- set up events
ev_search_combo.select_actions.extend (agent select_item_from_search_key)
ev_search_combo.return_actions.extend (agent find_item_by_key)
end

ev_search_combo: EV_COMBO_BOX

In the debugger I can verify that this logic works correctly, and at some point, the text is shown highlighted in the rich text pane.

However, further processing occurs on the EV_COMBO_BOX, such that focus is returned to the combo box, and the text selection in the rich text disappears.

When I debug, I discover that there is event processing for the class EV_INTERNAL_COMBO_FIELD_IMP on_key_down, which first calls EV_COMBO_BOX.on_key_down (which is what calls my routine, i.e. does the intended work) as 'parent', and then calls EV_INTERNAL_COMBO_FIELD_IMP.on_key_down, performing 'default processing'. Apparently, 'default processing' for this is to grab focus again, and select the typed in text.

THis is EV_INTERNAL_COMBO_FIELD_IMP.on_key_down - you can see it invokes parent.on_key_down (starred), where parent will be the EV_COMBO_BOX_IMP:

on_key_down (virtual_key, key_data: INTEGER_32)
-- Executed when a key is pressed.
-- We verify that there is indeed a command to avoid
-- the creation of an object for nothing.
-- (export status {NONE})
require -- from WEL_WINDOW
exists: exists
do
if not (virtual_key = {WEL_VK_CONSTANTS}.vk_down or virtual_key = {WEL_VK_CONSTANTS}.vk_up) then
parent.increment_level;
parent.on_key_down (virtual_key, key_data) *******
if parent.has_return_value then
set_message_return_value (parent.message_return_value)
end
if not parent.default_processing then
disable_default_processing
end;
parent.decrement_level
end
end

This exits, and we end up in WEL_DISPATCHER at the starred line:

if window.exists then
debug ("win_dispatcher")
print ("After look at windows table ")
print (window.generating_type);
Io.put_new_line
end;
window.increment_level
need_decrement := True
Result := window.process_message (hwnd, msg, wparam, lparam)
if window.has_return_value then   ************
returned_value := window.message_return_value
has_return_value := window.has_return_value
end
if window.default_processing then
Result := window.call_default_window_procedure (hwnd, msg, wparam, lparam) ++++++++++++++
end

This falls through to the line marked with ++++, which causes focus to return to the combo box.

THere is no obvious mechanism that I can find that allows the action of hitting Return in the combo box to result just in doing the intended work and leaving focus in the intended place (a text pane). 

Does anyone know a solution?

Eric Bezault

unread,
Dec 2, 2024, 2:46:28 PM12/2/24
to eiffel...@googlegroups.com, Thomas Beale
An ugly workaround could be to let `select_item_from_search_key`
and `find_item_by_key` add an action on idle (I don't remember
the exact routine name) to force again the focus on the rich text
after the default_processing took place.

--
Eric Bezault
mailto:er...@gobosoft.com
http://www.gobosoft.com
> --
> You received this message because you are subscribed to the Google
> Groups "Eiffel Users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to eiffel-users...@googlegroups.com
> <mailto:eiffel-users...@googlegroups.com>.
> To view this discussion visit
> https://groups.google.com/d/msgid/eiffel-users/4649bffd-e962-434d-82a3-1b76bc83776fn%40googlegroups.com <https://groups.google.com/d/msgid/eiffel-users/4649bffd-e962-434d-82a3-1b76bc83776fn%40googlegroups.com?utm_medium=email&utm_source=footer>.

Thomas Beale

unread,
Dec 2, 2024, 3:06:20 PM12/2/24
to Eiffel Users
I did think of that kind of thing, and it's probably my default approach if nothing better appears here. Obviously I'd like to avoid obscure solutions...

rfo amalasoft.com

unread,
Dec 2, 2024, 3:35:50 PM12/2/24
to eiffel...@googlegroups.com
It's not really that "ugly".  You're posting an event for later (asynch) processing to implement your specific logic after the built-in logic has a chance to complete.  At least that's the rationalization I use 🙂
R

From: eiffel...@googlegroups.com <eiffel...@googlegroups.com> on behalf of Thomas Beale <wolan...@gmail.com>
Sent: Monday, December 2, 2024 3:06 PM
To: Eiffel Users <eiffel...@googlegroups.com>
Subject: Re: [eiffel-users] How to make EV_COMBO_BOX release focus?
 
To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/eiffel-users/d9fc2f49-fd48-4bd2-9c73-80fee74ef99en%40googlegroups.com.

Thomas Beale

unread,
Dec 3, 2024, 3:02:57 PM12/3/24
to Eiffel Users
It's at least a bit ugly, since it violates the principle of least surprise, but it's not terrible. I discovered that to properly detect change in position of the carat in an EV_TEXT of any kind, you have to do the same thing after receiving a keypress (e.g. arrows) or mouse button click. For the edification of anyone who cares, use this kind of pattern:

event_receive_and_set_up (args)
-- set up to do something on receipt of an event
do
....
ev_application.add_idle_action_kamikaze (agent do_the_work)
....
end

        do_the_work
do
....
end

The kamikaze form of that call is used to do once-only processing, which is usually what you want.
Reply all
Reply to author
Forward
0 new messages