Как в OpenEdge ABL / Progress 4GL получить триггер RIGHT-MOUSE-CLICK для выполнения щелчка левой кнопкой мыши по умолчанию, чтобы переместить фокус
Я использую OpenEdge ABL / Progress 4GL. У меня есть виджет браузера, заполненный строками. Когда я щелкаю левой кнопкой мыши по строке, строка выделяется, и эта строка теперь находится в фокусе. Я хочу, чтобы, когда я щелкаю правой кнопкой мыши по другой строке для прогресса, выполнял "щелчок левой кнопкой мыши" (чтобы переместить фокус на строку, по которой щелкнули правой кнопкой мыши), а затем щелкаю правой кнопкой мыши.
4 ответа
Я уже ответил на этот вопрос здесь: как в OpenEdge ABL / Progress 4GL найти идентификатор строки, по которой в браузере щелкнули правой кнопкой мыши.
Я не уверен, какова политика с этим дублирующим вопросом, но я повторяю свой ответ здесь, я надеюсь, что все в порядке.
У меня была похожая ситуация; Я хотел ответить на щелчок правой кнопкой мыши в обзоре. Щелчок правой кнопкой мыши не выбирает строку, по которой вы щелкаете, поэтому мне пришлось программно выяснить, какой это была строка. Приведенная ниже кодировка определяет, по какой строке вы щелкнули, и выберет ее. Боюсь, это действительно так сложно.
Это происходит в событии MOUSE-MENU-DOWN просмотра:
DEFINE VARIABLE iRowHeight AS INTEGER NO-UNDO.
DEFINE VARIABLE iLastY AS INTEGER NO-UNDO.
DEFINE VARIABLE iRow AS INTEGER NO-UNDO.
DEFINE VARIABLE hCell AS HANDLE NO-UNDO.
DEFINE VARIABLE iTopRowY AS INTEGER NO-UNDO.
/* See if there are ANY rows in view... */
IF SELF:NUM-ITERATIONS = 0 THEN
DO:
/* No rows, the user clicked on an empty browse widget */
RETURN NO-APPLY.
END.
/* We don't know which row was clicked on, we have to calculate it from the mouse coordinates and the row heights. No really. */
SELF:SELECT-ROW(1). /* Select the first row so we can get the first cell. */
hCell = SELF:FIRST-COLUMN. /* Get the first cell so we can get the Y coord of the first row, and the height of cells. */
iTopRowY = hCell:Y - 1. /* The Y coord of the top of the top row relative to the browse widget. Had to subtract 1 pixel to get it accurate. */
iRowHeight = hCell:HEIGHT-PIXELS. /* SELF:ROW-HEIGHT-PIXELS is not the same as hCell:HEIGHT-PIXELS for some reason */
iLastY = LAST-EVENT:Y. /* The Y position of the mouse event (relative to the browse widget) */
/* calculate which row was clicked. Truncate so that it doesn't round clicks past the middle of the row up to the next row. */
iRow = 1 + TRUNCATE((iLastY - iTopRowY) / iRowHeight, 0).
IF iRow > 0 AND iRow <= SELF:NUM-ITERATIONS THEN
DO:
/* The user clicked on a populated row */
Your coding here, for example:
SELF:SELECT-ROW(iRow).
END.
ELSE DO:
/* The click was on an empty row. */
SELF:DESELECT-ROWS().
RETURN NO-APPLY.
END.
Надеюсь, это поможет.
Проверьте Справочник ABL для событий мыши (стр. 1834 Справочного руководства ABL 10.2B).
Обычный метод состоит в том, чтобы захватить рассматриваемое событие с "ON event-name OF widget-name", затем применить другое событие к виджету (APPLY "mouse-select-click" к b-name), а затем сказать AVM игнорировать оригинальное событие с "ВОЗВРАЩЕНИЕ НЕТ ПРИМЕНЕНИЯ".
Это будет выглядеть примерно так:
ON MOUSE-MENU-CLICK OF b-name
DO:
APPLY "mouse-select-click" TO SELF.
RETURN NO-APPLY.
END.
Предостережение: я не уверен, какое событие вызывает щелчок правой кнопкой мыши, поэтому вам нужно будет адаптировать этот код в соответствии с требованиями.
Чтобы расширить основной ответ, вот несколько дополнительных заметок и пример кода.
1. Вы должны знать высоту заголовков и заголовка.
2. Вы можете динамически прикрепить меню, если у вас были стандартные функции просмотра.
3. Multi-Select браузеры действуют немного по-другому.
ON 'right-mouse-down':U ANYWHERE DO:
RUN set_focus (SELF).
IF SELF:TYPE = 'BROWSE' THEN DO:
RETURN NO-APPLY.
END.
ELSE DO:
APPLY 'menu-drop' TO SELF.
END.
END.
PROCEDURE set_focus.
DEF INPUT PARAM i_object AS HANDLE NO-UNDO.
DEF VAR l_was_row_one_selected AS LOG NO-UNDO.
DEF VAR l_header_y AS DEC NO-UNDO.
DEF VAR w_browse_title_bar_height AS DEC NO-UNDO INITIAL 19. /* determine this for your UI */
DEF VAR o_labels AS CHAR NO-UNDO.
DEF VAR o_procedures AS CHAR NO-UNDO.
DEF VAR h_menu AS HANDLE NO-UNDO.
DEF VAR h_menu_item AS HANDLE NO-UNDO.
DEF VAR l_count AS INT NO-UNDO.
/* given an object ... */
IF i_object:TYPE = 'browse' THEN DO:
IF i_object:NUM-SELECTED-ROWS = 0
THEN ASSIGN l_was_row_one_selected = FALSE.
ELSE ASSIGN l_was_row_one_selected = i_object:IS-ROW-SELECTED(1) NO-ERROR.
i_object:SELECT-ROW(1) NO-ERROR.
IF ERROR-STATUS:ERROR THEN RETURN.
l_header_y = MAX(1,i_object:FIRST-COLUMN:Y). /* in case there are no column headers */
IF i_object:TITLE <> ? THEN l_header_y = l_header_y - w_browse_title_bar_height.
IF l_was_row_one_selected = FALSE THEN i_object:DESELECT-SELECTED-ROW(1) NO-ERROR.
/* this section selects the correct row, based on where it was clicked, minus the height of the headers divided by row height */
i_object:SELECT-ROW(
INT(
1 +
TRUNC(
(LAST-EVENT:Y - l_header_y) / i_object:FIRST-COLUMN:HEIGHT-PIXELS
,0)
)
)
NO-ERROR.
APPLY 'ENTRY':u TO i_object. /* to get focus properly */
APPLY 'VALUE-CHANGED':u TO i_object.
/* use some rule to find associated dynamic menu items, e.g. maintenance options, finding related data*/
RUN find_menu_stuff (i_object:NAME, OUTPUT o_labels, OUTPUT o_procedures).
IF o_labels = '' THEN RETURN.
/* this finds a popup menu, if any */
h_menu = i_object:POPUP-MENU NO-ERROR.
IF VALID-HANDLE(h_menu) THEN RETURN. /* already created previously */
/* create a popup menu */
CREATE MENU h_menu.
ASSIGN
h_menu:POPUP-ONLY = TRUE
i_object:POPUP-MENU = h_menu
.
/* add the standard maintenance options (they still may not be supported though) */
DO l_count = 1 TO NUM-ENTRIES (o_labels):
IF ENTRY(l_count,o_labels) = 'Rule' THEN DO:
CREATE MENU-ITEM h_menu_item
ASSIGN
SUBTYPE = 'RULE'
PARENT = h_menu
.
END.
ELSE DO:
CREATE MENU-ITEM h_menu_item
ASSIGN
PARENT = h_menu
LABEL = ENTRY(l_count,o_labels)
SENSITIVE = TRUE
TRIGGERS:
ON CHOOSE PERSISTENT RUN pp_apply_maint_action IN THIS-PROCEDURE (SELF, ENTRY(l_count,o_procedures)).
END TRIGGERS.
END.
END.
END.
IF VALID-HANDLE(h_menu)
THEN APPLY 'menu-drop' TO h_menu.
/* MENU-DROP - Supported only when the POPUP-ONLY attribute is set to TRUE and the
menu is set as a popup for some other widget */
END PROCEDURE.
PROCEDURE find_menu_stuff.
/* do lookups or other general or specific things here */
END.
По сути, вы должны определить триггер следующим образом:
ON RIGHT-MOUSE-CLICK OF myBrowseRow DO:
APPLY "ENTRY" TO myBrowse IN FRAME myFrame.
/* Code to focus a particular row in the browse. */
APPLY "ENTRY" TO SELF IN BROWSE myBrowse.
END.
Проблема может заключаться в том, что вам придется добавить этот триггер к каждой строке в обзоре, потому что AFAIK невозможно определить, какая строка была нажата правой кнопкой мыши, если вы установите триггер только для самого просмотра...