IntelliSenseBox von BuxFix funktional erweiterbar ?

  • Hallo zusammen.

    Ich habe mir schon ein paar Sachen mit Autoit für die Arbeit gebastelt.
    Derzeit bin ich dabei eine Telefonbuchsuche zu basteln, was soweit auch funktioniert, aber man will ja das Design und die Funktionalität immer weiter verbessern :D

    Als Vorlage diente mir die angepasste IntelliSenseBox mit OnEvent + AcceleratorKeys von GtaSpider -> IntelliSenseBox

    Die aktuelle GUI (das Design und die Maße) sind nur zum testen der Funktionalität ;)
    Bisher habe ich _GUICtrlListBox_FindString angepasst und mit _GUICtrlListBox_FindInText ersetzt, da meine Einträge mehre Inhalte haben.
    Somit kann ich wie in meinem angepassten Beispiel nach Angela oder aber auch nach Merkel suchen.
    Der Eintrag wird auch gefunden und markiert, anschließend wird dieser mit Enter oder Mouse-Klick in das Inputfeld übernommen.
    Zum anwählen der Rufnummer des gefundenen Eintrages lese ich das Input-Feld per Klick auf anrufen dann aus und übergebe dann mittels StringRegExp und dem Pattern (\d+) alle Zahlen an die Messagebox (später an den Telefonclient).
    Wobei der Telefonclient auch den kompletten Eintrag akzeptieren würde und intern die Buchstaben und Sonderzeichen ignoriert.

    Soweit so gut.

    Wäre eine Anpassung bei der IntelliSenseBox von BuxFix für folgende 2 Punkte möglich?

    1. Die dargestellten Treffer in der ListBox sollten waehrend der Eingabe eingeschränkt werden, d.h. nur die Treffer anzeigen, die aufgrund der bisherigen Eingabe noch relevant sind.
    z.B bei der Eingabe von Hamburg sollen dann nur die Einträge mit Hamburg bleiben.
    Das würde ich dann gerne mit Punkt 2 kombinieren.

    2. Die ListBox soll sich entsprechend der Anzahl der Treffer in der Höhe dynamisch angepassen.

    Wäre schön wenn mir jemand einen umsetzbaren Vorschlag hätte :)

    Hier der bisher funktionstüchtige Code

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <ListBoxConstants.au3>
    #include <WindowsConstants.au3>
    #include <GUIListBox.au3>
    #include <WinAPI.au3>
    #include <Misc.au3>
    Opt("GUICloseOnESC", 0)
    Opt("GuiOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    #Region - Deklarationen für Sense
    Global $show = False
    Global $indexB = -1
    Global $SenseGui, $SenseCtrl, $guiBox, $box
    Global $POSSenseGui[2]

    [/autoit] [autoit][/autoit] [autoit]

    #Region Box
    ; Hier die Auswahldaten (braucht nicht sortiert sein):
    Global $aData[10] = ['Hamburg Hans Mustermann 040111111', 'Hamburg Georg Schuster 040222222', 'Hamburg Susi Bergmann 040333333', 'Hamburg Tina Schuhmann 040444444', 'Bremen Gabi Herzlos 0421111111', 'Bremen Ralf Beckmann 0421222222', 'Bremen Andreas Berg 0421333333', 'Bremen Dieter Bohlen 0421444444', 'Berlin Angela Merkel 030111111', 'Berlin Gido Westerwelle 030222222']
    $guiBox = GUICreate('', 200, 155, 0, 0, $WS_POPUP, $WS_EX_TOPMOST + $WS_EX_TOOLWINDOW)
    $box = _GUICtrlListBox_Create($guiBox, '', 0, 0, 200, 156, BitOR($LBS_SORT, 0x00B00002), 0)
    ; ListBox muß 1 Pixel höher als GUI sein - sonst fehlerhafte Darstellung
    For $i = 0 To UBound($aData) - 1 ; falls Daten mit _FileReadToArray gelesen werden: StartIndex=1
    _GUICtrlListBox_AddString($box, $aData[$i])
    Next
    WinSetTrans($guiBox, "", 200)
    #EndRegion Box

    [/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND")
    GUIRegisterMsg($WM_MOVE, "_WM_MOVE")
    GUIRegisterMsg(0x231, "_WM_ENTERSIZEMOVE")
    #EndRegion - Deklarationen für Sense

    [/autoit] [autoit][/autoit] [autoit]

    #Region Main
    $Form1 = GUICreate('Intelli Sense Box', 400, 300, 200, 50)
    GUISetOnEvent(-3, "_Exit")
    $SenseGui = $Form1 ; <== Für Allgemeingültigkeit Zuweisung an $SenseGui
    $Input = GUICtrlCreateInput('', 10, 10, 300, 21)
    $SenseCtrl = $Input ; <== Für Allgemeingültigkeit Zuweisung an $SenseCtrl
    $hInput = GUICtrlGetHandle($Input)
    GUICtrlCreateButton("anrufen", 320, 10, 50, 20)
    GUICtrlSetOnEvent(-1, "anruftest")
    GUISetState()
    #EndRegion Main
    Local $Dumm[5]
    $Dumm[0] = GUICtrlCreateDummy()
    For $i = 1 To 4
    $Dumm[$i] = GUICtrlCreateDummy()
    GUICtrlSetOnEvent(-1, "_Dummy")
    Next

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Dim $AccelKeys[4][2] = [["{ENTER}", $Dumm[1]],["{ESC}", $Dumm[2]],["{UP}", $Dumm[3]],["{DOWN}", $Dumm[4]]]
    GUISetAccelerators($AccelKeys)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While True
    Sleep(500)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func anruftest()
    $rufnummerausgabe = GUICtrlRead($Input)
    $rufnummer1 = StringRegExp($rufnummerausgabe,"(\d+)",3) ;filtert alle Zahlen 0-9 raus und ignoriert den Rest
    MsgBox(262144, "Anruftest", $rufnummer1[0]) ; gibt das gefilterte Ergebnis aus
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Dummy()
    If Not $show Then Return
    Switch @GUI_CtrlId - $Dumm[0]
    Case 1;ENTER
    ControlSetText($SenseGui, '', $SenseCtrl, _GUICtrlListBox_GetText($box, $indexB))
    GUISetState(@SW_HIDE, $guiBox)
    $show = False
    Case 2 ;ESC
    GUISetState(@SW_HIDE, $guiBox)
    $show = False
    Case 3 ;UP
    If $indexB > 0 Then
    $indexB -= 1
    _GUICtrlListBox_SetCurSel($box, $indexB)
    Sleep(90)
    EndIf
    Case 4;DOWN
    If $indexB < _GUICtrlListBox_GetCount($box) - 1 Then
    $indexB += 1
    _GUICtrlListBox_SetCurSel($box, $indexB)
    Sleep(90)
    EndIf
    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Dummy

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

    [/autoit] [autoit][/autoit] [autoit]

    Func MY_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $nNotifyCode = BitShift($wParam, 16)
    Local $hCtrl = $lParam
    Local $hSenseCtrl = $SenseCtrl
    If Not IsHWnd($hSenseCtrl) Then $hSenseCtrl = GUICtrlGetHandle($hSenseCtrl)
    If ($nNotifyCode = 1024 Or $nNotifyCode = 6) And $hCtrl = $hSenseCtrl Then
    Local $str = ControlGetText($SenseGui, '', $SenseCtrl)
    $indexB = _GUICtrlListBox_FindInText($box, $str)
    _GUICtrlListBox_SetCurSel($box, $indexB)
    $caret = _CaretPos()
    If Not @error And Not $show Then
    If $caret[3] + $caret[4] - 95 < 0 Then ; Platz für Liste über dem Ctrl ausreichend?
    WinMove($guiBox, '', $caret[0], $caret[1] + 25) ; Versatz 25 (Ctrlhöhe+5) unter y vom Ctrl
    Else
    WinMove($guiBox, '', $caret[0], $caret[1] - 95) ; Versatz 95 (Boxhöhe+10) über y vom Ctrl
    EndIf
    GUISetState(@SW_SHOWNOACTIVATE, $guiBox)
    $show = True
    EndIf
    ElseIf $hCtrl = $box And $nNotifyCode = 1 Then
    $indexB = _GUICtrlListBox_GetCurSel($box)
    ControlSetText($SenseGui, '', $SenseCtrl, _GUICtrlListBox_GetText($box, $indexB))
    GUISetState(@SW_HIDE, $guiBox)
    $show = False
    ElseIf $show And $nNotifyCode = 512 And $hCtrl = $lParam And Not $hCtrl = $box Then
    GUISetState(@SW_HIDE, $guiBox)
    $show = False
    EndIf
    Return $GUI_RUNDEFMSG
    EndFunc ;==>MY_WM_COMMAND

    [/autoit] [autoit][/autoit] [autoit]

    Func _WM_ENTERSIZEMOVE($hWnd)
    If $hWnd = $SenseGui Then $POSSenseGui = WinGetPos($SenseGui)
    EndFunc ;==>_WM_ENTERSIZEMOVE

    [/autoit] [autoit][/autoit] [autoit]

    Func _WM_MOVE($hWnd)
    If $hWnd = $SenseGui Then
    Local $pos = WinGetPos($guiBox)
    Local $postemp = WinGetPos($SenseGui)
    WinMove($guiBox, "", $pos[0] - ($POSSenseGui[0] - $postemp[0]), $pos[1] - ($POSSenseGui[1] - $postemp[1]))
    $POSSenseGui = WinGetPos($SenseGui)
    EndIf
    EndFunc ;==>_WM_MOVE

    [/autoit] [autoit][/autoit] [autoit]

    Func _CaretPos()
    Local $old = Opt("CaretCoordMode", 0) ;relative mode
    Local $c = WinGetCaretPos() ;relative caret coords
    Local $w = WinGetPos("") ;window's coords
    Local $f = ControlGetFocus("", "") ;text region "handle"
    Local $e = ControlGetPos("", "", $f) ;text region coords
    Local $h = ControlGetHandle("", "", $f) ;Ctrl-Handle
    Local $t[5]
    If IsArray($c) And IsArray($w) And IsArray($e) Then
    If _WinAPI_IsClassName($SenseCtrl, 'Edit') Then ; Input wird als Edit-Class erkannt
    $t[0] = $c[0] + $w[0] + $e[0]
    ElseIf _WinAPI_IsClassName($SenseCtrl, 'ComboBox') Then
    $t[0] = $w[0] + $e[0]
    EndIf
    $t[1] = $c[1] + $w[1] + $e[1]
    $t[2] = $h
    $t[3] = $w[1]
    $t[4] = $e[1]
    Opt("CaretCoordMode", $old)
    Return $t ;absolute screen coords of caret cursor
    Else
    Opt("CaretCoordMode", $old)
    SetError(1)
    EndIf
    EndFunc ;==>_CaretPos
    #EndRegion - SenseFunc's

    [/autoit]
  • Morgen, also ich denke das wird schon möglich sein ;) in der Zeile 76 in der Intellisensebox.au3 wird das Input Control ausgelesen, nun müsstest du eine Funktion schreiben die dir ein Array der Daten durchsucht auf "matches" und daraufhin das ListviewControl anpasst

    ich würde so vorgehen, Eingabe wird getätigt, "Berlin"
    nun kommt deine Funktion und sucht das Telefondatenarray nach dem String "Berlin" ab und schreibt dieses in ein neues Temporäres Array, nun vergleichst du die Einträge in deinem ListviewControl mit den Einträgen in dem Array und löschst alle Einträge die nicht im Array vorkommen

    [autoit]

    _GUICtrlListBox_DeleteString($hWnd, $iIndex)

    [/autoit]


    anschließend zeigst du erst dein ListviewControl an, alle weiteren Funktionen müssen bei dieser Methode nicht angepasst werden soweit ich das sehe

    nun zu der Dynamischen Änderung, du könntest einfach eine Funktion zwischenschalten, die alle Einträge in dem Array zählt und aufgrund der Anzahl dann die Größe ändert Z.B: 15 Pixel Pro Eintrag also

    [autoit]


    Local $getUb = Ubound($ArraymitdenEintraegen)-1
    Local $Hoehe = $getUb*15 ; und daraufhin dann dein Control anpassen

    [/autoit]

    hoffe mal ich habe keinen Denkfehler mit drin :D ist noch so früh ^^
    Gruß Marvin