Контекстные меню

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

Контекстные меню

Сообщение Eugenio » 06.11.2004 (Сб) 11:29

Уважаемые мэтры. Для показа контекстных меню, я до сих пор пользовался меню, созданными заранее (не отображаемыми в строке меню главного окна) - т.е., я пользовался Menu Editor'ом. А очччень хотелось бы знать, как создать меню и особенно контекстное меню "на лету" (at run time).
Есть ли у меня вопрос? У меня всегда есть вопрос

A.A.Z.
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3035
Зарегистрирован: 30.06.2003 (Пн) 13:38

Сообщение A.A.Z. » 06.11.2004 (Сб) 11:41

Например, так:
Код: Выделить всё
Const MF_CHECKED = &H8&
Const MF_APPEND = &H100&
Const TPM_LEFTALIGN = &H0&
Const MF_DISABLED = &H2&
Const MF_GRAYED = &H1&
Const MF_SEPARATOR = &H800&
Const MF_STRING = &H0&
Private Type POINTAPI
    x As Long
    y As Long
End Type
Private Declare Function CreatePopupMenu Lib "user32" () 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, ByVal lprc As Any) As Long
Private Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Long, ByVal bRevert As Long) 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 Any) As Long
Private Declare Function DestroyMenu Lib "user32" (ByVal hMenu As Long) As Long
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Dim hMenu As Long
Private Sub Form_Load()
    'KPD-Team 1998
    'URL: http://www.allapi.net/
    'E-Mail: KPDTeam@Allapi.net
    'Create an empty popupmenu
    hMenu = CreatePopupMenu()
    'Append a few menu items
    AppendMenu hMenu, MF_STRING, ByVal 0&, "Hello !"
    AppendMenu hMenu, MF_GRAYED Or MF_DISABLED, ByVal 0&, "Testing ..."
    AppendMenu hMenu, MF_SEPARATOR, ByVal 0&, ByVal 0&
    AppendMenu hMenu, MF_CHECKED, ByVal 0&, "TrackPopupMenu"
End Sub
Private Sub Form_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    Dim Pt As POINTAPI
    'Get the position of the mouse cursor
    GetCursorPos Pt
    If Button = 1 Then
        'Show our popupmenu
        TrackPopupMenu hMenu, TPM_LEFTALIGN, Pt.x, Pt.y, 0, Me.hwnd, ByVal 0&
    Else
        'Show our form's default popup menu
        TrackPopupMenu GetSystemMenu(Me.hwnd, False), TPM_LEFTALIGN, Pt.x, Pt.y, 0, Me.hwnd, ByVal 0&
    End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
    'Destroy our menu
    DestroyMenu hMenu
End Sub

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 06.11.2004 (Сб) 11:53

Впечатляет!
А как отлавливается выбранный пункт?
И можно ли создавать подменю?

А не могли бы и про API-функции для главного меню?
Есть ли у меня вопрос? У меня всегда есть вопрос

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 06.11.2004 (Сб) 12:45

Хотим по-тяжёлой? Нет проблем :)
http://bbs.vbstreets.ru/viewtopic.php?p=56536#56536
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 06.11.2004 (Сб) 13:14

To GSerg

Спасибо, со временем всё будет прочитано и пригодится - не сомневаюсь. :)

А пока охота заодно вот чего у мэтров спросить:

1. Как пройтись в цикле по control'ам чужого окна. У меня одна единственная идея: поскольку идентификатор контрола в GetDLgItem - это integer, вроде бы, то можно просто
Код: Выделить всё

IntItem  = 0
pItem = GetDlgItem(hwnd,IntItem)

Do While pItem

... ' тут какие-то действия

IntItem = IntItem + 1
pItem = GetDlgItem(hwnd,IntItem)
Loop

ну или типа того. А может, есть где-нибудь их count?
2. Как получить указатель на панель инструментов в чужом окне?

3. Как обрабатывать события, происходящие в чужом окне?
Мне бы там хотелось нажатие на одну из кнопок отловить :?:
Последний раз редактировалось Eugenio 06.11.2004 (Сб) 14:05, всего редактировалось 2 раз(а).
Есть ли у меня вопрос? У меня всегда есть вопрос

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 06.11.2004 (Сб) 13:49

Как A.A.Z. сказал :)
Выбранный пункт отлавливается как результат trackpopupmenu (если установлен флаг TPM_RETURNCMD). Подменю - создаём новое меню и вызываем setmenuiteminfo, установив в структурке hSubMenu и флаг, указывающий, что этот мембер валиден :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 06.11.2004 (Сб) 14:08

