2012-02-14 2 views
3

Язык: Прогресс 10.1CКак программно управлять всплывающее меню на нескольких динамических виджетов Прогресс

У меня есть форма для Windows, и на нем я динамически создать несколько виджетов (Toggle-боксы в данном случае). Я могу создать что-нибудь от 0 до 64 виджетов, в зависимости от того, сколько пользовательских настроек в текущей коллекции. По мере того, как пользователь переходит из одной коллекции в другую, виджеты удаляются или создаются по мере необходимости. Форма будет изменяться в зависимости от количества отображаемых виджетов.

Пользователь может проверить любое количество из них и выполнить определенные процессы на проверенных элементах, выбрав действия из панели меню, панели инструментов или сочетаний клавиш. Но я также хочу, чтобы пользователь имел возможность щелкнуть правой кнопкой мыши по одному виджету, который должен вызывать всплывающее меню с действиями, которые могут выполняться только с одним нажатием, независимо от того, установлен он или нет.

Само по себе это довольно прямолинейно. Раньше я делал такие вещи (на других языках), имея одно всплывающее меню, которое появляется, когда пользователь нажимает на любой из динамических элементов управления. Но мне сложно справляться с этой простой вещью:

У меня нет одного всплывающего меню, которое отвечает на правый щелчок всех виджетов. Я попытался создать одно всплывающее меню, а затем, создав каждый динамический виджет, я установил в это меню свой атрибут всплывающего меню. Проблема в том, что меню можно применять только к одному виджету. Как только я назначил его Widget1, я не могу назначить его Widget2. Это заставляет думать о создании отдельного, но идентичного меню для каждого виджета. И поскольку виджеты уничтожаются и воссоздаются, так будут и эти меню. За один сеанс я создам и уничтожу сотни или даже тысячи этих одинаковых меню, в то время как пользователь может использовать один из них один или два раза. Или совсем нет. Так что это не похоже на хороший вариант для меня.

Моим следующим решением было бы создать единое меню, которое я могу запрограммировать, но все попытки программного всплытия меню завершились неудачно. Я попробовал ПРИМЕНИТЬ «МЕНЮ-ДРОП» К МЕНЮ MyMenu и другие подобные вещи, и я не могу для жизни понять, как это сделать. Мне также очень сложно найти информацию об этом. Как будто никто еще не пробовал этого, и редкие случаи, когда кто-то спрашивал об этом, не было удовлетворительных ответов. Я подозреваю, что этого не может быть сделано.

Пробуя все эти вещи, у меня также были бесконечные проблемы с событиями MOUSE-MENU-DOWN, MOUSE-MENU-UP и MOUSE-MENU-CLICK. MOUSE-MENU-CLICK, похоже, никогда не произойдет, а не для моих динамических виджетов. Я не могу понять, почему. Иногда MOUSE-MENU-UP происходит, но это зависит от того, что происходит в MOUSE-MENU-DOWN и других событиях виджетов, а также родителей виджетов. Я не смог точно определить, когда это будет или не будет срабатывать, это очень противоречиво. MOUSE-MENU-DOWN - единственное, что я могу рассчитывать на стрельбу.

Итак: я не могу показать меню программно, я могу показать его только, щелкнув правой кнопкой мыши на родительском меню. Единственный способ избежать сотен одинаковых меню - открыть всплывающее меню для родителя виджетов, например, по умолчанию.

Со статическим всплывающим меню на фрейме по умолчанию я могу щелкнуть правой кнопкой мыши на виджетах, и меню появится, но оно появится, если я щелкнул в любом месте кадра. Я могу отключить меню, а затем в щелчке правой кнопкой мыши на виджет, я включил его. Это работает очень хорошо в первый раз; если я нажимаю в любом месте кадра, ничего не происходит (меню отключено), но если я нажму на мой виджет, меню будет включено и всплывет. Ура! Но теперь меню включено, и теперь оно появляется, если я щелкнул правой кнопкой мыши в любом месте, на кнопках, пустом пространстве, индикаторах выполнения и т. Д. Когда я снова отключу его? После того, как меню выскочит, пользователь может щелкнуть в любом месте, и меню исчезнет. Нет события, которое срабатывает, когда меню закрыто, поэтому я застрял.

