powered by simpleCommunicator - 2.0.38     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / TrackPopupMenu
12 сообщений из 12, страница 1 из 1
TrackPopupMenu
    #39882100
Damir_85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте. Скажите как определить какая команда была выбрана в контекстном меню, у меня все время возвращает функция единицу.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
Const ID_N = 101
  Const ID_S = 102
  Const ID_K = 103
 
 Dim m As Long
  Dim i As Long
  Dim h As Long
  Dim r As Rect



Код: vbnet
1.
2.
3.
4.
5.
6.
7.
Private Sub UserForm_Initialize()
h = FindWindow(vbNullString, "UserForm1")
  m = CreatePopupMenu()
  AppendMenu m, MF_STRING, ID_N, "Íàñòðîéêà ïðîôèëÿ..."
  AppendMenu m, MF_STRING, ID_S, "Ñîçäàòü ïðîôèëü..."
  AppendMenu m, MF_STRING, ID_K, "Êàòàëîã ïðîôèëåé..."
End Sub



Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Private Sub CommandButton1_Click() 
  
  i = TrackPopupMenu(m, TPM_RETURNCMD, 250, 250, 0, h, r)
 
  Select Case i
    Case ID_N
      MsgBox "1"
    Case ID_S
      MsgBox "2"
    Case ID_K
    
      MsgBox "3"
  End Select
End Sub


По нажатию кнопки появляется меню, выбираю пункт, а i всегда 1
...
Рейтинг: 0 / 0
TrackPopupMenu
    #39883879
Damir_85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прочитав кучу статей , понял что нужно делать субклассирование.
К примеру , если я объявлю функцию для обработки сообщений формы (ну естественно через функцию SetwindowLong и AddresOf укажу что именно эта функция будет обрабатывать сообщения), как мне узнать какая команда была выбрана, вернее насколько помню она содержится в параметре wparam , то ли в старшем байте, то ли в младшем). Какими функциями ее выделить. И если например на ту или иную команду открывается та или иная форма, это открытие формы описывать тут же, в WindowProc?

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Function WindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal_
    wParam As Long, ByVal lParam As Long) As Long
Dim lReturn As Long

  'вначале позволим произвести обработку стандартной оконной процедуре , а затем сами
  lReturn = CallWindowProc(OldWndProc, hwnd, Msg, wParam, lParam)
  Select Case Msg 'проверяем сообщения
    Case WM_CONTEXTMENU 'если нужное нам, то выполняем некоторые действия 
                       
   ...
    ...
  End Select
...
Рейтинг: 0 / 0
TrackPopupMenu
    #39884463
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Damir_85Прочитав кучу статей , понял что нужно делать субклассирование.
Ничего там не надо, много лишнего лепишь. На рабочий код, и разбирайся сам что у тебя не так. И не разбрасывай переменные по разным процедурам.

Код формы:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
Option Explicit

Private Sub Form_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
  If Button = vbRightButton Then
    'PopupMenu
    Dim hMenu As Long
    Dim pt As POINTAPI
    Dim rc As RECT
    Dim lReturn As Long
    GetCursorPos pt
    hMenu = CreatePopupMenu()
    AppendMenu hMenu, MF_STRING, 1, "Ïóíêò #1"
    AppendMenu hMenu, MF_STRING, 2, "Ïóíêò #2"
    AppendMenu hMenu, MF_STRING, 3, "Ïóíêò #3"
    lReturn = TrackPopupMenu(hMenu, TPM_LEFTBUTTON Or TPM_RETURNCMD, pt.x, pt.y, 0, Me.hwnd, rc)
    Select Case lReturn
      Case 1:
        MsgBox "Ïóíêò #1"
      Case 2:
        MsgBox "Ïóíêò #2"
      Case 3:
        MsgBox "Ïóíêò #3"
      Case Else
    End Select
    DestroyMenu hMenu
  End If

End Sub



Код модуля:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
Option Explicit

Public Type RECT
  Left As Long
  Top As Long
  Right As Long
  Bottom As Long
End Type

Public Type POINTAPI
  x As Long
  y As Long
End Type

Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Boolean

Public Const MF_STRING = &H0&

