Code : Tout sélectionner
#include <TreeViewConstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <Constants.au3>
#include <ListboxConstants.au3>
#include <GuiListBox.au3>
#include <Array.au3>
Opt("GUIOnEventMode", 1)
Enum $__GUI_CREATE, $__GUI_DELETE, $__GUI_SHOW, $__GUI_HIDE, $__GUI_RESIZE, $__GUI_MOVE
Enum _
$__gComboBox_iActive, _ ; Si le comboBox est actif ou non
$__gComboBox_hGui, _ ; La GUI du comboBox
$__gComboBox_iLB, _ ; Le CtrlID du ListView du comboBox
$__gComboBox_hLB, _ ; Le Handle ListView du comboBox
$__gComboBox_hParentGui, _ ; La GUI Parente du comboBox (contenant le input et le bouton)
$__gComboBox_iIsVisible, _ ; Si le comboBox est affiché ou pas
$__gComboBox_iInput, _ ; CtrlID du input
$__gComboBox_hInput, _ ; Handle du input
$__gComboBox_sFillFunc, _ ; Fonction de remplissage du comboBox
$__gComboBox_iItemHeight, _ ; Hauteur d'un item
$__gComboBox_iMaxItems ; Maximum d'items à afficher dans la comboBox
Global $__gComboBox_aArray[1][11] = [[0, "", "", "", "", "", "", "", "", ""]]
; Juste pour les tests
Global $__g_aItems1 = StringSplit("salut,la,compagnie,je,m'appel,matwachich,et,ceci,est,un,test,de,mon,nouveau,comboBox,interactif,et voici enfin un item super long pour voir le comportement du listBox", ",")
Global $__g_aItems2 = StringSplit("Ceci,est,la,2,e,liste,de,valeurs,possibles,pour,le,2,e,comboBox", ",")
;==========================================================================
Global $GUI_Parent, $GUI_ENFANT1, $GUI_ENFANT2, $Tab
_GUI_Parent()
While 1
Sleep(1000)
WEnd
Func _GUI_Parent()
Global $GUI_Parent = GUICreate("Parent", 753, 606, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
Global $Control = GUICtrlCreateTreeView(7, 8, 193, 513, BitOR($GUI_SS_DEFAULT_TREEVIEW,$WS_BORDER))
Global $Control_0 = GUICtrlCreateTreeViewItem("Test", $Control)
GUICtrlSetOnEvent(-1, "_GUI_ENFANT1_ON")
GUISetState(@SW_SHOW, $GUI_Parent)
_GUI_ENFANT1()
EndFunc
Func _GUI_ENFANT1()
Global $GUI_ENFANT1 = GUICreate("", 545, 513, 201, 8, BitOr($WS_CHILD,$WS_TABSTOP), -1, $GUI_Parent)
Global $Tab = GUICtrlCreateTab(7, 0, 520, 514)
GUICtrlSetOnEvent(-1, "_TAB_Change")
Global $TabSheet1 = GUICtrlCreateTabItem("TabSheet1")
GUICtrlSetState(-1,$GUI_SHOW)
Global $TabSheet2 = GUICtrlCreateTabItem("TabSheet2")
Global $Checkbox1 = GUICtrlCreateCheckbox("Checkbox1", 96, 48, 97, 17)
Global $Button1 = GUICtrlCreateButton("Button1", 112, 88, 75, 25)
GUICtrlCreateTabItem("")
GUISetState(@SW_HIDE, $GUI_ENFANT1)
_GUI_ENFANT2()
EndFunc
Func _GUI_ENFANT2()
Global $GUI_ENFANT2 = GUICreate("", 457, 405, 32, 50, $WS_POPUP, $WS_EX_MDICHILD, $GUI_ENFANT1)
GUIRegisterMsg($WM_MOVE, "MY_WM_MOVE")
GUISetBkColor(0x3A6EA5)
$I_Combo1 = GUICtrlCreateInput("", 86, 48, 201, 27)
GUICtrlSetFont(-1, 12, 400, 0, "Cambria")
$B_Combo1 = GUICtrlCreateButton("", 288, 48, 25, 27)
$iCombo1 = _Combo_Init($GUI_ENFANT2, $I_Combo1, '_FillFunc', 10)
GUISetState(@SW_HIDE, $GUI_ENFANT2)
EndFunc
Func _TAB_Change()
If GUICtrlRead($Tab) = 0 Then
GUISetState(@SW_SHOW, $GUI_ENFANT1)
GUISetState(@SW_SHOW, $GUI_ENFANT2)
Else
GUISetState(@SW_SHOW, $GUI_ENFANT1)
GUISetState(@SW_HIDE, $GUI_ENFANT2)
EndIf
EndFunc
Func _GUI_ENFANT1_ON()
GUISetState(@SW_SHOW, $GUI_ENFANT1)
GUISetState(@SW_SHOW, $GUI_ENFANT2)
EndFunc
Func _Exit()
Exit
EndFunc
Func MY_WM_MOVE($hWnd, $Msg, $wParam, $lParam)
; viewtopic.php?f=3&t=5111&start=0&hilit=Suivi+de+gui
Local $nNotifyCode, $nID, $hCtrl, $aGui1
$nNotifyCode = BitShift($wParam, 16)
$nID = BitAND($wParam, 0x0000FFFF)
$hCtrl = $lParam
$aGui1 = WinGetPos($GUI_ENFANT1)
If $nID <> 2 And $nNotifyCode = 0 Then
WinMove($GUI_ENFANT2, "", $aGui1[0] + 32, $aGui1[1] + 50)
_WinAPI_SetWindowPos($GUI_ENFANT2, $HWND_TOP, 0, 0, 0, 0, BitOR($SWP_NOMOVE, $SWP_NOSIZE))
EndIf
EndFunc ;==>MY_WM_COMMAND
Func _FillFunc($iComboID, $sSearch, $iMax)
Local $aItems = Eval('__g_aItems' & $iComboID) ; on selectionne la liste à prendre en compte selon le comboBox
; ---
Local $aRet[1] = [0], $extended = 0
For $i = 1 To $aItems[0]
If Not $sSearch Or StringInStr($aItems[$i], $sSearch) Then
ReDim $aRet[$aRet[0] + 2]
$aRet[0] += 1
$aRet[$aRet[0]] = $aItems[$i]
EndIf
; ---
If $aRet[0] >= $iMax Then
$extended = 1
ExitLoop
EndIf
Next
Return SetError(0, $extended, $aRet)
EndFunc
; ===============================================================================================================================
; Fonctions de l'UDF
Func _Combo_Init($hGui, $iInputCtrl, $iFillFunc, $iMaxItems = 15)
ReDim $__gComboBox_aArray[$__gComboBox_aArray[0][0] + 2][11]
$__gComboBox_aArray[0][0] += 1
Local $iArrayIndex = $__gComboBox_aArray[0][0]
; ---
$__gComboBox_aArray[$iArrayIndex][$__gComboBox_iActive] = 1
$__gComboBox_aArray[$iArrayIndex][$__gComboBox_hParentGui] = $hGui
$__gComboBox_aArray[$iArrayIndex][$__gComboBox_iInput] = $iInputCtrl
$__gComboBox_aArray[$iArrayIndex][$__gComboBox_hInput] = GUICtrlGetHandle($iInputCtrl)
$__gComboBox_aArray[$iArrayIndex][$__gComboBox_sFillFunc] = $iFillFunc
$__gComboBox_aArray[$iArrayIndex][$__gComboBox_iMaxItems] = $iMaxItems
; ---
__GUI_ComboBox($iArrayIndex)
GUIRegisterMsg(0x0111, '__Combo_WM_COMMAND')
; ---
Return $iArrayIndex
EndFunc
Func _Combo_SetFont($iComboID, $iSize = 8.5, $iWeight = 400, $sName = Default, $iQuality = 2)
If $iComboID < 1 Or $iComboID > $__gComboBox_aArray[0][0] Then Return SetError(1, 0, 0)
; ---
GUICtrlSetFont($__gComboBox_aArray[$iComboID][$__gComboBox_iLB], $iSize, $iWeight, $sName, $iQuality)
$__gComboBox_aArray[$iComboID][$__gComboBox_iItemHeight] = _GUICtrlListBox_GetItemHeight($__gComboBox_aArray[$iComboID][$__gComboBox_hLB])
EndFunc
Func _Combo_SetMaxItems($iComboID, $iMaxItems = 15)
If $iComboID < 1 Or $iComboID > $__gComboBox_aArray[0][0] Then Return SetError(1, 0, 0)
; ---
$__gComboBox_aArray[$iComboID][$__gComboBox_iMaxItems] = $iMaxItems
EndFunc
Func _Combo_ButtonClick($iComboID)
If $iComboID < 1 Or $iComboID > $__gComboBox_aArray[0][0] Then Return SetError(1, 0, 0)
; ---
If $__gComboBox_aArray[$iComboID][$__gComboBox_iIsVisible] Then
__GUI_ComboBox($iComboID, $__GUI_HIDE)
Else
__Combo_UpdatePositionAndWidth($iComboID)
__Combo_Fill($iComboID, GUICtrlRead($__gComboBox_aArray[$iComboID][$__gComboBox_iInput]))
__GUI_ComboBox($iComboID, $__GUI_SHOW)
ControlFocus($__gComboBox_aArray[$iComboID][$__gComboBox_hParentGui], "", $__gComboBox_aArray[$iComboID][$__gComboBox_iInput])
EndIf
EndFunc
Func _Combo_SetActive($iComboID, $iActive)
If $iComboID < 1 Or $iComboID > $__gComboBox_aArray[0][0] Then Return SetError(1, 0, 0)
; ---
$__gComboBox_aArray[$iComboID][$__gComboBox_iActive] = $iActive
Return 1
EndFunc
Func _Combo_Destroy($iComboID)
If $iComboID < 1 Or $iComboID > $__gComboBox_aArray[0][0] Then Return SetError(1, 0, 0)
; ---
__GUI_ComboBox($iComboID, $__GUI_DELETE)
; ---
_ArrayDelete($__gComboBox_aArray, $iComboID)
$__gComboBox_aArray[0][0] -= 1
; ---
Return 1
EndFunc
; ===============================================================================================================================
; Internals
; Adapte la taille et la position au input
Func __Combo_UpdatePositionAndWidth($iComboID)
Local $aSize = ControlGetPos($__gComboBox_aArray[$iComboID][$__gComboBox_hParentGui], "", $__gComboBox_aArray[$iComboID][$__gComboBox_iInput])
Local $tPoint = DllStructCreate("int X; int Y")
DllStructSetData($tPoint, "X", $aSize[0])
DllStructSetData($tPoint, "Y", $aSize[1])
_WinAPI_ClientToScreen($__gComboBox_aArray[$iComboID][$__gComboBox_hParentGui], $tPoint)
; ---
__GUI_ComboBox($iComboID, $__GUI_RESIZE, $aSize[2], 100)
__GUI_ComboBox($iComboID, $__GUI_MOVE, DllStructGetData($tPoint, "X"), DllStructGetData($tPoint, "Y") + $aSize[3])
EndFunc
; Adapte la hauteur au nombre d'items
Func __Combo_UpdateHeight($iComboID, $iItems)
__GUI_ComboBox($iComboID, $__GUI_RESIZE, Default, ($__gComboBox_aArray[$iComboID][$__gComboBox_iItemHeight] * $iItems) + 4)
EndFunc
; Remplir le LV du comboBox
Func __Combo_Fill($iComboID, $sSearch)
Local $aData = Call($__gComboBox_aArray[$iComboID][$__gComboBox_sFillFunc], $iComboID, $sSearch, $__gComboBox_aArray[$iComboID][$__gComboBox_iMaxItems])
Local $iSetMore = @extended
If Not IsArray($aData) Or $aData[0] = 0 Then Return 0 * _GUICtrlListBox_ResetContent($__gComboBox_aArray[$iComboID][$__gComboBox_hLB])
; ---
If $iSetMore > 1 Then $iSetMore = 1
If $iSetMore < 0 Then $iSetMore = 0
; ---
__Combo_UpdateHeight($iComboID, $aData[0] + $iSetMore) ; Quand $iSetMore est à 1, on rajoute de la hauteur pour un item de plus qui contiendra "..."
; ---
_GUICtrlListBox_BeginUpdate($__gComboBox_aArray[$iComboID][$__gComboBox_hLB])
_GUICtrlListBox_ResetContent($__gComboBox_aArray[$iComboID][$__gComboBox_hLB])
For $i = 1 To $aData[0]
_GUICtrlListBox_AddString($__gComboBox_aArray[$iComboID][$__gComboBox_hLB], $aData[$i])
Next
If $iSetMore Then _GUICtrlListBox_AddString($__gComboBox_aArray[$iComboID][$__gComboBox_hLB], "..." & Chr(0))
; ---
_GUICtrlListBox_EndUpdate($__gComboBox_aArray[$iComboID][$__gComboBox_hLB])
; ---
Return 1
EndFunc
; Remplir le input avec le text de l'item
Func __Combo_SetInput($iComboID)
Local $sRead = GUICtrlRead($__gComboBox_aArray[$iComboID][$__gComboBox_iLB])
If Not $sRead Or $sRead = "..." & Chr(0) Then Return 0
; ---
GUICtrlSetData($__gComboBox_aArray[$iComboID][$__gComboBox_iInput], $sRead)
Return 1
EndFunc
; ===============================================================================================================================
; Internals GUI
Func __Combo_WM_COMMAND($hWnd, $msgID, $wParam, $lParam)
For $i = 1 To $__gComboBox_aArray[0][0]
If Not $__gComboBox_aArray[$i][$__gComboBox_iActive] Then ContinueLoop
; ---
If $lParam = $__gComboBox_aArray[$i][$__gComboBox_hInput] Then
If (BitShift($wParam, 16) <> 768) Then Return "GUI_RUNDEFMSG" ; From GuiOnChangeRegister.au3
; ---
Local $sRead = GUICtrlRead($__gComboBox_aArray[$i][$__gComboBox_iInput])
If Not $sRead Then
__GUI_ComboBox($i, $__GUI_HIDE)
Else
__Combo_UpdatePositionAndWidth($i)
; ---
If __Combo_Fill($i, $sRead) Then
__GUI_ComboBox($i, $__GUI_SHOW)
Else
__GUI_ComboBox($i, $__GUI_HIDE)
EndIf
; ---
ControlFocus($__gComboBox_aArray[$i][$__gComboBox_hParentGui], "", $__gComboBox_aArray[$i][$__gComboBox_iInput])
EndIf
; ---
Return "GUI_RUNDEFMSG"
EndIf
; ---
If $lParam = $__gComboBox_aArray[$i][$__gComboBox_hLB] Then
If BitShift($wParam, 16) = $LBN_SELCHANGE Then
If __Combo_SetInput($i) Then __GUI_ComboBox($i, $__GUI_HIDE)
EndIf
; ---
Return "GUI_RUNDEFMSG"
EndIf
Next
; ---
Return "GUI_RUNDEFMSG"
EndFunc
Func __GUI_ComboBox($iArrayIndex, $iFlag = $__GUI_CREATE, $iWidth = Default, $iHeight = Default)
If $iArrayIndex > $__gComboBox_aArray[0][0] Or $iArrayIndex < 1 Then Return SetError(1, 0, 0)
; ---
Switch $iFlag
Case $__GUI_CREATE
; BitOR($WS_SYSMENU, $WS_POPUP), BitOR($WS_EX_TOPMOST, $WS_EX_WINDOWEDGE, $WS_EX_TOOLWINDOW) anciens flags
$__gComboBox_aArray[$iArrayIndex][$__gComboBox_hGui] = GUICreate("", 100, 100, -1, -1, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_DISABLED, $WS_EX_MDICHILD), $__gComboBox_aArray[$iArrayIndex][$__gComboBox_hParentGui])
$__gComboBox_aArray[$iArrayIndex][$__gComboBox_iLB] = GUICtrlCreateList("", 0, 0, 100, 100, BitOR($WS_VSCROLL, $LBS_NOINTEGRALHEIGHT))
GUICtrlSetResizing(-1, 102) ; $GUI_DOCKBORDERS
$__gComboBox_aArray[$iArrayIndex][$__gComboBox_hLB] = GUICtrlGetHandle(-1)
; ---
$__gComboBox_aArray[$iArrayIndex][$__gComboBox_iItemHeight] = _GUICtrlListBox_GetItemHeight($__gComboBox_aArray[$iArrayIndex][$__gComboBox_hLB])
; ---
$__gComboBox_aArray[$iArrayIndex][$__gComboBox_iIsVisible] = 0
Case $__GUI_RESIZE
WinMove($__gComboBox_aArray[$iArrayIndex][$__gComboBox_hGui], "", Default, Default, $iWidth, $iHeight)
Case $__GUI_MOVE
WinMove($__gComboBox_aArray[$iArrayIndex][$__gComboBox_hGui], "", $iWidth, $iHeight)
Case $__GUI_SHOW
GuiSetState(@SW_SHOW, $__gComboBox_aArray[$iArrayIndex][$__gComboBox_hGui])
$__gComboBox_aArray[$iArrayIndex][$__gComboBox_iIsVisible] = 1
Case $__GUI_HIDE
GuiSetState(@SW_HIDE, $__gComboBox_aArray[$iArrayIndex][$__gComboBox_hGui])
$__gComboBox_aArray[$iArrayIndex][$__gComboBox_iIsVisible] = 0
Case $__GUI_DELETE
GuiDelete($__gComboBox_aArray[$iArrayIndex][$__gComboBox_hGui])
$__gComboBox_aArray[$iArrayIndex][$__gComboBox_hGui] = 0
EndSwitch
EndFunc