Да, я уже просмотрел инфу про TrackPopupMenu. просто сначала не понял - у A.A.Z там звозвращаемое значение никуда не принимается.
Скажите че-нидь на следующие вопросы, а?
Есть ли у меня вопрос? У меня всегда есть вопрос

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 06.11.2004 (Сб) 15:23

1. EnumChildWindows
2. Один из них будет Toolbar :)
3. Прямой сабклассинг чужого окна запрещён по объективным причинам. Это возможно только через хуки - но почитай сначала тему про расширения часиков в трее :) Поищи, не поленись. Автор A.A.Z.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 06.11.2004 (Сб) 17:16

Вероятно, я туп, как дерево, но я не понял, при чем тут Shell_NotifyIcon.
Понятно, что с помощью EnumChildWindows я получу в callback процедуру все дескрипторы, по ним получу свойства (WINDOWCLASSEX) для каждого контрола, получу указатель на его оконную процедуру.. А чего с ней сделать для моих целей я плохо представляю.
Задача заключается в том, чтобы перехватить события определенного контрола (это - или кнопка в клиентской части, или на панели инстурментов)
Есть ли у меня вопрос? У меня всегда есть вопрос

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 06.11.2004 (Сб) 18:29

А она тут и ни причём.
Просто я ж говорю - нельзя сабклассить просто так чужое приложение, потому что указатель на процедуру не имеет смысла в контекста другого процесса.
Топик щас поищу, ты его не нашёл, я смотрю :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 06.11.2004 (Сб) 18:31

Во, читай всё подряд :)
http://bbs.vbstreets.ru/viewtopic.php?t=10245
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 06.11.2004 (Сб) 21:16

Потому я и предположил, что наверно туп - я топик нашел, но ничего, что поможет, там не обнаружил :)
Spy++ - не знаю, никогда не пользовался.
использование SendMessage - не очень понимаю, ни одного примера не видал никогда, тем более SendMessageCallBack.
Но насчет hook'ов намек понял. Идет поиск.. :)
Есть ли у меня вопрос? У меня всегда есть вопрос

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 06.11.2004 (Сб) 22:25

Spy++ - утилита из комплекта visual studio.
Качать API-Guide с www.allapi.net!!!
И не ищи. Потому что данный хук должен быть глобальным, объяснение фиговости чего и приводится в данном топике :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 14.11.2004 (Вс) 15:21

2 GSerg.
1. Спасибо за пример с меню - отличный. Все переписал, на нем основываясь.
2. А нет чего-то вроде WM_USER, чтобы все-таки получить какой-то "абсолютный" адрес своей процедуры (добавив к AddressOf)?
(и передать в SetWindowLong(НайденныйКонтрол)) :)
Есть ли у меня вопрос? У меня всегда есть вопрос

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 14.11.2004 (Вс) 16:51

1. Да на здоровье :)
2. Обломись :) Конечно, физическая память одна для всех, но, тем не менее, указатель из чужого АП смысла не имеет. Даже если ты переведёшь указатель из одного АП в указатель другого АП (интересно как :)), то это будет работать (если не вызовет memory access violation :)) только пока абсолютно всё умещается в физической оперативке без маппинга. Короче, здесь играйте, а здесь рыбу заворачивали. :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 14.11.2004 (Вс) 17:28

GSerg писал(а):Даже если ты переведёшь указатель из одного АП в указатель другого АП (интересно как :))

Единственный способ - через file mapping-и, но здесь требуется явная кооперация обеих программ.
Без помощи другой программы этот "перевод" адреса из одного АП в другое неосуществим в принципе.
Изображение

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 14.11.2004 (Вс) 21:14

Да, с физической памятью я уж сообразил. Но это, кстати, точно так?
И access violation опять же..
Чего ж делать-то?! Переходить на C и писать dll с экспортируемой функцией, к-рая бы замещала WindowProc?
Последний раз редактировалось Eugenio 14.11.2004 (Вс) 22:09, всего редактировалось 2 раз(а).
Есть ли у меня вопрос? У меня всегда есть вопрос

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 14.11.2004 (Вс) 21:16

tyomitch писал(а):Единственный способ - через file mapping-и, но здесь требуется явная кооперация обеих программ.

Вот именно. Вторая должна точно знать, куда лезть
Хотя, если все таки через hook'и, то знать-то должна будет моя же dll,
которую должен будет загрузить хакнутый (хукнутый) процесс.
Но dll-то должна быть обычная. С экспортируемой процедурой. И опять же access violation..
Так что, блин..
Говорила мама, изучай C как следует :) . Я IDE VC++ хреново умею пользоваться. Хотя, там по Wizard'у на каждый шаг.
Есть ли у меня вопрос? У меня всегда есть вопрос


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

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

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

    TopList