powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Отслеживание перемещения по меню
15 сообщений из 15, страница 1 из 1
Отслеживание перемещения по меню
    #36278996
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хочется реализовать следующее:
При перемещении по меню выделяются его пункты.
Отследить выделение конкретного пункта и отобразить в Statusbar подсказку.
(Это применяется во многих программах, напр. Outlook Expess)
Пока не заморачиваюсь и использую стандартное меню vb6.
Про пункт меню вижу только 'Click'
Надо что-то типа OnSelected (menuitem)
Реализуемо ли это как нибудь по простому?
...
Рейтинг: 0 / 0
Отслеживание перемещения по меню
    #36279184
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет. Нужно сабклассить форму.

Jah loves you.
...
Рейтинг: 0 / 0
Отслеживание перемещения по меню
    #36279700
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо, не буду тратить время на ерунду.
За 10 лет работы с Outlook Express я только на днях обратил внимание на этот "эффект". Стало быть для юзера он бесполезен и его "внедрение" не стоит описанных усилий.
...
Рейтинг: 0 / 0
Отслеживание перемещения по меню
    #36289768
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С учетом новых экспериментов таки сделал:
http://www.vb-helper.com/howto_display_menu_message.html

Код: plaintext
1.
2.
3.
4.
5.
    '----------------------------------------------
    'загрузка событий меню
    OldMenuWindowProc = SetWindowLong( _
        hwnd, GWL_WNDPROC, _
        AddressOf NewMenuWindowProc)
    '----------------------------------------------

Код: plaintext
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.
Public Function NewMenuWindowProc(ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, _
  ByVal lParam As Long) As Long
  
Const WM_MENUSELECT = &H11F
Const WM_EXITMENULOOP = &H212
Const MF_BYPOSITION = &H400&

Dim menu_id As Long
Dim menu_caption As String
Dim menu_caption1 As String
Dim length As Long
    If msg = WM_MENUSELECT Then
        ' Get the menu ID.
        menu_id = (wParam And &HFFFF&)
        'menu_id = LowOrd(wParam)
        ' Get the menu caption.
        menu_caption = Space$( 1024 )
        length = GetMenuString(lParam, menu_id, menu_caption, _
            Len(menu_caption),  0 )
        menu_caption = Left$(menu_caption, length)
        If InStr(menu_caption, "ГЛЮК_TOP_MENU") >  0  Then 'View(main)-поправка
            menu_caption1 = Space$( 1024 )
            length = GetMenuString(lParam, menu_id, menu_caption1, _
                Len(menu_caption1), MF_BYPOSITION)
            menu_caption1 = Left$(menu_caption1, length)
            If (InStr(menu_caption1, "&View") >  0 ) And (InStr(menu_caption1, "F3") =  0 ) Then
                menu_caption = ""
            End If
        ElseIf InStr(menu_caption, ГЛЮК_ЕЩЕ") > 0 Then 'Help(main)-поправка
        '...
        End If
        
        Form1.StatusBar1.Panels(1).Text = GetHelpMenuStr(menu_caption)
    ElseIf msg = WM_EXITMENULOOP Then
        Form1.StatusBar1.Panels(1).Text = "Bla-bla-bla"
    End If

    ' Invoke the old menu proc.
    NewMenuWindowProc = CallWindowProc( _
        OldMenuWindowProc, hwnd, msg, wParam, _
        lParam)
End Function

1) Глючит оно только в некот.(известно каких) пунктах меню
Присваивает одинаковые menu_id 1-2-3-4 в верхней строке меню и первом столбце меню (пунктов у меня много), хотя lParam и разные, но результат один.
Получается два неоднозначных пункта с одинаковыми именами, приходится для них дополнительно вызывать MF_BYPOSITION чтобы отсечь верхнюю строку меню

2) При играх с WindowProc не только для меню, но и для Listview если в среде VB6 закрывать приложение крестиком (END засунуто в form_unload), то среда vb6 молча закрывается. Если END убрать закрывается с критической ошибкой. На работе приложения как exe это не сказывается.
Терпимо, но с чего бы это...
...
Рейтинг: 0 / 0
Отслеживание перемещения по меню
    #36291444
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С того, что не восстанавливаете оригинальную WindowProc.

Jah loves you.
...
Рейтинг: 0 / 0
Отслеживание перемещения по меню
    #36291859
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>не восстанавливаете оригинальную WindowProc
и как это сделать?
Что то добавить в ф-цию New*Winproc?
Или присвоить Old*WinProc чего нибудь при form_unload?
Я уже думал пробовал присваивать 0, vbNULL, NULL и т.п. Это не помогало...
...
Рейтинг: 0 / 0
Отслеживание перемещения по меню
    #36291972
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SetWindowLong( _
hwnd, GWL_WNDPROC, _
OldMenuWindowProc)

Jah loves you.
...
Рейтинг: 0 / 0
Отслеживание перемещения по меню
    #36292118
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Private Sub Form_Unload(Cancel As Integer)
    'отмена событий меню
    SetWindowLong hwnd, GWL_WNDPROC, _
        OldMenuWindowProc
    'отмена событий Toolbar
    SetWindowLong Toolbar1.hwnd, GWL_WNDPROC, _
        OldToolBarWindowProc
        MsgBox "ok"
    End
End Sub
Не-а.
vb6 схлопывается все равно как мыльный пузырь c ok или без него.
...
Рейтинг: 0 / 0
Отслеживание перемещения по меню
    #36292184
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выложите пример.

Jah loves you.
...
Рейтинг: 0 / 0
Отслеживание перемещения по меню
    #36292220
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А лучше посмотрите здесь как лично я устанавливаю и снимаю сабклассинг.
...
Рейтинг: 0 / 0
Отслеживание перемещения по меню
    #36292258
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Private Sub Form_Load()
...
    '----------------------------------------------
    'загрузка событий меню
    OldMenuWindowProc = SetWindowLong( _
        hwnd, GWL_WNDPROC, _
        AddressOf NewMenuWindowProc)
    'загрузка событий Toolbar
    OldToolBarWindowProc = SetWindowLong(Toolbar1.hwnd, GWL_WNDPROC, _
        AddressOf NewToolBarWindowProc)
    '----------------------------------------------
..
end sub
А сами ф-ции практически целиком приведены в этом топике и соседнем про toolbar
Но добавление "про меню" вполне достаточно (в form_load+ф-ция в модуле), чтоб этот "вылет" начал происходить при выходе.

Но не целый же код моего приложения выкладывать? Да и не хотелось бы
...
Рейтинг: 0 / 0
Отслеживание перемещения по меню
    #36292279
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еже это может быть из-за End, это глючная команда, не используйте ее.

Jah loves you.
...
Рейтинг: 0 / 0
Отслеживание перемещения по меню
    #36292435
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Странно, убрал END и даже без строк "восстанавливаете оригинальную WindowProc", то что пытался писать в form_unload, все стало корректно.
Но 2 дня назад без end вылетало с критич. ошибкой , вроде ничего сильно нового не дописывал, кроме WindowProc для toolbar, даже код "стопорить невидимые столбцы в ListView" еще не интегрировал.

А End я ставлю обычно на автомате, т.к. в нек. моих "разработках" после закрытия формы если этого не делать, приложение не закрывается (как правило если main+много форм и что-то м.б. упускаю). Здесь сейчас вроде закрывается, но кабы не сглазить, закрываться должно гарантированно.

М.б. проще это End все таки вставлять перед компиляцией конечного рабочего exe-шника?
Потому как для готового exe никаких негативов же нету.
...
Рейтинг: 0 / 0
Отслеживание перемещения по меню
    #36292668
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77если этого не делать, приложение не закрываетсяЭто означает, что приложение спроектировано не правильно, уничтожаются не все объекты, возможно где-то возникают циклические ссылки.

Jah loves you.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Отслеживание перемещения по меню
    #38226426
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий771) Глючит оно только в некот.(известно каких) пунктах меню
Присваивает одинаковые menu_id 1-2-3-4 в верхней строке меню и первом столбце меню (пунктов у меня много), хотя lParam и разные, но результат один.
Получается два неоднозначных пункта с одинаковыми именами, приходится для них дополнительно вызывать MF_BYPOSITION чтобы отсечь верхнюю строку меню

Недочитал я MSDN:
WM_MENUSELECT message
MSDNwParam
...If the selected item opens a drop-down menu or submenu, this parameter contains the index of the drop-down menu or submenu in the main menu, and the lParam parameter contains the handle to the main (clicked) menu; use the GetSubMenu function to get the menu handle to the drop-down menu or submenu.
Там другой код для drop-down menu or submenu должен быть.
Плюс надо отдельно заниматься SYSMENU (меню окна Restore...Move..Close)-либо подавлять, либо описывать.
Хотя мой старый (чуть глючный) код тьфу-тьфу подавлял пункты Sysmenu.

