Как в 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 невозможно определить, какая строка была нажата правой кнопкой мыши, если вы установите триггер только для самого просмотра...

Другие вопросы по тегам