Public Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As Long, _
 ByVal wFlags As Long, ByVal wIDNewItem As Long, Optional ByVal lpNewItem As String) As Long
Public Declare Function CreatePopupMenu Lib "user32" () As Long
Public Declare Function DestroyMenu Lib "user32" (ByVal hMenu As Long) As Boolean

'uFlags
'which mouse button the shortcut menu tracks
Public Const TPM_LEFTBUTTON = &H0 'òîëüêî ëåâàÿ êíîïêà ìûøè
'to control discovery of the user selection without having to set up a parent window for the menu
Public Const TPM_RETURNCMD = &H100& 'returns the menu item identifier of the user's selection in the return value.

Public Declare Function TrackPopupMenu Lib "user32" (ByVal hMenu As Long, _
 ByVal uFlags As Long, ByVal x As Long, ByVal y As Long, ByVal nReserved As Long, _
 ByVal hwnd As Long, ByRef prcRect As RECT) As Long
...
Рейтинг: 0 / 0
TrackPopupMenu
    #39884466
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чет с русским беда, когда из старой студии сюда копируешь.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
Option Explicit

Private Sub Form_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
  If Button = vbRightButton Then
    'PopupMenu
    Dim hMenu As Long
    Dim pt As POINTAPI
    Dim rc As RECT
    Dim lReturn As Long
    GetCursorPos pt
    hMenu = CreatePopupMenu()
    AppendMenu hMenu, MF_STRING, 1, "Number #1"
    AppendMenu hMenu, MF_STRING, 2, "Number #2"
    AppendMenu hMenu, MF_STRING, 3, "Number #3"
    lReturn = TrackPopupMenu(hMenu, TPM_LEFTBUTTON Or TPM_RETURNCMD, pt.x, pt.y, 0, Me.hwnd, rc)
    Select Case lReturn
      Case 1:
        MsgBox "Number #1"
      Case 2:
        MsgBox "Number #2"
      Case 3:
        MsgBox "Number #3"
      Case Else
    End Select
    DestroyMenu hMenu
  End If

End Sub
...
Рейтинг: 0 / 0
TrackPopupMenu
    #39884542
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще, если честно непонятно зачем тебе API,
в VB6 все это через свой конструктор делается, а контекстное меню помнится своей функцией вызывается (делается в том же конструкторе).

API и "субклассирование" нужны тогда, когда надо сделать что-то хитрое,
например добавить картинки в меню (а для этого на XP надо еще менять высоту итемов),
или например надо знать по какому итему елозит мышка, чтоб отображать подсказки в StatusBar.
При этом заметь сам скелет меню можно и проще делать в том же конструкторе.

А если просто стандартные классические меню без картинок, то API тебе не нужны.
...
Рейтинг: 0 / 0
TrackPopupMenu
    #39884562
Damir_85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

Спасибо. Дело втом , что я на VBA пишу, под Corel Draw. Там также как, например, в Excel если писать макрос, минимум компонентов, и меню нету
...
Рейтинг: 0 / 0
TrackPopupMenu
    #39884563
Damir_85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати , а если картинку для каждого пункта контекстного меню ставить, это уже через API , т.е сложно?
И маленький вопрос, в контекстном меню можно ли блокировать некоторые команды , а то что то писал MF_GRAYED и MF_DISABLED что то не блокировалось
...
Рейтинг: 0 / 0
TrackPopupMenu
    #39884599
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Damir_85,

Вообще чтоб сделать хорошо и красиво попотеть придется, не день и не два.

А вообще иконки в VB6 меню тяжело добавить?

Там куски кода и готовые тест-проекты вложены.

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

С VBA не работал, у меня все это в .Net давно перенесено, можешь еще в разделе .Net по моим топикам поискать, суть внедрения API та же.

Методология для XP и Висты сильно отличается, для Висты проще.
Для Win10/8.1/7 также как для Висты.
...
Рейтинг: 0 / 0
TrackPopupMenu
    #39885049
Damir_85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Теперь заработало. Ошибка была в том, что не объявил значение константы TPM_RETURNCMD
Только у меня не по нажатию кнопки мыши работает , а по нажатию кнопки на форме

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
Private Type POINTAPI
  x As Long
  y As Long
End Type


Const TPM_RETURNCMD = &H100&


Private Declare Function CreatePopupMenu Lib "user32" () As Long
Private Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As Long, ByVal wflags As Long, ByVal wIDNewItem As Long, ByVal lpnewitem As String) As Long
Private Declare Function TrackPopupMenu Lib "user32" (ByVal hMenu As Long, ByVal wflags As Long, ByVal x As Long, ByVal y As Long, ByVal nreserved As Long, ByVal hwnd As Long, lprc As Rect) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpclassname As String, ByVal lpwindowname As String) As Long
Private Declare Function DestroyMenu Lib "user32" (ByVal hMenu As Long) As Boolean
Private Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long
Private Sub CommandButton1_Click()
  Dim m As Long
  Dim lReturn As Long
  Dim h As Long
  Dim i As Integer
  Dim r As Rect
  Dim pt As POINTAPI
  
  h = FindWindow(vbNullString, "UserForm1")
  m = CreatePopupMenu()
  AppendMenu m, MF_STRING, 500, "Настройка профиля..."
  AppendMenu m, MF_STRING, 600, "Создать профиль..."
  AppendMenu m, MF_STRING, 700, "Каталог профилей..."
  pt.x = CommandButton2.left
  pt.y = CommandButton2.top + CommandButton1.Height
  ClientToScreen h, pt
  lReturn = TrackPopupMenu(m, TPM_RETURNCMD, pt.x, pt.y, 0, h, r)
  Select Case lReturn
    Case 500
      MsgBox "500"
    Case 600
      MsgBox "600"
    Case 700
      MsgBox "700"
  End Select
  DestroyMenu m
End Sub



Хотел спросить, а почему ClientToScreen некоректно работает в VBA. Меню должно появляться под левым нижним углом кнопки, а оно по высоте появляется где то по верхнему краю кнопки, и сдвинуто от левого верхнего угла кнопки влево приблизительно на расстояние, которое отведено в меню для пиктограмм для пунктов меню. Я же вот прописал:

Код: vbnet
1.
2.
pt.x = CommandButton2.left
pt.y = CommandButton2.top + CommandButton1.Height


Да и выравнивание меню по x и y по умолчанию левый верхний угол для TrackPopuMenu
Я пробовал использовать GetWindowRect, так Rect.Left и Rect.Top вообще уводят меню ниже формы и вбок
...
Рейтинг: 0 / 0
TrackPopupMenu
    #39885121
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Damir_85
Меню должно появляться под левым нижним углом кнопки


В .NET так делаю
Код: vbnet
1.
2.
3.
4.
   Dim pt As POINTAPI : pt.x = sender.Left : pt.y = sender.Bottom
    ClientToScreen(sender.parent.Handle, pt)
    'ранее выводили в {Control.MousePosition.X, Control.MousePosition.Y}
    Dim lReturn As Integer = TrackPopupMenu(hMenu, TPM_LEFTBUTTON Or TPM_RETURNCMD, pt.x, pt.y, 0, Me.Handle)


В vb6 не делал, сам пробуй.
...
Рейтинг: 0 / 0
TrackPopupMenu
    #39885421
Damir_85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кстати , нашел вот такую штуку, незнаю может название команды не правильно напишу, но пишется так.
Код: vbnet
1.
2.
pt.x=Command1.Left \ Screen.Twipsperpixelx
pt.y =(Command1.top+Command1.Height)\Screen.TwipsperpixelY


Про перевод пикселей в твипы и наоборот немного прочитал, т.к в vba нету Screen. Для чего делить на твипы?
...
Рейтинг: 0 / 0
TrackPopupMenu
    #39886005
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Damir_85,

для того, что у контролов vb координаты в твипах, а координаты GDI - в пикселях. однако, координаты в VBA тоже в пикселях, поэтому Screen не нужен.

автор Ошибка была в том, что не объявил значение константыв настройках редактора vba есть галочка "требовать объявления переменных", она во все модули option explicit прописывает, что исключает такие детские, но иногда сложно уловимые ошибки.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / TrackPopupMenu
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]