Что нового

Видимое содержимое невидимого окна

Prog

Продвинутый
Сообщения
640
Репутация
80
Это значит что, что я могу абсолютно безбоязненно гонять эту прогру часами?
Нагрузка на ЦП это нормально и комп сломаться не должен, если вы об этом.
Я это все знаю, но там получается галочки на пункты контекстного ставить не получается.
Я не просто так дал ссылку на функцию GUICtrlCreateMenu. Там находится пример установки / снятия галочки.
Код:
#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>

Example1()

; Пример 1GUICtrlCreateMenu

Func Example1()
    Local $contextmenu, $button, $buttoncontext, $buttonitem, $msg
    Local $newsubmenu, $textitem, $fileitem, $saveitem, $infoitem

    ; правый клик на gui выводит контекстное меню.
    ; правый клик на кнопке "ok" выводит контекстное меню кнопки.

    GUICreate("Моё контекстное меню в GUI", 300, 200)

    $contextmenu = GUICtrlCreateContextMenu()

    $button = GUICtrlCreateButton("OK", 100, 100, 70, 20)
    $buttoncontext = GUICtrlCreateContextMenu($button)
    $buttonitem = GUICtrlCreateMenuItem("О кнопке", $buttoncontext)

    $newsubmenu = GUICtrlCreateMenu("Новое", $contextmenu)
    $textitem = GUICtrlCreateMenuItem("Текст", $newsubmenu)

    $fileitem = GUICtrlCreateMenuItem("Открыть", $contextmenu)
    $saveitem = GUICtrlCreateMenuItem("Сохранить", $contextmenu)
    GUICtrlCreateMenuItem("", $contextmenu) ; разделитель

    $infoitem = GUICtrlCreateMenuItem("Информация", $contextmenu)

    GUISetState()

    ; Запускается цикл опроса GUI до тех пор пока окно не будет закрыто
    While 1
        $msg = GUIGetMsg()

        if $msg = $infoitem Then
             If BitAND(GUICtrlRead($infoitem), $GUI_CHECKED) = $GUI_CHECKED Then ; Если галочка в наличии, тогда
                GUICtrlSetState($infoitem, $GUI_UNCHECKED) ; Убирает галочку
            Else ; Иначе
                GUICtrlSetState($infoitem, $GUI_CHECKED) ; Ставит галочку
             EndIf
        endif

        If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    WEnd
    GUIDelete()
EndFunc
Кликайте по пункту "Информация".
 
Автор
M

mathem

Новичок
Сообщения
68
Репутация
0
Нагрузка на ЦП это нормально и комп сломаться не должен, если вы об этом.
Спасибо большое! Эти слова сказаны именно в той форме, которую мне нужно было.
Я не просто так дал ссылку на функцию GUICtrlCreateMenu. Там находится пример установки / снятия галочки.
Я тут ползаморочился с получением в читабельном для человека виде состояний элементов Gui. На идею меня натолкнула пример к функции GUICtrlGetState и я попробовал так:
Код:
#include <GUIConstants.au3>

GUICreate("My GUI")
$radio2 = GUICtrlCreateRadio ("Radio 2", 10, 40, 120, 20)
$button2 = GUICtrlCreateButton ("Button 2", 10+150, 40, 120, 20)
GUISetState (@SW_SHOW)

While 1
    $msg = GUIGetMsg()
   
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    Select
    Case $msg = $button2
        $data2 = StringFormat('%d', GUICtrlRead($radio2))
        MsgBox(4096, '', "Состояние $radio2: " & $data2)
    EndSelect
Wend

Да, выводить-то это выводило правильно состояние $radio2, когда $radio2 отмечено и не отмечено, но у меня было такое впечатление, что применение функции StringFormat в данном случае - это как из пушки по воробьям. Тогда я попробовал более простой вариант:
Код:
#include <GUIConstants.au3>

GUICreate("My GUI")
$radio2 = GUICtrlCreateRadio ("Radio 2", 10, 40, 120, 20)
$button2 = GUICtrlCreateButton ("Button 2", 10+150, 40, 120, 20)
GUISetState (@SW_SHOW)

While 1
    $msg = GUIGetMsg()
   
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    Select
    Case $msg = $button2
        $data2 = String(GUICtrlRead($radio2))
        MsgBox(4096, '', "Состояние $radio2: " & $data2)
    EndSelect
Wend

И снова все работало как и ожидалось, но и снова осталось ощущение еще не до конца упрощенности кода. Наконец я попробовал такой вариант (заодно и попробовал изменять с помощью полученных сведений состояния элементов окна):
Код:
#include <GUIConstants.au3>
GUICreate("My GUI radio")
$radio1 = GUICtrlCreateRadio ("Radio 1", 10, 10, 120, 20)
$button1 = GUICtrlCreateButton("Button 1", 10+150, 10, 120, 20)
;GUICtrlSetState ($radio1,$GUI_CHECKED)
$radio2 = GUICtrlCreateRadio ("Radio 2", 10, 40, 120, 20)
$button2 = GUICtrlCreateButton ("Button 2", 10+150, 40, 120, 20)
$checkbox = GUICtrlCreateCheckbox("checkbox", 10, 70)
$button3= GUICtrlCreateButton ("Button 3", 10+150, 70, 120, 20)
$button = GUICtrlCreateButton ("button", 10, 100, 120, 20)
$buttoncontext = GUICtrlCreateContextMenu($button)
$punkt_1 = GUICtrlCreateMenuitem("Изменение состояния пункта контекстного меню кнопкой",$buttoncontext)
$punkt_2 = GUICtrlCreateMenuitem("Изменение состояния пункта контекстного меню самим этим пунктом",$buttoncontext)
;GUICtrlSetState (-1,$GUI_CHECKED)
$button4 = GUICtrlCreateButton ("Button 4", 10+150, 100, 120, 20)

;$listview = GUICtrlCreateListView ("col1  |col2|col3  ",10,170,200,150)

GUISetState ()
While 1
    $msg = GUIGetMsg()
   
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop

    Select
        Case $msg = $button1
        $data1 = GUICtrlRead($radio1)
        MsgBox(4096, '', GUICtrlRead($radio1))
        Case $msg = $button2
        $data2_0 = GUICtrlRead($radio2)
        MsgBox(4096, '', "Состояние $Radio2 до изменения: " & $data2_0)       
        GUICtrlSetState($radio2, 5-$data2_0)
        $data2_1 = GUICtrlRead($radio2)
        MsgBox(4096, '', "Состояние $Radio2 после изменения: " & $data2_1)       
        Case $msg = $button3
        $data3_0 = GUICtrlRead($checkbox)
        MsgBox(4096, '', "Состояние $checkbox до изменения: " & $data3_0)       
        GUICtrlSetState($checkbox, 5-$data3_0)
        $data3_1 = GUICtrlRead($checkbox)
        MsgBox(4096, '', "Состояние $checkbox после изменения: " & $data3_1)               
        Case $msg = $button4
        $data4_1_0 = GUICtrlRead($punkt_1)
        MsgBox(4096, '', "Состояние $punkt_1 до изменения: " & $data4_1_0)       
        GUICtrlSetState($punkt_1, 68+65-$data4_1_0)
        $data4_1_1 = GUICtrlRead($punkt_1)
        MsgBox(4096, '', "Состояние $punkt_1 после изменения: " & $data4_1_1)       
        Case $msg = $punkt_2
        $data4_2_0 = GUICtrlRead($punkt_2)
        MsgBox(4096, '', "Состояние $punkt_2 до изменения: " & $data4_2_0)       
        GUICtrlSetState($punkt_2, 68+65-$data4_2_0)
        $data4_2_1 = GUICtrlRead($punkt_2)
        MsgBox(4096, '', "Состояние $punkt_2 после изменения: " & $data4_2_1)       
        EndSelect
Wend

и снова все работает, как и задумывалось. Здесь, например, у $radio2 состояние изменяется на 5-$data2_0, потому что 5=$GUI_CHECKED+$GUI_UNCHECKED . А вот в русской справке по функции GUICtrlSetState нет числовых эквивалентов состояний элементов, что не добавляет ей удобности в использовании. Оно, конечно, подсмотреть значения этих констант можно и в файле GUIConstantsEx.au3 или даже использовать эти константы не по значениям, а просто по именам, но тем не менее. А вот для пункта контекстного меню численные значения этих констант состояний имеют почему-то другие значения: когда этот пункт не отмечен галочкой, это состояние имеет значение 68, а когда отмечен, то - 65, что нашло отражение в коде.

@InnI, @Prog большое спасибо за помощь!
Сообщение автоматически объединено:

С listview пока не стал заморачияаться, потому что пока не совсем ясно, что это такое и для чего нужно).
 
Последнее редактирование:

Prog

Продвинутый
Сообщения
640
Репутация
80
А вот в русской справке по функции GUICtrlSetState нет числовых эквивалентов состояний элементов
И не нужно, т. к. магические числа. Необходимо выделить требуемый бит функцией BitAND().
А вот для пункта контекстного меню численные значения этих констант состояний имеют почему-то другие значения: когда этот пункт не отмечен галочкой, это состояние имеет значение 68, а когда отмечен, то - 65, что нашло отражение в коде.
Потому что это не одно состояние, а несколько. Используйте BitOR() и BitAND().
С listview пока не стал заморачиваться, потому что пока не совсем ясно, что это такое и для чего нужно).
Список нужен?
 
Автор
M

mathem

Новичок
Сообщения
68
Репутация
0
И что? Значения магических чисел - это список констант, оговоренный и утвержденный, известный каждому приличному программисту? Читая по вашей ссылке, не создается такое впечатление.
Необходимо выделить требуемый бит функцией BitAND().
Ваще не понял. И полбеды было бы, если бы не понял, как выделять. А не понял-то что и из чего выделять.
Потому что это не одно состояние, а несколько.
Дык, естественно, несколько. Но у каждого-то состояния есть свое (оговоренное и утвержденное) значение. Я вот о чем.
Используйте BitOR() и BitAND().
Опять не понял.
Пока нет).
 

Prog

Продвинутый
Сообщения
640
Репутация
80
Значения магических чисел - это список констант
Когда вы видите в коде число 128 о чем оно говорит? А когда видите $GUI_SHOW понятно что это показ GUI. Для AutoIt все равно что будет число или константа. Это нужно для нас чтобы понимать код и не запутаться в нем.

Это основы программирования https://ru.wikipedia.org/wiki/Битовая_операция
BitAND это "побитовое И".

А не понял-то что и из чего выделять.
Выделять из того что возвращает GUICtrlRead.
Читали описание функций?
 
Автор
M

mathem

Новичок
Сообщения
68
Репутация
0
Это основы программирования https://ru.wikipedia.org/wiki/Битовая_операция
BitAND это "побитовое И".
С математической стороной битовых операций я знаком, спасибо. У меня заминка именно в применении операций BitOR и BittAND в программировании в автиите. Я не понимаю, почему, например, вот здесь:

If BitAND(GUICtrlRead($infoitem), $GUI_CHECKED) = $GUI_CHECKED

для проверки того, отмечен пункт контекстного меню галочкой или нет, можно применить команду (операцию) BittAND. И почему для этого нужно применять именно BittAND, а не BitOR??? Вот что для меня сегодня тайна за семью печатями. Или для подобных целей можно применять и команду BitOR тоже? Я понимаю, что задаю дикие с точки зрения посвященного человека вопросы, просто у меня нет понимания этого. Вот и выкручиваюсь окольными путями, наподобие такого:

Код:
GUICtrlSetState($radio2, 5-$data2_0)
(хотя в данном конкретном случае у меня такое впечатление, что у меня получилось даже проще, чем в примерах в документации), держа в голове, что когда-нибудь нужно-таки разобраться с применением BittAND и BitOR в автоите, особенно с различиями в их применении.
 
Последнее редактирование:

Prog

Продвинутый
Сообщения
640
Репутация
80
для проверки того, отмечен пункт контекстного меню галочкой или нет, можно применить команду (операцию) BittAND.
Потому что нужно выделить из результата GUICtrlRead, бит(ы) заданные в константе $GUI_CHECKED.
Те биты что сброшены в $GUI_CHECKED, обнулятся в результате GUICtrlRead. То есть очистка данных от установленных лишних бит которые сейчас нам не нужны. Понимаете?
И почему для этого нужно применять именно BittAND, а не BitOR???
Потому что логические И и ИЛИ выполняют противоположные действия.
И сбрасывает биты, а ИЛИ устанавливает. Посмотрите статью в википедии по ссылке выше. Там есть примеры.
 
Автор
M

mathem

Новичок
Сообщения
68
Репутация
0
Те биты что сброшены в $GUI_CHECKED, обнулятся в результате GUICtrlRead.
Давайте по порядку. Вот мы написали равенство
$GUI_CHECKED в левой и правой частях этого равенства - одна и та же де сущность? Правильно? А при вычислении ]BitAND([URL='https://autoit-script.ru/docs/functions/guictrlread.htm']GUICtrlRead($infoitem), $GUI_CHECKED) вместо операндов этой операции будут подставлены двоичное представления числа 68, если галочки на пункте "Информация" контекстного меню нет или двоичное представления числа 65, если эта галочка на этом пункте есть и двоичное представление числового эквивалента состояния $GUI_CHECKE, т. е. двоичное представление числа 1 (здесь пока это число 1 записано в десятичной системе счисления). Все правильно?
 
Последнее редактирование:

Prog

Продвинутый
Сообщения
640
Репутация
80
на пункте "Информация" контекстного меню нет или двоичное представления числа 65
Не обязательно должно быть это число. BitAND обнулит все биты кроме тех что в $GUI_CHECKED и число может измениться.
Запустите посмотрите
Код:
#include <GUIConstantsEx.au3>
$x = BitOR($GUI_CHECKED, $GUI_SHOW, $GUI_ENABLE, $GUI_FOCUS)
MsgBox(0, "", $x)
$y = BitAND($x, $GUI_CHECKED)
MsgBox(0, "", $y)
if $y = $GUI_CHECKED Then
    MsgBox(0, "", "$y = $GUI_CHECKED")
endif
В этом коде проверяемый бит не установлен и условие не выполнится
Код:
#include <GUIConstantsEx.au3>
$x = BitOR($GUI_SHOW, $GUI_ENABLE, $GUI_FOCUS)
MsgBox(0, "", $x)
$y = BitAND($x, $GUI_CHECKED)
MsgBox(0, "", $y)
if $y = $GUI_CHECKED Then
    MsgBox(0, "", "$y = $GUI_CHECKED")
endif
 
Автор
M

mathem

Новичок
Сообщения
68
Репутация
0
Давайте по порядку, пожалуйста, последовательно: иначе мне не так, сижу и гадаю, то ли так понимаю, то ли не так. Мне просто, кроме того, как в инете, в реале не с кем общаться на эти темы. Итак, на это:
$GUI_CHECKED в левой и правой частях этого равенства - одна и та же де сущность?
я так и не получил ответа. Просто кто-нибудь понимающий проговорите яано, правильно ли я это понимаю или нет. Хотя, с другой стороны я и понимаю, что не только здесь, а и вообще: в одном и том же коде одно и тоже обозначение одного и того же чего-то должно, просто обязано (без присвоения этому чему в каком-то месте кода другого значения) иметь одно и то же значение.
Запустите посмотрите
Сейчас посмотрю, спасибо.
 

Prog

Продвинутый
Сообщения
640
Репутация
80
сижу и гадаю, то ли так понимаю, то ли не так.
Работа с битами это основы программирования и они в том или ином виде присутствуют во всех языках. Работу с ними нужно изучить и понять.
$GUI_CHECKED в левой и правой частях этого равенства - одна и та же де сущность?
Константа та же. Здесь дело не в ней, а в том что выполняет функция BitAND.
Сравнение можно упростить до
Код:
if BitAND(GUICtrlRead($infoitem), $GUI_CHECKED) Then
То есть нужно проверить равен результат нулю или нет. Он может быть равен 0 или значению $GUI_CHECKED которое в данном случае не равно 0.
Просто кто-нибудь понимающий проговорите яано, правильно ли я это понимаю или нет.
В википедии все ясно написано и показан пример.
Побитовое «И»бинарная операция, действие которой эквивалентно применению логического «И» к каждой паре битов, которые стоят на одинаковых позициях в двоичных представлениях операндов. Другими словами, если оба соответствующих бита операндов равны 1, результирующий двоичный разряд равен 1; если же хотя бы один бит из пары равен 0, результирующий двоичный разряд равен 0.
Код:
0011
0101
----
0001
Из начальных классов школы помните как прибавлять в столбик? В 1 и 2 строке бинарные числа (не сами числа, а их биты) над которыми проводится операция "логические И".
Обратите внимание если один из битов равен 0, то результат тоже нулевой. Только если оба бита равны 1, то результат 1.
По моему все очень просто.
 
Автор
M

mathem

Новичок
Сообщения
68
Репутация
0
BitOR($GUI_CHECKED, $GUI_SHOW, $GUI_ENABLE, $GUI_FOCUS)
У меня в двоичном представлении получилось 101010001 -9 бинарных цифр, ы байте же 8 бинарных цифр. Такое может быть?
Из начальных классов школы помните как прибавлять в столбик?
Дык само собой в столбик. Как-нибудь по-другому мне бы и в голову не пришло.

Здесь дело не в ней
В левой части равенства да, не в ней. В равенстве же в целом дело и в значении этой константы тоже. Иначе бессмысленно написанное здесь:
н может быть равен 0 или значению $GUI_CHECKED которое в данном случае не равно 0.
 
Последнее редактирование:

Prog

Продвинутый
Сообщения
640
Репутация
80
У меня в двоичном представлении получилось 101010001 -9 бинарных цифр, В байте же 8 бинарных цифр. Такое может быть?
В AutoIt есть только один универсальный тип переменных - Variant. Скорее всего автоматически используется целочисленный тип 32 бита (4 байта).
 
Автор
M

mathem

Новичок
Сообщения
68
Репутация
0
Он может быть равен 0 или значению $GUI_CHECKED которое в данном случае не равно 0.
А, а $GUI_CHECKED значение BitAND(GUICtrlRead($infoitem), $GUI_CHECKED) (если BitAND(GUICtrlRead($infoitem), $GUI_CHECKED) не равно 0) может равняться потому что в двоичном представлении значения $GUI_CHECKED только одна единица, правильно? Если бы в двоичном представлении значения $GUI_CHECKED было больше одой единице, то мог бы представиться случай, когда значение BitAND(GUICtrlRead($infoitem), $GUI_CHECKED) , будучи отличным от 0, было бы отличным и от $GUI_CHECKED? Правильно?
Сообщение автоматически объединено:

Скорее всего автоматически используется целочисленный тип 32 бита (4 байта).
А может и целочисленный тип 64 бита:
Поддерживаются целые числа со знаком и числа с плавающей запятой: Int32, Int64 и Double. Размер целого числа в битах зависит от его величины и определяется автоматически.
Перевод сделан переводом фрагмента отсюда. Хотя стоп. В 32-разрядгой системе могут производиться операции с 64-разрядгыми числами?
 
Последнее редактирование:

Prog

Продвинутый
Сообщения
640
Репутация
80
Если бы в двоичном представлении значения $GUI_CHECKED было больше одой единице, то мог бы представиться случай, когда значение BitAND(GUICtrlRead($infoitem), $GUI_CHECKED) , будучи отличным от 0, было бы отличным и от $GUI_CHECKED? Правильно?
BitAND обнуляет все биты которые в $GUI_CHECKED равны нулю и результат будет нулевой или равен $GUI_CHECKED.
А может и целочисленный тип 64 бита
AutoIt сам выбирает тип (и это не очень хорошо), так что все возможно.
В 32-разрядгой системе могут производиться операции с 64-разрядгыми числами?
Программно могут. 64 бит рассматриваются как 2 переменные по 32 бита.
 

InnI

