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

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

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

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

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

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

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

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

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

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

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

3
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 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
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
05.08.2014, 22:08  [ТС]
Привет.
В таком случае мне придется тебя взять соавтором, т.к. дальше без тебя не справлюсь )
Черт с ними, с разделителями. Мне твой вариант понравился )

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

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

Так что сам разберусь.
Только стрелочку бы как-то дорисовать справа от пункта,
чтобы было понятно, что он каскадный.
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru