Как разместить всплывающее меню прямо под кнопкой в ​​VB6

У меня есть приложение VB6. Есть основная форма. В нем находится пользовательский элемент управления. Этот пользовательский элемент управления имеет кнопку. Когда я нажимаю кнопку, я хочу, чтобы всплывающее меню отображалось так, чтобы верхний левый угол меню находился прямо под нижним левым краем кнопки.

if I do:

frm.PopupMenu mnuBlah

меню появляется там, где находится мышь.

если я попытаюсь предоставить координаты

frm.PopupMenu mnuBlah, btn.Left, btn.Top + btn.Height

математика получается совершенно неправильной, и меню отображается не так, как нужно.

Я не совсем уверен, какой тип координат требуется для вызова PopupMenu и как вычислить положение под кнопкой.


person AngryHacker    schedule 03.07.2009    source источник


Ответы (3)


PopupMenu требует координаты X и Y в ScaleMode формы, в которой всплывает меню. В данном случае это, вероятно, означает пользовательский контроль.

Но это действительно зависит от того, где вы обрабатываете событие MouseDown. (Вы не получаете координаты с помощью события Click.) Если ваш обработчик событий находится в самом пользовательском элементе управления, у вас не должно возникнуть проблем с использованием предоставленных координат. Однако в опубликованном вами коде отсутствует параметр Flags (должен быть vbPopupMenuLeftAlign), что может объяснить, почему ваша система координат не работает. Кроме того, вы должны определить меню как свойство самого пользовательского элемента управления.

С другой стороны, если вы вызываете событие MouseDown из пользовательского элемента управления и обрабатываете его в содержащей форме, всплывающее меню должно быть свойством содержащей формы. В этом случае можно игнорировать параметры X и Y, но расчеты координат придется производить самостоятельно. Левый край кнопки относительно основной формы будет суммой левого края пользовательского элемента управления и смещения кнопки внутри элемента управления. Аналогичная математика будет работать для расчета нижнего края кнопки. Другими словами:

Private Sub UserControl1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    PopupMenu mnuPopup, vbPopupMenuLeftAlign, _
        UserControl1.Left + UserControl1.Button.Left, _
        UserControl1.Top + UserControl1.Button.Top + UserControl1.Button.Height
End Sub

Обратите внимание, что для этого потребуется также предоставить кнопку (Button) как свойство пользовательского элемента управления, чтобы вы могли получить доступ к его свойствам Left, Top и Height. Это достаточно просто:

Public Property Get Button() As CommandButton
    Set Button = Command1
End Property

Поднять событие также достаточно просто; просто поставь

Public Event MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

в верхней части пользовательского элемента управления, затем используйте это:

RaiseEvent MouseDown(Button, Shift, X, Y)

в событии MouseDown кнопки в пользовательском элементе управления.

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

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

Таким образом, вы на самом деле не будете вызывать событие MouseDown; скорее вы должны вызывать такие события, как OptionOneSelected, OptionTwoSelected или OptionThreeSelected. (Более значимые имена, конечно, были бы намного лучше.)

В любом случае, я надеюсь, что это не слишком поздно, чтобы быть полезным...

person JeffK    schedule 15.07.2009

Вам нужно передать флаг vbPopupMenuLeftAlign методу PopupMenu. Обратите внимание, это противоречит документации по методу PopupMenu (может ли Microsoft действительно допустить ошибку?), но это работает.

frm.PopupMenu mnuBlah, vbPopupMenuLeftAlign, btn.Left, btn.Top + btn.Height
person raven    schedule 06.07.2009

Вам нужно включить значения высоты и левого края для родительского контейнера (обычно это форма, но также может быть фрейм или какой-либо другой контейнер).

Я думаю, вы ищете что-то вроде этого:

btn.Parent.PopupMenu mnuBlah, vbPopupMenuLeftAlign , btn.Left, btn.Top + btn.Height
person Brian Willis    schedule 03.07.2009
comment
Это не компилируется, и даже если вы исправите это так, чтобы оно компилировалось, оно не работает. - person raven; 16.07.2009
comment
@raven Как я уже упоминал в своем ответе, у меня не было удобного компилятора, чтобы проверить это. Эта модифицированная версия должна работать. - person Brian Willis; 17.07.2009