Wenn Standard-Ctrl nicht das bieten, was du dir vorstellst, bleibt nur die Alternative des selber Basteln.
Das ist nicht ganz ohne, aber auf jeden Fall auch eine interessante Herausforderung. Wie man eigene Controls baut, kannst du z.B. hier ansehen.
Beiträge von BugFix
-
-
Das Skript funktioniert so, wie es ist.
Das Problem liegt wohl in Windows und/oder MS-Office begraben. (Zugriffsrechte)
Lösche mal das Makro aus der Arbeitsmappe und speicher diese ab.
Dann Mappe öffnen, Makro mit Rekorder aufzeichnen unter demselben Namen ("Align_Z") und abspeichern.
Arbeitsmappe schließen und dann das AutoItskript starten - nun funzt alles wie gewollt.
-
Ein Listview Control hat nur eine Höhe für alle Zeilen. Das ist ererbt von der Win32 Control-Klasse.
Eine Manipulation durch den User ist nicht vorgesehen. Es gibt einfach keinen Parameter für die Zeilenhöhe. Darum kann man hier auch nicht mit $NM_CUSTOMDRAW schrauben.
Der Trick mit dem Icon ist zwar nicht besonders schön, aber wenn du schon (warum auch immer) die Zeilenhöhe ändern möchtest, dann mach es halt so.
Listviews sind als Einzeilen-Control konzipiert. Wenn du diese Struktur vergewaltigen möchtest, beschwer dich nicht, wenns schief geht. Ein Frosch kann schließlich auch nicht fliegen, selbst wenn du ihm diese Eigenschaft in den Binärcode schreiben würdest.
-
Warum passiert da nichts?
Keine Ahnung warum bei dir nichts passiert. Statusbarerkennung funktioniert und Aufruf von Programmen auch (Notepad kann ich nicht testen, das deinstallier ich immer
) -
Wobei die Abweichung nicht linear in der Reihenfolge der Timer ist, was ich etwas merkwürdig finde. Vielleicht hat dazu mal jemand eine Erklärung parat?
Da muss ich auch raten. Meine Vermutung ist, dass Timer sich überlagern. Scheinbar werden sie dann nicht, wie ich eigentlich annahm, in einen Queue geschoben, sondern verfallen und werden erst beim nächsten Aufruf bearbeitet. Möglicherweise eine Art Lease-Time innerhalb der ein Adlibaufruf nach Ablauf des Intervalls bearbeitet werden muss.
Aber das ist alles nur Fischen im Trüben.
-
Aber wir bewegen uns dan im Millisekundenbereich
Grundsätzlich ja. Wenn du in der Schleife aber noch andere Dinge betreibst kann das relevant werden. Soll der Counter nur im Sekundentakt generieren kommt es selbst auf 2..3 Zehntel nicht an. Verwendest du ihn aber z.b. für eine Stoppuhr sind Timer das einzig Brauchbare.
Aber auch bei 10 Countern, die parallel laufen, kannst du schnell pro Abarbeiten jedes Counters 1 Zehntel verbraten. Dann hast du schnell mal einen Sekundensprung drin, was einfach doof aussieht.
-
PS: Zum Powerpoint es gibt keinen MacroRecorder weil da nur Viewer vorhanden ist.

Irgendwie kommt mir das wie beim Arzt vor:
"Herr Doktor, stimmts ich habe Lungen-Krebs." - "Nein, Sie haben eine Bronchitis." - "Ach, Sie können es mir ruhig sagen, ich verkrafte das." - "Aber Sie haben keinen Krebs, sondern wirklich nur eine Bronchitis." - "Also Hr. Doktor, nur weil ich ein alter Mann bin, müssen Sie mich nicht anlügen..."Nur weil du dir in den Kopf gesetzt hast, es ginge nicht mit VBA, muss das nicht die Wahrheit sein (und ist es auch nicht). Was glaubst du denn, womit der Viewer arbeitet...
Aber wir wollen Dir keine Hilfe aufzwingen, kannst ruhig am "Krebs" dahinsiechen.
-
Ja.
Kontinuierlich Abfragen ob Maus über der Statusbar. Wenn ja: Cursor setzen auf Hand-Symbol, wenn nein zurücksetzen auf Standard.
Auswertung Mausklick: Wenn Leftklick und Cursor über Statusbar dann Aktion ausführen.Edit: Nur Öffnen, wenn du keine Idee hast, wie man das umsetzt.
Spoiler anzeigen
[autoit]$gui = GUICreate('Test')
[/autoit] [autoit][/autoit] [autoit]
$info_own = "meine Homepage"$StatusBar = _GUICtrlStatusBar_Create($gui)
[/autoit] [autoit][/autoit] [autoit]
Dim $StatusBar_PartsWidth[1] = [-1]
_GUICtrlStatusBar_SetParts($StatusBar, $StatusBar_PartsWidth)
_GUICtrlStatusBar_SetText($StatusBar, @TAB & $info_own, 0)
_GUICtrlStatusBar_SetMinHeight($StatusBar, 25)GUISetState()
[/autoit] [autoit][/autoit] [autoit]While 1
[/autoit] [autoit][/autoit] [autoit]
$nMsg = GUIGetMsg()
$MouseOver = _MouseOverBar()
_SwitchCursor($MouseOver)
Switch $nMsg
Case -3
Exit
Case $GUI_EVENT_PRIMARYDOWN
If $MouseOver Then ConsoleWrite('Klick auf Statusbar' & @LF) ; ShellExecute('http://www.Deine-Homepage.de')
EndSwitch
WEndFunc _MouseOverBar()
[/autoit] [autoit][/autoit] [autoit]
local $old = Opt('MouseCoordMode', 0)
Local $aM = MouseGetPos()
Opt('MouseCoordMode', $old)
Local Static $yBar = 0, $hBar = 0, $wGui = 0
If $hBar = 0 Then
Local $aGui = WinGetPos($gui)
local $tRect = _WinAPI_GetClientRect($StatusBar)
$hBar = _GUICtrlStatusBar_GetHeight($StatusBar)
$yBar = $aGui[3] - DllStructGetData($tRect, "Bottom")
$wGui = $aGui[2]
EndIf
If $aM[1] >= $yBar And $aM[1] <= $yBar + $hBar And _
$aM[0] >=0 And $aM[0] <= $wGui Then
Return True
Else
Return False
EndIf
EndFuncFunc _SwitchCursor($_over)
[/autoit]
Local Static $cursHand = False
If $_over And (Not $cursHand) Then
GUISetCursor(0, 1)
$cursHand = True
ElseIf (Not $_over) And $cursHand Then
GUISetCursor(2)
$cursHand = False
EndIf
EndFunc -
Was um Himmels Willen soll denn diese kranke Mausklickerei?! Sowas darf nur die wirklich allerletzte Lösung sein, wenn nichts mehr geht.
Powerpoint ist ein Office-Programm und somit sollte der Lösungsansatz über Zugriff auf das Objekt erfolgen. MakroRekorder in VBA einschalten, klicken, was zu klicken ist. Dann das Makro von VBA nach AutoIt portieren. Das ist ein sinnvoller Lösungsansatz. -
Im Prenzip ist das alles ganzeinfach. Man braucht nur ein MessageLoopModus und eine While Schleife, einpaar Variablen und einige If Abfragen
Nun, das ist eine seeehr optimistische Aussage.
Kannst du vergessen, wenn du mit mehreren Countdown arbeiten willst, viel zu ungenau.
Alles was mit Zeitintervallen zu tun hat, sollte man über Timer regeln. Damit bekommt man sauber mehrere Countdowns zum Laufen, die sich auch nicht in die Quere kommen.
AdlibRegister ist schon parallel, aber wenn du mehrere Adlibs hast, können sich die Intervalle überschneiden und dann werden sie auch in der Reihenfolge ihres "Anklopfens" abgearbeitet. -
Ich weiß nicht ob es da schon irgendwelche Musterlösungen gibt (hast du gründlich gesucht? DE-Forum, EN-Forum, Google).
Rein vom Ablauf würde ich eine Client-Server Struktur verwenden innerhalb der du die Datenpakete auf dein Limit festlegen kannst (Paketgröße, Anzahl Pakete in Zeiteinheit).
Du löst also vom Client deine Aktion aus und der Server hat die Verbindung zum Netz. Wenn deine Daten dort vollzählig angekommen sind startet die entsprechende Aktion. das Ergebnis wird dann ebenfalls in der definierten Paketgröße zurückgeliefert.
Ob das exakt so umzusetzen ist, kann ich dir nicht sagen. TCP/IP-Kram ist nicht so mein Ding. Aber als Anstoß zum Suchen sollte es ausreichen. -
Na da bin ich ja platt.
Die Funktion (übrigens vom Chef Jos persönlich) ist buggy! In der zweiten Dimension werden immer nur 3 Werte geschrieben. Fehler habe ich gefunden und bereits im BugTracker veröffentlicht.Hier ein funktionierende und auch deutlich schnellere Version der Funktion:
Spoiler anzeigen
[autoit]Func _FileWriteFromArray($File, $a_Array, $i_Base = 0, $i_UBound = 0, $s_Delim = "|")
[/autoit] [autoit][/autoit] [autoit]
; Check if we have a valid array as input
If Not IsArray($a_Array) Then Return SetError(2, 0, 0)
Local $iDims = UBound($a_Array, 0)
If $iDims > 2 Then Return SetError(4, 0, 0); determine last entry
[/autoit] [autoit][/autoit] [autoit]
Local $last = UBound($a_Array) - 1
If $i_UBound < 1 Or $i_UBound > $last Then $i_UBound = $last
If $i_Base < 0 Or $i_Base > $last Then $i_Base = 0; Open output file for overwrite by default, or use input file handle if passed
[/autoit] [autoit][/autoit] [autoit]
Local $hFile
If IsString($File) Then
$hFile = FileOpen($File, $FO_OVERWRITE)
Else
$hFile = $File
EndIf
If $hFile = -1 Then Return SetError(1, 0, 0); Write array data to file
[/autoit] [autoit][/autoit] [autoit]
Local $s_Temp = '', $ErrorSav = 0
Switch $iDims
Case 1
For $x = $i_Base To $i_UBound
$s_Temp &= $a_Array[$x] & @CRLF
Next
If FileWrite($hFile, $s_Temp) = 0 Then $ErrorSav = 3
Case 2
For $x = $i_Base To $i_UBound
$s_Temp &= $a_Array[$x][0]
;~ For $y = 1 To $iDims ; == FAILURE -- we need "Ubound($a_Array, 2) -1" !!
For $y = 1 To Ubound($a_Array, 2) -1
$s_Temp &= $s_Delim & $a_Array[$x][$y]
Next
$s_Temp &= @CRLF
Next
If FileWrite($hFile, $s_Temp) = 0 Then $ErrorSav = 3
EndSwitch; Close file only if specified by a string path
[/autoit] [autoit][/autoit] [autoit]
If IsString($File) Then FileClose($hFile); Return results
[/autoit]
If $ErrorSav Then Return SetError($ErrorSav, 0, 0)
Return 1
EndFunc ;==>_FileWriteFromArray -
Sorry, hatte mich verguckt. Default ist ja "0" - ich hatte "1" in Erinnerung. Könnte tatsächlich ein Bug sein, mal die Funktion durchleuchten.
-
Habe mal die Text Datei überprüft. Und es fehlt die 3 und 4 Spalte ??? Ist das bei euch auch so?
Einfach mal die Hilfe zu _FileWriteFromArray lesen. Da war doch was mit StartIndex..
-
Kann es sein, dass deine AutoIt-Version eeetwaaaas veraltet ist?
Aus deinem Code läßt sich kein Fehler ableiten (auch wenn das Durchlaufen des Arrays mit Spalte als führendem Index mich anfangs verwirrt hat.
In älteren Versionen (allerdings wirklich schon lang her) war dieser Befehl nicht auf 2D-Arrays anwendbar.
-
Hier nun ein kleiner Exkurs zu Lua Objekten.
Der Begriff "Objekt" ist in Lua eigentlich fehl am Platze, da es keinen Speichertyp Objekt gibt. In Lua spielt sich alles in Tables (Arrays) ab. Sämtliche Funktionen sind in Tables hinterlegt und Objekte sind nur Tables mit Zusatzfunktion.
Hier mal ein ganz einfaches Objekt ( eine Eigenschaft, eine Methode )
PHP
Alles anzeigenlocal object1 = { eigenschaft = nil, -- bei Erstellung hat Eigenschaft keinen Wert methode = function(self, param1) if self.eigenschaft ~= nil then -- Eigenschaft hat einen Wert return param1 * self.eigenschaft -- Rückgabe Produkt Wert-Eigenschaft * Wert-Parameter else -- erster Aufruf Methode, Eigenschaft noch ohne Wert self.eigenschaft = param1 -- Wert-Parameter an Eigenschaft zuweisen und return param1 -- diesen Wert zurückgeben end end }
Die Methode enthält als ersten Parameter das Schlüsselwort "self". Dies ist gewissermassen die Referenz auf den umschließenden Table-Konstruktor "{}", der der lokalen Variablen "object" zugewiesen wurde.
Somit ist innerhalb des Objektes (table object) ein Zugriff auf andere Mitglieder des Objektes (Eigenschaften und Methoden) möglich. Dazu wird das Schlüsselwort "self" genutzt.
Zugriff auf Eigenschaft, lesend: "wert = self.property", schreibend: "self.property = wert". Zugriff auf Methode: "retVal = self:Methode(param)" oder "retVal = self.Methode(self, param)".
Auf das erstellte Objekt läßt sich dann analog zugreifen. Nur wird statt "self" die Objektvariable verwendet. Diese kann ich aber vor Anwendung auch an eine andere Variable übergeben:PHPlocal o = object Zugriff auf Eigenschaft, lesend: wert = o.property schreibend: o.property = wert Zugriff auf Methode: retVal = o:Methode(param) oder retVal = o.Methode(o, param)
Bitte beim Methodenaufruf die beiden möglichen Syntaxformen beachten. Entweder "Objekt-Doppelpunkt-Methode(Parameter)" oder "Objekt-Punkt-Methode(Objekt, Parameter)".
Wir können die Methoden unseres Objektes auch bequem in einem anderen Objekt anwenden. Dazu weisen wir dem anderen Objekt diese Methode einfach mit Bezug auf das Quellobjekt zu:PHP
Alles anzeigenlocal object2 = { eigenschaft = nil, methode = object1.methode } local ret = object1:methode(12) print('Ergebnis', ret) ---> 12 ret = object1:methode(12) print('Ergebnis', ret) ---> 144 ret = object2:methode(12) print('Ergebnis', ret) ---> 12 ret = object2:methode(12) print('Ergebnis', ret) ---> 144Und hier ein kleines Anwendungsbeispiel.
Wir erstellen ein simples Taschenrechner-Objekt, das folgendes können soll:
- 4 Grundrechenarten (Übergabe von 2 Werten)
- Speichern eines bestimmten Wertes, Speicherabruf, Speicher löschen
- autom. Speichern letztes und aktuelles Ergebnis
- abrufbare Historie (gesamt od. bestimmter Schritt) der durchgeführten Rechnungen, Historie löschenSpoiler anzeigen
PHP
Alles anzeigenlocal objCalculator = { -- Properties lastResult = nil, currResult = nil, memVal = nil, history = {}, -- Methoden -- Historie Verwaltung addHistory = function(self, op, a, b, res) table.insert(self.history, {op, a, b, res}) end, -- ohne Positionsabgabe wird die letzte Operation zurückgegeben in einem table {'operation', param1, param2, Ergebnis} und zweiter Rückgabewert ist die Positionsnummer getHistory = function(self, pos) local max = #self.history if max == 0 then return nil, 0 end if pos == nil or pos > max then pos = max elseif pos < 1 then pos = 1 end return self.history[pos], pos end, clearHistory = function(self) self.history = {} end, -- Speicherverwaltung setMem = function(self, v) self.memVal = v end, getMem = function(self) return self.memVal end, clearMem = function(self) self.memVal = nil end, switchResults = function(self, result) self.lastResult = self.currResult self.currResult = result end, -- Rechnen add = function(self, a, b) local res = a+b self:switchResults(res) self:addHistory('add', a, b, res) return res end, sub = function(self, a, b) local res = a-b self:switchResults(res) self:addHistory('sub', a, b, res) return res end, mul = function(self, a, b) local res = a*b self:switchResults(res) self:addHistory('mul', a, b, res) return res end, div = function(self, a, b) local res if b == nil then res = nil else res = a/b end self:switchResults(res) self:addHistory('div', a, b, res) return res end, } local Rechner = objCalculator local Ergebnis Ergebnis = Rechner:add(2,4) print('2+4',Ergebnis) Ergebnis = Rechner:sub(12,3) print('12-3',Ergebnis) Ergebnis = Rechner:mul(7,8) print('7*8',Ergebnis) Ergebnis = Rechner:div(72,9) print('72/9',Ergebnis) Rechner:setMem(Rechner.currResult) print('getMem',Rechner:getMem()) Rechner:clearMem() print('Speicher gelöscht',Rechner:getMem()) -- Auslesefunktion für die komplette Historie local History = function() local sHistorie, tCalc, iPos = '' while iPos ~= 0 do tCalc, iPos = Rechner:getHistory(iPos) if not tCalc then break else sHistorie = '['..iPos..'] '..table.concat(tCalc, '\t')..'\n'..sHistorie iPos = iPos -1 end end if sHistorie ~= '' then print(sHistorie) else print('keine Historie Daten') end end print('Historie gesamt') History() print('Historie 3.te Rechenoperation') local t = Rechner:getHistory(3) print(unpack(t)) Rechner:clearHistory() print('Historie gelöscht') History()
Das funktioniert alles, wie gewünscht.
Der nächste Schritt ist nun, eine Klasse zu erstellen.
Wozu Klassen?
Wenn ich mehrere Objekte erstellen möchte, mit demselben Verhalten (Accounts, User in einem Spiel etc.) definiere ich einmalig ein Objekt dieser Klasse. Und immer wenn ich ein neues identisches Objekt benötige, wird eine neue Instanz des Klassenobjektes erstellt.
Klassen im strengen Sinne gibt es in Lua nicht. Lua verwendet stattdessen das Prototyp-Konzept um Klassen zu emulieren. Dazu erstellen wir ein Objekt, das ausschließlich als Prototyp für seine Instanzen existiert.
In Lua wird das, wie folgt, umgesetzt:
In diesem Fall ist "b" das Klassenobjekt. Mit diesem Aufruf durchsucht "a" das Objekt "b" nach Eigenschaften und Methoden, die es selbst nicht hat. Die MetaMethode "__index" sorgt für die Vererbung.
Das wenden wir jetzt auf das erste Bsp. an und fügen dem Objekt die Methode "create" hinzu:PHP
Alles anzeigenlocal objPrototyp = { eigenschaft = nil, methode = function(self, param1) if self.eigenschaft ~= nil then return param1 * self.eigenschaft else self.eigenschaft = param1 return param1 end end, create = function(self, obj) obj = obj or {} setmetatable(obj, self) self.__index = self return obj end } local newObj = objPrototyp:create() local ret = newObj:methode(12) print('Ergebnis', ret) ---> 12 ret = newObj:methode(12) print('Ergebnis', ret) ---> 144
Nun wollen wir ein anderes Objekt erstellen und diesem Objekt die Eigenschaften und Methoden des Prototyps hinzufügen:PHP
Alles anzeigenlocal objX = { name = 'Test', getName = function(self) return self.name end } print( objX:getName() ) ---> "Test" objX = objPrototyp:create(objX) ret = objX:methode(12) print('Ergebnis', ret) ---> 12 ret = objX:methode(12) print('Ergebnis', ret) ---> 144
Jetzt testen, ob die alten Eigenschaften und Methoden noch zur Verfügung stehen
Und das funktioniert.
Ich kann also auf diese Weise nicht nur neue Objekte erstellen, sondern auch Objekte "mixen". Das ermöglicht gutes modulares Arbeiten.Lua kennt in Objekten keine Unterscheidung zwischen privat und public. Das liegt in der Tabellenstruktur begründet.
Aber das ist kein Hindernis. Hier mal ein einfaches Bsp. eine Methode nur unter Bedingungen ausführen zu lassen:PHP
Alles anzeigenlocal oMuster = { security = 0, -- erlaubt nicht das Ausführen der Methode "methA" val1 = nil, val2 = nil, methA = function(self, a, b) if self.security == 1 then self.val1 = a self.val2 = b return a*b else return nil end end, create = function(self, obj) obj = obj or {} setmetatable(obj, self) self.__index = self return obj end } local o1 = oMuster:create{security = 1} -- neues Objekt erstellen und gleichzeitig Eigenschaft "security" setzen local o2 = oMuster:create() -- neues Objekt erstellen mit Standardwert für Eigenschaft "security" print(o1:methA(2,6)) ---> 12 print(o2:methA(2,6)) ---> nil -
Synchronisieren ist ein heißes Eisen. Die meisten DBs die ich kenne (z.B. eMail-Accounts) synchronisieren nur in eine Richtung. Das ist natürlich völlig sinnfrei, wenn Daten auch offline verändert werden.
Hier musst du selbst festlegen, wass möglich sein darf.
- Daten sollen on UND off bearbeitet werden können
Das ist eigentlich das Worst-Szenario. Derselbe Datensatz wurde On- und Offline verändert. Wie willst du nun synchronisieren?
Wenn Daten hinzukommen ist das unproblematisch, einfach beides zusammenschmeissen. Aber wenn z.B. ein Wert (z.B. typischer Durchmesser) online auf 12 und offline auf 10 gesetzt wird, muß eine Richtlinie greifen: Wer hat Vorrang.
Wenn nur du offline ändern kannst und sagst: Ich bin Chef, ich hab recht, ist die Synchronisationsrichtung klar. Off überschreibt On.
Das ist eigentlich das Wesentliche hierbei: Klarheit darüber welche Angaben "richtiger"
sind. -
Ich mach recht wenig mit Grafik, aber zu Glücksrad würden mir als erstes
_GDIPlus_GraphicsDrawPie und
_GDIPlus_MatrixRotate
einfallen. Lies dich da mal ein und probiere die Bsp. -
Hi,
ich habe meinen Startpost mal etwas aktualisiert und werde demnächst hier etwas mehr Inhalte einbringen. -