1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. BugFix

Beiträge von BugFix

  • SciTE - Array: Indexwerte automatisch setzen & statische Zuweisungen erstellen

    • BugFix
    • 22. November 2021 um 14:20

    Ich kann mich erinnern, dass wir vor langer Zeit festgestellt hatten, dass NPP ein nettes Feature besitzt:

    - Rechteckige Markierung (also Cursormarkierung in einer Spalte über mehrere Zeilen, <Shift+Alt+Arrow up/down>)

    - Aufruf Funktion

    - Eintragen Startwert und Schrittweite

    - Ausfüllen an allen Cursorpositionen

    EDIT v 0.3

    • Einrückungsposition der Arrayvariable wird übernommen
    • Dialogsprache (Standard EN u. GER, Erkennung anhand der "locale.properties"), kann auf weitere Sprachen ergänzt werden
    • Fehler bei falschen oder ungültigen Ubound-Werten beseitigt

    EDIT v 0.2

    Der Funktionsumfang wurde nun erweitert, die Operationen werden anhand der Markierung vorgenommen (ein Hotkey für alles) .

    • Eintragen von Index mit Auswahl von Start und Schrittweite bei Rechteckmarkierung (s.o.)
    • Erstellen von statischen Zuweisungen für 1D/2D-Arrays mit indexwerten anhand der Deklarationszeile. Es braucht nur die Arravariable markiert werden. Es wird immer getestet, ob davor Global/Local/Dim steht.
    • Erstellen von statischen Zuweisungen für 1D/2D-Arrays mit indexwerten anhand abgefragter Werte per Strip-Dialog bei Arrayvariablen ohne Deklarations-Keywort
    • To-Do: mögliche Einrückungen berücksichtigen

    Bsp. rechteckige Auswahl

    vorher ("|"=Cursor):

    AutoIt
    $array[|]
    $array[|]
    $array[|]
    $array[|]

    Starwert=0, Schrittweite=1

    nachher:

    AutoIt
    $array[0]
    $array[1]
    $array[2]
    $array[3]

    Bsp. Markierung Array-Deklaration

    vorher:

    AutoIt
    Global $arTest[3][2]

    nachher:

    AutoIt
    Global $arTest[3][2]
    $arTest[0][0] = |
    $arTest[0][1] =
    $arTest[1][0] =
    $arTest[1][1] =
    $arTest[2][0] =
    $arTest[2][1] =

    Bsp. Markierung Array ohne Deklaration

    vorher:

    AutoIt
    $arTest[0][0]

    nachher (Abfrage Anzahl Elemente im Strip-Dialog):

    AutoIt
    $arTest[0][0] = |
    $arTest[0][1] =
    $arTest[1][0] =
    $arTest[1][1] =
    $arTest[2][0] =
    $arTest[2][1] =

    Wir hatten damals auch eine AutoIt Variante dafür erstellt.

    Hier nun meine Lua-Lösung.

    Die Schrittweite kann kombiniert werden mit - * /, + ist die Voreinstellung.

    Zur Eingabe wird der Strip-Dialog von SciTE verwendet.

    strip_dlg.png  

    Das Skript speichern und einer Tastenkombination zuweisen.

    Code: SetArrayIndex.lua [v 0.3]
    -- TIME_STAMP   2021-12-05 18:05:21   v 0.3
    -- coding:utf-8
    
    
    --    v 0.3    added:    The position in the line (indentation) is taken into account
    --          added:  The dialogs support English and German language by default (evaluation of the "locale.properties" file).
    --                  Other languages can be used by replacing the German terms in the "tSetIndex.t_trans" table.
    --          fixed:  Errors when using declarations without valid ubound value.
    --    v 0.2    added:    Static array assignment lines with/without declaration (1D/2D array)
    
    local tSetIndex = {}
    
    
    do
        tSetIndex.f_onstrip  = nil
        tSetIndex.t_rect     = {{false}}
        tSetIndex.s_start    = nil
        tSetIndex.s_end      = nil
        tSetIndex.s_mode     = nil
        tSetIndex.s_count    = nil
        tSetIndex.l_start    = nil
        tSetIndex.l_end      = nil
        tSetIndex.l_text     = nil
        tSetIndex.indent     = nil
        tSetIndex.i_1        = 0
        tSetIndex.i_2        = 0
        tSetIndex.caret      = nil
    
        -- If your locale is neither English nor German, write here a unique line from your locale.properties.
        -- Here you can find your local properties: https://github.com/moltenform/scite-files/blob/main/files/translations_list.md
    
        tSetIndex.locale_pattern    = "# Updated german translations"   -- i.e.: french: "# locale.fr.properties" or italian: "# locale.it.properties"
        tSetIndex.t_trans           = {}                                -- Replace the German terms with those of your language.
        tSetIndex.t_trans.start     = {'Start value', 'Startwert'}
        tSetIndex.t_trans.step      = {'Step size, can be combined with:', 'Schrittweite, kann kombiniert werden mit:'}
        tSetIndex.t_trans.start_ix  = {'Start index', 'Start Index'}
        tSetIndex.t_trans.start_ix1 = {'Start index 1', 'Start Index 1'}
        tSetIndex.t_trans.start_ix2 = {'Start index 2', 'Start Index 2'}
        tSetIndex.t_trans.num       = {'Number of elements', 'Anzahl Elemente'}
        tSetIndex.t_trans.num1      = {'Count 1', 'Anzahl 1'}
        tSetIndex.t_trans.num2      = {'Count 2', 'Anzahl 2'}
        tSetIndex.t_trans.apply     = {'Apply', 'Übernehmen'}
        tSetIndex.b_locale          = false
    
        tSetIndex.IsLocale = function(self)
            local fh = io.open(props['SciteDefaultHome']..'/locale.properties')
            if fh == nil then return false end  -- default installation: english
            local s = fh:read('*a') fh:close()
            if s:find(self.locale_pattern) then return true end
            return false
        end
    
    
        tSetIndex.Ternary = function(self, _cond, _if_val, _else_val)
            if _cond == true then return _if_val else return _else_val end
        end
    
    
        tSetIndex.Init = function(self)
            self.s_start  = editor.SelectionStart
            self.s_end    = editor.SelectionEnd
            if self.s_start > self.s_end then self.s_start, self.s_end = self.s_end, self.s_start end
            self.s_mode   = editor.SelectionMode
            self.s_count  = editor.Selections
            self.l_start  = editor:LineFromPosition(self.s_start)
            self.l_end    = editor:LineFromPosition(self.s_end)
            self.b_locale = self:IsLocale()
        end
    
    
        --[[
            check for declaration (Global/Local/Dim): true/false
            read ubound-size(declaration)/index-value(otherwise)
            returns:    true, ubound1, ubound2
                  or    false, index1, index2
            If no array variable is selected, the following is returned: false, nil, nil
        ]]
        tSetIndex.IsDeclaration = function(self, _line)
            local arr1D = '%$[%w_]+%[(%d-)%]'
            local arr2D = '%$[%w_]+%[(%d-)%]%[(%d-)%]'
            local pattern = {}
            table.insert(pattern, '(%s-)[Gg][Ll][Oo][Bb][Aa][Ll]%s-'..arr2D)
            table.insert(pattern, '(%s-)[Gg][Ll][Oo][Bb][Aa][Ll]%s-'..arr1D)
            table.insert(pattern, '(%s-)[Ll][Oo][Cc][Aa][Ll]%s-'..arr2D)
            table.insert(pattern, '(%s-)[Ll][Oo][Cc][Aa][Ll]%s-'..arr1D)
            table.insert(pattern, '(%s-)[Dd][Ii][Mm]%s-'..arr2D)
            table.insert(pattern, '(%s-)[Dd][Ii][Mm]%s-'..arr1D)
            local indent, ub1, ub2
            for i=1, #pattern do
                indent, ub1, ub2 = _line:match(pattern[i])  -- if 2nd index empty: ub2==''
                if ub1 ~= nil then
                    self.indent = indent
                    return true, ub1, ub2                   -- without 2nd index: ub2==nil
                end
            end
            -- if no declaration: detection type 1D/2D, read possible index values
            local indent, i1, i2 = _line:match('(%s-)'..arr2D)
            if i1 ~= nil then
                self.indent = indent
                return false, i1, i2
            else
                indent, i1 = _line:match('(%s-)'..arr1D)
                self.indent = indent
                return false, i1
            end
        end
    
    
        tSetIndex.InsertByDeclaration = function(self, _ub1, _ub2)
            local ar_type, l_ub1, l_ub2 = nil
            if _ub2 == nil then
                if (_ub1 == '' or tonumber(_ub1) == 0) then
                    print('! FAILURE: No or no valid ubound in the declaration.') return
                else
                    ar_type = 1
                    l_ub1 = tostring(_ub1 -1):len()
                end
            else
                if (_ub1 == '' or tonumber(_ub1) == 0) then
                    print('! FAILURE: No or no valid ubound 1 in the declaration.') return
                else
                    if (_ub2 == '' or tonumber(_ub2) == 0) then
                        print('! FAILURE: No or no valid ubound 2 in the declaration.') return
                    else
                        l_ub1 = tostring(_ub1 -1):len()
                        l_ub2 = tostring(_ub2 -1):len()
                        ar_type = 2
                    end
                end
            end
            local s_insert, v, s_idx = ''
            v = self.l_text:match('(%$[%w_]+)%[%d-%]')
            if ar_type == 1 then        -- 1D array
                for i=1, _ub1 do
                    s_idx = ('[%s%d]'):format((' '):rep(l_ub1-tostring(i-1):len()), i-1)
                    s_insert = s_insert..self.indent..v..s_idx..' = \n'
                    if self.caret == nil then self.caret = self.s_end + s_insert:len() +1 end
                end
            elseif ar_type == 2 then    -- 2D array
                for i=1, _ub1 do
                    for j=1, _ub2 do
                        s_idx = ('[%s%d][%s%d]'):format((' '):rep(l_ub1-tostring(i-1):len()), i-1, (' '):rep(l_ub2-tostring(j-1):len()), j-1)
                        s_insert = s_insert..self.indent..v..s_idx..' = \n'
                        if self.caret == nil then self.caret = self.s_end + s_insert:len() +1 end
                    end
                end
            end
            local posIns = editor:PositionFromLine(self.l_start +1)
            editor:InsertText(posIns, s_insert)
            editor:SetSelection(self.caret, self.caret)
        end
    
    
        tSetIndex.StripInsertNoDeclarationAr1D = function(self, _id, _change)
            if _id == 4 and _change == 1 then
                local start, count = tonumber(scite.StripValue(1)), tonumber(scite.StripValue(3))
                local i_len, s_idx = tostring(count + start):len()
                local s = editor:GetSelText()
                local v, s_insert = s:match('(%$[%w_]+)%[%d-%]'), ''
                for i=start, start+count-1 do
                    s_idx = ('[%s%d]'):format((' '):rep(i_len-tostring(i):len()), i)
                    s_insert = s_insert..self:Ternary(i==start,'',self.indent)..v..s_idx..' = \n'
                    if self.caret == nil then self.caret = self.s_end + 3 end
                end
                editor:ReplaceSel(s_insert)
                editor:SetSelection(self.caret, self.caret)
                scite.StripShow('')
            end
        end
    
    
        tSetIndex.StripInsertNoDeclarationAr2D = function(self, _id, _change)
            if _id == 8 and _change == 1 then
                local start1, start2 = tonumber(scite.StripValue(1)), tonumber(scite.StripValue(3))
                local count1, count2 = tonumber(scite.StripValue(5)), tonumber(scite.StripValue(7))
                local i_len1, i_len2, s_idx1, s_idx2 = tostring(count1 + start1):len(), tostring(count2 + start2):len()
                local s = editor:GetSelText()
                local v, s_insert = s:match('(%$[%w_]+)%[%d-%]%[%d-%]'), ''
                for i=start1, start1+count1-1 do
                    for j=start2, start2+count2-1 do
                        s_idx = ('[%s%d][%s%d]'):format((' '):rep(i_len1-tostring(i):len()), i, (' '):rep(i_len2-tostring(j):len()), j)
                        s_insert = s_insert..self:Ternary(i==start,'',self.indent)..v..s_idx..' = \n'
                        if self.caret == nil then self.caret = self.s_end + 3 end
                    end
                end
                editor:ReplaceSel(s_insert)
                editor:SetSelection(self.caret, self.caret)
                scite.StripShow('')
            end
        end
    
    
        tSetIndex.GetRect = function(self)
            local tRet, s, e = {}
            repeat
                s = editor:GetLineSelStartPosition(self.l_start)
                e = editor:GetLineSelEndPosition(self.l_start)
                if s ~= e then return end   -- don't use if text is selected
                table.insert(tRet, {self.l_start,s})
                self.l_start = self.l_start +1
                self.s_count = self.s_count -1
            until self.s_count == 0
            self.t_rect = tRet
        end
    
    
        tSetIndex.StripRectSetIndex = function(self, _id, _change)
            if _id == 4 and _change == 1 then
                if not self.t_rect[1][1] then
                    print('! FAILURE: The rectangular selection includes text.')
                    scite.StripShow('') return
                end
                local start, step = scite.StripValue(1), scite.StripValue(3)
                local pos_add, v_ins, int
                local op, step = step:match('^([-*/]-)(%d+)')
                if tonumber(step) == 0 then
                    print('! FAILURE: No step width is set')
                    self.t_rect = {{false}} scite.StripShow('') return
                end
                -- set 1st value
                editor:InsertText(self.t_rect[1][2], start)
                pos_add = tostring(start):len()
                for i=2, #self.t_rect do
                    if op == '-' then
                        v_ins = tostring(start - step)
                    elseif op == '*' then
                        if tonumber(start) == 0 then
                            print('! FAILURE: Multiplication by zero remains zero')
                            self.t_rect = {{false}} scite.StripShow('') return
                        end
                        v_ins = tostring(start * step)
                    elseif op == '/' then
                        if tonumber(start) == 0 then
                            print('! FAILURE: Any attempt to divide the zero remains zero')
                            self.t_rect = {{false}} scite.StripShow('') return
                        end
                        int, frac = math.modf(start / step)
                        if int == 0 or frac ~= 0 then
                            print('! FAILURE: The division ( '..tostring(start)..' / '..tostring(step)..' ) does not have an integer result')
                            self.t_rect = {{false}} scite.StripShow('') return
                        end
                        v_ins = tostring(start / step)
                    else
                        v_ins = tostring(start + step)
                    end
                    editor:InsertText(self.t_rect[i][2] + pos_add, v_ins)
                    pos_add = pos_add + v_ins:len()
                    start = tonumber(v_ins)
                end
                scite.MenuCommand(IDM_SAVE)
                self.t_rect = {{false}} -- reset
                scite.StripShow('')
            end
        end
    
    
        tSetIndex.ShowStripIndex = function(self)
            local idx = self:Ternary(self.b_locale, 2, 1)
            local strip_def_index = ("!'%s'[]'%s [ - * / ]'[]((%s))"):format(self.t_trans.start[idx], self.t_trans.step[idx], self.t_trans.apply[idx])
            scite.StripShow(strip_def_index)
            scite.StripSet(1, 0)
            scite.StripSet(3, 1)
        end
    
    
        tSetIndex.ShowStripAr1D = function(self)
            local idx = self:Ternary(self.b_locale, 2, 1)
            local strip_def_index = ("!'%s'[]'%s'[]((%s))"):format(self.t_trans.start_ix[idx], self.t_trans.num[idx], self.t_trans.apply[idx])
            scite.StripShow(strip_def_index)
            scite.StripSet(1, self.i_1)
        end
    
    
        tSetIndex.ShowStripAr2D = function(self)
            local idx = self:Ternary(self.b_locale, 2, 1)
            local strip_def_index = ("!'%s'[]'%s'[]'%s'[]'%s'[]((%s))"):format(self.t_trans.start_ix1[idx], self.t_trans.start_ix2[idx], self.t_trans.num1[idx], self.t_trans.num2[idx], self.t_trans.apply[idx])
            scite.StripShow(strip_def_index)
            scite.StripSet(1, self.i_1)
            scite.StripSet(3, self.i_2)
        end
    end
    
    
    OnStrip = function(_id, _change)
        tSetIndex:f_onstrip(_id, _change)
    end
    
    
    
    tSetIndex:Init()
    
    if tSetIndex.s_mode == SC_SEL_RECTANGLE then
        tSetIndex.f_onstrip = tSetIndex.StripRectSetIndex
        tSetIndex:GetRect()
        tSetIndex:ShowStripIndex()
    elseif tSetIndex.s_mode == SC_SEL_STREAM then
        if tSetIndex.s_count == 1 then                                  -- no selection or one selection over multiple lines
            if tSetIndex.s_start == tSetIndex.s_end then return end     -- no selection
            if tSetIndex.l_start == tSetIndex.l_end then                -- selection in one line
                tSetIndex.l_text = editor:GetLine(tSetIndex.l_start)
                local b_decl, ub1, ub2 = tSetIndex:IsDeclaration(tSetIndex.l_text)
                if b_decl then
                    tSetIndex:InsertByDeclaration(ub1, ub2)
                else
                    tSetIndex.i_1 = ub1
                    tSetIndex.i_2 = ub2
                    if ub2 == nil then
                        if ub1 ~= nil then
                            tSetIndex.f_onstrip = tSetIndex.StripInsertNoDeclarationAr1D
                            tSetIndex:ShowStripAr1D()
                        end
                    else
                        tSetIndex.f_onstrip = tSetIndex.StripInsertNoDeclarationAr2D
                        tSetIndex:ShowStripAr2D()
                    end
                end
            else                                                        -- selection over multiple lines
                output:ClearAll()
                print('! Selection over multiple lines.\n> This function supports either text selection in one line, i.e.: "Global $ar[10][2]", "$array[]" or rectangular selection without text selection.')
            end
        end
    end
    Alles anzeigen

    Dateien

    SetArrayIndex.lua 14,19 kB – 347 Downloads
  • SciTE - Leerzeichen statt Tabs, Tab Ersetzen in SciTE und Dateien

    • BugFix
    • 20. November 2021 um 11:06

    Tabs im Editor sind recht nützlich, um das Skript schön strukturiert darzustellen.

    Aber genaugenommen interessieren uns dabei nicht die Tabs selbst, sondern die Funktionalität fehlende Zeichen bis zur nächsten Tabposition aufzufüllen. Daraus resultiert aber auch der (m.M.n.) große Nachteil von Tabs: Obwohl sie nur ein Zeichen darstellen, können sie den Platz von 1...tab.size Zeichen einnehmen.

    Z.B. hat man etwas geschrieben, was mit (nicht vollem) Tab ausgerichtet wurde. Später ergänzt man vor dem Tab noch etwas und möchte von der Tabposition rückwärts eine Tabweite löschen. Der Tab hat nun evtl. nur noch 1 Zeichen Breite und ich muss also den Tab und anschliessend die davor befindlichen Leerzeichen extra löschen. Das ganze Tab-Handling gefällt mir persönlich nicht.

    SciTE bietet die Möglichkeit, statt des Tabs Leerzeichen einzufügen. Dazu muss die Property use.tabs=0 gesetzt sein.

    Es werden dann statt eines Tabs die Leerzeichen bis zur nächsten Tabposition eingefügt. Optisch ist das Verhalten soweit analog. Der Vorteil von Leerzeichen ist auch, dass die Darstellung in unterschiedlichen Editoren identisch ist. Man sieht ja schon, dass bei Skriptdarstellung hier im Forum die Formatierung ziemlich zerrissen wird, wenn Textbereiche enthalten sind.

    Wer also auf Leerzeichen statt Tabs umsatteln möchte, dem kann ich hiermit noch weitere Funktionalität mitgeben:

    • Löschen aller Zeichen vom Cursor bis zur nächsten/vorigen Tabposition in der aktuellen Zeile <Shift+Delete> / <Shift+Backspace>
    • Löschen aller Zeichen bei Rectangular Selection bis zur nächsten/vorigen Tabposition in allen ausgewählten Zeilen. Die Selection bleibt nach der Operation erhalten, sodass Folgeoperationen über den Markierungsbereich möglich sind. <Shift+Delete> / <Shift+Backspace> **nur gültig, wenn kein Text markiert ist
    • Springen zur nächsten/vorigen Tabposition in der aktuellen Zeile <Alt+Arrow_Right> / <Alt+Arrow_Left>

    Die Datei über die SciTEStartup.lua laden. Erforderlich ist auch die CommonTools.lua

    EDIT zu TabReplace

    Ich habe noch ergänzt um ein Lua-Skript, mit dem in der aktuell in SciTE geöffneten Datei on-the-fly die Tab-Ersetzung durchgeführt wird.

    • TabReplaceSciTE.lua abspeichern
    • in der SciTEUser.properties einem Shortcut zuweisen:
      command.name.20.*=Replace TAB in current file
      command.20.*=dofile ("DEIN_PFAD/TabReplaceSciTE.lua")
      command.mode.20.*=subsystem:lua,savebefore:no
      command.shortcut.20.*=Ctrl+Alt+F10
      Die Angaben in ROT anpassen!
    • Als Standard wird TAB-Size=4 verwendet. Falls andere Größe erforderlich, muss in der TabReplaceSciTE.lua die letzte Zeile angepasst werden:
      TabReplace_FileInSciTE(4) -- If required: Change the TAB size here

    EDIT

    Als Ergänzung (AutoIt- und Lua-Skript):

    In vorhandenen Dateien alle TAB durch die der Position (und der vorgegebenen TAB-Weite) entsprechende Anzahl von Leerzeichen ersetzen.

    Dazu muss zeilenweise durch die Datei iteriert werden, da der Zeilenanfang als "Position 0" zur Berechnung der TAB-Positionen erforderlich ist.

    Mein Grundgedanke war, in AutoIt die Datei mit _FileReadToArray einlesen, durchiterieren und ggf. TAB ersetzen, mit _FileWriteFromArray zurückschreiben. Aber _FileWriteFromArray hat den Dateiinhalt verändert, plötzlich stimmten bei einigen Zeilen die eingefügten Ersetzungsstrings nicht mehr, obwohl diese korrekt berechnet und gespeichert wurden. Somit stelle ich nun den Schreibstring aus dem Array selbst zusammen - und es geht.

    Aber auch die Lua-Version (die hatte ich zuerst erstellt) hat mich Schweiß gekostet. Das zeilenweise Einlesen einer Datei scheint zu einer Manipulation des Zeilenendes zu führen, was wiederum zu falschen Tabpositionen und somit falscher Länge der Ersetzungsstrings führte. Beim Zusammenstellen des Schreibstrings aus den eingelesenen Zeilen wurden MAC-Zeilenumbrüche (CR) eingefügt, gleich zwei hintereinander. Aber das in Kombination mit meinem angehängten CRLF führte dann wenigstens zur korrekten Ersetzung der TAB. Die CR-CR zu entfernen war dann das kleinste Übel. :whistling:

    TabReplace
    AutoIt: TabReplace.au3
    ;-- TIME_STAMP   2022-03-16 12:36:59   v 0.1
    
    
    #include <File.au3>
    
    ;===================================================================================================
    ; Function Name....: _TabReplace_File
    ; Description......: Replaces TAB in all lines of the file with the number of spaces corresponding to the columns.
    ; .................: Overwrites the file with the replaced content.
    ; Parameter(s).....: $_sPath    The files path.
    ; .................: $_iMode    The files mode. Default is UTF8-with-BOM(128).
    ; .................: $_iTabsize TAB size in number of characters. If it is omitted, 4 is used.
    ; Return Value(s)..: Count of replacements
    ; Author...........: BugFix (autoit<at>bug-fix.info)
    ;===================================================================================================
    Func _TabReplace_File($_sPath, $_iMode=128, $_iTabsize=4)
        If Not FileExists($_sPath) Then Return SetError(1,0,0)
        Local $fh = FileOpen($_sPath, $_iMode)
        Local $aFile, $iReplacements = 0, $sWrite, $sLine
        _FileReadToArray($fh, $aFile, 0)
        FileClose($fh)
        For $i = 0 To UBound($aFile) -1
            $sLine = $aFile[$i]
            $iReplacements += _TabReplace_Line($sLine, $_iTabsize)
            $sWrite &= $sLine & @CRLF
        Next
        If $iReplacements = 0 Then Return 0
        Local $fh = FileOpen($_sPath, $_iMode + 2)
        FileWrite($fh, $sWrite)
        FileClose($fh)
        Return $iReplacements
    EndFunc  ;==>_TabReplace_File
    
    
    ;===================================================================================================
    ; Function Name....: _TabReplace_Line
    ; Description......: Replaces TAB in a row (ByRef) with the number of spaces corresponding to the column.
    ; Parameter(s).....: $_line     A line of text whose TAB are to be replaced by spaces.
    ; .................: $_iTabsize TAB size in number of characters. If it is omitted, 4 is used.
    ; Return Value(s)..: Count of replacements
    ; Author...........: BugFix (autoit<at>bug-fix.info)
    ;===================================================================================================
    Func _TabReplace_Line(ByRef $_line, $_iTabsize=4)
        If StringRegExp($_line, '^[\r\n]+$') Then Return 0
        If $_line = '' Then Return 0
        StringRegExp($_line, '\t', 1)
        Local $posTab = @extended -1
        If $posTab = -1 Then Return 0
        Local $aTab[50]
        Local $sRepl = '', $iLen = 0, $sumLen = 0, $index = -1
        Local $aRepl[] = ['',' ','  ','   ','    ']
        While $posTab <> -1
            $index += 1
            If $index = UBound($aTab) Then ReDim $aTab[UBound($aTab)+50]
            $iLen = ($_iTabsize - Mod(($posTab + $sumLen -1), $_iTabsize))
            $sumLen += $iLen -1
            $sRepl = $aRepl[$iLen]
            $aTab[$index] = $sRepl
            StringRegExp($_line, '\t', 1, $posTab +1)
            $posTab = @extended -1
        WEnd
        ; Ersetzung
        For $i = 0 To $index
            $_line = StringRegExpReplace($_line, '\t', $aTab[$i], 1)
        Next
        Return $index +1
    EndFunc  ;==>_TabReplace_Line
    Alles anzeigen
    Lua
    -- TIME_STAMP 2022-03-16 12:37:55 v 0.1
    
    
    ----------------------------------------------------------------------------------------------------
    --[[
    in...: _line A line of text whose TAB are to be replaced by spaces.
    .....: _tabsize TAB size in number of characters. If it is omitted, 4 is used.
    out..: The line, with TAB replaced if necessary, and the number of replacements.
    ]]
    ----------------------------------------------------------------------------------------------------
    TabReplace_Line = function(_line, _tabsize)
        if _line:find('^[\r\n]+$') then return _line, 0 end -- only a line break
        if _line == '' then return _line, 0 end             -- only a empty string
        local posTab = _line:find('\t')
        if posTab == nil then return _line, 0 end           -- no TAB included
        _tabsize = _tabsize or 4 -- default TAB width
        local tTab, s, sRep, iLen, sumLen = {}, ' ', '', 0, 0
        while posTab ~= nil do
            -- calculation replacement string, taking into account characters to be inserted
            iLen = (_tabsize - ((posTab + sumLen -1) % _tabsize))
            sumLen = sumLen + iLen -1            -- total length of the replacements
            sRep = s:rep(iLen)                   -- create replacement string
            table.insert(tTab, sRep)             -- save to table
            posTab = _line:find('\t', posTab +1) -- find next TAB
        end
        local idx = 0
        _line = _line:gsub('\t', function() idx = idx +1 return tTab[idx] end)
        return _line, idx
    end
    ----------------------------------------------------------------------------------------------------
    
    
    ----------------------------------------------------------------------------------------------------
    --[[
    in...: _file Path of the file whose TAB are to be replaced by spaces.
    .....: _tabsize TAB size in number of characters. If it is omitted, 4 is used.
    out..: Success true, count-of-replacements
    .....: Failure false, 0
    ]]
    ----------------------------------------------------------------------------------------------------
    TabReplace_File = function(_file, _tabsize)
        local fh = io.open(_file, "rb") -- check if file exists
        if fh == nil then return false, 0 end
        local read = fh:read('*a')
        local lineBreak = read:find('\r')
        if lineBreak ~= nil then lineBreak = string.char(13,10) else lineBreak = string.char(10) end
        local nRepl, sumRepl, newLine, sWrite = 0, 0, '', ''
        fh:seek("set")
        for line in fh:lines() do
            newLine, nRepl = TabReplace_Line(line, _tabsize)
            sWrite = string.format('%s%s%s', sWrite, newLine, lineBreak)
            sumRepl = sumRepl + nRepl
        end
        fh:close()
    
        -- • file:lines() zerstört das Zeilenende?
        -- • Füge ich kein CRLF an, wird LF verwendet, was dazu führt, dass die berechneten Ersatzstrings für TAB falsch sind.
        -- • Füge ich CRLF an, ist das Ergebnis: "Zeileninhalt" & CR & CR & CRLF.
        -- • Deshalb wird das doppelte CR hier entfernt.
        sWrite = sWrite:gsub('\r\r', '')
    
        if sumRepl == 0 then return true, 0 end
        fh = io.open(_file, "w+")
        fh:write(sWrite)
        fh:close()
        return true, sumRepl
    end
    ----------------------------------------------------------------------------------------------------
    Alles anzeigen
    Lua
    -- TIME_STAMP 2022-03-17 10:43:14 v 0.1
    -- Replace TAB in current SciTE buffer
    
    
    
    ----------------------------------------------------------------------------------------------------
    --[[
    in...: _line A line of text whose TAB are to be replaced by spaces.
    .....: _tabsize TAB size in number of characters. If it is omitted, 4 is used.
    out..: The line, with TAB replaced if necessary, and the number of replacements.
    ]]
    ----------------------------------------------------------------------------------------------------
    TabReplace_Line = function(_line, _tabsize)
        if _line:find('^[\r\n]+$') then return _line, 0 end -- only a line break
        if _line == '' then return _line, 0 end             -- only a empty string
        local posTab = _line:find('\t')
        if posTab == nil then return _line, 0 end           -- no TAB included
        _tabsize = _tabsize or 4 -- default TAB width
        local tTab, s, sRep, iLen, sumLen = {}, ' ', '', 0, 0
        while posTab ~= nil do
            -- calculation replacement string, taking into account characters to be inserted
            iLen = (_tabsize - ((posTab + sumLen -1) % _tabsize))
            sumLen = sumLen + iLen -1             -- total length of the replacements
            sRep = s:rep(iLen)                    -- create replacement string
            table.insert(tTab, sRep)              -- save to table
            posTab = _line:find('\t', posTab +1)  -- find next TAB
        end
        local idx = 0
        _line = _line:gsub('\t', function() idx = idx +1 return tTab[idx] end)
        return _line, idx
    end
    ----------------------------------------------------------------------------------------------------
    
    
    ----------------------------------------------------------------------------------------------------
    --[[
    Replaces all TAB in the file currently open in SciTE
    ]]
    ----------------------------------------------------------------------------------------------------
    TabReplace_FileInSciTE = function(_tabsize)
        local caret = editor.CurrentPos
        local fvl = editor.FirstVisibleLine
        local content = ''
        for i=0, editor.LineCount -1 do
            local line = editor:GetLine(i)
            line = TabReplace_Line(line, _tabsize)
            content = content..line
        end
        editor:BeginUndoAction()
        editor:ClearAll()
        editor:InsertText(0, content)
        editor:EndUndoAction()
        editor.CurrentPos = caret
        editor:SetSel(caret, caret)
        editor.FirstVisibleLine = fvl
    end
    ----------------------------------------------------------------------------------------------------
    
    
    TabReplace_FileInSciTE(4) -- If required: Change the TAB size here
    Alles anzeigen


    EDIT v 0.2

    SCRIPT BREAKING CHANCE - Um mit unterschiedlichen Tabweiten arbeiten zu können, wird jetzt ausschließlich die dateispezifische Property ("use.tabs.$(file.pattern.EXT)=0" oder "use.tabs.EXT=0") genutzt! use.tabs=0 ist allgemeingültig und wird deshalb nicht weiter unterstützt. Deshalb ist auch die Version 0.6 der CommonTools.lua erforderlich. Die erforderlichen Anpassungen in der Properties-Datei sind im Skriptkopf erläutert.

    Lua
    -- TIME_STAMP   2022-02-14 16:13:55   v 0.2
    -- coding:utf-8
    
    --[[
        Load with "SciTEStartup.lua"
        Require: "CommonTools.lua" ( https://autoit.de/thread/87485-scite-commontools/?postID=704965#post704965 )
                min. version: v 0.6
    
        To use with spaces as tab (property "use.tabs.$(file.pattern.EXT)=0" or "use.tabs.EXT=0"). Don't use "use.tabs=0"!
        If the property is set to ">0", the script will not respond.
        For use with values other than the default, see remarks.
    
        Additional functions        <Shift+Backspace>                                       <Shift+Del>
            single caret         :  Delete chars from caret until previous tab position     Delete chars from caret until next tab position
            rectangular selection:              As above, but in each line of selection
                                                The rectangular selection remains after the operation.
                                    <Alt+Arrow_Left>                                        <Alt+Arrow_Right>
            single caret            Skip to previous Tab position                           Skip to next Tab position
    
    
        Remarks:
            The default Tab size is 4. You can change this setting specified for your file types. The following properties need changes:
            tab.size.$(file.pattern.EXT)=VALUE
            indent.size.$(file.patterns.EXT)=VALUE
    
            The (not file type specific) values:
            tab.indents=1
            backspace.unindents=1
            should also set.
            If tab.indents is set then pressing tab within indentation whitespace indents by indent.size rather than inserting a tab character.
            If backspace.unindents then pressing backspace within indentation whitespace unindents by indent.size rather than deleting the character before the caret.
    ]]
    
    --  v 0.2   changed:    SCRIPT BREAKING CHANCE - Now only file specific properties ("use.tabs.$(file.pattern.EXT)=0" or "use.tabs.EXT=0") are considered!
    
    
    local ct = require 'CommonTools'
    
    Tabspaces = EventClass:new(Common)
    
    -- Gets the carets column and position
    Tabspaces.Caret = function(self)
        local pos = editor.CurrentPos
        local col = editor.Column[editor.CurrentPos]
        return col, pos
    end
    
    
    -- Gets a table with {{line,pos}} for rectangular selection without selected text [caret only!]
    Tabspaces.GetRect = function(self)
        local tRet = {}
        local selLines = editor.Selections
        if (editor.SelectionMode == 0) or
            (selLines < 2) or (editor.SelectionIsRectangle == false) then
            return false, {}
        end
        local s_start = editor.SelectionStart
        local s_end = editor.SelectionEnd
        if s_start > s_end then s_start, s_end = s_end, s_start end
        local line, s, e = editor:LineFromPosition(s_start)
        repeat
            s = editor:GetLineSelStartPosition(line)
            e = editor:GetLineSelEndPosition(line)
            if s ~= e then return false, {} end   -- don't use with selected text
            table.insert(tRet, {line,s})
            line = line +1
            selLines = selLines -1
        until selLines == 0
        return true, tRet
    end
    
    
    -- Deletes all characters left/right from cursor until the previous/next Tab position in line from caret
    -- left side,  keys: <Shift+Backspace>
    -- right side, keys: <Shift+Del>
    Tabspaces.DeleteLine = function(self, b_right)
        local colCaret, posCaret = self:Caret()
        local colTab, posTab
        if b_right then
            colTab, posTab = ct:EditorTabColPosInLine()     -- next Tab
            local posLast = editor.LineEndPosition[editor:LineFromPosition(posCaret)]
            if posTab > posLast then posTab = posLast end
        else
            colTab, posTab = ct:EditorTabColPosInLine(true) -- previous Tab
        end
        editor:SetSelection(posTab, posCaret)
        editor:ReplaceSel('')
    end
    
    
    -- Performs the deletion in the selected line(s) on the right or left side
    Tabspaces.DeleteLeftRight = function(self, b_right)
        local bRect, tRect = self:GetRect()
        if bRect then
            for i = #tRect, 1, -1  do
                editor.CurrentPos = tRect[i][2]
                self:DeleteLine(b_right)
            end
            scite.MenuCommand(IDM_SAVE)
            local col = editor.Column[editor.CurrentPos]
            editor.RectangularSelectionAnchor = editor:FindColumn(tRect[1][1], col)
            for i = 2, #tRect  do
                editor.RectangularSelectionCaret = editor:FindColumn(tRect[i][1], col)
            end
        else
            self:DeleteLine(b_right)
        end
    end
    
    -- Skip to previous/next Tab position
    -- left side,  keys: <Alt+Arrow_Left>
    -- right side, keys: <Alt+Arrow_Right>
    Tabspaces.SkipLeftRight = function(self, b_right)
        local colCaret, posCaret = self:Caret()
        local posTab
        if b_right then
            _, posTab = ct:EditorTabColPosInLine()     -- next Tab
            local posLast = editor.LineEndPosition[editor:LineFromPosition(posCaret)]
            if posTab > posLast then posTab = posLast end
        else
            _, posTab = ct:EditorTabColPosInLine(true) -- previous Tab
        end
        editor:SetSelection(posTab, posTab)
    end
    
    Tabspaces.OnKey = function(self, _keycode, _shift, _ctrl, _alt)
        if ct:PropExt('use.tabs.', props['FileExt']) == '0' then    -- file type specific setting is required
            local tKeys = {[8]='backspace',[37]='ar_left', [39]='ar_right', [46]='delete'}
            local key = tKeys[_keycode]
            if key == nil then return nil end
            if _shift and not _ctrl and not _alt then
                if key == 'backspace' then
                    self:DeleteLeftRight()
                    return true
                elseif key == 'delete' then
                    self:DeleteLeftRight(true)
                    return true
                else
                    return nil
                end
            elseif not _shift and not _ctrl and _alt then
                if key == 'ar_left' then
                    self:SkipLeftRight()
                    return true
                elseif key == 'ar_right' then
                    self:SkipLeftRight(true)
                    return true
                else
                    return nil
                end
            end
        end
        return nil
    end
    Alles anzeigen

    Dateien

    Tabspaces.lua 6,01 kB – 348 Downloads TabReplace.au3 3,03 kB – 291 Downloads TabReplace.lua 3,32 kB – 289 Downloads TabReplaceSciTE.lua 2,63 kB – 305 Downloads
  • Untermenüs aufrufen

    • BugFix
    • 18. November 2021 um 13:21
    Zitat von HansJ54

    Bei diesen dynamisch aufgebauten Ctrls (aus der csv-Datei) könnte ich nämlich auch nur dynamisch feststellen, wo ein bestimmter Button gerade liegt, da durch die Änderung der csv auch die neue Pos. vom Button bestimmt wird.

    Ich habe dir jetzt mal ein Bsp. erstellt, wie du aus einer csv-Datei abhängig von der Anzahl der Einträge Button erstellst und diese abfragst.

    Neue Einträge in der csv werden so vollautomatisch berücksichtigt.

    Du kannst natürlich auch Checkboxen verwenden, wenn dir das mehr gefällt. Allerdings entspräche das nicht deren Bestimmung und du müsstest diese nach der Aktion jedes mal deaktivieren.

    AutoIt
    #include <File.au3>
    #include <WindowsConstants.au3>
    #include <WinAPISys.au3>
    
    Global $pathCSV = @ScriptDir & '\streamlink.csv'
    
    ; Bsp csv-Datei
    ; GRUPPE;NAME;LINK
    Global $gsCSV = _
    'BR Radio;Bayern 1;https://dispatcher.rndfnk.com/br/br1/obb/mp3/mid' & @CRLF & _
    'BR Radio;Bayern 2;https://dispatcher.rndfnk.com/br/br2/nord/mp3/mid' & @CRLF & _
    'BR Radio;Bayern 3;https://dispatcher.rndfnk.com/br/br3/live/mp3/mid' & @CRLF & _
    'BR Radio;BR-Klassik;https://dispatcher.rndfnk.com/br/brklassik/live/mp3/mid' & @CRLF & _
    'BR Radio;BR24;https://dispatcher.rndfnk.com/br/br24/live/mp3/mid' & @CRLF & _
    'BR Radio;BR24live;https://dispatcher.rndfnk.com/br/br24live/live/mp3/mid' & @CRLF & _
    'BR Radio;BR Schlager;https://dispatcher.rndfnk.com/br/brschlager/live/mp3/mid' & @CRLF & _
    'BR Radio;BR Heimat;https://dispatcher.rndfnk.com/br/brheimat/live/mp3/mid' & @CRLF & _
    'BR Radio;Puls;https://dispatcher.rndfnk.com/br/puls/live/mp3/mid' & @CRLF & _
    ';DLF;https://st01.sslstream.dlf.de/dlf/01/128/mp3/stream.mp3?aggregator=web' & @CRLF & _  ; keine Gruppe
    'HR;hr1;http://metafiles.gl-systemhaus.de/hr/hr1_2.m3u' & @CRLF & _
    'HR;hr2 kultur;http://metafiles.gl-systemhaus.de/hr/hr2_2.m3u' & @CRLF & _
    'HR;hr3;http://metafiles.gl-systemhaus.de/hr/hr3_2.m3u' & @CRLF & _
    'HR;hr4;http://metafiles.gl-systemhaus.de/hr/hr4_2.m3u' & @CRLF & _
    'HR;hr iNFO;http://metafiles.gl-systemhaus.de/hr/hrinfo_2.m3u' & @CRLF & _
    'HR;YOUFM;http://metafiles.gl-systemhaus.de/hr/youfm_2.m3u' & @CRLF & _
    'WDR;WDR 1LIVE;https://wdr-1live-live.icecastssl.wdr.de/wdr/1live/live/mp3/128/stream.mp3' & @CRLF & _
    'WDR;WDR 2;https://wdr-wdr2-rheinland.icecastssl.wdr.de/wdr/wdr2/rheinland/mp3/128/stream.mp3' & @CRLF & _
    'WDR;WDR 3;https://wdr-wdr3-live.icecastssl.wdr.de/wdr/wdr3/live/mp3/128/stream.mp3' & @CRLF & _
    'WDR;WDR 4;https://wdr-wdr4-live.icecastssl.wdr.de/wdr/wdr4/live/mp3/128/stream.mp3' & @CRLF & _
    'WDR;WDR 5;https://wdr-wdr5-live.icecastssl.wdr.de/wdr/wdr5/live/mp3/128/stream.mp3' & @CRLF & _
    'WDR;WDR COSMO;https://wdr-cosmo-live.icecastssl.wdr.de/wdr/cosmo/live/mp3/128/stream.mp3' & @CRLF & _
    'WDR;WDR EVENT;https://wdr-wdr-event.icecastssl.wdr.de/wdr/wdr/event/mp3/128/stream.mp3' & @CRLF & _
    'WDR;WDR VERA;https://wdr-vera-live.icecastssl.wdr.de/wdr/vera/live/mp3/128/stream.mp3' & @CRLF
    
    ; zur Demo csv im Skriptordner erstellen
    If Not FileExists($pathCSV) Then FileWrite($pathCSV, $gsCSV)
    
    ; aus CSV ein 2D-Array erstellen
    Global $gaStreamLink ; [0][0]=Zähler
    _FileReadToArray($pathCSV, $gaStreamLink, 1, ';')
    
    Global $gaCtrl[1][3] = [[0]] ; [0][0]=Zähler, [n][0]=ID, [n][1]=zugehörige Sub-Gui, [n][2]=url
    Global $iMsg, $aWinPos, $aCtrlPos
    Global $iXadd = _WinAPI_GetSystemMetrics(5) ; SM_CXBORDER
    Global $iYadd = _WinAPI_GetSystemMetrics(51) ; SM_CYSMCAPTION
    
    
    Global $hMain = _createGUI('Test', 400, 300)
    GUISetState()
    
    While True
        $iMsg = GUIGetMsg()
        For $i = 1 To $gaCtrl[0][0]
            If $iMsg = $gaCtrl[$i][0] Then
                If $gaCtrl[$i][1] = Null Then ; hat keine Sub-Gui
                    ; URL abrufen
                    ConsoleWrite('Button: "' & GUICtrlRead($gaCtrl[$i][0]) & '", url: "' & $gaCtrl[$i][2] & '"' & @CRLF)
                Else
                    If $gaCtrl[$i][2] = Null Then     ; Button zum Aufruf der Sub-Gui
                        $aWinPos = WinGetPos($hMain)
                        $aCtrlPos = ControlGetPos($hMain, '', $iMsg)
                        WinMove($gaCtrl[$i][1], '', $aWinPos[0]+$aCtrlPos[0]+$iXadd, $aWinPos[1]+$aCtrlPos[1]+$iYadd)
                        GUISetState(@SW_SHOW, $gaCtrl[$i][1])
                    Else                            ; Button auf Sub-Gui
                        ; URL abrufen
                        ConsoleWrite('Button: "' & GUICtrlRead($gaCtrl[$i][0]) & '", url: "' & $gaCtrl[$i][2] & '"' & @CRLF)
                        ; Sub-Gui ausblenden
                        GUISetState(@SW_HIDE, $gaCtrl[$i][1])
                    EndIf
                EndIf
                ExitLoop
            EndIf
        Next
        Switch $iMsg
            Case -3
                Exit
        EndSwitch
    WEnd
    
    
    
    Func _createGUI($_Title, $_w=-1, $_h=-1, $_x=-1, $_y=-1)
        Local $hGui = GUICreate($_Title, $_w, $_h, $_x, $_y)
        Local $iMargin = 10, $iHeightCtrl = 20, $iWidthCtrl = 100, $ixSub = $iMargin, $iySub
        Local $ixMain = $iMargin, $iyMain = 0 - $iHeightCtrl
        Local $sGroupCurr = '', $hSubCurr = 0, $bCreateSub, $iCountCtrlSub = 0
        For $i = 1 To $gaStreamLink[0][0]
            ; Abschluss letzte Gruppe (Sub-Gui), Größe anpassen
            If $i > 1 And $sGroupCurr <> $gaStreamLink[$i][0] Then
                $aWinPos = WinGetPos($hGui)
                WinMove($hSubCurr, '', $iMargin, Default, Default, ($iCountCtrlSub*$iHeightCtrl)+(($iCountCtrlSub+1)*$iMargin))
                $iCountCtrlSub = 0
                $hSubCurr = 0
            EndIf
            $gaCtrl[0][0] += 1
            ReDim $gaCtrl[$gaCtrl[0][0] +1][3]
            If $gaStreamLink[$i][0] = '' Then ; keine Gruppe - einzelner Button auf Haupt-Gui
                $iyMain += $iHeightCtrl + $iMargin
                $sGroupCurr = ''
                $hSubCurr = 0
                $gaCtrl[$gaCtrl[0][0]][0] = GUICtrlCreateButton($gaStreamLink[$i][1], $ixMain, $iyMain, $iWidthCtrl, $iHeightCtrl)
                $gaCtrl[$gaCtrl[0][0]][1] = Null
                $gaCtrl[$gaCtrl[0][0]][2] = $gaStreamLink[$i][2]
            Else
                If ($sGroupCurr = '')  Or ($sGroupCurr <> '' And $sGroupCurr <> $gaStreamLink[$i][0]) Then
                    $sGroupCurr = $gaStreamLink[$i][0]
                    $bCreateSub = True
                Else
                    $bCreateSub = False
                EndIf
                If $bCreateSub Then
                    $bCreateSub = False
                    $iySub = 0 - $iHeightCtrl ; y auf Startwert setzen
                    $hSubCurr = GUICreate($gaStreamLink[$i][1], (2*$iMargin)+$iWidthCtrl, (2*$iMargin)+$iHeightCtrl, -1, -1, BitOR($WS_BORDER,$WS_POPUP), $WS_EX_MDICHILD, $hGui)
                    ; Button zum Aufruf der Sub auf Main
                    GUISwitch($hGui)
                    $iyMain += $iHeightCtrl + $iMargin
                    $gaCtrl[$gaCtrl[0][0]][0] = GUICtrlCreateButton($gaStreamLink[$i][0], $ixMain, $iyMain, $iWidthCtrl, $iHeightCtrl)
                    $gaCtrl[$gaCtrl[0][0]][1] = $hSubCurr
                    $gaCtrl[$gaCtrl[0][0]][2] = Null
                    ; ersten Button der Gruppe auf der Sub erstellen
                    $gaCtrl[0][0] += 1
                    ReDim $gaCtrl[$gaCtrl[0][0] +1][3]
                    GUISwitch($hSubCurr) ; auf neue Sub wechseln und dort Ctrl erstellen
                    $iySub += $iHeightCtrl + $iMargin
                    _SubCreateCtrl($hSubCurr, $gaStreamLink[$i][1], $ixSub, $iySub, $iWidthCtrl, $iHeightCtrl, $gaStreamLink[$i][2])
                    $iCountCtrlSub += 1
                    GUISwitch($hGui)
                Else
                    GUISwitch($hSubCurr) ; auf aktuelle Sub wechseln und dort Ctrl erstellen
                    $iySub += $iHeightCtrl + $iMargin
                    _SubCreateCtrl($hSubCurr, $gaStreamLink[$i][1], $ixSub, $iySub, $iWidthCtrl, $iHeightCtrl, $gaStreamLink[$i][2])
                    $iCountCtrlSub += 1
                    GUISwitch($hGui)
                EndIf
            EndIf
        Next
        If $hSubCurr <> 0 Then    ; Abschluss letzte Gruppe (Sub-Gui), Größe anpassen
            $aWinPos = WinGetPos($hGui)
            WinMove($hSubCurr, '', $iMargin, Default, Default, ($iCountCtrlSub*$iHeightCtrl)+(($iCountCtrlSub+1)*$iMargin))
        EndIf
        Return $hGui
    EndFunc
    
    
    Func _SubCreateCtrl($_hSub, $_Text, $_x, $_y, $_w, $_h, $_link)
        $gaCtrl[$gaCtrl[0][0]][0] = GUICtrlCreateButton($_Text, $_x, $_y, $_w, $_h)
        $gaCtrl[$gaCtrl[0][0]][1] = $_hSub
        $gaCtrl[$gaCtrl[0][0]][2] = $_link
    EndFunc
    Alles anzeigen
  • Kann man "GUICtrlSetFont" zentral auf alle Controls setzen?

    • BugFix
    • 18. November 2021 um 09:39

    Einfach GUISetFont verwenden, damit setzt man die Standardwerte für alle Control auf der GUI.

  • Untermenüs aufrufen

    • BugFix
    • 17. November 2021 um 16:50
    Zitat von HansJ54

    Gleich noch zwei Fragen:

    kann man einen Button bei GUICtrlCreateButton( ) über eine Textvariable definieren, also statt

    $idButtonSophos = GUICtrlCreateButton("Sophos", 8, 20, 60, 30, $BS_MULTILINE)

    so was in der Art wie

    $sName = "Sophos"

    $idButton & $sName = GUICtrlCreateButton($sName, 8, 20, 60, 30, $BS_MULTILINE)

    Geht vermutlich nicht oder doch?

    Alles anzeigen

    Könnte man machen (schau dir mal Assign und Eval an), ist aber nicht unbedingt zu empfehlen.

    "Sprechende" Variablen lassen sich dann besser über ein "Scripting.Dictionary" definieren.

    Grundsätzlich kann man das (meine Empfehlung) aber mit Arrays absolut dynamisch lösen.

    Zitat von HansJ54

    kann man ein Submenü auch an einen Button

    $aCheckboxes[$i] = GUICtrlCreateRadio("&" & $aVersichererListe[$i], ...)

    hängen, wenn man die Nummer oder den Namen kennt?

    Wenn du mit Submenü jetzt die Sub-Gui meinst: ja. Ob das Event von einem Button, Radiobutton oder einer Checkbox ausgelöst wird ist völlig egal. Selbst ein Klick auf ein Label könnte dafür genutzt werden.

    Kannst ja mal probieren. Aber bevor du dein Mammutskript umbaust, melde dich bei Problemen, vielleicht auch mit einer abgespeckten Version, die dein System verdeutlicht.


    EDIT

    Was jetzt eigentlich total außen vor geblieben ist: Für dynamische Daten gibt es ja auch dynamische Control: Listbox, Listview, Treeview, Tab, TreeviewTab.

    Das erleichtert deutlich die Verarbeitung einer großen Anzahl von Daten.

  • Untermenüs aufrufen

    • BugFix
    • 17. November 2021 um 09:36
    Zitat von HansJ54

    Beispiel WDR: damit mir WDR1 WDR2 WDR3 WDR4 WDR5 nicht so viel Platz wegnehmen, ist meine Idee, bei Klick auf WDR einfach ein neues kleines Fenster zu öffnen über dem aktuellen Fenster mit 5 Buttons für die 5 WDR.

    Ich habe mal ein Bsp. mit Popup-Child-Windows erstellt. Das entspricht wohl dem, was du möchtest:

    EDIT

    Ich habe noch angepasst, dass die Sub-Gui auch genau an dem Button platziert werden, der sie öffnet.

    AutoIt
    #include <WindowsConstants.au3>
    #include <WinAPISys.au3>
    
    ; Haupt-Gui
    Global $hGuiMain = GUICreate('Test')
    Global $idWDR = GUICtrlCreateButton('WDR', 20, 20, 60, 21)
    Global $idSWR = GUICtrlCreateButton('SWR', 20, 50, 60, 21)
    Global $idHR = GUICtrlCreateButton('HR', 20, 80, 60, 21)
    Global $idBR = GUICtrlCreateButton('BR', 20, 110, 60, 21)
    
    ; Sub-Gui's --> als Child & Popup --> da keine Closebutton muss bei jedem Buttonklick danach das Child ausgeblendet werden
    Global $hGuiWDR = GUICreate('Sub - WDR', 100, 160, -1, -1, BitOR($WS_BORDER,$WS_POPUP), $WS_EX_MDICHILD, $hGuiMain)
    Global $idWDR1 = GUICtrlCreateButton('WDR1', 20, 10, 60, 20)
    Global $idWDR2 = GUICtrlCreateButton('WDR2', 20, 40, 60, 20)
    Global $idWDR3 = GUICtrlCreateButton('WDR3', 20, 70, 60, 20)
    Global $idWDR4 = GUICtrlCreateButton('WDR4', 20, 100, 60, 20)
    Global $idWDR5 = GUICtrlCreateButton('WDR5', 20, 130, 60, 20)
    
    Global $hGuiSWR = GUICreate('Sub - SWR', 100, 110, -1, -1, BitOR($WS_BORDER,$WS_POPUP), $WS_EX_MDICHILD, $hGuiMain)
    Global $idSWR1 = GUICtrlCreateButton('SWR1', 20, 10, 60, 20)
    Global $idSWR2 = GUICtrlCreateButton('SWR2', 20, 40, 60, 20)
    Global $idSWR3 = GUICtrlCreateButton('SWR3', 20, 70, 60, 20)
    
    Global $hGuiHR = GUICreate('Sub - HR', 100, 130, -1, -1, BitOR($WS_BORDER,$WS_POPUP), $WS_EX_MDICHILD, $hGuiMain)
    Global $idHR1 = GUICtrlCreateButton('HR1', 20, 10, 60, 20)
    Global $idHR2 = GUICtrlCreateButton('HR2', 20, 40, 60, 20)
    Global $idHR3 = GUICtrlCreateButton('HR3', 20, 70, 60, 20)
    Global $idHR4 = GUICtrlCreateButton('HR4', 20, 100, 60, 20)
    
    Global $hGuiBR = GUICreate('Sub - BR', 100, 130, -1, -1, BitOR($WS_BORDER,$WS_POPUP), $WS_EX_MDICHILD, $hGuiMain)
    Global $idBR1 = GUICtrlCreateButton('BR1', 20, 10, 60, 20)
    Global $idBR2 = GUICtrlCreateButton('BR2', 20, 40, 60, 20)
    Global $idBR3 = GUICtrlCreateButton('BR3', 20, 70, 60, 20)
    Global $idBRClassic = GUICtrlCreateButton('BR Klassik', 20, 100, 60, 20)
    
    
    GUISetState(@SW_SHOW, $hGuiMain)  ; Angabe der GUI hier erforderlich, sonst wird die zuletzt erstellte verwendet!
    
    Global $aSub[][2] = [[$idWDR,$hGuiWDR],[$idSWR,$hGuiSWR],[$idHR,$hGuiHR],[$idBR,$hGuiBR]]
    Global $iMsg, $aWinPos, $aCtrlPos
    Global $iXadd = _WinAPI_GetSystemMetrics(5) ; SM_CXBORDER
    Global $iYadd = _WinAPI_GetSystemMetrics(51) ; SM_CYSMCAPTION
    While True
        $iMsg = GUIGetMsg()
        For $i = 0 To UBound($aSub) -1
            If $iMsg = $aSub[$i][0] Then
                $aWinPos = WinGetPos($hGuiMain)
                $aCtrlPos = ControlGetPos($hGuiMain, '', $iMsg)
                WinMove($aSub[$i][1], '', $aWinPos[0]+$aCtrlPos[0]+$iXadd, $aWinPos[1]+$aCtrlPos[1]+$iYadd)
                GUISetState(@SW_SHOW, $aSub[$i][1])
                ExitLoop
            EndIf
        Next
        Switch $iMsg
            Case -3
                Exit
            Case $idWDR1, $idWDR2, $idWDR3, $idWDR4, $idWDR5
                ConsoleWrite('>[CLICKED] Sub-Gui "WDR", Ctrl: "' & GUICtrlRead($iMsg) & '"' & @CRLF)
                GUISetState(@SW_HIDE, $hGuiWDR)
            Case $idSWR1, $idSWR2, $idSWR3
                ConsoleWrite('>[CLICKED] Sub-Gui "SWR", Ctrl: "' & GUICtrlRead($iMsg) & '"' & @CRLF)
                GUISetState(@SW_HIDE, $hGuiSWR)
            Case $idHR1, $idHR2, $idHR3, $idHR4
                ConsoleWrite('>[CLICKED] Sub-Gui "HR", Ctrl: "' & GUICtrlRead($iMsg) & '"' & @CRLF)
                GUISetState(@SW_HIDE, $hGuiHR)
            Case $idBR1, $idBR2, $idBR3, $idBRClassic
                ConsoleWrite('>[CLICKED] Sub-Gui "BR", Ctrl: "' & GUICtrlRead($iMsg) & '"' & @CRLF)
                GUISetState(@SW_HIDE, $hGuiBR)
        EndSwitch
    WEnd
    Alles anzeigen

    1_main.PNG

    2_sub_wdr.PNG

    3_sub_swr.PNG

    4_sub_br.PNG

  • Untermenüs aufrufen

    • BugFix
    • 16. November 2021 um 19:36
    Zitat von HansJ54

    Mein Problem ist ausschließlich das Öffnen der neuen Gui on top der alten und das Beenden der Gui und der Rücksprung in die alte Gui nach Ausführen eines Befehls (oder Esc), den Rest habe ich im Griff. Bei meinen bisherigen Versuchen war nach Schließen der neuen Gui die alte tot, ist aber vermutlich nur ein Befehl der mir fehlt.

    Achso, also wesentlich einfacher, als ich dachte.

    Alle GUI sind im Voraus zu erstellen. Bei Bedarf (Buttonklick) wird die jeweilige GUI mit GUISetState(@SW_SHOW, $hwndGuiSub) angezeigt. Da die GUI und somit deren Ctrl im Vorfeld definiert sind, können auch alle Ctrl in derselben Schleife abgefragt werden.

    Wichtig ist nur, dass beim Schliessen der Sub-GUI NICHT der Befehl Exit ausgeführt wird, sondern GUISetState(@SW_HIDE, $hwndGuiSub) ( s. Zeilen #56 bis #63 in meinem Skript )

  • Abluftanlage mit Bypass - Steuerung mit Nano?

    • BugFix
    • 16. November 2021 um 14:31
    Zitat von GML

    Stichwort Belimo, das sollte dich auf den richtigen Weg führen

    Danke, da findet man tatsächlich Einiges.

    Aber die kompletten Einheiten mit Motor sind ja entzückend bepreist, >200 €. :/

    Da ist es finanziell erheblich günstiger einen Bypass ohne Motor zu kaufen (habe ich für ca. 25 € gefunden) und dann selbst einen Antrieb dranzubauen. Da favorisiere ich aber statt des Stellantriebs (unnütz teuer) einen Linearantrieb. 50 mm Hub reichen völlig aus bei 750N. Der bewegt die Klappe ohne zu mucken hin und her. Kostet auch nur etwa 25 €.

    Aber Danke für den wertvollen Hinweis. :thumbup:

  • Untermenüs aufrufen

    • BugFix
    • 16. November 2021 um 11:48
    Zitat von HansJ54

    soll ein zusätzliches (Sub-)Gui-Fenster darüber aufgehen mit neuen Buttons.

    Ich habe mal ein minimales Muster erstellt, mit dem du zur Laufzeit Gui erstellen kannst und darauf Button und Label. Ist ohne jede Fehlerabfrage. Kannst du dann beliebig um andere Ctrl und Parameter erweitern.

    AutoIt
    ;-- TIME_STAMP   2021-11-16 15:24:46
    
    ; Die zu erstellenden Gui werden hier mit Hwnd und Titel gespeichert
    Global $ga_Gui[100][2] = [[0]]          ; [0][0]=Counter, [n][0]=Hwnd, [n][1]=Titel
    
    ; Da Ctrl erst zur Laufzeit erstellt werden, müssen diese Global verfügbar sein
    Global $ga_CtrlID[1000][3] = [[0]]        ; [0][0]=Counter, [n][0]=HwndGui, [n][1]=CtrlID, [n][2]=zugewiesene_Funktion
    
    
    
    Global $hGuiMain = GUICreate('Test')
    GUICtrlCreateLabel('Wähle Ctrl-Typ und gib die Parameter an', 10, 20)
    Global $idCombo = GUICtrlCreateCombo('', 100, 40, 100, 20)
    GUICtrlSetData(-1, 'Button|Label', 'Button')
    GUICtrlCreateLabel('Zuweisbare Funktionen', 230, 20)
    Global $idComboFunc = GUICtrlCreateCombo('', 230, 40, 100, 20)
    GUICtrlSetData(-1, '_A|_B|_C|_D| ', '')
    Global $idAssignFunc = GUICtrlCreateButton('Funktion zuweisen', 230, 70, 100, 21)
    GUICtrlCreateLabel('Text', 10, 73)
    Global $idCtrlText = GUICtrlCreateInput('', 100, 70, 100, 20)
    GUICtrlCreateLabel('X', 10, 103)
    Global $idCtrlX = GUICtrlCreateInput('', 40, 100, 40, 20)
    GUICtrlCreateLabel('Y', 90, 103)
    Global $idCtrlY = GUICtrlCreateInput('', 120, 100, 40, 20)
    GUICtrlCreateLabel('W', 170, 103)
    Global $idCtrlW = GUICtrlCreateInput('-1', 200, 100, 40, 20)
    GUICtrlCreateLabel('H', 250, 103)
    Global $idCtrlH = GUICtrlCreateInput('-1', 280, 100, 40, 20)
    Global $idAddArg = GUICtrlCreateButton('Hinzufügen zu Arg-Array', 10, 140, 200, 21)
    
    GUICtrlCreateLabel('Titel neue GUI', 10, 203)
    Global $idGuiTitle = GUICtrlCreateInput('', 100, 200, 100, 20)
    GUICtrlCreateLabel('W', 10, 233)
    Global $idGuiW = GUICtrlCreateInput('', 40, 230, 40, 20)
    GUICtrlCreateLabel('H', 90, 233)
    Global $idGuiH = GUICtrlCreateInput('', 120, 230, 40, 20)
    GUICtrlCreateLabel('W', 170, 233)
    Global $idGuiX = GUICtrlCreateInput('-1', 200, 230, 40, 20)
    GUICtrlCreateLabel('H', 250, 233)
    Global $idGuiY = GUICtrlCreateInput('-1', 280, 230, 40, 20)
    Global $idNew = GUICtrlCreateButton('Erstelle neue Gui mit Arg-Array', 10, 270, 200, 21)
    
    GUICtrlCreateLabel('Erstellte Gui', 10, 333)
    Global $idComboGui = GUICtrlCreateCombo('', 100, 330, 100, 20)
    Global $idShowGui = GUICtrlCreateButton('Wähle Gui aus Combo und zeige sie an.', 10, 360, 200, 21)
    
    GUISetState()
    
    Global $iMsg, $hwndActive = $hGuiMain
    Global $aArg[1][7] = [[Null]], $sGuiList = '', $hwndTmp, $sFuncTmp = ''
    Global $aEmpty = $aArg
    
    While True
        $iMsg = GUIGetMsg()
        Switch $iMsg
            Case -3
                If $hwndActive = $hGuiMain Then
                    Exit
                Else
                    GUISetState(@SW_HIDE, $hwndActive)
                    $hwndActive = $hGuiMain
                    GUISetState(@SW_SHOWNORMAL, $hGuiMain)
                EndIf
            Case $idAssignFunc
                $sFuncTmp = GUICtrlRead($idComboFunc)
                ControlCommand($hGuiMain, '', $idComboFunc, 'SelectString', ' ')
            Case $idAddArg
                If $aArg[0][0] <> Null Then ReDim $aArg[UBound($aArg)+1][7]
                $aArg[UBound($aArg)-1][0] = GUICtrlRead($idCombo) ; Typ
                $aArg[UBound($aArg)-1][1] = GUICtrlRead($idCtrlText)
                $aArg[UBound($aArg)-1][2] = GUICtrlRead($idCtrlX)
                $aArg[UBound($aArg)-1][3] = GUICtrlRead($idCtrlY)
                $aArg[UBound($aArg)-1][4] = GUICtrlRead($idCtrlW)
                $aArg[UBound($aArg)-1][5] = GUICtrlRead($idCtrlH)
                $aArg[UBound($aArg)-1][6] = $sFuncTmp
                $sFuncTmp = ''
                _ResetInput('ctrl')
            Case $idNew
                _CreateGui(GUICtrlRead($idGuiTitle), GUICtrlRead($idGuiW), GUICtrlRead($idGuiH), GUICtrlRead($idGuiX), GUICtrlRead($idGuiY), $aArg)
                If $sGuiList <> '' Then
                    $sGuiList &= '|' & GUICtrlRead($idGuiTitle)
                Else
                    $sGuiList = GUICtrlRead($idGuiTitle)
                EndIf
                GUICtrlSetData($idComboGui, '|' & $sGuiList)
                _ResetInput('gui')
                $aArg = $aEmpty
            Case $idShowGui
                $hwndTmp = _GetGui(GUICtrlRead($idComboGui))
                GUISetState(@SW_SHOW, $hwndTmp)
                $hwndActive = $hwndTmp
        EndSwitch
        ; alle Ctrl aus erstellten Gui auf Aktion prüfen
        If $ga_CtrlID[0][0] > 0 Then
            For $i = 1 To $ga_CtrlID[0][0]
                If $ga_CtrlID[$i][1] = $iMsg Then
                    ConsoleWrite('>[CLICKED] Fenster: "' & WinGetTitle($ga_CtrlID[$i][0]) & '", Ctrl: "' & GUICtrlRead($ga_CtrlID[$i][1]) & '"' & @CRLF)
                    ; verknüpfte Funktion ausführen
                    If $ga_CtrlID[$i][2] <> '' Then Call($ga_CtrlID[$i][2])
                    ExitLoop
                EndIf
            Next
        EndIf
    WEnd
    
    Func _ResetInput($_sWhat)
        Switch $_sWhat
            Case 'ctrl'
                GUICtrlSetData($idCtrlText, '')
                GUICtrlSetData($idCtrlX, '')
                GUICtrlSetData($idCtrlY, '')
                GUICtrlSetData($idCtrlW, '-1')
                GUICtrlSetData($idCtrlH, '-1')
            Case 'gui'
                GUICtrlSetData($idGuiTitle, '')
                GUICtrlSetData($idGuiW, '')
                GUICtrlSetData($idGuiH, '')
                GUICtrlSetData($idGuiX, '-1')
                GUICtrlSetData($idGuiY, '-1')
        EndSwitch
    EndFunc
    
    ; Im 2D-Array $_aArg werden Angaben zu den Ctrl, die erstellt werden sollen, übergeben: [n]['Typ', 'Text', x, y, w, h, zugewiesene_Funktion]
    Func _CreateGui($_sTitle, $_w, $_h, $_x, $_y, $_aArg)
        $ga_Gui[0][0] += 1
        $ga_Gui[$ga_Gui[0][0]][0] = GUICreate($_sTitle, $_w, $_h, $_x, $_y)
        $ga_Gui[$ga_Gui[0][0]][1] = $_sTitle
        ; create Ctrl
        For $i = 0 To UBound($_aArg) -1
            $ga_CtrlID[0][0] += 1
            $ga_CtrlID[$ga_CtrlID[0][0]][0] = $ga_Gui[$ga_Gui[0][0]][0] ; Hwnd Gui
            Switch $_aArg[$i][0]
                Case 'Button'
                    $ga_CtrlID[$ga_CtrlID[0][0]][1] = GUICtrlCreateButton($_aArg[$i][1], $_aArg[$i][2], $_aArg[$i][3], $_aArg[$i][4], $_aArg[$i][5])
                Case 'Label'
                    $ga_CtrlID[$ga_CtrlID[0][0]][1] = GUICtrlCreateLabel($_aArg[$i][1], $_aArg[$i][2], $_aArg[$i][3], $_aArg[$i][4], $_aArg[$i][5])
            EndSwitch
            $ga_CtrlID[$ga_CtrlID[0][0]][2] = $_aArg[$i][6]                ; Func
        Next
    EndFunc
    
    Func _GetGui($_sTitle)
        For $i = 1 To $ga_Gui[0][0]
            If $ga_Gui[$i][1] = $_sTitle Then Return $ga_Gui[$i][0]
        Next
    EndFunc
    
    ; hier werden Funktionen erstellt, die ausgewählt werden können
    Func _A()
        ConsoleWrite('Funktion "_A" wurde ausgeführt' & @CRLF)
    EndFunc
    
    Func _B()
        ConsoleWrite('Funktion "_B" wurde ausgeführt' & @CRLF)
    EndFunc
    
    Func _C()
        ConsoleWrite('Funktion "_C" wurde ausgeführt' & @CRLF)
    EndFunc
    
    Func _D()
        ConsoleWrite('Funktion "_D" wurde ausgeführt' & @CRLF)
    EndFunc
    Alles anzeigen

    EDIT

    Zitat von BugFix

    Ein "Baukasten" für den Anwender aus beliebigen Ctrl ist nicht möglich.

    Das hat weiterhin Bestand, auch wenn das hier im ersten Moment nach Baukasten ausschaut. Was nicht enthalten ist - müsstest du noch definieren - was denn bei Klick auf die neu erstellten Button passiert. Dazu musst du bereits im Vorfeld alle möglichen Funktionen erstellen und kannst diese dann ja auch zum Zuordnen in einer Combo bereitstellen. (EDIT: Habe ich im Bsp. noch ergänzt.) Dann hast du fast eine eierlegende Wollmilchsau. :rofl:

  • Hallo in die Runde!

    • BugFix
    • 16. November 2021 um 09:59

    Hallo Holger,

    auch von mir noch ein Willkommensgruß.

    Übrigens bist du vermutlich das erste AutoIt.de-Mitglied mit (vollständigem) Namen und Avatar aus dem realen Leben. ;)

  • Variablen in SQLite schreiben (INSERT)

    • BugFix
    • 16. November 2021 um 09:53
    Zitat von Holger Esseling

    wobei es mir im ersten Schritt sehr lieb ist, die Dinge einmal (für mich) verständlich zu schreiben, bis sie funktionieren.

    Das ist eine vernünftige Einstellung. SQLite verfügt über eine extrem umfangreiche Dokumentation, die in einigen Teilen für den reinen AutoIt-Anwender sicher schwierig zu lesen ist, da diese Umsetzung (sofern in der SQLite.au3 erfolgt) innerhalb der UDF stattfindet.

    Jedoch muss man ja auch nicht das Rad neu erfinden. Man kann auch sehr gut verstehen, wenn man sich die UDF vornimmt und versucht nachzubilden, was dort passiert.

    Wir haben aber auch ein Unterforum Datenbanken - dort findest du sicher auch einige Anregungen.

  • Untermenüs aufrufen

    • BugFix
    • 16. November 2021 um 00:29

    Ja, kann man.

    Es muss aber im Skript definiert sein, welche Möglichkeiten bestehen und was bei welcher Auswahl passiert. Ein "Baukasten" für den Anwender aus beliebigen Ctrl ist nicht möglich. Du müsstest hier also schon mal sehr konkret sagen Was und Wie passieren soll.

    Aber warum versteifst du dich auf diese Lösung? Evtl. X-Y-Problem? Du hast ein Problem und meinst X sei die richtige Lösung und versuchst mit großem Aufwand das umzusetzen und übersiehst, dass Y zu einem besseren Ergebnis führen kann.

    Bis jetzt sehe ich nichts, was gegen die Menüvariante spricht.

  • Abluftanlage mit Bypass - Steuerung mit Nano?

    • BugFix
    • 15. November 2021 um 17:00

    Hallo,

    ich habe ein Problem und brauche mal möglichst viel Expertise.

    Status:

    Ich habe eine Abluftanlage mit Wärmetauscher. Somit wird die abgesaugte Luft mit gleicher Menge Frischluft bei nahezu gleicher Temperatur ersetzt.

    Bisher ist das für die Absaugung des Wohnraums (Bad, Toilette, Küche).

    Ich würde nun gerne auch den Keller mit einbeziehen (zum regelmäßigen Entfeuchten). Dieser hat jedoch ein deutlich unterschiedliches Temperaturniveau.

    Somit würde ich gern über eine separate Steuerung umschalten auf Absaugung Keller oder Wohnraum.

    Das Kanalsystem ist Abluftrohr mit Durchmesser 125mm in Verbindung mit Flachkanal 150x80mm.

    Nun habe ich beim Hersteller angefragt, ob es ein 3-Wege Ventil gibt. - Leider nicht.

    Habt ihr evtl. sowas irgendwo gesehen? Geringfügig unterschiedliche Maße sollten kein Problem sein.

    Ich habe mal eine Zeichnung erstellt, wie das etwa aussehen sollte.

    Abluft-3Wege-Ventil.PNG

    Notfalls bleibt wohl nur DIY - vielleicht hat das ja schon wer gemacht? :love:

    Ich denke da an eine Ventilklappe mit Magnetschaltung oder etwas in der Art.

    Bin für jede Anregung dankbar.

  • Variablen in SQLite schreiben (INSERT)

    • BugFix
    • 15. November 2021 um 11:00

    Hab mal eine Schaufel geholt und einen gaaanz alten Beitrag von mir ausgegraben :rofl:

    Beitrag

    SQLiteMore.au3

    Hi,
    da SQLite seine Stärken dann ausspielen kann, wenn viele Operationen auf einen Schlag abgearbeitet werden sollen, ist es wenig sinnvoll jeden INSERT- oder UPDATE-Vorgang separat zu coden.
    Mit den UDF _SQLite_INSERT() und _SQLite_UPDATE() besteht die Möglichkeit weitestgehend ohne SQL-Syntax zu arbeiten (außer WHERE-Klausel bei UPDATE).
    Die Daten können als String (Einzeloperation) oder als Array übergeben werden.
    Ich denke, das spart eine ganze Menge Schreibarbeit. ;)


    Edit 11.05.2014
    Ich habe mal…
    BugFix
    1. Mai 2008 um 16:55

    Könnte auch hilfreich sein.

  • SciTE - neues Skript für Timestamp / Versionierung

    • BugFix
    • 14. November 2021 um 11:13

    Neue Version v 0.3, s. Startpost.

    Es können Ausnahmen für das Backup hinzugefügt werden (Ordnernamen, Dateinamen oder Dateiname beginnt/endet mit ...).

    Zitat von Bitnugger

    Zudem, denke ich, musst du dein Script Au3OptMustDeclareVars.lua anpassen... denn das verschiebt den TimeStamp evtl. wieder in die erste Zeile, oder in eine andere, falls beim Speichern bereits Text eingegeben wurde.

    Habe mir das nochmal angeschaut.

    Das im Skript zu ändern ist nicht erforderlich. Da beide Skripte im Lua-Startup Skript geladen werden, ist hier die Reihenfolge wichtig:

    1. OptMustDeclareVars

    2. TimeStamp

    Timestamp wird dann auch nach DeclareVars aufgerufen und verschiebt dann die Einträge korrekt.

  • SciTE - CommonTools

    • BugFix
    • 14. November 2021 um 10:50

    Neue Version 0.5, s. Startpost

  • Untermenüs aufrufen

    • BugFix
    • 14. November 2021 um 09:53

    Also ehrlich gesagt, kann ich nur raten, was du willst.

    Hier mal meine Vermutung:

    Du hast sehr viele Menüpunkte, die du zur Auswahl benötigst.

    Dazu verwendet man Untermenüs. Wenn ich deinen Screenshot richtig interpretiere, beginnen viele Menüpunkte mit demselben Buchstaben - danach kannst du gruppieren.

    Hier mal ein simples Bsp.

    AutoIt
    Global $hGui = GUICreate('Test')
    Global $idMnu = GUICtrlCreateMenu('Main Menu')
    Global $idMnuSub1 = GUICtrlCreateMenu('Versicherer', $idMnu)
    Global $idMnuSub1_1 = GUICtrlCreateMenu('§', $idMnuSub1)
    Global $idMnuSub1_1_1 = GUICtrlCreateMenuItem('§ 123', $idMnuSub1_1)
    Global $idMnuSub1_1_2 = GUICtrlCreateMenuItem('§ 135', $idMnuSub1_1)
    Global $idMnuSub1_1_3 = GUICtrlCreateMenuItem('§ 179', $idMnuSub1_1)
    Global $idMnuSub1_2 = GUICtrlCreateMenu('A', $idMnuSub1)
    Global $idMnuSub1_2_1 = GUICtrlCreateMenuItem('Arroganz', $idMnuSub1_2)
    Global $idMnuSub1_2_2 = GUICtrlCreateMenuItem('Aquise AG', $idMnuSub1_2)
    Global $idMnuSub1_2_3 = GUICtrlCreateMenuItem('Azure', $idMnuSub1_2)
    Global $idMnuSub1_3 = GUICtrlCreateMenu('B', $idMnuSub1)
    Global $idMnuSub1_3_1 = GUICtrlCreateMenuItem('Balu', $idMnuSub1_3)
    Global $idMnuSub1_3_2 = GUICtrlCreateMenuItem('Berta', $idMnuSub1_3)
    Global $idMnuSub1_3_3 = GUICtrlCreateMenuItem('Bonzo', $idMnuSub1_3)
    Global $idMnuSub1_4 = GUICtrlCreateMenu('C', $idMnuSub1)
    Global $idMnuSub1_5 = GUICtrlCreateMenu('D', $idMnuSub1)
    Global $idMnuSub1_6 = GUICtrlCreateMenu('E', $idMnuSub1)
    Global $idMnuSub1_7 = GUICtrlCreateMenu('F', $idMnuSub1)
    Global $idMnuSub1_8 = GUICtrlCreateMenu('G', $idMnuSub1)
    
    ; bei der großen Anzahl wäre ein Array für die ID sinnvoll
    
    GUISetState()
    
    Global $iMsg
    While True
        $iMsg = GUIGetMsg()
        Switch $iMsg
            Case -3
                Exit
            Case $idMnuSub1_1_1
                ConsoleWrite('Clicked: ' & "MenuItem('§ 123')" & @CRLF)
            Case $idMnuSub1_1_2
                ConsoleWrite('Clicked: ' & "MenuItem('§ 135')" & @CRLF)
            Case $idMnuSub1_1_3
                ConsoleWrite('Clicked: ' & "MenuItem('§ 179')" & @CRLF)
            ; usw.: Case ...
        EndSwitch
    WEnd
    Alles anzeigen

    EDIT:

    Ich habe mal noch eine Array-Variante erstellt. Der Vorteil liegt hier in einer übersichtlicheren Gestaltung und mit wachsender Anzahl an Menüpunkten wird im Vergleich der Schreibaufwand geringer, da die Erstellung in einer Schleife abläuft. Du kannst auch die Anzahl der Menüs und deren Item jederzeit gut anpassen. Wäre auch außerhalb des Programms machbar, wenn du die Daten aus einer Ini- oder Konfigurationsdatei lädst.

    AutoIt
    Global $hGui = GUICreate('Test')
    
    ; Hauptmenü erstellen
    Global $idMnu = GUICtrlCreateMenu('Main Menu')
    Global $idMnuSub1 = GUICtrlCreateMenu('Versicherer', $idMnu)
    
    ; jetzt die Umtermenüs für $idMnuSub1 erstellen, darauf referenzieren deren Menü-Item
    Global Enum $IDM_Para, $IDM_A, $IDM_B, $IDM_C, $IDM_D, $IDM_E, $IDM_F, $IDM_G, $IDM_counter
    Global $aMnuSub1[$IDM_counter][2] = [[0,'$'],[0,'A'],[0,'B'],[0,'C'],[0,'D'],[0,'E'],[0,'F'],[0,'G']]
    For $i = 0 To $IDM_counter -1
        $aMnuSub1[$i][0] = GUICtrlCreateMenu($aMnuSub1[$i][1], $idMnuSub1)
    Next
    
    ; jetzt die Menü-Item erstellen, als Menu-ID mit Enum-Variablen als Index auf $aMnuSub1 für die jeweiligen Meüpunkte verweisen
    Global $aMnuSub1_Item[][3] = [ _    ; [Item-ID, Menu-ID, 'Text Menu-Item']
    [0, $aMnuSub1[$IDM_Para][0], '$ 123'], _
    [0, $aMnuSub1[$IDM_Para][0], '$ 135'], _
    [0, $aMnuSub1[$IDM_Para][0], '$ 179'], _
    [0, $aMnuSub1[$IDM_A][0], 'Arroganz'], _
    [0, $aMnuSub1[$IDM_A][0], 'Aquise AG'], _
    [0, $aMnuSub1[$IDM_A][0], 'Azure'], _
    [0, $aMnuSub1[$IDM_B][0], 'Balu'], _
    [0, $aMnuSub1[$IDM_B][0], 'Berta'], _
    [0, $aMnuSub1[$IDM_B][0], 'Bonzo'] _
    ]
    For $i = 0 To UBound($aMnuSub1_Item) -1
        $aMnuSub1_Item[$i][0] = GUICtrlCreateMenuItem($aMnuSub1_Item[$i][2], $aMnuSub1_Item[$i][1])
    Next
    
    GUISetState()
    
    Global $iMsg
    While True
        $iMsg = GUIGetMsg()
        ; wurde eines der Item geklickt
        For $i = 0 To UBound($aMnuSub1_Item) -1
            If $iMsg = $aMnuSub1_Item[$i][0] Then ConsoleWrite('Clicked: MenuItem "' & $aMnuSub1_Item[$i][2] & '"' & @CRLF)
        Next
    
        Switch $iMsg
            Case -3
                Exit
        EndSwitch
    WEnd
    Alles anzeigen
  • Alternative zu "Sleep"

    • BugFix
    • 2. November 2021 um 20:07

    Guck mal in die Hilfe unter Makros. ;)

  • Änderungen im Script verfolgen

    • BugFix
    • 1. November 2021 um 14:17
    Zitat von Moombas

    Ich glaube nicht das Scite so etwas aktuell hat, da müsstest du dann selber Tätig werden und alle Zwischenschritte manuell abspeichern und ggf. mit Versionen versehen.

    SciTE bringt das nicht mit, aber ich habs gemacht: SciTE - neues Skript für Timestamp / Versionierung :whistling:

  • Fehler in der deutschen Hilfe bitte hier melden (Hilfedatei 3.3.14.5 2021.07.31)

    • BugFix
    • 23. Oktober 2021 um 22:14
    Zitat

    Was das Schlüsselwort Dim betrifft, so ist seine empfohlene Verwendung darauf beschränkt, ein bestehendes Array zu leeren

    Igittigitt, wer kommt denn auf solch kranke Ideen. Wenn sowas notwendig ist, dann sicher nicht nur einmalig. Dafür erstellt man einmal ein Leerarray (das dann z. B. $g_aEmpty heißt) und weist dieses dann jedes mal zu.

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™