Автор Тема: Контекстное меню для пунктов меню трея  (Прочитано 538 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Vanguger [?]

  • Новичок
  • *
  • Сообщений: 34
  • Репутация: 0
  • Пол: Мужской
    • Webarion
    • Награды
  • Версия AutoIt: 3.3.14.0
Привет! Подскажите, как, или возможно ли вообще сделать контекстное меню, открывающееся кликом правой кнопки мыши, по пунктам меню в трее. Нужно, чтобы клик ПКМ по [Пункт1,Пункт2] открывал контекстное меню [Действие1,Действие2,Действие3]:

Код: AutoIt [Выделить]
#Include <ModernMenuRaw.au3>
#NoTrayIcon

Opt("TrayMenuMode", 1 + 2)
_TrayIconSetClick(-1, 2 + 16)

_TrayIconCreate("", @AutoItExe, -1)
_TrayCreateContextMenu()
_TrayIconSetState()

$i1 =_TrayCreateItem('Пункт1')
$i2 =_TrayCreateItem('Пункт2')


Русское сообщество AutoIt

Контекстное меню для пунктов меню трея
« Отправлен: Июль 04, 2018, 03:40:34 »

Оффлайн alex33 [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 1419
  • Репутация: 177
  • Пол: Мужской
    • alekssamos ВКонтакте
    • Награды
  • Версия AutoIt: 3.3.12.0
Пример из справки:
Код: AutoIt [Выделить]
$iSettings = TrayCreateMenu("Настройки") ; Создаёт меню трея и подменю с двумя пунктами.
$iDisplay = TrayCreateItem("Монитор", $iSettings)
$iPrinter = TrayCreateItem("Принтер", $iSettings)

А если обойтись обычными подменю?


Добавлено: Июль 04, 2018, 14:07:27
Я никогда и не видел таких меню, в которых еще одно по правому клику открывается. Разве что меню Пуск.

Оффлайн Vanguger [?]

  • Новичок
  • *
  • Сообщений: 34

  • Автор темы
  • Репутация: 0
  • Пол: Мужской
    • Webarion
    • Награды
  • Версия AutoIt: 3.3.14.0
Я тоже не видел подобной реализации, но вдруг) У меня в меню трея, висят файлы для быстрого доступа, и вот понадобилось сделать выбор из нескольких действий по отношению к файлу. Самое идеальное для меня, это дополнительное меню через ПКМ. А обычное подменю не использую, так как прикручены иконки от файлов. В общем это похоже на меню Open Server своей реализации.

Оффлайн Vanguger [?]

  • Новичок
  • *
  • Сообщений: 34

  • Автор темы
  • Репутация: 0
  • Пол: Мужской
    • Webarion
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Контекстное меню для пунктов меню трея
« Ответ #3, Отправлен: Август 16, 2018, 05:50:58 »
Немного приблизился к решению, но есть загвоздка. В следующем примере при клике правой в любом месте, меню появляется, а в меню трея нет, блокирует. Вот как бы это обойти?

Код: AutoIt [Выделить]
#include <WindowsConstants.au3>
#include <GuiMenu.au3>
#include <WinAPI.au3>

#include <UserInput.au3>

Opt('TrayMenuMode', 3)

$m1 = TrayCreateMenu("M1")
$m1i1 = TrayCreateItem('M1I1', $m1)
$m1i2 = TrayCreateItem('M1I2', $m1)
$m1i3 = TrayCreateItem('M1I3', $m1)
$m2 = TrayCreateMenu("M2")
$m2i1 = TrayCreateItem('M2I1', $m2)
$m2i2 = TrayCreateItem('M2I2', $m2)
$m2i3 = TrayCreateItem('M2I3', $m2)

$i1 = TrayCreateItem('I1')
$i2 = TrayCreateItem('I2')

TrayCreateItem('')
$Exit = TrayCreateItem('Exit')

TraySetState()

While 1
    $aRead = _UserInput_Read('[:ALLMOUSE:]')
    If $aRead[0] Then
        If $aRead[1] = '02' Then
            ConsoleWrite('Клик правой'&@CRLF)
            _ShowPopupMenu_Proc()
        EndIf
    EndIf
    Sleep(10)
WEnd


Func _ShowPopupMenu_Proc()
    Local $hDlg, $cDummy, $nContextMenu, $hContextMenu, $nHide_MItem, $nExit_MItem, $hTimer, $aMousePos, $nResult
    $hDlg = GUICreate('', 1, 1, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW)
    $cDummy = GUICtrlCreateDummy()
    $nContextMenu = GUICtrlCreateContextMenu($cDummy)
    $hContextMenu = GUICtrlGetHandle($nContextMenu)
    $nHide_MItem = GUICtrlCreateMenuItem('Пункт1', $nContextMenu)
    $nShowMsg_MItem = GUICtrlCreateMenuItem('Пункт2', $nContextMenu)
    GUICtrlCreateMenuItem('', $nContextMenu)
    $nExit_MItem = GUICtrlCreateMenuItem('Выход', $nContextMenu)
    GUISetState(@SW_SHOW, $hDlg)
    $aMousePos = MouseGetPos()
    $nResult = _GUICtrlMenu_TrackPopupMenu($hContextMenu, $hDlg, $aMousePos[0] - 27, $aMousePos[1] - 12, 1, 1, 2)
    Switch $nResult
        Case $nShowMsg_MItem
            MsgBox(64, 'Заголовок', 'Сообщение')
        Case $nExit_MItem
            Exit
    EndSwitch
    GUIDelete($hDlg)
EndFunc   ;==>_ShowPopupMenu_Proc
 


Русское сообщество AutoIt

Re: Контекстное меню для пунктов меню трея
« Ответ #3 Отправлен: Август 16, 2018, 05:50:58 »

Оффлайн InnI [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 3887
  • Репутация: 1023
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Контекстное меню для пунктов меню трея
« Ответ #4, Отправлен: Август 16, 2018, 14:47:17 »
Vanguger
Для AutoIt отображение всплывающего меню такая же блокирующая операция, как вывод MsgBox.

Оффлайн Vanguger [?]

  • Новичок
  • *
  • Сообщений: 34

  • Автор темы
  • Репутация: 0
  • Пол: Мужской
    • Webarion
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Контекстное меню для пунктов меню трея
« Ответ #5, Отправлен: Август 16, 2018, 19:27:10 »
Для AutoIt отображение всплывающего меню такая же блокирующая операция, как вывод MsgBox.

Хорошо, тогда, как в данном примере, программно закрыть меню трея, чтобы после закрытия отобразилось контекстное? Я что-то не нашел способ, должен же он быть.
Мне для этой структуры нужен доп. функционал по правой:
Нажмите для отображения изображения в оригинальном размере.
« Последнее редактирование: Август 16, 2018, 20:08:53 от Vanguger »

Оффлайн InnI [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 3887
  • Репутация: 1023
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Контекстное меню для пунктов меню трея
« Ответ #6, Отправлен: Август 17, 2018, 02:50:08 »
Как вариант
Код: AutoIt [Выделить]
#include <WindowsConstants.au3>
#include <TrayConstants.au3>
#include <SendMessage.au3>
#include <WinAPISys.au3>
#include <GuiMenu.au3>
#include <Timers.au3>
#include <Misc.au3>

Opt("TrayMenuMode", 3)
Opt("WinWaitDelay", 11)

$MainItemName = ""
$ShowPopup = False

$GUI = GUICreate("", 0, 0, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW)
GUISetState()

$MainDummy = GUICtrlCreateDummy()
$MainPopup = GUICtrlCreateContextMenu($MainDummy)
$M1 = GUICtrlCreateMenu("M1", $MainPopup)
$M11 = GUICtrlCreateMenuItem("M11", $M1)
$M12 = GUICtrlCreateMenuItem("M12", $M1)
$M2 = GUICtrlCreateMenu("M2", $MainPopup)
$M21 = GUICtrlCreateMenuItem("M21", $M2)
$M22 = GUICtrlCreateMenuItem("M22", $M2)
$M3 = GUICtrlCreateMenuItem("M3", $MainPopup)
$M4 = GUICtrlCreateMenuItem("M4", $MainPopup)

$cDummy = GUICtrlCreateDummy()
$nContextMenu = GUICtrlCreateContextMenu($cDummy)
$nHide_MItem = GUICtrlCreateMenuItem("Пункт1", $nContextMenu)
$nShowMsg_MItem = GUICtrlCreateMenuItem("Пункт2", $nContextMenu)
GUICtrlCreateMenuItem("", $nContextMenu)
$nExit_MItem = GUICtrlCreateMenuItem("Выход", $nContextMenu)

While 1
  Switch TrayGetMsg()
    Case $TRAY_EVENT_SECONDARYUP
      $Timer = _Timer_SetTimer($GUI, 33, "Timer")
      _GUICtrlMenu_TrackPopupMenu(GUICtrlGetHandle($MainPopup), $GUI)
  EndSwitch
  Switch GUIGetMsg()
    Case $M11
      MsgBox(0, "", "Выбран пункт M11")
    Case $M12
      MsgBox(0, "", "Выбран пункт M12")
    Case $M21
      MsgBox(0, "", "Выбран пункт M21")
    Case $M22
      MsgBox(0, "", "Выбран пункт M22")
    Case $M3
      MsgBox(0, "", "Выбран пункт M3")
    Case $M4
      MsgBox(0, "", "Выбран пункт M4")
    Case $nHide_MItem
      MsgBox(0, "", "Пункт1 вызван для " & $MainItemName)
    Case $nShowMsg_MItem
      MsgBox(0, "", "Пункт2 вызван для " & $MainItemName)
    Case $nExit_MItem
      Exit
  EndSwitch
  If $ShowPopup Then
    $ShowPopup = False
    _GUICtrlMenu_TrackPopupMenu(GUICtrlGetHandle($nContextMenu), $GUI)
  EndIf
WEnd

Func Timer($hWnd, $iMsg, $iIDTimer, $iTime)
  If _IsPressed("02") Then
    _Timer_KillTimer($GUI, $Timer)
    While _IsPressed("02")
      Sleep(11)
    WEnd
    $MainItemName = ""
    Local $tPoint = _WinAPI_GetMousePos()
    Local $PopUp = _WinAPI_WindowFromPoint($tPoint)
    If _WinAPI_GetClassName($PopUp) = "#32768" Then
      Local $hMenu = _SendMessage($PopUp, $MN_GETHMENU)
      $MainItemName = _GUICtrlMenu_GetItemText($hMenu, _GUICtrlMenu_MenuItemFromPoint($PopUp, $hMenu))
      $ShowPopup = True
    EndIf
    WinActivate("[class:#32768]")
  EndIf
EndFunc


Оффлайн Vanguger [?]

  • Новичок
  • *
  • Сообщений: 34

  • Автор темы
  • Репутация: 0
  • Пол: Мужской
    • Webarion
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Контекстное меню для пунктов меню трея
« Ответ #7, Отправлен: Август 17, 2018, 05:16:31 »
Как вариант

Благодарю InnI! Внимательно изучу этот вариант. Я то уже начал подумывать в сторону имитации контекстного меню, с нужным функционалом, без блокировки. Тоже уже набросал немного сырой, но работающий. С костылями, ну блин :stars:, хоть как-то уже, для себя пойдёт.

Код: AutoIt [Выделить]
#include <MouseOnEvent.au3>
#include <GuiMenu.au3>
Opt('TrayMenuMode', 3)

$m1 = TrayCreateMenu("M1")
$m1i1 = TrayCreateItem('M1I1', $m1)
$m1i2 = TrayCreateItem('M1I2', $m1)
$m1i3 = TrayCreateItem('M1I3', $m1)
$m2 = TrayCreateMenu("M2")
$m2i1 = TrayCreateItem('M2I1', $m2)
$m2i2 = TrayCreateItem('M2I2', $m2)
$m2i3 = TrayCreateItem('M2I3', $m2)
$i1 = TrayCreateItem('I1')
$i2 = TrayCreateItem('I2')
TrayCreateItem('')
$Exit = TrayCreateItem('Exit')

TraySetState()

$hMenu = TrayItemGetHandle(0)

_MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT, "__ClickMouseR")

While 1
  Switch TrayGetMsg()
        Case $Exit
            Exit
    EndSwitch
    Sleep(10)
WEnd

Func __ClickMouseR()

Local $sPMLine = "" & @CRLF
    $sPMLine &= "#include <WindowsConstants.au3>" & @CRLF
    $sPMLine &= "#include <GuiMenu.au3>" & @CRLF
    $sPMLine &= "Local $hDlg, $cDummy, $nContextMenu, $hContextMenu, $nHide_MItem, $nExit_MItem, $hTimer, $aMousePos, $nResult" & @CRLF
    $sPMLine &= "$hDlg = GUICreate('', 1, 1, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW)" & @CRLF
    $sPMLine &= "$cDummy = GUICtrlCreateDummy()" & @CRLF
    $sPMLine &= "$nContextMenu = GUICtrlCreateContextMenu($cDummy)" & @CRLF
    $sPMLine &= "$hContextMenu = GUICtrlGetHandle($nContextMenu)" & @CRLF
    $sPMLine &= "$nHide_MItem = GUICtrlCreateMenuItem('Пункт1', $nContextMenu)" & @CRLF
    $sPMLine &= "$nShowMsg_MItem = GUICtrlCreateMenuItem('Пункт2', $nContextMenu)" & @CRLF
    $sPMLine &= "GUISetState(@SW_SHOW, $hDlg)" & @CRLF
    $sPMLine &= "$aMousePos = MouseGetPos()" & @CRLF
    $sPMLine &= "$nResult = _GUICtrlMenu_TrackPopupMenu($hContextMenu, $hDlg, $aMousePos[0]-50, $aMousePos[1]-10, 1, 1, 2)" & @CRLF
    $sPMLine &= "Switch $nResult" & @CRLF
    $sPMLine &= "   Case $nShowMsg_MItem" & @CRLF
    $sPMLine &= "       MsgBox(64, 'Заголовок', 'Сообщение')" & @CRLF
    $sPMLine &= "EndSwitch" & @CRLF
    $sPMLine &= "GUIDelete($hDlg)" & @CRLF
    $sPMLine &= "FileDelete(@ScriptFullPath)" & @CRLF
    $sPMLine &= "Exit" & @CRLF

    Local $hFile = FileOpen(@ScriptDir & '\consoleMenu.tmp', 2)
    FileWrite($hFile, $sPMLine)
    FileClose($hFile)

    Run(@AutoItExe & ' /AutoIt3ExecuteScript "' & @ScriptDir & '\consoleMenu.tmp"')

EndFunc   ;==>_ShowPopupMenu_Proc
 



Добавлено: Август 17, 2018, 07:41:44
В общем, всё у меня получилось. Так как список приложений для меню у меня отдаёт модуль(отдельный скрипт) и он же обрабатывает клики, то ему я и поручил создавать дополнительное контекстное меню. Ядро в этом случае просто говорит модулю, что клик правой кнопкой и отдаёт ему параметры клика. Получилось так как нужно и даже менюха не закрывается  :ok:

InnI, спасибо за подсказки!
« Последнее редактирование: Август 31, 2018, 17:38:32 от Vanguger »

Русское сообщество AutoIt

Re: Контекстное меню для пунктов меню трея
« Ответ #7 Отправлен: Август 17, 2018, 05:16:31 »

Оффлайн Vanguger [?]

  • Новичок
  • *
  • Сообщений: 34

  • Автор темы
  • Репутация: 0
  • Пол: Мужской
    • Webarion
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Контекстное меню для пунктов меню трея
« Ответ #8, Отправлен: Сентябрь 15, 2018, 02:45:47 »
Протестировал пару недель то, что у меня здесь ранее получилось. Должен сказать, что без глюков не обошлось. Контекстное меню, которое вызывается из стороннего скрипта, хоть и накладывается на основное, но вызывает некоторые аномалии и неудобства в работе, иногда это приводит к зависанию. Поэтому мне пришлось создать имитацию контекстного меню без блокировки, и с теми возможностями, которые мне были нужны. Результат на скриншоте. Пример ниже, под спойлером, можно скачать сразу архивом. Возможно кому-то и пригодится. Версия AutoIt 3.3.14.5, другие не проверял. Конечно есть ещё тут над чем поработать, но в целом такое поведение КМ меня устраивает:

ContextLM.au3
(нажмите для показа/скрытия)

Пример.au3
(нажмите для показа/скрытия)

Архив с подробным описанием:
https://yadi.sk/d/0ZrPOdL4fKiKRg

Скриншот:
Нажмите для отображения изображения в оригинальном размере.
« Последнее редактирование: Сентябрь 15, 2018, 14:13:48 от Vanguger, Причина: обновление кода »

Русское сообщество AutoIt

Re: Контекстное меню для пунктов меню трея
« Ответ #8 Отправлен: Сентябрь 15, 2018, 02:45:47 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
2 Ответов
5053 Просмотров
Последний ответ Январь 26, 2010, 03:38:33
от Alexey
17 Ответов
11195 Просмотров
Последний ответ Ноябрь 07, 2010, 11:57:05
от aleratorio
0 Ответов
1947 Просмотров
Последний ответ Январь 21, 2012, 20:08:29
от komorov74
2 Ответов
1772 Просмотров
Последний ответ Март 06, 2014, 14:40:21
от erlik
4 Ответов
1147 Просмотров
Последний ответ Апрель 27, 2014, 03:49:18
от joiner
8 Ответов
2829 Просмотров
Последний ответ Июль 09, 2015, 06:20:32
от pvnn
6 Ответов
1793 Просмотров
Последний ответ Март 30, 2016, 16:53:24
от InnI
2 Ответов
726 Просмотров
Последний ответ Февраль 23, 2017, 11:45:15
от Khaibit
0 Ответов
690 Просмотров
Последний ответ Апрель 20, 2017, 19:46:49
от Pahuchiy
1 Ответов
518 Просмотров
Последний ответ Январь 22, 2018, 19:05:00
от Alofa