С Новым годом! Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18030 / 7733 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16

Контекстное меню в виде объектов на форме

05.08.2014, 17:29. Показов 2296. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет !

Нужно создать на форме подобие контекстного меню с разделительными линиями.
Чтобы каждый пункт меню был отдельным объектом, которые можно перетягивать между собой
(по сути меняю местами пункты).

Подскажите, что лучше взять за основу.

Смотрел тему Клонирование существующего изображения (массива изображений)
Собственно, если брать PictureBox нужно уметь на нем сделать надпись (изменить надпись).
В качестве разделителей можно просто нарисовать на форме линии между объектами.
Хотя линии тоже в идеале нужны как объекты.

Нормально или какие еще варианты? Я с графикой не очень дружу.
Спасибо.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.08.2014, 17:29
Ответы с готовыми решениями:

Контекстное меню для TextBox на форме
Форумчане добрый вечер! Подскажите сложно сделать контекстное на поле TextBox типа: Отменить _________ Вырезать Копировать ...

Как создать контекстное меню. Например нажимая на richTextBox правой кнопкой мыши, мне бы предоставлялось контекстное меню
Как создать контекстное меню. Например нажимая на richTextBox правой кнопкой мыши, мне бы предоставлялось контекстное меню???

Контекстное меню по нажатию правой кнопки мыши на форме
Приветствую Вас! Подскажите пожалуйста, как сделать так, чтобы при нажатии в любом произвольном месте экрана правой кнопкой мыши,...

3
Модератор
10046 / 3892 / 883
Регистрация: 22.02.2013
Сообщений: 5,846
Записей в блоге: 79
05.08.2014, 21:35
Лучший ответ Сообщение было отмечено The trick как решение

Решение

Можно использовать меню, там пункты - есть объекты.
Вот накидал примерчик перетаскивание пунктов меню:
Visual Basic
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
Option Explicit
 
Private Type MENUINFO
   cbSize           As Long
   fMask            As Long
   dwStyle          As Long
   cyMax            As Long
   hbrBack          As Long
   dwContextHelpID  As Long
   dwMenuData       As Long
End Type
 
Private Declare Function SetMenuInfo Lib "user32.dll" (ByVal hmenu As Long, ByRef MENUINFO As MENUINFO) As Long
Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
 
Private Const WM_ENTERIDLE As Long = &H121
Private Const WM_MENUSELECT As Long = &H11F
Private Const WM_INITMENU As Long = &H116
Private Const WM_MENUDRAG = &H123
Private Const MIM_STYLE As Long = &H10
Private Const MNS_DRAGDROP = &H20000000
Private Const MF_MOUSESELECT As Long = &H8000&
Private Const MF_HILITE As Long = &H80&
 
Dim WithEvents oSub As clsTrickSubclass
 
Private Sub Form_Load()
    Dim mnu As Menu
    Dim idx As Long
    
    ' Создание динамического меню
    For idx = 0 To 10
        If idx Then Load mnuItem(idx)
        With mnuItem(idx)
            .Visible = True
            .caption = Choose(idx + 1, "Dinamic", "-", _
                                       "Moveable", "-", _
                                       "Menu", "-", _
                                       "Move", "-", _
                                       "Any", "Item", _
                                       "The trick")
        End With
    Next
    
    ' Включаем сабклассинг
    Set oSub = New clsTrickSubclass
    oSub.Hook hwnd
 
End Sub
 
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    
    ' Показываем меню при клике правой кнопкой мыши
    If Button = vbRightButton Then
        PopupMenu mnuContext
    End If
    
End Sub
 
Private Sub mnuItem_Click(Index As Integer)
    ' Пристанавливаем сабклассинг
    oSub.PauseSubclass
    ' Показываем пункт
    MsgBox mnuItem(Index).caption
    ' Возобновляем сабклассинг
    oSub.ResumeSubclass
End Sub
 
