Вывод меню посредством TrackPopupMenu

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
NIC
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 175
Зарегистрирован: 26.04.2005 (Вт) 4:50

Вывод меню посредством TrackPopupMenu

Сообщение NIC » 28.04.2008 (Пн) 21:20

Ситуация такая.
Создаю в редакторе VB6 меню формы.
Делаю его Visible=false.

Но при таком свойстве меню не отображаеться на экране,если его вывести через TrackPopUpMenu.
Хотя методом формы PopUpMenu его показывает.

Код: Выделить всё
Option Explicit
Private Declare Function GetMenu Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function GetSubMenu Lib "user32.dll" (ByVal hMenu As Long, ByVal nPos As Long) As Long
Private Declare Function TrackPopupMenu Lib "user32.dll" (ByVal hMenu As Long, ByVal wFlags As Long, ByVal X As Long, ByVal Y As Long, ByVal nReserved As Long, ByVal hwnd As Long, ByRef lprc As RECT) As Long
Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = 2 Then
Dim lprc As RECT
Dim hm&, hsm&
hm = GetMenu(hwnd)
hsm = GetSubMenu(hm, 0)
TrackPopupMenu hsm, 0, 0, 0, 0, hwnd, lprc

'Me.PopupMenu pmenu - так показывает!
End If
End Sub


В чём может быть "несудьба"??? :lol:

visualman
Бывалый
Бывалый
 
Сообщения: 228
Зарегистрирован: 08.02.2002 (Пт) 19:06
Откуда: Russia

Сообщение visualman » 28.04.2008 (Пн) 22:27

Перед строкой:
hm = GetMenu(hwnd)

Вставь:
mnu_Main.Visible = True

Меню не покажется в контейнере формы, а а вылезет по TrackPopupMenu

А после:
TrackPopupMenu hsm, 0, 0, 0, 0, hwnd, lprc

Вставь:
mnu_Main.Visible = False

GetSubMenu видимо не работает с невидимыми пунктами (чисто предположение) Проверять влом ))
Причиной ошибок в коде служит давление со стороны руководства и жесткие временные рамки, им установленные.

NIC
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 175
Зарегистрирован: 26.04.2005 (Вт) 4:50

Сообщение NIC » 28.04.2008 (Пн) 22:35

Спасибо.
Дело в том что есть известный класс "trayiconwithballoon" и мне надо добвавить его в библу ActiveX но там используються передача ссылки на обьект.Например
Код: Выделить всё
Public Sub CallPopupMenu(Window As Form, PopMenu As Menu, Optional Flags, Optional X, Optional Y, Optional DefMenu)


А в скомпилированной Dll ссылки на обекты недопускаються.
Соответствено надо передать hWND,и по нему вызвать меню API функцией TrackPopupMenu.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 28.04.2008 (Пн) 22:47

А в скомпилированной Dll ссылки на обекты недопускаються.

Да с чего бы это?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

NIC
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 175
Зарегистрирован: 26.04.2005 (Вт) 4:50

Сообщение NIC » 28.04.2008 (Пн) 22:55

Ошибку выдаёт

NIC
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 175
Зарегистрирован: 26.04.2005 (Вт) 4:50

Сообщение NIC » 28.04.2008 (Пн) 23:06

Хакер,посмотри пожалуйста вот эту попытку сборки в ActiveX Dll.
Вложения
1.rar
TrayIcon
(3.38 Кб) Скачиваний: 86

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 28.04.2008 (Пн) 23:22

Ошибку выдаёт

Хочется буркнуть "Мать твою" и дать ссылку на один из тысячи постов, где я или кто-либо ещё упрекают автора в том, что он не говорит, какую именно ошибку ему "выдаёт".

Да что за болезнь такая массовая?

Мне не нужен аттач твой. Здесь вообще не нужно было бы моё участие, если бы не было этого дурацкого подхода: Увидел сообщение об ошибке, и не читая, чего там пишут, ткнул ОК, огорчившись тому, что что-то не так.

Если бы ты прочитал и постарался вникнуть в смысл ошибки, ты бы увидел:
Private object modules cannot be used in public object modules as parameters or return types for public procedures, as public data members, or as fields of public user defined types

И сделал бы вывод, что VB.Form - это Private object module. И додумался бы до того, что если бы туда поставить что-то Public-чное, то никакой ошибки бы небыло.

Так что TLB тебе в помощь.

Да что там TLB, поставь вместо Form публичный Object а внутри скастуй ссылку обратно к типу Form.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

NIC
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 175
Зарегистрирован: 26.04.2005 (Вт) 4:50

Сообщение NIC » 28.04.2008 (Пн) 23:33

Дык,я хотел пойти другим путём.


Соответствено надо передать hWND,и по нему вызвать меню API функцией TrackPopupMenu.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 28.04.2008 (Пн) 23:35

NIC
Каким другим-то?

Соответствено надо передать hWND,и по нему вызвать меню API функцией TrackPopupMenu.

Так что мешает передавать всё-таки ссылку на объект? Хоть что-либо мешает?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

NIC
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 175
Зарегистрирован: 26.04.2005 (Вт) 4:50

Сообщение NIC » 28.04.2008 (Пн) 23:44

И сделал бы вывод, что VB.Form - это Private object module. И додумался бы до того, что если бы туда поставить что-то Public-чное, то никакой ошибки бы небыло.


И что там может быть Public- чное,в Form1?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 28.04.2008 (Пн) 23:49

В form1 ничего публичного быть не может. А никто и не говорил, что должно быть.

Другой вопрос, почему человек, незнающий что такое private-типы, а что такое public-типы, рвётся юзать TrackPopupMenu и создавать ActiveXDLL-ки?

Тебе же сказали: поставь туда Object-ы и скастуй их к Form.
Или опиши в TLB какой-нибудь интерфейс, поставь аргументу этот тип, а форму заставь поддерживать этот интерфейс.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

NIC
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 175
Зарегистрирован: 26.04.2005 (Вт) 4:50

Сообщение NIC » 29.04.2008 (Вт) 0:04

Спасибо Хакер,сделал вот так
Код: Выделить всё
Public Sub CallPopupMenu(Window As Object, PopMenu As Object, Optional Flags, Optional X, Optional Y, Optional DefMenu)


Хакер писал(а):Другой вопрос, почему человек, незнающий что такое private-типы, а что такое public-типы, рвётся юзать TrackPopupMenu и создавать ActiveXDLL-ки?

Без комментариев...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 29.04.2008 (Вт) 0:07

NIC писал(а):Спасибо Хакер,сделал вот так
Код: Выделить всё
Public Sub CallPopupMenu(Window As Object, PopMenu As Object, Optional Flags, Optional X, Optional Y, Optional DefMenu)



И вероятно, то, что говорилось про кастование к Form, не сделал?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

NIC
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 175
Зарегистрирован: 26.04.2005 (Вт) 4:50

Сообщение NIC » 29.04.2008 (Вт) 0:51

А это что есть "кастование"?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 29.04.2008 (Вт) 0:57

Код: Выделить всё
Function foo(ByVal X As Object)
     Dim myX As CommandButton

     Set myX = X      ' Скастовали ссылку к типу CommandButton
     
     myX.Caption = "Ыка!"
End Function


Это грубо говоря, потому что вообще, слово "кастовать" имеет несколько другое значение.

Но вообще, ты выбрал поганый путь - более правильным было бы использование своего интерфейса, который бы поддерживала форма.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

NIC
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 175
Зарегистрирован: 26.04.2005 (Вт) 4:50

Сообщение NIC » 29.04.2008 (Вт) 1:05

Хакер,"догналось".
Многое прояснилось.
Программирование под NET Framework(к форуме не относиться),заставляет смотреть на это уже более "вооруженным" глазом.

Но,в примере как ты реалиовал "свой интерфейс" всё понятно.!!!
Спасибо тебе!

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 29.04.2008 (Вт) 1:08

Что за пример, в котором я реализовал "свой интерфейс"?

Если имеется ввиду приведённый выше, то в нём ничего такого нет.

Если бы там было IFormProvidesHWND вместо Object, не было бы никакого кастования, и в форме было Implements IFormProvidesHWND и Public Function IForm_ProvidesHWND_Hwnd(): ProvidesHWND = Me.Hwnd: End Function, то тогда да.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 29.04.2008 (Вт) 13:54

Эппельман утверждает, что при присвоении меню свойства pmenu.Visible=False бейсик не прячет его, а уничтожает (а когда нужно, опять создаёт). Поэтому если меню используется в АПИ он советует вместо pmenu.Visible=False делать pmenu.Caption="" и pmenu.Enabled=False
Артур
 
   

NIC
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 175
Зарегистрирован: 26.04.2005 (Вт) 4:50

Сообщение NIC » 29.04.2008 (Вт) 14:06

arthur2
с утверждением Эппельмана я пожалуй соглашусь.Если принять во-внимание факт,что меню это не окно,то и спрятать его не предоставляеться возможным.
Я где-то в Нэте видел код вывода меню чистыми API функциями без использования .PopUpMenu
:wink:

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 29.04.2008 (Вт) 14:45

Да можно его спрятать.

Создать меню:
hMenu = CreatePopupMenu()

Заполнить пунктами:
idCmd=1
Call InsertMenu(hMenu,-1,MF_BYPOSITION, idCmd, "ляляля")
idCmd=idCmd+1
Call InsertMenu(hMenu,-1,MF_BYPOSITION, idCmd, "шушушу")

Вот меню уже есть, и пункты в нём уже есть. Но оно не видимо.

rez = TrackPopupMenu(hMenu, 0, X, Y, 0, hwnd, 0&)
Вот оно уже видимо (rez станет равно idCmd того пункта, который выбран)

Кликнул по пункту - опять невидимо. Но не исчезло - можно снова трекать.
Артур
 
   

NIC
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 175
Зарегистрирован: 26.04.2005 (Вт) 4:50

Сообщение NIC » 29.04.2008 (Вт) 14:54

Имееться ввиду вызов из SysTray...


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 90

    TopList