Что нового

[Элементы GUI] GUICtrlCreateCombo перескакивает ввех вниз в цикле While и не получается выбрать

Andruxakonst

Новичок
Сообщения
21
Репутация
0
Уперся в тупик и не могу пока понять как действовать дальше.
В окне DriveGetDrive("REMOVABLE") заполняем GUICtrlCreateCombo циклически. т.к. необходимо при включенной программе отследить подключение флешки и вывести метку диска в Label. Но в моем скрипте, когда одна флешка вроде все норм, а вот когда 2, не получается, Combo открывается и начинает перескакивать с диска на диск "мерцая". Подскажите, может как по другому пути пойти?!

Код:
$Form1 = GUICreate("Копирование ПО ПФР на USB Flash v.1.4 (for куроторав!)", 500, 450, 193, 125,"", $WS_EX_COMPOSITED)
$Combo_Flesh = GUICtrlCreateCombo("", 24, 35, 50, 25)
$Label_Text = GUICtrlCreateLabel("Выберите устройство для копирования ", 30, 5, 403, 28)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
$Label_Text_Vibor = GUICtrlCreateLabel("Вы выбрвли диск: ", 90, 40, 100, 28)
$Label_Text_Lable = GUICtrlCreateLabel("", 200, 40, 150, 28)
$Button_EXIT = GUICtrlCreateButton("ВЫХОД", 380, 380, 107, 30, 0)
GUISetState(@SW_SHOW)

While 1
   Sleep(1000)
   $nMsg = GUIGetMsg()
	
   $Massive_Drive = DriveGetDrive("REMOVABLE")
   
   $i = $Massive_Drive[0]
   $j = $Massive_Drive[1]
   $s = 1
   
   If $j = "a:" Then ; исключаем диск А
	  
	  $s += 1
	  
		 For $D = $s to $i	
	  
			GUICtrlSetData($Combo_Flesh, $Massive_Drive[$D])
			
		 Next
		 
		 IF $i <= 1 Then
			
			GUICtrlSetData($Label_Text_Lable, "Устнойств не найдено")
		 Else 
			;MsgBox(1,"", "Else")
			;MsgBox(1,"", "Выбор - "& $Combo_Flesh)
			$Bukva_diska = GUICtrlRead($Combo_Flesh)
			;MsgBox(1,"", "Буква- "& $Bukva_diska)
			$Lable_diska = DriveGetLabel ($Bukva_diska)
			
			If $Lable_diska = "" Then
			   GUICtrlSetData($Label_Text_Lable, "Устройство без метки")
			EndIf
			
			GUICtrlSetData($Label_Text_Lable, $Lable_diska) ; выводит метку диска
			;MsgBox(1,"", "Lable - "&$Lable_diska)
			
		 EndIf
	  
   Else
		 ;MsgBox(1,"", "Else")
		 For $D = $s to $i	
	  
			GUICtrlSetData($Combo_Flesh, $Massive_Drive[$D],$Massive_Drive[$s])
			
		 Next
		 		
			;MsgBox(1,"", "Else")
			;MsgBox(1,"", "Выбор - "& $Combo_Flesh)
			$Bukva_diska = GUICtrlRead($Combo_Flesh)
			;MsgBox(1,"", "Буква- "& $Bukva_diska)
			$Lable_diska = DriveGetLabel ($Bukva_diska)
			
			If $Lable_diska = "" Then
			   GUICtrlSetData($Label_Text_Lable, "Устройство без метки")
			EndIf
			
			GUICtrlSetData($Label_Text_Lable, $Lable_diska) ; выводит метку диска
			;MsgBox(1,"", "Lable - "&$Lable_diska)
			
						
   EndIf
	
   		
   
		 
		 Switch $nMsg
				
			Case $GUI_EVENT_CLOSE 
				Exit
			Case $Button_EXIT 
				Exit
		 EndSwitch
WEnd
 
Автор
A

Andruxakonst