Извините за длинные промахи, я кратко изложить вопрос: я хочу, чтобы одно всплывающее меню появилось, когда пользователь щелкнул правой кнопкой мыши по одному из нескольких динамически созданных виджетов.


Используя ответ Тома, это то, как я реализовал его:

/* Somewhere in Control Definitions... */ 
DEFINE MENU m_Popup 
     MENU-ITEM m_Test1  LABEL "Test 1"  
     MENU-ITEM m_Test2  LABEL "Test 2".  

/* Somewhere, where I need to dynamically create the widgets. */ 
/* Loop through the items in the temp table and create a widget for each. */ 
FOR EACH ttItem BY ttItem.ItemName: 
    CREATE TOGGLE-BOX hWidget 
    ASSIGN 
      FRAME  = FRAME DEFAULT-FRAME:HANDLE 
      LABEL  = STRING(ttItem.ttItemName) 
    TRIGGERS: 
     ON MOUSE-MENU-DOWN PERSISTENT RUN GetMenu IN THIS-PROCEDURE. 
    END TRIGGERS. 
END. 

/* If the user right-clicks on any one of the widgets, this procedure */ 
/* is run with SELF being the widget that was clicked on. */ 
PROCEDURE GetMenu: 
    /* Remove the menu from its current owner and assign it to SELF. */ 
    MENU m_Popup:OWNER:POPUP-MENU = ?. 
    SELF:POPUP-MENU = MENU m_Popup:HANDLE. 
END PROCEDURE. 

/* The user clicks on one of the menu items */ 
/* Here SELF is the menu item that was clicked. I can */ 
/* get m_Popup from SELF:PARENT and the widget it was */ 
/* was assigned to from SELF:PARENT:OWNER.   */ 
ON CHOOSE OF MENU-ITEM m_Test1 
DO: 
    MESSAGE "You selected " SELF:LABEL " for " SELF:PARENT:OWNER:LABEL. 
END. 
+0

Какой язык? C#? – Perlnika

+0

Простите, это Прогресс 4GL. Я отвечу на текст вопроса. – RobertT

+0

У вас есть образец кода, который может помочь осветить проблемы? –

ответ

3

Мой приятель Майк Фехнер (который не является в настоящее время на SO, но кто делает этот материал намного больше, чем я) говорит мне что, в то время как этот пример является статическим, то очень похожее должно работать:

Procedure getMenu: 

    DEFINE INPUT PARAMETER phWidget AS HANDLE NO-UNDO. 
    DO WITH FRAME {&FRAME-NAME}: 
     FILL-IN-1:POPUP-MENU = ? . 
     FILL-IN-2:POPUP-MENU = ? . 
     FILL-IN-3:POPUP-MENU = ? . 
    END. 

    phWidget:POPUP-MENU = MENU POPUP-MENU-FILL-IN-1:HANDLE . 

END procedure. 

нА ПРАВОЙ MOUSE-DOWN всех трех филлер-ты "RUN getMenu (SELF)." чтобы украсть всплывающее меню у кого бы то ни было.

+0

Итак, я ошибся, я ** могу ** переназначить всплывающее меню, но сначала я должен отменить назначение его существующего владельца (с помощью POPUP-MENU =?). Это очень удобно знать, спасибо за это! Поскольку мои элементы управления являются динамическими и хранятся в таблице temp, я могу просто пропустить их, чтобы установить их всплывающие меню, поэтому это должно работать красиво. – RobertT

+0

Эй, Том, посмотри, что я нашел! Мне не нужно перебирать мои виджеты, я могу просто использовать владельца меню: 'MENU m_Popup: OWNER: POPUP-MENU =?. SELF: POPUP-MENU = MENU m_Popup: HANDLE.' – RobertT