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

Jah loves you.
...
Рейтинг: 0 / 0
29.10.2009, 14:11
    #36279700
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание перемещения по меню
Спасибо, не буду тратить время на ерунду.
За 10 лет работы с Outlook Express я только на днях обратил внимание на этот "эффект". Стало быть для юзера он бесполезен и его "внедрение" не стоит описанных усилий.
...
Рейтинг: 0 / 0
04.11.2009, 02:55
    #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
05.11.2009, 10:50
    #36291444
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание перемещения по меню
С того, что не восстанавливаете оригинальную WindowProc.

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

Jah loves you.
...
Рейтинг: 0 / 0
05.11.2009, 13:45
    #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
05.11.2009, 14:03
    #36292184
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание перемещения по меню
Выложите пример.

Jah loves you.
...
Рейтинг: 0 / 0
05.11.2009, 14:12
    #36292220
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание перемещения по меню
А лучше посмотрите здесь как лично я устанавливаю и снимаю сабклассинг.
...
Рейтинг: 0 / 0
05.11.2009, 14:21
    #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
05.11.2009, 14:26
    #36292279
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание перемещения по меню
Еже это может быть из-за End, это глючная команда, не используйте ее.

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

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

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

Jah loves you.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
15.04.2013, 17:44
    #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
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Отслеживание перемещения по меню / 15 сообщений из 15, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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