Новичок
Сообщения
21
Репутация
0
MnM, подскажи пожалуйста как прикрутить к примеру что бы IF Устройство подкл.\откл then Сообщ.
Что - понят не могу по примеру :(
 

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Andruxakonst
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
$GUI = GUICreate("Event Device", 256, 350)
GUICtrlCreateLabel("Лог подключений устройств", 0, 0, 147, 17)
$Edit = GUICtrlCreateEdit("", 0, 32, 249, 313)
GUIRegisterMsg($wm_devicechange,"__EventDevice")
GUISetState(@SW_SHOW)
While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd
Func __EventDevice($hWnd,$Msg,$wPar,$lPar)
	If $wPar=0x8000 Or $wPar=0x8004 Then;Выполнение определение устройства если отключилось или подключилось
		Local $tagDevice=DllStructCreate("int dbcvsize;int dbcvdevicetype;int dbcvreserved;int dbcvunitmask;" & _
                "ushort dbcvflags", $lPar)
		If DllStructGetData($tagDevice,"dbcvdevicetype")<>0x00000002 Then Return "gui_rundefmsg" ;Если устройство не является логическим диском то выход из функции
		Local $sDeviceN
		$sDeviceN=DllStructGetData($tagDevice,"dbcvunitmask")
		$sDeviceN=Log($sDeviceN)/Log(2)
		$sDeviceN=Chr(65+$sDeviceN)&":";Получение матем-им путем имени отключенного или подключенного диска
		Switch $wPar
			Case 0x8000
				GUICtrlSetData($Edit,"Подключено устройство с именем - "&$sDeviceN&@CRLF,1)
			Case 0x8004
				GUICtrlSetData($Edit,"Устройство с именем - "&$sDeviceN&" отключено"&@CRLF,1)
		EndSwitch
	EndIf
	Return "gui_rundefmsg"
EndFunc
 
Автор
A

Andruxakonst

Новичок
Сообщения
21
Репутация
0
MnM, а [?]
что делает? что-то по справке не нашел.
И для развития, подскажи. Ф-ция находится после цикла while, я понять не могу как она выполняется, независимо от цикла (однавременно, параллельно)?

Код:
DllStructCreate("int dbcvsize;int dbcvdevicetype;int dbcvreserved;int dbcvunitmask;" & _
                "ushort dbcvflags", $lPar)
и вот тут что-то не пойму. где искать ключевые слова?
 

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Andruxakonst сказал(а):
Выходит из функции передавая системе дефолтное сообщение(как я понимаю :smile:)
Andruxakonst сказал(а):
Ф-ция находится после цикла while, я понять не могу как она выполняется, независимо от цикла
Она зарегистрирована с помощью GUIRegisterMsg(), при определенном сообщении эта функция(после цикла) срабатывает, в данном случае зарегестрировано событие для устройств например: flash-памяь\cd и т.д.
Andruxakonst сказал(а):
и вот тут что-то не пойму. где искать ключевые слова?
Создается структура в которую помещаются данные из указателя который передается "функции после цикла"(буду для вас так называть :smile:) через переменную $lPar($lParam)
Какие именно вам нужны ключевые слова?


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

Andruxakonst
на счет return
[box class=highlight2]Ключевое слово Return может быть использовано для выхода из функции. В отличие от встроенных функций, пользовательские функции возвращают 0, если другое возвращаемое значение не задано.[/box]
OffTopic:
Какая прикольная штука получилась :laugh:



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

Если для вас очень трудно, то напишите в раздел "стол заказов"
 
Автор
A

Andruxakonst

Новичок
Сообщения
21
Репутация
0
MnM
Какие именно вам нужны ключевые слова?
Код:
DllStructCreate("int dbcvsize;int dbcvdevicetype;int dbcvreserved;int dbcvunitmask;" & _
                "ushort dbcvflags", $lPar)


int - это понятно, а dbcvsize, dbcvdevicetype и т.д. Где почитать про них.

Я только начинаю осваивать, по этому прошу прощения если задаю глупые вопросы. Просто не хочется тупо передирать, а хочется понять как работает!
За что тебе MnM спасибО! Кое что для меня разъяснено! Особенно на счет Return.
 

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Andruxakonst сказал(а):
Структуру например можно сумбурно сравнить с ассоциативным массивом, так вот эти слова как бы переменные которым присваивается значение из системы при помощи указателя $lParam из системной оболочки, при помощи этих слов можно получить данные dllstructgetdata()
про них немного сказано в справке тут на против параметра $lParam
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Andruxakonst,
Мой вариант.
Код:
#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <ComboConstants.au3>
#include <EditConstants.au3>

Opt('MustDeclareVars', 1)

Global $hGui, $nCombo, $nLabel, $nDummy, $nBtn, $nEdit, $sTitle = 'Флешки'

$hGui = GUICreate($sTitle, 300, 150)
$nCombo = GUICtrlCreateCombo('', 120, 70, 60, 20, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_DROPDOWNLIST))
$nLabel = GUICtrlCreateLabel('', 25, 30, 250, 20, BitOR($GUI_SS_DEFAULT_LABEL, $SS_CENTER, $SS_CENTERIMAGE))
$nEdit = GUICtrlCreateEdit('', 10, 10, 250, 20, $ES_READONLY)
$nBtn = GUICtrlCreateButton('...', 265, 10, 20, 20)
$nDummy = GUICtrlCreateDummy()
GUISetState()
_Update_Combo($nCombo, $nBtn)
_Update_Label($nLabel, $nCombo, $nEdit)
GUIRegisterMsg($WM_DEVICECHANGE, '_WM_DEVICECHANGE')

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
		Case $nCombo
			_Update_Label($nLabel, $nCombo, $nEdit)
		Case $nDummy
			_Update_Combo($nCombo, $nBtn)
			_Update_Label($nLabel, $nCombo, $nEdit)
		Case $nBtn
			_Update_Edit($nEdit, $nCombo)
	EndSwitch
