Что нового

GUI, элемент Checkbox, функция выбора

xlgrgrc

Знающий
Сообщения
91
Репутация
7
Перепробовал много вариантов но не могу понять работу работу Checkbox ов.

Вот аналогичный пример

Код:
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

$Form1_1 = GUICreate("Проба", 287, 456, 206, 153)
$exit = GUICtrlCreateButton("Выход (Ctrl+F12)", 144, 408, 137, 41, $WS_GROUP)
GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
$zap = GUICtrlCreateButton("Запуск", 8, 408, 129, 41, $WS_GROUP)
GUICtrlSetFont(-1, 16, 400, 0, "MS Sans Serif")
$Label3 = GUICtrlCreateLabel("1", 48, 80, 10, 17)
$Label4 = GUICtrlCreateLabel("2", 48, 104, 10, 17)
$Ch_m_1 = GUICtrlCreateCheckbox("Ch_m_1", 120, 80, 17, 17)
$Ch_m_2 = GUICtrlCreateCheckbox("Ch_m_2", 120, 104, 17, 17)
$Ch_k_1 = GUICtrlCreateCheckbox("Ch_k_1", 170, 80, 17, 17)
$Ch_k_2 = GUICtrlCreateCheckbox("Ch_k_2", 170, 104, 17, 17)
GUISetState(@SW_SHOW)

$qwe = 1   ; переменная для выхода из опроса

$m1 = 0
$m2 = 0
$k1 = 0
$k2 = 0

While $qwe = 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit

Case $exit
	Exit
Case $zap
	$qwe = 2   ; выход из опроса
	
Case $Ch_m_1
	$m1 = 1
Case $Ch_m_2
	$m2 = 1
	
Case $Ch_k_1
	$k1 = 1
	
Case $Ch_k_2
	$k2 = 1
EndSwitch
WEnd

MsgBox (0,"сообщение", $m1 & $m2 & $k1 & $k2)

;~ Далее действия



Все работает прекрасно. Но если нажать на чекбокс и нажать снова, то он запомнит первоначальное нажатие, а то что галочка снята не запоминается...

То есть, только на раз нужно раставлять все галочки и не менять ни чего.

Только чего и не делал. Я так понял у меня не правильно что то в корне сделано и сам разобраться не могу.
Думаю для спецов это пустяк, прошу помочь.
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Код:
While $qwe = 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE, $hExit
			Exit
		Case $zap
			$qwe = 2   ; выход из опроса
		Case $Ch_m_1
			$m1 = BitAnd(GUICtrlRead($Ch_m_1),$GUI_CHECKED)
		Case $Ch_m_2
			$m2 = BitAnd(GUICtrlRead($Ch_m_2),$GUI_CHECKED)
		Case $Ch_k_1
			$k1 = BitAnd(GUICtrlRead($Ch_k_1),$GUI_CHECKED)
		Case $Ch_k_2
			$k2 = BitAnd(GUICtrlRead($Ch_k_2),$GUI_CHECKED)
	EndSwitch
WEnd
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
xlgrgrc,
Или так:
Код:
#include <GUIConstantsEx.au3>

GUICreate('Test', 200, 200, 192)
$nCheckbox_1 = GUICtrlCreateCheckbox('Checkbox_1', 50, 20, 100, 20)
$nCheckbox_2 = GUICtrlCreateCheckbox('Checkbox_2', 50, 60, 100, 20)
GUISetState()


While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
		Case $nCheckbox_1
			If GUICtrlRead($nCheckbox_1) == $GUI_CHECKED Then
				MsgBox(64, 'Info', 'Checkbox_1 отмечен')
			Else
				MsgBox(64, 'Info', 'Checkbox_1 не отмечен')
			EndIf
		Case $nCheckbox_2
			If GUICtrlRead($nCheckbox_1) == $GUI_CHECKED Then
				MsgBox(64, 'Info', 'Checkbox_2 отмечен')
			Else
				MsgBox(64, 'Info', 'Checkbox_2 не отмечен')
			EndIf
	EndSwitch
WEnd
 
Автор
X

xlgrgrc

Знающий
Сообщения
91
Репутация
7
Спасибо большое... Домой приду оба варианта проверю и сравню )))
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
madmasles
В вашем (конкретном) примере ошибок как таковых нет, но я вам рекомендую обратить внимание на то что сделал Garrett, он использовал BitAND, и это считается более корректная форма проверки состояния элемента.

Вот пример где это будет критично:

Код:
#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>

$hGUI = GUICreate("Test Script", 300, 200)

$nButton = GUICtrlCreateCheckbox("Button", 20, 40, 60, 20, BitOr($GUI_SS_DEFAULT_CHECKBOX, $BS_AUTO3STATE))
GUICtrlSetState(-1, $GUI_INDETERMINATE)

GUISetState(@SW_SHOW, $hGUI)

If GUICtrlRead($nButton) == $GUI_CHECKED Then MsgBox(64, '== Usage', 'Checked') ;Это не срабатывает, т.е при чтений содержатся и другие значения состояний
If BitAND(GUICtrlRead($nButton), $GUI_CHECKED) Then MsgBox(64, 'BitAND Usage', 'Checked')

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd


Дело в том, что BitAND нужен чтобы убедиться что в прочитанном значений содержится $GUI_CHECKED, а не равняется ему, т.к мы имеем и другие значения (в этом случае ещё и $GUI_INDETERMINATE).
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
CreatoR

Только не BitOR(), а BitAND():

Код:
BitAND(GUICtrlRead($nButton), $GUI_CHECKED) Then MsgBox(64, 'BitOR Usage', 'Checked')


:smile:
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
CreatoR [?]
я вам рекомендую обратить внимание на то что сделал Garrett
Спасибо. Конечно я обратил внимание на сообщение Garrett`а и отметил его, ИМХО, заслуженно, весьма полезным. :IL_AutoIt_1:
 
Автор
X

xlgrgrc

Знающий
Сообщения
91
Репутация
7
Ну все уловил ) Щас пока до конца не понял но работает... Со временем само придет )))

А ещё вопрос не отходя от кассы, только не знаю писать в эту тему http://autoit-script.ru/index.php?topic=5763.0 или в текущей...

Суть такая. Допустим я взял и создал кучу этих чекбоксов циклом...
и пробую по аналогии считать данные циклом:
Код:
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

$Form1_1 = GUICreate("Проба", 287, 456, 206, 153)
$exit = GUICtrlCreateButton("Выход", 144, 408, 137, 41, $WS_GROUP)
GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
$zap = GUICtrlCreateButton("Запуск", 8, 408, 129, 41, $WS_GROUP)
GUICtrlSetFont(-1, 16, 400, 0, "MS Sans Serif")

Dim $label[1000]
Dim $Checkbox[1000]
Dim $dCheckbox[1000]

For $i = 1 To 10
    $label[$i] = GUICtrlCreateLabel($i, 48, 60+20*$i, 17, 17)
Next

For $i = 1 To 10
    $Checkbox[$i] = GUICtrlCreateCheckbox($i, 117, 60+20*$i, 17, 17)
Next

For $i = 11 To 20
    $Checkbox[$i] = GUICtrlCreateCheckbox($i, 169, 60+20*($i-10), 17, 17)
Next

For $i = 21 To 30
    $Checkbox[$i] = GUICtrlCreateCheckbox($i, 220, 60+20*($i-20), 17, 17)
Next





GUISetState(@SW_SHOW)

$qwe = 1   ; переменная для выхода из опроса

$m1 = 0
$m2 = 0
$k1 = 0
$k2 = 0

While $qwe = 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit

Case $exit
    Exit
Case $zap
    $qwe = 2   ; выход из опроса
	
For  $i = 1 To 30
Case $Checkbox[$i]
	$dCheckbox[$i] = BitAnd(GUICtrlRead($Checkbox[$i]),$GUI_CHECKED)
Next	
	
	
    

EndSwitch
WEnd

;~MsgBox (0,"сообщение", $m1 & $m2 & $k1 & $k2)

;~ Далее действия



Сразу ошибка...
Dim $dCheckbox[1000] - этот массив в итоге запоминает была галочка или нет...
Я так понимаю, что ошибка состоит в том что перебор Case идет внутри GUIGetMsg().

GUIGetMsg() - получает 1 раз ранные и их можно через Case выбрать.

Есть вариант опросить каждый из 30 чекбоксов в отдельности... Но это писанины будет много. Крайний вариант.


Добавлено:
Сообщение автоматически объединено:

Помудрил и вышло )))

Код:
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

$Form1_1 = GUICreate("Проба", 287, 456, 206, 153)
$exit = GUICtrlCreateButton("Выход", 144, 408, 137, 41, $WS_GROUP)
GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
$zap = GUICtrlCreateButton("Запуск", 8, 408, 129, 41, $WS_GROUP)
GUICtrlSetFont(-1, 16, 400, 0, "MS Sans Serif")

Dim $label[1000]
Dim $Checkbox[1000]
Dim $dCheckbox[1000]

For $i = 1 To 10
    $label[$i] = GUICtrlCreateLabel($i, 48, 60+20*$i, 17, 17)
Next

For $i = 1 To 10
    $Checkbox[$i] = GUICtrlCreateCheckbox($i, 117, 60+20*$i, 17, 17)
Next

For $i = 11 To 20
    $Checkbox[$i] = GUICtrlCreateCheckbox($i, 169, 60+20*($i-10), 17, 17)
Next

For $i = 21 To 30
    $Checkbox[$i] = GUICtrlCreateCheckbox($i, 220, 60+20*($i-20), 17, 17)
Next





GUISetState(@SW_SHOW)

$qwe = 1   ; переменная для выхода из опроса

$m1 = 0
$m2 = 0
$k1 = 0
$k2 = 0

While $qwe = 1
For  $i = 1 To 30

$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit

Case $exit
    Exit
Case $zap
    $qwe = 2   ; выход из опроса

 Case $Checkbox[1] To $Checkbox[30]
	For  $i = 1 To 30
	$dCheckbox[$i] = BitAnd(GUICtrlRead($Checkbox[$i]),$GUI_CHECKED)
	Next


EndSwitch
Next
WEnd



For  $i = 1 To 30
	If $dCheckbox[$i] <>0 Then
		MsgBox (0,$i , $dCheckbox[$i])
	endIf
Next
;~ Далее действия




Вся загвоздка в была в

Код:
Case $Checkbox[1] To $Checkbox[30]
	For  $i = 1 To 30
	          $dCheckbox[$i] = BitAnd(GUICtrlRead($Checkbox[$i]),$GUI_CHECKED)
	Next


Щас все работает. Всем спасибо ))) Узнал как всегда много нового )))
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
xlgrgrc,
Я обычно в одном массиве все данные храню:
Код:
#include <GUIConstantsEx.au3>
#include <Array.au3>

Dim $aCheckbox[6][3] = [[5],['Checkbox №', 0, 0],['Checkbox №', 0, 1],['Checkbox №', 0, 0], _
		['Checkbox №', 0, 1],['Checkbox №', 0, 0]]

GUICreate('Test', 200, 50 + $aCheckbox[0][0] * 30)
For $i = 1 To $aCheckbox[0][0]
	$aCheckbox[$i][1] = GUICtrlCreateCheckbox($aCheckbox[$i][0] & $i, 50, 10 + 30 * ($i - 1), 100, 20)
	If $aCheckbox[$i][2] Then GUICtrlSetState(-1, $GUI_CHECKED)
Next
$nButton = GUICtrlCreateButton('Click', 50, 10 + $aCheckbox[0][0] * 30, 100, 30)
GUISetState()

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $aCheckbox[1][1] To $aCheckbox[$aCheckbox[0][0]][1]
			For $i = 1 To $aCheckbox[0][0]
				If $nMsg = $aCheckbox[$i][1] Then
					$aCheckbox[$i][2] = BitAND(GUICtrlRead($nMsg), $GUI_CHECKED)
				EndIf
			Next
		Case $nButton
			_ArrayDisplay($aCheckbox)
	EndSwitch
WEnd
 
Автор
X

xlgrgrc

Знающий
Сообщения
91
Репутация
7
Попробую и так сделать ) Спасибо.
 
Верх