[решено] Создание меню кнопки

Аватара пользователя
malev

[решено] Создание меню кнопки

Сообщение malev »

Подскажите как создать меню кнопки, только не контекстное по правой кнопке мыши а обычное через левую. В справке по контекстному меню есть пример и с обычным для собственной кнопки, но как то слишком мудрено через вызовы dll. Есть ли вариант попроще.
Аватара пользователя
malev

Re: [решено] Создание меню кнопки

Сообщение malev »

Цитата malev:



В справке по контекстному меню есть пример и с обычным для собственной кнопки, но как то слишком мудрено через вызовы dll. Есть ли вариант попроще.
[решено] Создание меню кнопки




Нет, для показа меню (тем более в определённом месте) вызов Dll необходим.
Аватара пользователя
Creat0R

Re: [решено] Создание меню кнопки

Сообщение Creat0R »

Цитата malev:



но как то слишком мудрено через вызовы dll
[решено] Создание меню кнопки




Проще врятли есть... Просто не обращай внимания на те функции, работа которых непонятна и все.

Код:

Код: Выделить всё

#include 
Opt("GUIOnEventMode", 1) 
$hMainWin= GUICreate("Form1", 408, 229, 192, 193)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Pro_Exit") 
$hMainBut = GUICtrlCreateButton("Кнопка", 104, 56, 201, 97, 0)
GUICtrlSetOnEvent(-1, '_ButtonPressed') 
$hMenu = GUICtrlCreateContextMenu($hMainBut) 
GUICtrlCreateMenuItem('1', $hMenu) 
GUICtrlSetOnEvent(-1, '_1')
GUICtrlCreateMenuItem('2', $hMenu) 
GUICtrlSetOnEvent(-1, '_2') 
GUISetState(@SW_SHOW)
While 1
Sleep(50)
WEnd
Func _1() 
MsgBox(0,"","вызвана функция 1",2)
EndFunc 
Func _2() 
MsgBox(0,"","вызвана функция 2",2)
EndFunc 
Func _Pro_Exit()
Exit
EndFunc
Func _ButtonPressed() 
_ShowMenu($hMainWin, $hMainBut, $hMenu ) 
EndFunc 
;----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Func _ShowMenu($hWnd, $CtrlID, $nContextID) 
Local $arPos, $x, $y 
Local $hMenu = GUICtrlGetHandle($nContextID) 
$arPos = ControlGetPos($hWnd, "", $CtrlID) 
$x = $arPos[0] 
$y = $arPos[1] + $arPos[3] 
_ClientToScreen($hWnd, $x, $y) 
_TrackPopupMenu($hWnd, $hMenu, $x, $y) 
EndFunc ;==>ShowMenu 
; Convert the client (GUI) coordinates to screen (desktop) coordinates 
Func _ClientToScreen($hWnd, ByRef $x, ByRef $y) 
Local $stPoint = DllStructCreate("int;int") 
DllStructSetData($stPoint, 1, $x) 
DllStructSetData($stPoint, 2, $y) 
DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint)) 
$x = DllStructGetData($stPoint, 1) 
$y = DllStructGetData($stPoint, 2) 
; release Struct not really needed as it is a local 
$stPoint = 0 
EndFunc ;==>ClientToScreen 
; Show at the given coordinates (x, y) the popup menu (hMenu) which belongs to a given GUI window (hWnd) 
Func _TrackPopupMenu($hWnd, $hMenu, $x, $y) 
DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0) 
EndFunc ;==>TrackPopupMenu 
;----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Аватара пользователя
beve

Re: [решено] Создание меню кнопки

Сообщение beve »

Ну раз нельзя так нельзя, все равно спасибо
Аватара пользователя
malev

Re: [решено] Создание меню кнопки

Сообщение malev »

Ну раз нельзя так нельзя, все равно спасибо
Аватара пользователя
malev

Re: [решено] Создание меню кнопки