Как-то так:
Код: 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.
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.
Private Const WM_MENUSELECT = &H11F
Private Const WM_EXITMENULOOP = &H212
Private Const MF_BYPOSITION = &H400&
Private Const MF_POPUP = &H10&
Private Const MF_HILITE = &H80&
Private Const MF_SYSMENU = &H2000&

Private Const SC_RESTORE = &HF120&
Private Const SC_MOVE = &HF010&
Private Const SC_SIZE = &HF000&
Private Const SC_MINIMIZE = &HF020&
Private Const SC_MAXIMIZE = &HF030&
Private Const SC_CLOSE = &HF060&

...
  ' menu
  Dim menu_id As Long
  Dim menu_caption As String
  Dim length As Long
  Dim LW_wParam As Long 'LOWORD(wParam)
  Dim HW_wParam As Long 'HIWORD(wParam)


    Case WM_MENUSELECT 'menu
      LW_wParam = LOWORD(wParam)
      HW_wParam = HIWORD(wParam)
      Select Case LW_wParam
        Case SC_RESTORE 'SYSMENU
          menu_caption = "SC_RESTORE"
        Case SC_MOVE 'SYSMENU
          menu_caption = "SC_MOVE"
        Case SC_SIZE 'SYSMENU
          menu_caption = "SC_SIZE"
        Case SC_MINIMIZE 'SYSMENU
          menu_caption = "SC_MINIMIZE"
        Case SC_MAXIMIZE 'SYSMENU
          menu_caption = "SC_MAXIMIZE"
        Case SC_CLOSE 'SYSMENU
          menu_caption = "SC_CLOSE"
        Case Else
          If lParam = GetMenu(Form1.hWnd) Then
            menu_caption = "" 'не отображаем примечания для меню верхнего уровня
          ElseIf HW_wParam And MF_SYSMENU Then
            menu_caption = "" 'не отображаем примечания для системного меню верхнего уровня
          Else
            If HW_wParam And MF_POPUP Then
              'selected item opens a drop-down menu
              'wParam - contains the index of the drop-down menu or submenu in the main menu
              'lParam - contains the handle to the main (clicked) menu
              menu_id = GetSubMenu(lParam, LW_wParam)
            Else
              'command item
              'wParam - contains the identifier of the menu item
              'lParam - handle to the menu that was clicked
              menu_id = LW_wParam
             End If
            
            ' Get the menu caption.
            menu_caption = Space$(1024)
            length = GetMenuString(lParam, menu_id, menu_caption, _
             Len(menu_caption), 0)
            menu_caption = Left$(menu_caption, length)
          End If
      End Select
      Form1.StatusBar1.Panels(1).Text = GetHelpMenuStr(menu_caption)
    Case WM_EXITMENULOOP 'menu
      Form1.StatusBar1.Panels(1).Text = "My proga description"

Private Function GetHelpMenuStr(str As String) As String
  Dim temp As String
  If (str = "SC_RESTORE") Then 'SYSMENU
    temp = "Restore the window to normal size"
  ElseIf (str = "SC_MOVE") Then 'SYSMENU
    temp = "Change the window position"
  ElseIf (str = "SC_SIZE") Then 'SYSMENU
    temp = "Change the window size"
  ElseIf (str = "SC_MINIMIZE") Then 'SYSMENU
    temp = "Reduce the window to an icon"
  ElseIf (str = "SC_MAXIMIZE") Then 'SYSMENU
    temp = "Enlarge the window to full size"
  ElseIf (str = "SC_CLOSE") Then 'SYSMENU
    temp = "Close the active window and prompts to save the documents"
  '==================================
...
  ElseIf InStr(str, "E&xit") > 0 Then
    temp = "Quit the application"
  '==================================



Есть вопрос.
Существуют ли системные стандартные описания подпунктов SYSMENU типа

Код: vbnet
1.
2.
3.
4.
5.
  Dim temp As String
  If (str = "SC_RESTORE") Then 'SYSMENU
    temp = "Restore the window to normal size"
  ElseIf (str = "SC_MOVE") Then 'SYSMENU
    temp = "Change the window position"


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


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