DyadyaGenya
Знающий
- Сообщения
- 300
- Репутация
- 10
Доброго времени суток. Пробую создать выпадающий список, чтобы была возможность множественного выбора. Тоесть чтобы можно было выбрать несколько пунктов из выпадающего списка. Но пока у меня ничего не получается. На форуме нашел похожую тему https://autoit-script.ru/threads/gu...kix-variantov-iz-vypadajuschego-spiska.23324/
Хорошая штука, но интересно, есть выпадающие списки на основе GUICtrlCreateCombo или GUICtrlCreateCheckbox или нет?
Пробую на основе этого примера из меню сделать выпадающий комбосписок. Там функция-пример Example2() с кнопками. Делаю так:
Но как бы не совсем тот результат, что хотелось бы. Где и что не так я делаю?
Слегка продвинулся, уже можно сделать множественный выбор, но не все решилось. Сделал так:
Оставшиеся проблемы:
1. Не могу сделать проверку на выставленный чекбокс и считать текст выбранного пункта, хотя бы одного.
2. Выпадающий список гаснет (скрывается) после клика на любом из пунктов.
3. Забыл про третью проблему. Пока не получается сделать тоже самое с Combo списком. В примере пробы есть. Можно посмотреть результаты, если раскомментировать строки.
Нашел вот такой способ отслеживать клики: https://autoit-script.ru/docs/userfunctions/wm_command.htm
В этом примере вроде считывает значение выбранных пунктов. Попробовал использовать у себя, но почему-то текст пункта не читает, только его позицию (или порядковый номер). Может быть нужно все выделенные пункты считывать в массив, но с другой стороны, отражается реакция на установку/снятие галочки, значит можно и без массива. Делаю так:
И есть ещё одна проблема, странность. В оригинале функция WM_COMMAND запускается строкой:
Но в таком виде список хоть и работает, но клики по нему не считываются. Посмотрел что такое $WM_COMMAND. Константа из включенного файла WindowsConstants.au3 равная 0x0111. Подставил значение напрямую и в таком виде работает. В своем примере нерабочий вариант закоментил, чтоб была возможность проверить тем, кто заинтересовался.
Так что хоть слегка и продвинулся, но проблемы всё те же.
Хорошая штука, но интересно, есть выпадающие списки на основе GUICtrlCreateCombo или GUICtrlCreateCheckbox или нет?
Сообщение автоматически объединено:
Пробую на основе этого примера из меню сделать выпадающий комбосписок. Там функция-пример Example2() с кнопками. Делаю так:
Код:
#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <ComboConstants.au3>
#include <WindowsConstants.au3>
; Opt('MustDeclareVars', 1) ; принуждает объявлять все переменные
Global $hGui = GUICreate("Чекбоксы из меню", 400, 400)
Global $hCombo = GUICtrlCreateCombo("Выбрать пункт", 10, 10, 100, 0, $BS_FLAT) ; Если убрать $BS_FLAT, то остается только один пункт выпадающего списка. А с ним список заданного размера, при нажатии на который появляются пункты меню.
; Сначала создан элемент - пустышка (Dummy) и контекстное меню для него, которое будет пристроено к выпадающему списку
Global $OptionsDummy = GUICtrlCreateDummy()
;Создаем контекстное меню
Global $OptionsContext = GUICtrlCreateContextMenu($OptionsDummy)
; Создаем пункты меню
Global $Opt1 = GUICtrlCreateMenuItem("Пункт1", $OptionsContext)
;GUICtrlSetState(-1, $GUI_CHECKED) ; Устанавливаем чекбокс по умолчанию выбранным для элемента
Global $Opt2 = GUICtrlCreateMenuItem("Пункт2", $OptionsContext)
Global $Opt3 = GUICtrlCreateMenuItem("Пункт3", $OptionsContext)
Global $Opt4 = GUICtrlCreateMenuItem("Пункт4", $OptionsContext)
GUICtrlSetState(-1, $GUI_CHECKED)
Global $Opt5 = GUICtrlCreateMenuItem("Пункт5", $OptionsContext)
Global $Opt6 = GUICtrlCreateMenuItem("Пункт6", $OptionsContext)
Global $Opt7 = GUICtrlCreateMenuItem("Пункт7", $OptionsContext)
GUISetState()
While 1
Local $msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
ExitLoop
Case $hCombo
ShowMenu($hGui, $msg, $OptionsContext)
EndSwitch
WEnd
GUIDelete()
Но как бы не совсем тот результат, что хотелось бы. Где и что не так я делаю?
Сообщение автоматически объединено:
Слегка продвинулся, уже можно сделать множественный выбор, но не все решилось. Сделал так:
Код:
#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <WindowsConstants.au3>
; Opt('MustDeclareVars', 1) ; принуждает объявлять все переменные
Local $hGui, $OptionsBtn, $OptionsDummy, $OptionsContext, $msg
$hGui = GUICreate("Мой GUI", 400, 400)
; $OptionsBtn = GUICtrlCreateCombo("Выбор пункта", 10, 10, 100, 20, 0x3)
$OptionsBtn = GUICtrlCreateButton("Выбор пункта", 10, 10, 100, 20, 0x3)
; $OptionsBtn = GUICtrlCreateButton("Выбор пункта", 10, 10, 100, 20, $BS_FLAT)
; $OptionsBtn = GUICtrlCreateCombo("Выбрать пункт", 10, 10, 100, 20, $WS_TABSTOP + $CBS_DROPDOWN)
; Сначала создан элемент - пустышка (Dummy) и контекстное меню для него, которое будет пристроено к кнопке "Выбрать пункт"
$OptionsDummy = GUICtrlCreateDummy()
;Создаем контекстное меню
$OptionsContext = GUICtrlCreateContextMenu($OptionsDummy)
; Создаем пункты меню
$Opt1 = GUICtrlCreateMenuItem("Пункт1", $OptionsContext)
;GUICtrlSetState(-1, $GUI_CHECKED)
$Opt2 = GUICtrlCreateMenuItem("Пункт2", $OptionsContext)
$Opt3 = GUICtrlCreateMenuItem("Пункт3", $OptionsContext)
$Opt4 = GUICtrlCreateMenuItem("Пункт4", $OptionsContext)
$Opt5 = GUICtrlCreateMenuItem("Пункт5", $OptionsContext)
$Opt6 = GUICtrlCreateMenuItem("Пункт6", $OptionsContext)
$Opt7 = GUICtrlCreateMenuItem("Пункт7", $OptionsContext)
GUISetState()
While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
ExitLoop
Case $OptionsBtn
ShowMenu($hGui, $msg, $OptionsContext)
Case $Opt1 To $Opt7
If BitAND(GUICtrlRead($msg), $GUI_CHECKED) = $GUI_CHECKED Then
GUICtrlSetState($msg, $GUI_UNCHECKED)
Else
$check = GUICtrlSetState($msg, $GUI_CHECKED)
ConsoleWrite("Выбрано 1 " & GUICtrlRead($check, 1) & @CR)
EndIf
; По идее тут должна была бы сработать проверка хотя бы на один выставленный чекбокс, но не срабатывает
If _IsChecked($check) Then
ConsoleWrite("Выбрано 2 " & GUICtrlRead($msg) & @CR)
EndIf
EndSwitch
WEnd
GUIDelete()
;проверка чекбокса
Func _IsChecked($idControlID)
Return BitAND(GUICtrlRead($idControlID), $GUI_CHECKED) = $GUI_CHECKED
EndFunc ;==>_IsChecked
; Отображает меню в данном GUI окне, которое принадлежит данному элементу в GUI
Func ShowMenu($hWnd, $CtrlID, $nContextID)
ConsoleWrite("функция ShowMenu" & @CR)
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
; Конвертирует клиентские координаты (GUI) в абсолютные координаты экрана (desktop)
Func ClientToScreen($hWnd, ByRef $x, ByRef $y)
ConsoleWrite("функция ClientToScreen" & @CR)
Local $stPoint = DllStructCreate("int;int")
DllStructSetData($stPoint, 1, $x)
DllStructSetData($stPoint, 2, $y)
; См. также _WinAPI_ClientToScreen
DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint))
$x = DllStructGetData($stPoint, 1)
$y = DllStructGetData($stPoint, 2)
; обнулять структуру не обязательно, так как она локальна
$stPoint = 0
EndFunc
; Показать контекстное меню (hMenu) принадлежащее GUI окну (hWnd) в указанных координатах (x, y)
Func TrackPopupMenu($hWnd, $hMenu, $x, $y)
ConsoleWrite("функция TrackPopupMenu" & @CR)
; См. также _GUICtrlMenu_TrackPopupMenu
DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0)
EndFunc
1. Не могу сделать проверку на выставленный чекбокс и считать текст выбранного пункта, хотя бы одного.
2. Выпадающий список гаснет (скрывается) после клика на любом из пунктов.
Сообщение автоматически объединено:
3. Забыл про третью проблему. Пока не получается сделать тоже самое с Combo списком. В примере пробы есть. Можно посмотреть результаты, если раскомментировать строки.
Сообщение автоматически объединено:
Нашел вот такой способ отслеживать клики: https://autoit-script.ru/docs/userfunctions/wm_command.htm
В этом примере вроде считывает значение выбранных пунктов. Попробовал использовать у себя, но почему-то текст пункта не читает, только его позицию (или порядковый номер). Может быть нужно все выделенные пункты считывать в массив, но с другой стороны, отражается реакция на установку/снятие галочки, значит можно и без массива. Делаю так:
Код:
#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <WindowsConstants.au3>
#include <GuiMenu.au3>
; Opt('MustDeclareVars', 1) ; принуждает объявлять все переменные
Local $hGui, $OptionsBtn, $OptionsDummy, $OptionsContext, $msg
$hGui = GUICreate("Мой GUI", 400, 400)
GUIRegisterMsg(0x0111, "_WM_COMMAND")
; GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") ; этот вариант не работает, пояснения дальше.
; $OptionsBtn = GUICtrlCreateCombo("Выбор пункта", 10, 10, 100, 20, 0x3)
$OptionsBtn = GUICtrlCreateButton("Выбор пункта", 10, 10, 100, 20, 0x3)
; $OptionsBtn = GUICtrlCreateButton("Выбор пункта", 10, 10, 100, 20, $BS_FLAT)
; $OptionsBtn = GUICtrlCreateCombo("Выбрать пункт", 10, 10, 100, 20, $WS_TABSTOP + $CBS_DROPDOWN)
; Сначала создан элемент - пустышка (Dummy) и контекстное меню для него, которое будет пристроено к кнопке "Выбрать пункт"
$OptionsDummy = GUICtrlCreateDummy()
;Создаем контекстное меню
$OptionsContext = GUICtrlCreateContextMenu($OptionsDummy)
; Создаем пункты меню
$Opt1 = GUICtrlCreateMenuItem("Пункт1", $OptionsContext)
;GUICtrlSetState(-1, $GUI_CHECKED)
$Opt2 = GUICtrlCreateMenuItem("Пункт2", $OptionsContext)
$Opt3 = GUICtrlCreateMenuItem("Пункт3", $OptionsContext)
$Opt4 = GUICtrlCreateMenuItem("Пункт4", $OptionsContext)
$Opt5 = GUICtrlCreateMenuItem("Пункт5", $OptionsContext)
$Opt6 = GUICtrlCreateMenuItem("Пункт6", $OptionsContext)
$Opt7 = GUICtrlCreateMenuItem("Пункт7", $OptionsContext)
GUISetState()
While 1
$msg = GUIGetMsg()
;$hWnd = WinWaitActive("[CLASS:Мой GUI]")
Switch $msg
Case $GUI_EVENT_CLOSE
ExitLoop
Case $OptionsBtn
ShowMenu($hGui, $msg, $OptionsContext)
Case $Opt1 To $Opt7
If BitAND(GUICtrlRead($msg), $GUI_CHECKED) = $GUI_CHECKED Then
GUICtrlSetState($msg, $GUI_UNCHECKED)
Else
$check = GUICtrlSetState($msg, $GUI_CHECKED)
ConsoleWrite("Выбрано 1 " & GUICtrlRead($check) & GUICtrlRead($check, 0) & GUICtrlRead($check, 1) & @CR)
EndIf
; По идее тут должна была бы сработать проверка хотя бы на один выставленный чекбокс, но не срабатывает
If _IsChecked($check) Then
ConsoleWrite("Выбрано 2 " & GUICtrlRead($msg) & @CR)
EndIf
EndSwitch
WEnd
GUIDelete()
Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
ConsoleWrite("функция _WM_COMMAND" & @CR)
ConsoleWrite("Параметр $wParam = " & $wParam & @CR)
Local $nNotifyCode = BitShift($wParam, 16)
ConsoleWrite("Параметр $nNotifyCode = " & $nNotifyCode & @CR)
Local $nID = BitAND($wParam, 0x0000FFFF)
ConsoleWrite("Параметр $nID = " & $nID & ' = ' & GUICtrlRead($nID) & @CR)
;Local $nNotifyCode, $nID
Return "GUI_RUNDEFMSG"
EndFunc ;==>MY_WM_COMMAND
;проверка чекбокса
Func _IsChecked($idControlID)
Return BitAND(GUICtrlRead($idControlID), $GUI_CHECKED) = $GUI_CHECKED
EndFunc ;==>_IsChecked
; Отображает меню в данном GUI окне, которое принадлежит данному элементу в GUI
Func ShowMenu($hWnd, $CtrlID, $nContextID)
ConsoleWrite("функция ShowMenu" & @CR)
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
; Конвертирует клиентские координаты (GUI) в абсолютные координаты экрана (desktop)
Func ClientToScreen($hWnd, ByRef $x, ByRef $y)
ConsoleWrite("функция ClientToScreen" & @CR)
Local $stPoint = DllStructCreate("int;int")
DllStructSetData($stPoint, 1, $x)
DllStructSetData($stPoint, 2, $y)
; См. также _WinAPI_ClientToScreen
DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint))
$x = DllStructGetData($stPoint, 1)
$y = DllStructGetData($stPoint, 2)
; обнулять структуру не обязательно, так как она локальна
$stPoint = 0
EndFunc
; Показать контекстное меню (hMenu) принадлежащее GUI окну (hWnd) в указанных координатах (x, y)
Func TrackPopupMenu($hWnd, $hMenu, $x, $y)
ConsoleWrite("функция TrackPopupMenu" & @CR)
; См. также _GUICtrlMenu_TrackPopupMenu
DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0)
EndFunc
Код:
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
Но в таком виде список хоть и работает, но клики по нему не считываются. Посмотрел что такое $WM_COMMAND. Константа из включенного файла WindowsConstants.au3 равная 0x0111. Подставил значение напрямую и в таком виде работает. В своем примере нерабочий вариант закоментил, чтоб была возможность проверить тем, кто заинтересовался.
Так что хоть слегка и продвинулся, но проблемы всё те же.
Последнее редактирование: