nikita1996spb
Новичок
- Сообщения
- 19
- Репутация
- 0
Здравствуйте! Искал возможность изменения значения в Input в зависимости от выделенного значения Сombobox в этой теме:
http://autoit-script.ru/index.php?topic=23490
Мой вариант кода:
Решение, предложенное Alofa:
Ещё раз опишу задачу:
есть файл с парными данными, разделенными пробелом. Данные из 2 столбца добавляются в Listview, в который на первом месте находится вариант "Нет", а на последнем "Другое". Если выбирается вариант "Нет", то Input становится пустым и нередактируемым и меняет фоновый цвет на "нормальный". Если выбран один из вариантов из файла, то Input также становится нередактиремым, но в нем появляется соответствующая "пара", которая проходит проверку IsFamily(): если успешно - фоновый цвет становится "нормальным", если нет - красным. Если выбрано "Другое", Input становится редактиремым, фон меняется на белый в случае успешного прохождения проверки или красным в случае неудачи(это делается "налету").
В моем варианте список сильно лагает при раскрывании, а в варианте Alofa не происходит проверки Input. Насколько я понял, это из-за отсутствия взаимодействия WM_NOTIFY и Input. Собственно вопрос: как реализовать и то, и другое без лагов?
http://autoit-script.ru/index.php?topic=23490
Мой вариант кода:
Код:
#include <EditConstants.au3>
#Include <Array.au3>
#Include <GuiComboBox.au3>
#include <ComboConstants.au3>
#include <GuiComboBoxEx.au3>
#Include <WindowsConstants.au3>
#Include <GUIConstantsEx.au3>
#Include <Constants.au3>
#include <GuiEdit.au3>
#include <String.au3>
$Debug_Ed = False
$Debug_CB = False
$winname = "123"
$gw = 1040
$gh = 640
$g = GUICreate($winname,$gw,$gh,-1,-1,BitOR($GUI_SS_DEFAULT_GUI,$WS_MAXIMIZEBOX,$WS_SIZEBOX ))
GUISetFont(11)
$cfgfile = "config.txt"
#CS
ОФОРМЛЕНИЕ
#CE
$prevo1 = "Нет"
;Чтение
$objects = FileRead($cfgfile)
$objects = StringReplace($objects,@CRLF," ")
$objects = StringSplit($objects," ")
$oblist="Нет|"
For $i=2 To $objects[0] Step 2
$oblist &= $objects[$i] & "|"
Next
$oblist &= "Другое"
;Параметры
$obj1 = _GUICtrlComboBoxEx_Create($g,$oblist,600,158,150,25*($objects[0]/2+1),$CBS_DROPDOWNLIST)
$obj1c = GUICtrlCreateInput("",800,158,120,25)
#CS
Начальные параметры
#CE
_GUICtrlComboBoxEx_SetCurSel($obj1,0)
#CS
ПРОГРАММНАЯ ЧАСТЬ
#CE
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_COMMAND,'WM_COMMAND')
Func IsFamily($s)
If (StringRight($s,2)=="вна") Or (StringRight($s,3)=="вич") Or ($s=="") Then
Return 1
Else
Return 0
EndIf
EndFunc
Func checkparams()
Local $c=0
If (Not IsFamily(GUICtrlRead($obj1c))) And (_GUICtrlComboBoxEx_GetCurSel($obj1)>0) Then
$c=1
GUICtrlSetBkColor($obj1c,0xFF0000)
Else
If _GUICtrlComboBoxEx_GetCurSel($obj1)==(_GUICtrlComboBoxEx_GetCount($obj1)-1) Then
GUICtrlSetBkColor($obj1c,0xFFFFFF)
Else
If (_GUICtrlComboBoxEx_GetCurSel($obj1)>0) And (Not (GUICtrlRead($obj1c)==$objects[(_GUICtrlComboBoxEx_GetCurSel($obj1)*2-1)])) Then
GUICtrlSetBkColor($obj1c,0xFFFF00)
Else
GUICtrlSetBkColor($obj1c,0xD4D0C8)
EndIf
EndIf
EndIf
Return $c
EndFunc
;WM и вспомогательные
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $iwParam
Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
$iCode = DllStructGetData($tNMHDR, "Code")
Switch $hWndFrom
Case $obj1
Switch $iCode
Case $CBEN_GETDISPINFOA, $CBEN_GETDISPINFOW
$tInfo = DllStructCreate($tagNMCOMBOBOXEX, $ilParam)
Local $params=_GUICtrlComboBoxEx_GetItem ($obj1, DllStructGetData($tInfo, "Item"))
If Not ($prevo1==$params[0]) Then
Local $ocsi=_GUICtrlComboBoxEx_FindStringExact($obj1,$params[0])
If ($ocsi>0) And ($ocsi<=$objects[0]/2) Then
GUICtrlSetStyle($obj1c,$ES_READONLY)
GUICtrlSetData($obj1c,$objects[($ocsi*2-1)])
ElseIf $ocsi<=0 Then
GUICtrlSetStyle($obj1c,$ES_READONLY)
GUICtrlSetData($obj1c,"")
Else
GUICtrlSetStyle($obj1c,$ES_LEFT)
GUICtrlSetData($obj1c,"")
EndIf
$prevo1=$params[0]
EndIf
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc
Func WM_COMMAND($hWnd,$imsg,$iwParam,$ilParam)
Local $nNotifyCode,$nID,$sText
$nNotifyCode = BitShift($iwParam,16)
$nID = BitAND($iwParam,0xFFFF)
Switch $hWnd
Case $g
Switch $nID
Case $obj1c
If $nNotifyCode == $EN_CHANGE Then
checkparams()
EndIf
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc
Func _GetComboBoxEx($ilParam)
$tInfo = DllStructCreate($tagNMCOMBOBOXEX, $ilParam)
Local $aItem = _GUICtrlComboBoxEx_GetItem ($obj1, DllStructGetData($tInfo, "Item"))
Return @lf & "--> hwndfrom:" & @tab & DllStructGetData($tInfo, "hWndFrom") & @LF & _
"-->IDFrom:" & @tab & DllStructGetData($tInfo, "IDFrom") & @LF & _
"-->Code:" & @tab & DllStructGetData($tInfo, "Code") & @LF & _
"-->Mask:" & @tab & DllStructGetData($tInfo, "Mask") & @LF & _
"-->Item:" & @tab & DllStructGetData($tInfo, "Item") & @LF & _
"-->Text:" & @TAB & $aItem[0] & @LF & _
"-->TextMax:" & @TAB & $aItem[1] & @LF & _
"-->Indent:" & @TAB & $aItem[2] & @LF & _
"-->Image:" & @TAB & $aItem[3] & @LF & _
"-->SelectedImage:" & @TAB & $aItem[4] & @LF & _
"-->OverlayImage:" & @TAB & $aItem[5] & @LF & _
"-->Param:" & @TAB & $aItem[5]
EndFunc
GUISetState(@SW_SHOW)
checkparams()
While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
Exit
Case $GUI_EVENT_MINIMIZE
GUISetState(@SW_MINIMIZE,$g)
Case $GUI_EVENT_RESTORE
GUISetState(@SW_RESTORE,$g)
Case $GUI_EVENT_MAXIMIZE
GUISetState(@SW_MAXIMIZE,$g)
EndSwitch
WEnd
Код:
#include <EditConstants.au3>
#include <Array.au3>
#include <GuiComboBox.au3>
#include <ComboConstants.au3>
#include <GuiComboBoxEx.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <Constants.au3>
#include <GuiEdit.au3>
#include <String.au3>
$Debug_Ed = False
$Debug_CB = False
$winname = "123"
$gw = 1040
$gh = 640
$g = GUICreate($winname, $gw, $gh, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX))
GUISetFont(11)
$cfgfile = "config.txt"
#CS
ОФОРМЛЕНИЕ
#CE
$prevo1 = "Нет"
;Чтение
$objects = FileRead($cfgfile)
$objects = StringReplace($objects, @CRLF, " ")
$objects = StringSplit($objects, " ")
$oblist = "Нет|"
For $i = 2 To $objects[0] Step 2
$oblist &= $objects[$i] & "|"
Next
$oblist &= "Другое"
;Параметры
$obj1 = _GUICtrlComboBoxEx_Create($g, $oblist, 600, 158, 150, 25 * ($objects[0] / 2 + 1), $CBS_DROPDOWNLIST)
$obj1c = GUICtrlCreateInput("", 800, 158, 120, 25)
#CS
Начальные параметры
#CE
_GUICtrlComboBoxEx_SetCurSel($obj1, 0)
#CS
ПРОГРАММНАЯ ЧАСТЬ
#CE
Global $k = 0
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW)
checkparams()
While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
Exit
Case $GUI_EVENT_MINIMIZE
GUISetState(@SW_MINIMIZE, $g)
Case $GUI_EVENT_RESTORE
GUISetState(@SW_RESTORE, $g)
Case $GUI_EVENT_MAXIMIZE
GUISetState(@SW_MAXIMIZE, $g)
EndSwitch
WEnd
; ======= Ф У Н К Ц И И ========================================================================
;WM и вспомогательные
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $iwParam
Local $hWndFrom, $iCode, $tNMHDR, $tInfo
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iCode = DllStructGetData($tNMHDR, "Code")
Switch $hWndFrom
Case $obj1
Switch $iCode
Case $CBEN_GETDISPINFOA, $CBEN_GETDISPINFOW
$tInfo = DllStructCreate($tagNMCOMBOBOXEX, $ilParam)
Local $params = _GUICtrlComboBoxEx_GetItem($obj1, DllStructGetData($tInfo, "Item"))
If Not ($prevo1 == $params[0]) Then
Local $ocsi = _GUICtrlComboBoxEx_FindStringExact($obj1, $params[0])
If ($ocsi > 0) And ($ocsi <= $objects[0] / 2) Then
GUICtrlSetStyle($obj1c, $ES_READONLY)
GUICtrlSetData($obj1c, $objects[($ocsi * 2 - 1)])
ElseIf $ocsi <= 0 Then
GUICtrlSetStyle($obj1c, $ES_READONLY)
GUICtrlSetData($obj1c, "")
Else
GUICtrlSetStyle($obj1c, $ES_LEFT)
GUICtrlSetData($obj1c, "")
EndIf
$prevo1 = $params[0]
EndIf
checkparams()
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY
Func checkparams()
Local $c = 0, $iColor, $iGetCurSel = _GUICtrlComboBoxEx_GetCurSel($obj1), $sInputRead = GUICtrlRead($obj1c)
; Не надо вызывать 100 раз одну и ту же функцию, чтобы узнать одно и то же значение
Local Static $iColorPrev
If (Not IsFamily($sInputRead)) And ($iGetCurSel > 0) Then
$c = 1
$iColor = 0xFF0000
Else
If $iGetCurSel = (_GUICtrlComboBoxEx_GetCount($obj1) - 1) Then
$iColor = 0xFFFFFF
Else
If ($iGetCurSel > 0) And (Not ($sInputRead == $objects[($iGetCurSel * 2 - 1)])) Then
$iColor = 0xFFFF00
Else
$iColor = 0xD4D0C8
EndIf
EndIf
EndIf
If $iColor <> $iColorPrev Then
GUICtrlSetBkColor($obj1c, $iColor)
$iColorPrev = $iColor
EndIf
Return $c
EndFunc ;==>checkparams
Func IsFamily($s)
If (StringRight($s, 2) == "вна") Or (StringRight($s, 3) == "вич") Or ($s == "") Then
Return 1
Else
Return 0
EndIf
EndFunc ;==>IsFamily
Ещё раз опишу задачу:
есть файл с парными данными, разделенными пробелом. Данные из 2 столбца добавляются в Listview, в который на первом месте находится вариант "Нет", а на последнем "Другое". Если выбирается вариант "Нет", то Input становится пустым и нередактируемым и меняет фоновый цвет на "нормальный". Если выбран один из вариантов из файла, то Input также становится нередактиремым, но в нем появляется соответствующая "пара", которая проходит проверку IsFamily(): если успешно - фоновый цвет становится "нормальным", если нет - красным. Если выбрано "Другое", Input становится редактиремым, фон меняется на белый в случае успешного прохождения проверки или красным в случае неудачи(это делается "налету").
В моем варианте список сильно лагает при раскрывании, а в варианте Alofa не происходит проверки Input. Насколько я понял, это из-за отсутствия взаимодействия WM_NOTIFY и Input. Собственно вопрос: как реализовать и то, и другое без лагов?