WEnd

Func _WM_DEVICECHANGE($hWnd, $iMsg, $wParam, $lParam)
	Local Const $__DBT_DEVICEARRIVAL = 0x00008000, $__DBT_DEVICEREMOVECOMPLETE = 0x00008004
	Switch $wParam
		Case $__DBT_DEVICEARRIVAL, $__DBT_DEVICEREMOVECOMPLETE
			GUICtrlSendToDummy($nDummy)
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_DEVICECHANGE

Func _Update_Edit($n_Edit, $n_Combo)
	Local $s_Drive, $s_Path
	$s_Drive = GUICtrlRead($n_Combo)
	If Not $s_Drive Then
		GUICtrlSetData($n_Edit, '')
		Return
	EndIf
	$s_Path = FileSelectFolder('Выберите папку', $s_Drive, 3, '', $hGui)
	If @error Then
		GUICtrlSetData($n_Edit, '')
	Else
		GUICtrlSetData($n_Edit, $s_Path)
	EndIf
EndFunc   ;==>_Update_Edit

Func _Update_Label($n_Label, $n_Combo, $n_Edit)
	Local $s_Drive, $s_Data, $v_Tmp

	$s_Drive = GUICtrlRead($n_Combo)
	If Not $s_Drive Then
		GUICtrlSetData($n_Label, 'Вставьте (выберите) флешку.')
		GUICtrlSetData($n_Edit, '')
		Return
	EndIf
	$s_Data &= $s_Drive
	$v_Tmp = DriveGetLabel($s_Drive)
	If $v_Tmp Then $s_Data &= ' (' & $v_Tmp & ')'
	$v_Tmp = DriveSpaceTotal($s_Drive)
	If $v_Tmp Then
		$s_Data &= ' (' & Round($v_Tmp) & ' MB/'
	Else
		$s_Data &= ' (? MB/'
	EndIf
	$v_Tmp = DriveSpaceFree($s_Drive)
	If $v_Tmp Then
		$s_Data &= Round($v_Tmp) & ' MB)'
	Else
		$s_Data &= '? MB)'
	EndIf
	GUICtrlSetData($n_Label, $s_Data)
	If Not FileExists(GUICtrlRead($n_Edit)) Then GUICtrlSetData($n_Edit, '')
EndFunc   ;==>_Update_Label

Func _Update_Combo($n_Combo, $n_Btn)
	Local $a_Drive, $s_Data = '|', $s_Old

	$s_Old = GUICtrlRead($n_Combo)
	$a_Drive = DriveGetDrive('REMOVABLE')
	If @error Then
		GUICtrlSetData($n_Combo, '')
		GUICtrlSetState($n_Combo, $GUI_DISABLE)
		GUICtrlSetState($n_Btn, $GUI_DISABLE)
		WinSetTitle($hGui, '', $sTitle & ' (0)')
		Return
	Else
		GUICtrlSetState($n_Combo, $GUI_ENABLE)
		GUICtrlSetState($n_Btn, $GUI_ENABLE)
	EndIf
	For $i = 1 To $a_Drive[0]
		$s_Data &= StringUpper($a_Drive[$i]) & '|'
	Next
	GUICtrlSetData($n_Combo, $s_Data, $s_Old)
	WinSetTitle($hGui, '', $sTitle & ' (' & $a_Drive[0] & ')')
EndFunc   ;==>_Update_Combo
 
Автор
A

Andruxakonst

Новичок
Сообщения
21
Репутация
0
madmasles, спасибо! Теперь понял как сделать! Отличный пример!
 
Автор
A

Andruxakonst

Новичок
Сообщения
21
Репутация
0
:laugh: Работает!!! Дописал! Спасибо madmasles
и MnM! Очень помогли и дали хороший толчок в понимании!!!! :IL_AutoIt_1:

Кнопка "Dimmy" классная вещь! Как и Return!
 
Верх