' Оконная процедура формы
Private Sub oSub_WndProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long, Ret As Long, DefCall As Boolean)
    Static selMenu  As Long         ' Текущий выделенный пункт
    Static isDrag   As Boolean      ' Идет ли перетаскивание
    Static dragIdx  As Long         ' Перетаскиваемый пункт
    
    Select Case Msg
    
    ' При инициализации меню, инициализируем данные
    Case WM_INITMENU
        
        Dim info    As MENUINFO
        
        isDrag = False
        selMenu = -1
        dragIdx = -1
        
        ' Задаем стиль перетаскиваемого меню, так мы сможем контролировать видимость меню
        info.cbSize = Len(info)
        info.fMask = MIM_STYLE
        info.dwStyle = MNS_DRAGDROP
        
        ' Задаем
        SetMenuInfo wParam, info
    
    ' При выделении очередного пункта
    Case WM_MENUSELECT
    
        Dim flags As Long
        
        ' Получаем флаги
        flags = wParam \ &H10000
        
        ' Если пунт выделен не мышкой, то значит нам не нужно
        If (flags And MF_MOUSESELECT) = 0 Then DefCall = True: Exit Sub
        
        ' Если пункт подсвечен, то делаем его текущим
        If flags And MF_HILITE Then
            selMenu = wParam And &HFFFF&
        Else
        ' Разделители и недоступные пункты не помечаем
            selMenu = -1
        End If
        
        ' Если идет перетаскивание
        If isDrag Then
            ' Проверяем корректность пунктов для обмена
            If selMenu > 0 And dragIdx > 0 And selMenu <> dragIdx Then
                
                Dim mnu1 As Menu
                Dim mnu2 As Menu
                
                ' Преобразуем индексы меню
                If selMenu = 2 Then selMenu = 3
                If dragIdx = 2 Then dragIdx = 3
                
                ' Получаем объекты
                Set mnu1 = IndexToMenu(selMenu - 2)
                Set mnu2 = IndexToMenu(dragIdx - 2)
                
                ' Обмен
                Swap mnu1, mnu2
 
                ' Завершаем перетаскивание
                isDrag = False
                dragIdx = -1
                
            End If
        End If
    
    ' Для того чтобы получить возможность отследить нажатия из формы
    Case WM_ENTERIDLE
    
        ' Получаем состояние левой кнопки мыши
        If GetKeyState(vbKeyLButton) < 0 Then
            ' Нажата
            ' Если нет перетаскивания и пункт корректный, то начинаем перетаскивание этого пункта
            If (Not isDrag) And selMenu >= 0 Then
                isDrag = True
                dragIdx = selMenu
            End If
        ' Иначе отменяем перетаскивание
        Else: isDrag = False
        End If
    
    ' Возвращаем 0, чтобы не закрывалось меню при перетаскивании
    Case WM_MENUDRAG
        
        Ret = 0
        Exit Sub
        
    End Select
    
    ' Остальное нас не интересует
    DefCall = True
    
End Sub
 
' Обмен свойств пунктов меню
Private Sub Swap(mnu1 As Menu, mnu2 As Menu)
    Dim caption As String
    Dim checked As Boolean
    
    caption = mnu1.caption
    checked = mnu1.checked
    
    mnu1.caption = mnu2.caption
    mnu1.checked = mnu2.checked
    
    mnu2.caption = caption
    mnu2.checked = checked
End Sub
 
' Получить меню по индексу
Private Function IndexToMenu(ByVal Index As Long) As Menu
    Dim ctl As Object
    
    For Each ctl In Controls
        If TypeOf ctl Is Menu Then
            If Index = 0 Then Set IndexToMenu = ctl: Exit Function
            Index = Index - 1
        End If
    Next
End Function
Вложения
Тип файла: rar MoveableMenu.rar (15.0 Кб, 23 просмотров)
2
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18030 / 7733 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
05.08.2014, 22:08  [ТС]
Привет.
В таком случае мне придется тебя взять соавтором, т.к. дальше без тебя не справлюсь )
Черт с ними, с разделителями. Мне твой вариант понравился )

В дополнение к этому мне еще нужно вторая и третья группа подменю.
(аналог контекстного -> Right Click -> Создать -> Папку, ... + еще подгрупа)

Добавлено через 13 минут
Хотя тут уже ничего сложного нет. Просто создается еще одно такое же меню
при наведении на какой-то из пунктов (если не включен режим isDrag (спасибо за комментарии)).

Так что сам разберусь.
Только стрелочку бы как-то дорисовать справа от пункта,
чтобы было понятно, что он каскадный.
0
Модератор
10046 / 3892 / 883
Регистрация: 22.02.2013
Сообщений: 5,846
Записей в блоге: 79
05.08.2014, 22:14
Цитата Сообщение от Dragokas Посмотреть сообщение
Черт с ними, с разделителями. Мне твой вариант понравился )
Разделители также можно перетаскивать, просто я убрал их и неактивные пункты из операции перетаскивания.
Цитата Сообщение от Dragokas Посмотреть сообщение
Хотя тут уже ничего сложного нет. Просто создается еще одно такое же меню
при наведении на какой-то из пунктов (если не включен режим isDrag (спасибо за комментарии)).
Можно просто создать каскадное меню, как обычно. Только при преобразовании индексов в объекты, нужно сначала определять подменю. В идеале лучше сделать таблицу соответствия. Либо полностью делать меню на WinApi (ничего сложного, почти также просто как и стандартное меню в VB6).
Цитата Сообщение от Dragokas Посмотреть сообщение
Только стрелочку бы как-то дорисовать справа от пункта, чтобы было понятно, что он каскадный.
Рисовать в пунктах можно задавая им стиль OWNERDRAW. Хотя можно просто написать [Создать >]
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
05.08.2014, 22:14
Помогаю со студенческими работами здесь

По следам темы "Контекстное меню для TextBox на форме"
Выделено из https://www.cyberforum.ru/ms-access/thread2423596.html Eugene-LS, Eugene-LS, Здравствуйте подключил ваш код V5 к базе...

Исчезает контекстное меню программ в меню пуск
Доброго всем дня. Недавно появилась такая проблема: Кликаю на кнопку ПУСК, затем на ВСЕ ПРОГРАММЫ, а затем правой кнопкой мыши на любой...

Вложенное меню, контекстное меню
1. После запуска программы в окне изображается строка меню (Файл, Выход). 2. При выборе пункта меню Файл появляются пункты меню (Рисунки,...

Контекстное меню
Как по клику на ListBoxe правой кнопкой мыши выделять запись и с помощью контекстного меню удалять выделенную запись ?

Контекстное меню
На форме имеется несколько мемо. Сделал контекстное меню со стандартными действиями и привязал его к каждому мемо. Проблема: например,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru