powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Меню через WinAPI
5 сообщений из 5, страница 1 из 1
Меню через WinAPI
    #40038575
Damir_85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте
Я сделал для формы меню из двух пунктов File и About. При выборе первого пункта меню File , выпадает подменю с командами New Save Exit. Т.к. в VBA нет компонента меню, то чтобы не искать сторонние компоненты, то сделал меню на WinAPI. Работает через субклассирование.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
Function WindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim lReturn As Long

    
  lReturn = CallWindowProc(OldWndProc, hwnd, Msg, wParam, lParam)
  MsgBox WM_COMMAND
  Select Case Msg
    Case WM_COMMAND
      Select Case LowOrd(wParam)
        Case 2
          MsgBox "О программе..."
        Case 10
          MsgBox "New..."
        Case 20
          MsgBox "Save..."
        Case 30
          MsgBox "Exit..."
      End Select
  End Select
  WindowProc = lReturn
End Function


Это часть кода.Для тестирования меню вывожу просто сообщение о выбранном пункте. Вопрос такой: если форма запускается в модальном режиме, то при выборе пунктов меню появляются соответствующие сообщения, а при немодальном форма виснет. Проверял в Excel. Приходиться запускать Диспетчер задач, чтобы закрыть Excel
Вот полный текст:
Код: 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.
Public Const MF_STRING = &H0&
Public Const MF_POPUP = &H10&
Public Const MF_SEPARATOR = &H800&
Public Const MF_GRAYED = &H1&
Public Const MF_BYCOMMAND = &H0&
Public Const TPM_RETRUNCMD = &H100&
Const GWL_WNDPROC = -4
Const WM_MENUSELECT = &H11F&
Const WM_COMMAND = &H111&
Const WM_CONTEXTMENU = &H7B&
Const WM_MENUBASE = &H2000&

Declare Function CreateMenu Lib "user32" () As Long
Declare Function CreatePopupMenu Lib "user32" () As Long
Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As Long, ByVal wflags As Long, ByVal wIDNewItem As Long, ByVal lpnewitem As String) As Long
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, lprc As Rect) As Long
Declare Function EnableMenuItem Lib "user32" (ByVal hMenu As Long, ByVal wIDEnableItem As Long, ByVal wEnable As Long) As Long
Declare Function SetMenu Lib "user32" (ByVal hwnd As Long, ByVal hMenu As Long) As Long
Declare Function DestroyMenu Lib "user32" (ByVal hMenu As Long) As Boolean

Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpclassname As String, ByVal lpwindowname As String) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Function LowOrd(DbleWord As Long) As Integer
    If DbleWord And &H8000& Then
        LowOrd = &H8000 Or (DbleWord And &H7FFF&)
    Else
        LowOrd = DbleWord And &HFFFF&
    End If
End Function

Function WindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim lReturn As Long

    
  lReturn = CallWindowProc(OldWndProc, hwnd, Msg, wParam, lParam)
  MsgBox WM_COMMAND
  Select Case Msg
    Case WM_COMMAND
      Select Case LowOrd(wParam)
        Case 2
          MsgBox "Î ïðîãðàììå"
        Case 10
          MsgBox "Ñîçäàòü ïðîôèëü..."
        Case 20
          MsgBox "Íàñòðîèòü ïðîôèëü..."
        Case 30
          MsgBox "Êàòàëîã ïðîôèëåé..."
      End Select
  End Select
  WindowProc = lReturn
End Function
 
Public Sub ActivateSub()
  Dim hMenu As Long
  Dim hPopupMenu As Long
  
  hwnd = FindWindow(vbNullString, "UserForm1")
  hMenu = CreateMenu()
  hPopupMenu = CreatePopupMenu()
  AppendMenu hMenu, MF_STRING Or MF_POPUP, hPopupMenu, "File"
  AppendMenu hMenu, MF_STRING, 2, "About"
  AppendMenu hPopupMenu, MF_STRING, 10, "New"
  AppendMenu hPopupMenu, MF_STRING, 20, "Save"
  AppendMenu hPopupMenu, MF_SEPARATOR, 600, ""
  AppendMenu hPopupMenu, MF_STRING, 30, "Exit"
  SetMenu hwnd, hMenu
  OldWndProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Public Sub DeactivateSub()
  SetWindowLong hwnd, GWL_WNDPROC, OldWndProc
End Sub



Все объявлено в стандартном модуле, Activate Sub вызывается при активации формы, Deactivate Sub при деактивации чтобы передать адрес на стандартную обработку сообщений
...
Рейтинг: 0 / 0
Меню через WinAPI
    #40038973
Eolt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Этот код не будет компилироваться, по причине отсутствия декларации используемых типов
...
Рейтинг: 0 / 0
Меню через WinAPI
    #40039542
Damir_85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Eolt, но он же запускается когда я форму в модальном режиме запускаю, и работает как надо. В немодальном режиме форма виснет вместе с родительским приложением, либо нужно на другое окно переключиться, а потом вернуться назад, либо диспетчером задачу снять. Немного не понял про декларацию типов. Вроде все объявлено
...
Рейтинг: 0 / 0
Меню через WinAPI
    #40039566
Eolt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Damir_85
Eolt, но он же запускается когда я форму в модальном режиме запускаю, и работает как надо. В немодальном режиме форма виснет вместе с родительским приложением, либо нужно на другое окно переключиться, а потом вернуться назад, либо диспетчером задачу снять. Немного не понял про декларацию типов. Вроде все объявлено


Не может он запускаться, сразу выдаст ошибку на неизвестном типе, вот тут к примеру

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, lprc As Rect ) As Long

Тип Rect не задекларирован в коде
...
Рейтинг: 0 / 0
Меню через WinAPI
    #40039701
Damir_85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Eolt, нет задекларирован. Я его не добавил на форум. Вот он:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Private Type Rect
left As Long
right As Long
top As Long
bottom As Long
End Type

Private Type POINTAPI
  x As Long
  y As Long
End Type


Но по сути, TrackPopupMenu и не нужен, я пытаюсь сделать верхнее меню. Вынужден пока контекстное использовать, поэтому есть объявление
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Меню через WinAPI
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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