AutoIT Гуру
Сообщения
4,982
Репутация
1,460
@mathem
Работу BitAND лучше рассмотреть на примере WinGetState, которая возвращает набор состояний окна. Допустим она вернула 11. Что это значит? Смотрим в справку и получаем 1+2+8. А без справки? Перебираем известные состояния:
Код:
ConsoleWrite( BitAND(11, 1) & @CRLF) ; 1
ConsoleWrite( BitAND(11, 2) & @CRLF) ; 2
ConsoleWrite( BitAND(11, 4) & @CRLF) ; 0
ConsoleWrite( BitAND(11, 8) & @CRLF) ; 8

Вот и получается
Код:
If BitAND(WinGetState(""), $WIN_STATE_ACTIVE) = $WIN_STATE_ACTIVE Then ConsoleWrite("Окно активно" & @CRLF)
 
Автор
M

mathem

Новичок
Сообщения
68
Репутация
0
BitAND обнуляет все биты которые в $GUI_CHECKED равны нулю и результат будет нулевой или равен $GUI_CHECKED.
Это я понял, но
результат будет нулевой или равен $GUI_CHECKED.
потому что
в двоичном представлении значения $GUI_CHECKED только одна единица,
, но это не ответ на вот это:
Если бы в двоичном представлении значения $GUI_CHECKED было больше одой единице, то мог бы представиться случай, когда значение BitAND(GUICtrlRead($infoitem), $GUI_CHECKED) , будучи отличным от 0, было бы отличным и от $GUI_CHECKED? Правильно?
Меня сейчас ответ или коммент вот к этому моменту интересует.
 
Автор
M

mathem

Новичок
Сообщения
68
Репутация
0
Я уже ответил на этот вопрос.
Где? Вот здесь:
Запустите посмотрите
AutoIt код:
[#include<GUIConstantsEx.au3>
$x = ]BitOR[/URL]($GUI_CHECKED, $GUI_SHOW, $GUI_ENABLE, $GUI_FOCUS)
MsgBox[/URL](0, "", $x)
$y = ($x, $GUI_CHECKED)
MsgBox(0, "", $y)
$y = $GUI_CHECKED
MsgBox(0, "", "$y = $GUI_CHECKED")
В этом коде проверяемый бит не установлен и условие не выполнится
AutoIt код:
<#include<GUIConstantsEx.au3>
$x = BitOR[($GUI_SHOW, $GUI_ENABLE, $GUI_FOCUS)
MsgBox(0, "", $x)
$y = ($x, $GUI_CHECKED)
MsgBox(0, "", $y)
 $y = $GUI_CHECKED
MsgBox(0, "", "$y = $GUI_CHECKED")
? Естественно, уже запускал, смотрел. Но для меня это не ответ на то, о чем я спрашиваю. Мне сейчас нужно, чтобы какой-нибудь гуру автоита спустился со своих высот и объяснил мне точно то, о чем я спрашиваю, на языке, понятном мне.
 
Последнее редактирование:

Prog

Продвинутый
Сообщения
640
Репутация
80
Здесь.
То есть нужно проверить равен результат нулю или нет. Он может быть равен 0 или значению $GUI_CHECKED которое в данном случае не равно 0.

Мне сейчас нужно, чтобы какой-нибудь гуру автоита спустился со своих высот и объяснил мне точно то, о чем я спрашиваю, на языке, понятном мне.
На форумах обычно помогают, а не обучают. В сети много материала о битовых операциях.

Надеюсь так понятней будет.
Код:
#include <GUIConstantsEx.au3>
$x = BitOR($GUI_CHECKED, $GUI_SHOW, $GUI_ENABLE, $GUI_FOCUS)
MsgBox(0, BitOR($GUI_CHECKED, $GUI_SHOW), $x)
if BitAND($x, BitOR($GUI_CHECKED, $GUI_SHOW)) = BitOR($GUI_CHECKED, $GUI_SHOW) Then
    MsgBox(0, "", "$GUI_CHECKED и $GUI_SHOW")
endif
Уберите из второй строки $GUI_CHECKED или $GUI_SHOW и посмотрите что получится.
 
Верх