Tönt in der Tat interessant.
Doch ich weiss leider nicht, ob man damit auf ein Scripting.Dictionary zugreiffen kann.
Vermutlich eher nicht.
Aber da müssten die Spezialisten eher etwas dazu wissen...
Das ist leider nicht mein Beruf
Tönt in der Tat interessant.
Doch ich weiss leider nicht, ob man damit auf ein Scripting.Dictionary zugreiffen kann.
Vermutlich eher nicht.
Aber da müssten die Spezialisten eher etwas dazu wissen...
Das ist leider nicht mein Beruf
Trotzdem Danke!
Wird wohl in AutoIt so nicht auf Anhieb möglich sein.
Entweder muss nun mein Chef damit leben, oder jemand anderes bei uns muss das dann programmieren.
Wir werden sehen
Hallo AspirinJunkie
Danke für die Antwort.
In dem Fall werde ich vermutlich auf Delphi ausweichen (müssen).
Das müssen dann aber meine Arbeitskollegen übernehmen!
Ich habe mal einen Test gemacht:
Mein Programmteil, welcher sequentiell ausgeführt wird gegen den gleichen Programmteil, aber in Delphi geschrieben.
Das Resultat war, dass mein Script bloss 3% langsamer war, als das in Delphi!
Warum?
Weil es bei meinem Script zu 99% auf die Festplatten / CD / DVD / .... Geschwindigkeit ankommt.
Es muss (im Moment) praktisch nichts damit gemacht oder gerechnet werden.
Deshalb wäre es eine schöne Aufgabe in AutoIt. Aber schön wäre natürlich gewisse parallelisierung!
Danke für Deine Antwort.
Wenn niemand ein einfaches Beispiel oder eine "einfach" zu verwendende UDF hat, dann werde ich das wohl den Spezialisten bei uns übergeben müssen. Die machen dann das in Delphi, C# oder WPF.
Veronesi
Edit
Ach ja: So viel müsste ich ja gar nicht zwischen den Scripten kommunizieren.
Ich müsste einfach zwei Scripte mit Parametern starten.
Die können dann ca. 1h parallel arbeiten und müssen nie irgendwelche Daten austauschen.
Erst nach dieser Stunde müsste jedes Script einmal den Pointer auf das Scripting.Dictionary übergeben!
Hallo
OK, ich habe mich vermutlich nicht so klar ausgedrückt.
Kurzform, was ich möchte:
Ich möchte im Hauptprogramm eine Array ähnliche Struktur erstellen.
Diese Struktur soll dann in einem separaten Programm gefüllt werden.
Danach muss das Hauptprogramm diese Daten in der Struktur auswerten.
Ich denke, dass ich irgendwie mit einem Pointer auf ein Array (oder ähnlich) arbeiten muss.
Und die Struktur muss in einem separatem Programm abgefüllt werden! Also keine Funktion im Hauptprogramm!
Doch geht das überhaupt mit AutoIt?
Es muss kein Array sein, sondern einfach eine Array ähnliche Struktur.....
Das Element sollte Platz bieten für > 100 Millionen Einträge
Mein Programm funktioniert schon jetzt (mit Scripting.Dictionary), einfach wird alles im Hauptprogramm gemacht und deshalb sequentiell. Dies möchte ich optimieren.
Gruss Veronesi
Hallo Zusammen!
Aus diversen Gründen muss ich einige Programmfunktionen in eine separate Datei auslagern, welche ich vom Hauptprogramm aus anspreche.
Dies sind vor allem Zeitgründe.
Damit will ich nicht sagen, dass AutoIt zu langsam ist. Ganz und gar nicht. Es sind viel mehr die angeschlossenen Festplatten / Memory-Sticks etc. die langsam sind.
Nehmen wir an, ich muss für mein Projekt viele Dateien auf zwei verschiedenen Medien (Memory-Sticks oder CDs....) vergleichen.
Dann kann ich das entweder tun, in dem ich zuerst alle benötigten Daten vom Medium A einlese, danach vom Medium B und danach nach meinen Kriterien / Vorgaben vergleiche!
Das braucht aber viel Zeit.
Nun könnte ich aber Zeit sparen, in dem ich Medium A und Medium B parallel mit jeweils einem separaten Programm einlese und die gesammelten Daten dem Hauptprogramm zur Verfügung stelle, welches dann die Daten vergleicht!
Soweit zum Hintergrund.
Aber wie mache ich das?
Die Daten, sollen in ein Scripting.Dictionary eingelesen werden, welche ich mit
[autoit]
$oData1 = ObjCreate('Scripting.Dictionary')
$oData2 = ObjCreate('Scripting.Dictionary')
im Hauptprogramm erstelle.
Nun möchte ich aber nach dem Erstellen dieser Objekte jeweils einen Pointer auf diese Objekte den zwei nun zu startenden Programmen übergeben.
Diese Programme füllen dann diese Dictionaries ab und geben im Anschluss den Pointer wieder zurück.
Dann kann das Hauptprogramm mit dem Daten in den Scripting.Dictionaries weiterarbeiten!
Wie kann ich das bewerkstelligen?
Oder gibt es andere (schnelle!) Strukturen, welche anstelle von Scripting.Dictionary eingesetz werden können, auf welche dann mit einem Pointer gearbeitet werden kann?
(ArrayList, Hashtable, Queue und Stack habe ich schon versucht, aber die sind - in meinem Fall - langsamer als Scripting.Dictionary)
Ich muss ja die Tabellen schlussendlich auch wieder durchsuchen können. Und da ist halt das Scripting.Dictionary optimal!
Vielleicht könnte mir hier dieser Beitrag helfen???? (2. Beispiel) Klick
Gruss
Veronesi
Super!
Geht einwandfrei.
Für meine Zwecke habe ich es etwas umgebaut und vereinfacht.
Nicht so professionell wie Deine Lösung, aber für mich funktioniert es so super!
Ich möchte nämlich entscheiden können, welches Frame extrahiert wird. Und es wird nicht zwingend ein File geschrieben, sondern man kann sich auch das Handle zurückgeben lassen.
Da mein Programm sowieso mit GDI+ arbeitet, kann ich dann dieses Handle gleiche zum anzeigen verwenden. Ist natürlich schneller, als wenn ich es noch auf der Festplatte zwischenspeichere und danach wieder lade.
Aber wie gesagt, Dein Programm lief einwandfrei und so wie ich es in der Beschreibung gewünscht habe!
Danke!
#include <GDIPlus.au3>
_GDIPlus_Startup()
$sFile = @ScriptDir & "\a.gif"
Local $hFrameHandle
Local $iNumer = _CountFramesInGif($sFile)
For $i = 1 To $iNumer
$hFrameHandle = _ExtractFrame($sFile, "", $i)
_GDIPlus_ImageSaveToFile($hFrameHandle, @ScriptDir & "\" & $i & ".gif")
Next
_GDIPlus_Shutdown()
;Zählt die Anzahl der vorhandenen Bilder in einem animierten GIF
;$sGifFile ist die zu übergebende GIF Datei
Func _CountFramesInGif($sGifFile)
Local $hImage = _GDIPlus_ImageLoadFromFile($sGifFile)
Local $tDim = DllStructCreate("byte[" & 16 & "];")
$aResult = DllCall($ghGDIPDll, "uint", "GdipImageGetFrameDimensionsList", "hwnd", $hImage, "ptr", DllStructGetPtr($tDim), "int", 1)
If @error Then Return SetError(1, 0, 0)
Local $iFramesMax = 0
$aResult = DllCall($ghGDIPDll, "uint", "GdipImageGetFrameCount", "hwnd", $hImage, "ptr", DllStructGetPtr($tDim), "uint*", 0)
If @error Then Return SetError(2, 0, 0)
$iFramesMax = $aResult[3]
_GDIPlus_ImageDispose($hImage)
Return $iFramesMax
EndFunc ;==>_CountFramesInGif
;Extrahiert ein Bild aus einer animierten GIF Datei
;$sGifFile ist das animierte GIF
;$sSaveFile ist der Speicherpfad, wo das einzelne Bild gespeichert werden soll.
;Wird hier nichts übergeben (""), dann wird von dieser Funktion das Handle auf das extrahierte Bild zurückgegeben. Dieses kann mit GDI+ dann z.B. angezeigt werden.
;$iFrame = Nummer des Bildes, welches extrahiert werden soll. (Beginnend mit 1)
Func _ExtractFrame($sGifFile, $sSaveFile, $iFrame = 1)
Local $hImage = _GDIPlus_ImageLoadFromFile($sGifFile)
Local $iImgW = _GDIPlus_ImageGetWidth($hImage)
Local $iImgH = _GDIPlus_ImageGetHeight($hImage)
Local $iImgF = _GDIPlus_ImageGetPixelFormat($hImage)
Local $tDim = DllStructCreate("byte[" & 16 & "];")
$aResult = DllCall($ghGDIPDll, "uint", "GdipImageGetFrameDimensionsList", "hwnd", $hImage, "ptr", DllStructGetPtr($tDim), "int", 1)
If @error Then Return SetError(1, 0, 0)
Local $iFramesMax = 0
$aResult = DllCall($ghGDIPDll, "uint", "GdipImageGetFrameCount", "hwnd", $hImage, "ptr", DllStructGetPtr($tDim), "uint*", 0)
If @error Then Return SetError(2, 0, 0)
$iFramesMax = $aResult[3]
If $iFrame > $iFramesMax Then Return SetError(3, 0, 0)
[/autoit] [autoit][/autoit] [autoit]Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iImgW, "int", $iImgH, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0)
If @error Then Return SetError(4, 0, 0)
Local $hBitmap = $aResult[6]
Local $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)
Local $hFrame
DllCall($ghGDIPDll, "uint", "GdipImageSelectActiveFrame", "hwnd", $hImage, "ptr", DllStructGetPtr($tDim), "uint", $iFrame - 1)
$hFrame = _GDIPlus_BitmapCloneArea($hImage, 0, 0, $iImgW, $iImgH, $iImgF)
If $sSaveFile = "" Then
_GDIPlus_GraphicsDispose($hContext)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_ImageDispose($hImage)
Return $hFrame
Else
_GDIPlus_ImageSaveToFile($hFrame, $sSaveFile)
_GDIPlus_BitmapDispose($hFrame)
_GDIPlus_GraphicsDispose($hContext)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_ImageDispose($hImage)
Return True
EndIf
EndFunc ;==>_ExtractFrame
Veronesi
Vielen Dank!
Ich kann das gerade nicht testen (bin unterwegs)
Aber ich werde das heute Abend gerne testen.
Thx!!
Ob diese Funktion bei allen PDFs funktioniert musst Du testen.
Aber die sollte es. Bei meinem PDFs (alles nicht indizierte und nicht markierbare Texte) hat es funktioniert.
Die Funktion liest die Datei ein und durchsucht die nach speziellen Tags. Diese Tags werden in den PDFs dazu verwendet um die nächste Seite zu kennzeichnen. Ich filtere mit RegExp einfach danach und zähle die Fundstellen.
Sollte so mit allen PDFs > Version 3 funktionieren.
Üblich ist sowieso eine PDF Version > 4.
Freut mich, wenn es klappt.
Gruß Veronesi
Hallo akira2012
Mit dieser Funktion kannst Du die Anzahl der Seiten eines PDFs auslesen.
Viel Spass!
$File = @ScriptDir & "\a.pdf"
MsgBox(64, "Anzahl Seiten im PDF", _GetPDFPageCount($File))
Exit
Func _GetPDFPageCount($sFile)
Local $hFile = FileOpen($sFile)
Local $sPDF = FileRead($hFile)
FileClose($hFile)
Local $aRegExp = StringRegExp($sPDF, "/Type\s*/Page[^s]", 3)
If @error Then Return SetError(1, 0, 0)
Return UBound($aRegExp)
EndFunc ;==>_GetPDFPageCount
Gruss, Veronesi
Hi
Wie bereits im Titel erwähnt, suche ich nach einer Möglichkeit, alle Frames (Einzelbilder) aus einem animierten GIF zu extrahieren (als jeweils einzelne Datei abzuspeichern).
In diesem Link habe ich etwas mit GDI+ gefunden, aber als Laie habe ich große Probleme bei der Übersetzung nach AutoIt.
Link
Ich weiss schon nicht, wie ÜBERHAUPT anfangen.
Klar kann man das alles mit Photoshop oder IrfanView oder sonstigen gratis Konvertern machen. Aber ich sollte das direkt in AutoIt können.
Vielen Dank für Eure Hilfe!
Veronesi
BugFix
So ähnlich meinte ich es.
Gut, dann ist das wohl die einzige vernüftige Lösung.
Vielen Dank!!
BugFix
Das wusste ich nicht. Hab's eben noch nicht ausprobiert.
Aber wie kann ich dann gruppieren nach dem gleichen Bild?
Vermutlich muss ich alle verschiedenen Versionen zu einer Zeile zusammenfassen. Wenn dann in diese Zeile geklickt wird, geht ein 2. GUI auf, in welchem man die Version der angeklickten Software auswählen muss.....
Hallo zusammen
Ich habe folgendes Problem:
Ich habe ein Listview. Spalte A mit einem Produktbild, Spalte B mit Produktname / Version / Produktenummer.
Da mehrere Zeilen in diesem Listview das gleiche Produktbild haben (gleicher Name aber unterschiedliche Version) möchte ich das gerne zusammenfassen.
Also ein Bild und rechts daneben mehrere Zeilen Text.
Nun habe ich mir überlegt dass ich evtl. in EINER ZELLE mehrere Zeilen Text einbringen könnte. Doch wie schaffe ich es dann herauszufinden, auf welche ZEILE innerhalb dieser ZELLE der Benutzer geklickt hat?
Ich habe auch schon über die Gruppierfunktion vom Listview nachgedacht. Aber ich kann einem Gruppenheader kein Bild zuordnen.....
Gruss Veronesi
Hier eine mögliche Lösung:Ich erstelle die Links nicht im "Startmenü", sondern in einem separaten Ordner.
Dadurch erscheinen sie nicht als Tile (Kachel) auf der Metro.
Dann noch die Umgebungsvariable %Path% mit meinem eigenen Ordner erweitern!
Muss ich morgen gleich mal testen. Heute muss ich wieder Schulung geben
Leider funktioniert das nur, wenn man den ganzen Dateinamen eingibt. Es funktioniert nicht mit Teilen davon
Das ging etwas länger, das auszuprobieren. Ich habe früher auch schon dran gedacht, aber wegen dem Aufwand immer gescheut!
Also, vor der Änderung ein Regshot und danach. Dann die Registries vergleichen lassen.
Da gibt es diverse Änderungen!
Aber ich habe das Ganze mehrmals gemacht und es scheint, als haben die Änderungen an diesen Schlüsseln nichts mit dem Unpinnen der Metro zu tun. Es sind nämlich immer wieder andere Schlüssel, die ändern!
Also leider auch nichts.
Ebenfalls nichts mit dem Link, sorry.
M$ hat das gut versteckt!
Hallo misterspeed
Die Idee ist wirklich gut.
Ich habe es getestet:
- Metro zeigt keine Links an, die mit dem Attribut Hidden versehen sind!
- Auch dann nicht, wenn in den Einstellungen alle Dateien (auch versteckte) sichtbar gemacht werden!
Soweit also SEHR gut!
Leider findet dann die Metro Suche die Programme auch nicht mehr. Und genau das muss es ja......
Ist schon mal ein Anfang, aber die Suche müsste noch funktionieren!
Veronesi
Hallo misterspeed
In der ersten von Dir zitierten Frage geht es darum, ein Tile (von Notepad) zu erstellen.
Dies geht automatisch und ist leicht. Man muss bloss einen "Startmenüeintrag" (wie in Win7) erstellen. Windows macht daraus automatisch ein Tile.
Gut, klar, das ist keine besonders grossartige Möglichkeit, weil man es nicht genauer konfigurieren kann, aber das reicht mal grundsätzlich.
Ich möchte aber eher ein "Unpin" haben.
Klar, ich kann den "Startmenüeintrag" löschen. Dann verschwindet die Kachel. Aber dann ist auch kein Suche (auf der Metro!) für dieses Programm mehr möglich.
Es scheint wirklich keine API dazu zu geben!
Aber für mich ginge auch der umgekehrte Weg. Ich erstelle gar keinen Startmenüeintrag (ergo keine Kachel), füge aber IRGENDWIE dieses Programm zu den All Apps hinzu, so dass es in der Metro Suche gefunden wird!
Vielleicht ist ja das möglich?
Ich schreibe mal im MSDN Forum, aber vielleicht findet ja sonst jemand hier etwas heraus?
Lg, Veronesi