Du kannst doch bei Aufruf des jeweiligen Menüpunktes vor dem Ausführen abfragen, ob der angemeldete User Admin ist.
Beiträge von BugFix
-
-
Diese Funktion habe ich 20 mal per copy paste zu stehen.... das einzige was sich ändert, ist die rot markierte Zahl
Dann verwende die Funktion mit dem sich ändernden Wert als Parameter:
AutoIt
Alles anzeigenFunc Click($_koord) MouseClick("left", 1372, $_koord, 1) sleep(Random(500,1000)) MouseClick("left", 522, 487, 1) sleep(Random(500,1000)) For $a = 1 To $H a() Next MouseClick("left", 522, 487, 1) sleep(Random(500,1000)) Send("{LEFT}") sleep(Random(300,600)) For $a = 1 To $R b() Next EndFunc ; Aufruf Click(123)Gibt es eine Möglichkeit aus dem STRG + C kopierten Wert, neue Variablen "rauszuziehen"?
Schau dir mal ClipGet an.
Und mit den String- Funktionen kannst du dann den Inhalt rausziehen.
-
Bei einer Fehlermeldung soll sie den Text in rot ausgeben, ansonsten in schwarz.
Und warum färbst du dann erst Rot und anschließend sofort wieder Schwarz??
AutoItGUICtrlSetColor( $idEditField, $COLOR_RED ) GUICtrlSetData( $idEditField, $sValue & @CRLF & $sString ) GUICtrlSetColor( $idEditField, $COLOR_BLACK )Der Befehl gilt für den gesamten Inhalt des Controls!
Falls du nur teilweise färben möchtest, musst du ein RichEdit verwenden - aber das ist nicht die leichteste Kost.
-
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):
Starwert=0, Schrittweite=1
nachher:
Bsp. Markierung Array-Deklaration
vorher:
nachher:
AutoItGlobal $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:
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.
Das Skript speichern und einer Tastenkombination zuweisen.
Code: SetArrayIndex.lua [v 0.3]
Alles anzeigen-- 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 -
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.
TabReplace
AutoIt: TabReplace.au3
Alles anzeigen;-- 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_LineLua
Alles anzeigen-- 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 ----------------------------------------------------------------------------------------------------Lua
Alles anzeigen-- 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 hereEDIT 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
Alles anzeigen-- 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 -
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
Alles anzeigen#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 -
Einfach GUISetFont verwenden, damit setzt man die Standardwerte für alle Control auf der GUI.
-
Alles anzeigen
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?
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.
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.
-
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
Alles anzeigen#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 -
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 )
-
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.

-
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
Alles anzeigen;-- 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) EndFuncEDIT
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.
-
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.

-
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.
-
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.
-
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.
Notfalls bleibt wohl nur DIY - vielleicht hat das ja schon wer gemacht?

Ich denke da an eine Ventilklappe mit Magnetschaltung oder etwas in der Art.
Bin für jede Anregung dankbar.
-
Hab mal eine Schaufel geholt und einen gaaanz alten Beitrag von mir ausgegraben
BeitragSQLiteMore.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…
BugFix1. Mai 2008 um 16:55 Könnte auch hilfreich sein.
-
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 BitnuggerZudem, 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.
-
Neue Version 0.5, s. Startpost
-
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
Alles anzeigenGlobal $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 WEndEDIT:
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
Alles anzeigenGlobal $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