Сообщение malev »

Цитата malev:



как сделать меню с элементами цикле (ПунктМеню1, ПунктМеню2, ПунктМеню3) и чтобы для каждого была своя обработка
[решено] Создание меню кнопки




Изменённый пример из справки:





Код:

Код: Выделить всё

#include 
#include 
;
$hGUI = GUICreate("My GUI", 170, 40)
$OptionsBtn = GUICtrlCreateButton("&Options", 10, 10, 70, 20, $BS_FLAT)
; At first create a dummy control for the options and a contextmenu for it
$OptionsDummy = GUICtrlCreateDummy()
$OptionsContext = GUICtrlCreateContextMenu($OptionsDummy)
$OptionsCommon = GUICtrlCreateMenuItem("Common", $OptionsContext)
$OptionsFile = GUICtrlCreateMenuItem("File", $OptionsContext)
GUICtrlCreateMenuItem("", $OptionsContext)
$OptionsExit = GUICtrlCreateMenuItem("Exit", $OptionsContext)
$HelpBtn = GUICtrlCreateButton("&Help", 90, 10, 70, 20, $BS_FLAT)
; Create a dummy control and a contextmenu for the help too
$HelpDummy = GUICtrlCreateDummy()
$HelpContext = GUICtrlCreateContextMenu($HelpDummy)
$HelpWWW = GUICtrlCreateMenuItem("Website", $HelpContext)
GUICtrlCreateMenuItem("", $HelpContext)
$HelpAbout = GUICtrlCreateMenuItem("About...", $HelpContext)
GUISetState()
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $OptionsExit, $GUI_EVENT_CLOSE
            If $nMsg = $OptionsExit Then MsgBox(64, 'Title', "[Exit] item selected.", 0, $hGUI)
            ExitLoop
        Case $OptionsCommon
            MsgBox(64, 'Common...', "[Common] item selected.", 0, $hGUI)
        Case $OptionsFile
            MsgBox(64, 'File...', "[File] item selected.", 0, $hGUI)
        Case $OptionsBtn
            ShowMenu($hGUI, $nMsg, $OptionsContext)
        Case $HelpBtn
            ShowMenu($hGUI, $nMsg, $HelpContext)
        Case $HelpWWW
            MsgBox(64, "WWW...", "www.autoitscript.com", 0, $hGUI)
            ShellExecute("www.autoitscript.com")
        Case $HelpAbout
            MsgBox(64, "About...", "GUICtrlGetHandle-Sample", 0, $hGUI)
    EndSwitch
WEnd
; Show a menu in a given GUI window which belongs to a given GUI ctrl
Func ShowMenu($hWnd, $CtrlID, $nContextID)
    Local $arPos, $x, $y
    Local $hMenu = GUICtrlGetHandle($nContextID)
    $arPos = ControlGetPos($hWnd, "", $CtrlID)
    $x = $arPos[0]
    $y = $arPos[1] + $arPos[3]
    ClientToScreen($hWnd, $x, $y)
    TrackPopupMenu($hWnd, $hMenu, $x, $y)
EndFunc ;==>ShowMenu
; Convert the client (GUI) coordinates to screen (desktop) coordinates
Func ClientToScreen($hWnd, ByRef $x, ByRef $y)
    Local $stPoint = DllStructCreate("int;int")
    DllStructSetData($stPoint, 1, $x)
    DllStructSetData($stPoint, 2, $y)
    DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint))
    $x = DllStructGetData($stPoint, 1)
    $y = DllStructGetData($stPoint, 2)
    ; release Struct not really needed as it is a local
    $stPoint = 0
EndFunc ;==>ClientToScreen
; Show at the given coordinates (x, y) the popup menu (hMenu) which belongs to a given GUI window (hWnd)
Func TrackPopupMenu($hWnd, $hMenu, $x, $y)
    DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0)
EndFunc ;==>TrackPopupMenu
Аватара пользователя
Creat0R

Re: [решено] Создание меню кнопки

Сообщение Creat0R »

Это не то, во-первых создание пунктов меню должно идти в цикле, во вторых заранее неизвестно количество пунктов меню. Вот обрывки кода, с первым вроде разобрался, а вот со вторым нет



Код:

Код: Выделить всё

$max=IniRead("my.ini","Main","Max","1")
Dim $conMenu[$max]
For $men=1 to $max
    $conMenu[$men-1]=GUICtrlCreateMenuItem(IniRead("my.ini","CAP" & $men,"Caption","xxx"), $cmdUpd_submenu)
    GUICtrlSetOnEvent(-1, ?????)
Next
$nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $conMenu[0]
            MsgBox (0,"","000")
        Case $conMenu[1]
            MsgBox (0,"","111")
................................
        Case $conMenu[???]
            MsgBox (0,"","???")

GUICtrlSetOnEvent можно конечно не вызывать если напрямую использую или если вызывать то какую функцию ставить в параметрах, просто Menu не подойдет.



Может GUIGetMsg (1) вызывать??? Если да то что искать...
Аватара пользователя
malev

Re: [решено] Создание меню кнопки

Сообщение malev »

Цитата malev:



GUICtrlSetOnEvent можно конечно не вызывать
[решено] Создание меню кнопки




Оно вообще не нужно если обработка не происходит в режиме событии.



То что вам нужно так это использование возможностей Case:



Код:

Код: Выделить всё

$nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $conMenu[0] To $conMenu[$max]
            MsgBox (0,"", GUICtrlRead($nMsg)) ;Тут используем $nMsg, это и есть идентификатор вызванного контроля (пункт меню)


Цитата:



$conMenu[$men-1[/i]]



Вообще то лучше убрать -1, а в начале при объявлении массива добвавить (Dim $conMenu[$max+1]).



И ещё, это может быть опасно вот так задавать размерность массива используя переменную возвращаемую от IniRead ($max). Юзер ведь может там написать -1, и тогда скрипт вывалится с фатальной ошибкой (определение размерности массива). Нужно делать проверку таких переменных.




Цитата malev:



GUICtrlSetOnEvent(-1, ?????)
[решено] Создание меню кнопки




Нужно задать в начале Opt("GUIOnEventMode", 1), и тогда обрабатывать не в цикле, а в функции:





Код:

Код: Выделить всё

Opt("GUIOnEventMode", 1)
.....
For $men=1 to $max
    $conMenu[$men-1]=GUICtrlCreateMenuItem(IniRead("my.ini","CAP" & $men,"Caption","xxx"), $cmdUpd_submenu)
    GUICtrlSetOnEvent(-1, "_MenuEvents")
Next
.....
Func _MenuEvents()
    MsgBox(0,"", GUICtrlRead(@GUI_CtrlId)) ;Тут используем @GUI_CtrlId, это и есть идентификатор вызванного контроля (пункт меню)
EndFunc
Аватара пользователя
malev

Re: [решено] Создание меню кнопки

Сообщение malev »

MsgBox (0,"", GUICtrlRead($nMsg)) - возвращает почему-то одно и тоже у меня к примеру 68. А мне надо например 68, 69 или 70 для 3-х пунктов меню
Аватара пользователя
Creat0R

Re: [решено] Создание меню кнопки

Сообщение Creat0R »

Цитата malev:



возвращает почему-то одно и тоже у меня к примеру 68
[решено] Создание меню кнопки




Это состояние (State) элемента. Я забыл, для получения текста нужно так - GUICtrlRead($nMsg, 1).




Цитата malev:



А мне надо например 68, 69 или 70 для 3-х пунктов меню
[решено] Создание меню кнопки




Т.е идентификаторы? Ну так я же написал, $nMsg это и есть ID.
Ответить

Вернуться в «AutoIt»