Oops,
kleiner Syntaxfehler beim Aufruf.
Statt
command.44.*=dofile "C:\\PFAD\\ZUR\\ShowFuncDescript.lua"
richtig:
command.44.*=dofile C:\PFAD\ZUR\ShowFuncDescript.lua
Oops,
kleiner Syntaxfehler beim Aufruf.
Statt
command.44.*=dofile "C:\\PFAD\\ZUR\\ShowFuncDescript.lua"
richtig:
command.44.*=dofile C:\PFAD\ZUR\ShowFuncDescript.lua
Mal wieder ein kleines Tool:
Für alle Funktionen, die per #Include eingebunden sind, lässt sich hiermit aus der Include-Datei die Funktionsbeschreibung auslesen. Erkannt werden auch Includes mit relativen Pfadangaben zum Skriptverzeichnis. Recht nützlich für eigene UDF, bei denen man mal schnell die kpl. Parameterbeschreibung braucht. Aber auch bei den AutoIt eigenen UDF ist es manchmal recht hilfreich die originale Funktionsbeschreibung zu lesen, bzw. sie in der Konsole lesen zu können, während man die Parameter für die Funktion setzen will. Erspart das switchen in das Hilfefenster.
Wie gehts?
Die Datei "ShowFuncDescript.lua" in euren Lua-Skriptordner packen.
Eintrag in SciTEUser.properties
#44 Show Func Description
command.name.44.*=Show Func Description
command.44.*=dofile "C:\PFAD\ZUR\ShowFuncDescript.lua"
command.mode.44.*=subsystem:lua
command.shortcut.44.*=Ctrl+Alt+F
Statt der 44 könnt ihr auch eine andere freie Nummer verwenden.
Den HotKey könnt ihr natürlich auch anpassen.
In einem AU3-Skript den Cursor in den Funktionsnamen eines UDF-Aufrufes setzen und den HotKey ausführen. Ist eine Funktionsbeschreibung vorhanden (Kommentarzeilen direkt vor der Funktionsdeklaration), wird diese in die Konsole ausgegeben.
Viel Spaß damit.
EDIT 2018-01-20
- gefixed: Problem bei Datei ohne BOM
- added: Zuerst wird die Beschreibung im aktuell geöffneten Skript gesucht, erst dann in Includes.
v0.2
EDIT 2018-01-24
- added: Die Funktionsbeschreibung kann auch als Calltip angezeigt werden. Dazu einen Eintrag in SciTEUser.properties
# function description as calltip 0/1 No/Yes (default "0" = console output)
show.description.calltip=1
v0.3
Ich selbst benutze Tidy nicht, formatiere immer schon beim Schreiben.
Wenn aber da echt Bedarf besteht, ein individuell anpassbares Tidy zu erstellen, würde ich das mal in meine Agenda packen. Ich würde dann aber das ganze als SciTE-Plugin in Lua schreiben. Die gewünschten Optionen müsstet ihr dann mal zusammen stellen.
Mit Lua (der SciTE - internen Programmiersprache) lässt sich in einem (im Editor geöffneten) Skript, der durch den Lexxer festgestellte Typ abfragen. In der Lua - Sektion findet ihr Beispiel Code dafür (z. B. die Funktion SkipToComment in den OHK.Functions.
Ich hatte dort auch eine Funktion gepostet, die Kommentare bereits beim Schreiben an vordefinierter Spaltenposition erstellt.
Ich bin mir nicht im Klaren, was ich von deinen bisherigen Postings halten soll.
Zum einen erweckst du den Eindruck, Programmierkenntnisse zu haben und zum anderen ist dein Augenmerk fast ausschliesslich darauf gerichtet, Dinge zu kritisieren, die (deiner Meinung nach) Programmieranfängern zu viele Schwierigkeiten bereiten könnten. Warum du so denkst, ist mir schleierhaft.
Eine Programmiersprache zu erlernen setzt in jedem Fall Eigeninitiative voraus. Wenn man da mit der Doku nicht weiterkommt, kann man wunderbar im Forum nachfragen, Unterstützung ist garantiert!
Was aber auch klar ist: Das Forum ist kein Wolkenkuckucksheim. Wir sind keine Dschinns, die Gedanken und Wünsche erraten und erfüllen. Wir leisten Hilfe zur Selbsthilfe!
Ich finde, wir sollten Leute da abholen, wo sie stehen,
Nein, absolut nein! - Wir zeigen den Leuten gerne, wo es lang geht. Aber wir werden sie ganz sicher nicht abholen und somit jeden möglichen Lerneffekt im Vorhinein unterbinden.
Wer nicht bereit ist, sich Problemen zu stellen und nach Lösungen in Eigeninitiative zu suchen ist keiner Hilfe wert.
That's my two cents.
Edit:
Wenn du übrigens schon mit Notepad++ als AutoIt-Editor arbeitest - warum hast du dann nicht die Notepad-Konsole aktiviert? Es gibt genügend Installationsanweisungen, wie man N++ als Editor für AutoIt nutzen kann. Es ist zwar nicht sehr sinnvoll, weil z.B. die Autovervollständigung in N++ limitiert ist, aber die üblichen Dinge (Script-Test, Script-Run, Script-Kompilieren, Konsolenausgabe) lassen sich in N++ einbinden. Übrigens auch hier im Forum beschrieben - mal nach suchen.
Ich hatte mal ein Tool zum Umbenennen von Video-/Bilddateien geschrieben (RenameImages). Vielleicht hilft es dir.
Du musst zuerst alle Quellpfade in ein 1D Array packen, welches du an die Copy-Funktion übergibst:
Global $sINI = "PFAD_DEINER_INI"
; Sektion in Array lesen
Global $aSection = IniReadSection($sINI, 'Quellen')
; Werte (Pfade) in 1D-Array eintragen
Global $aPathList[$aSection[0][0]]
For $i = 1 To $aSection[0][0]
$aPathList[$i-1] = $aSection[$i][1]
Next
; dann "$aPathList" an Kopierfunktion übergeben
Alles anzeigen
EDIT:
Oder aber man erstellt sich eine allgemeingültige Funktion, um Sektionswerte in ein Array zu packen (wahlweise mit/ohne Zähler Elemente) und verwendet diese:
Global $sINI = "PFAD_DEINER_INI"
Global $sSEC = "Quellen"
Global $aRet = _IniRead_SectionValues($sINI, $sSEC, False) ; ohne Zähler an [0]
;~ Global $aRet = _IniRead_SectionValues($sINI, $sSEC) ; mit Zähler an [0]
_ArrayDisplay($aRet)
Func _IniRead_SectionValues($_sINI, $_sSection, $_bCounter=True)
Local $aSection = IniReadSection($_sINI, $_sSection)
Local $iErr = @error
If $iErr Then Return SetError($iErr,0,0)
Local $iCount = $_bCounter ? 1 : 0
Local $aValues[$aSection[0][0]+$iCount]
If $_bCounter Then $aValues[0] = $aSection[0][0]
For $i = 1 To $aSection[0][0]
$aValues[$i-1+$iCount] = $aSection[$i][1]
Next
Return $aValues
EndFunc
Alles anzeigen
Eine Übersicht über die Klassen und Interfaces der PortableDeviceAPI.dll findest du unter Windows 7 DLL File Information - PortableDeviceApi.dll.
Die CLSID der Objekte findest in der Registry im Zweig HKEY_CLASSES_ROOT, Suchbegriff 'PortableDeviceAPI.dll'.
Dazu findest du dann diese Einträge:
HKEY_CLASSES_ROOT\ CLSID\{0af10cec-2ecd-4b92-9581-34f6ae0637f3} PortableDeviceManager Class
HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{0af10cec-2ecd-4b92-9581-34f6ae0637f3} PortableDeviceManager Class
HKEY_CLASSES_ROOT\ CLSID\{1649b154-c794-497a-9b03-f3f0121302f3} PortableDeviceServiceFTM Class
HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{1649b154-c794-497a-9b03-f3f0121302f3} PortableDeviceServiceFTM Class
HKEY_CLASSES_ROOT\ CLSID\{43232233-8338-4658-ae01-0b4ae830b6b0} PortableDeviceDispatchFactory Class
HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{43232233-8338-4658-ae01-0b4ae830b6b0} PortableDeviceDispatchFactory Class
HKEY_CLASSES_ROOT\ CLSID\{728a21c5-3d9e-48d7-9810-864848f0f404} PortableDevice Class
HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{728a21c5-3d9e-48d7-9810-864848f0f404} PortableDevice Class
HKEY_CLASSES_ROOT\ CLSID\{A8792A31-F385-493C-A893-40F64EB45F6E} PSFactoryBuffer
HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{A8792A31-F385-493C-A893-40F64EB45F6E} PSFactoryBuffer
HKEY_CLASSES_ROOT\ CLSID\{ef5db4c2-9312-422c-9152-411cd9c4dd84} PortableDeviceService Class
HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{ef5db4c2-9312-422c-9152-411cd9c4dd84} PortableDeviceService Class
HKEY_CLASSES_ROOT\ CLSID\{f7c0039a-4762-488a-b4b3-760ef9a1ba9b} PortableDeviceFTM Class
HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{f7c0039a-4762-488a-b4b3-760ef9a1ba9b} PortableDeviceFTM Class
ebenfalls unter:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{...}
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\CLSID\{...}
Alles anzeigen
Dann googeln nach der ersten Klasse (PortableDeviceManager). Erster Fund ist gleich IPortableDeviceManager interface (Windows) - MSDN - Microsoft .
Dort findest du die Methoden und verlinkt deren Parameter.
Ebenfalls verlinkt sind die 'Client Interfaces'.
Nun müssen wir noch die IID der Interfaces finden. Unter MSDN ist auf Anhieb nichts zu finden. Also ist die zweite Anlaufstelle WinSDK. Googeln mit "winsdk PortableDeviceManager" bringt dir u.a.: winsdk-10/PortableDeviceApi.h at master · tpn/winsdk-10 · GitHub.
In der 'PortableDeviceApi.h' findest du alle erforderlichen Informationen.
Oder auch die reine Interfacebeschreibung in der PortableDeviceApi.idl.
Die Interfacebeschreibung erfolgt in AutoIt so:
$sTagInterface = "MethodName1 RetType(ParamType1;ParamType2;...); MethodName2 RetType(..."
Was mir im Moment nicht ganz klar ist, warum im Bsp. z.B. GetDeviceFriendlyName hresult(wstr;wstr;dword*) verwendet wird.
Laut MSDN:
HRESULT GetDeviceFriendlyName(
[in] LPCWSTR pszPnPDeviceID, Pointer to a null-terminated string that contains the device's Plug and Play ID.
[in, out] WCHAR *pDeviceFriendlyName, A caller-allocated buffer that is used to hold the user-friendly name for the device.
[in, out] DWORD *pcchDeviceFriendlyName On output, the number of characters that is returned by pDeviceFriendlyName
);
Ich hätte also eher verwendet: $sTagInterface = "GetDeviceFriendlyName HRESULT(wstr;wstr*;dword*)", was jedoch zum Absturz des Skriptes führt.
Aber vielleicht hat ja da jemand eine Erklärung für.
EDIT: Kaum hat man mühevoll seinen Post ordentlich mit viel Zeitaufwand formatiert, drängelt sich schon wer mit einer Antwort dazwischen. ![]()
Im EN-Forum gabs dazu einen Beitrag: https://www.autoitscript.com/forum/topic/17…rtable-devices/
EDIT:
Ich denke, das kann durchaus in einer Funktion untergebracht werden. Habe den Code mal angepasst.
#include <Array.au3>
#include <WinAPICom.au3>
Opt("MustDeclareVars", 1)
Local $aPnPDevices = GetPortableDevices()
If IsArray($aPnPDevices) Then _ArrayDisplay($aPnPDevices)
;~ Success: Return 2DArray [n][4] |;[n][0]$eDevID, [n][1]$eDevName, [n][2]$eDevManufacturer,[n][3] $eDevDescription
;~ Failure: Return 0
Func GetPortableDevices()
Local Const $sCLSID_PortableDeviceManager = "{0af10cec-2ecd-4b92-9581-34f6ae0637f3}"
Local Const $sIID_IPortableDeviceManager = "{a1567595-4c2f-4574-a6fa-ecef917b9a40}"
Local Const $sTagIPortableDeviceManager = "GetDevices hresult(ptr;dword*); RefreshDeviceList hresult(); " & _
"GetDeviceFriendlyName hresult(wstr;wstr;dword*); GetDeviceDescription hresult(wstr;wstr;dword*); " & _
"GetDeviceManufacturer hresult(wstr;wstr;dword*); GetDeviceManufacturer hresult(wstr;wstr;ptr;dword*dword*); " & _
"GetPrivateDevices hresult(ptr;dword*)"
Local Enum $eDevID, $eDevName, $eDevManufacturer, $eDevDescription
Local $aDevicesInfo[0][0] ;[n][0]$eDevID, [n][1]$eDevName, [n][2]$eDevManufacturer,[n][3] $eDevDescription
Local $oPortableDeviceManager = 0
Local $SizeofArray = 0
Local $hr = 0x80004005 ;E_Fail Just to Initialized <0
Local $taPnPDeviceIDs = 0
Local $tName = 0
$oPortableDeviceManager = ObjCreateInterface($sCLSID_PortableDeviceManager, $sIID_IPortableDeviceManager, $sTagIPortableDeviceManager)
If Not IsObj($oPortableDeviceManager) Then Return 0
If ($oPortableDeviceManager.GetDevices(Null, $SizeofArray)) < 0 Then Return 0
If $SizeofArray < 1 Then Return 0
$taPnPDeviceIDs = DllStructCreate("ptr[" & $SizeofArray & "]")
If ($oPortableDeviceManager.GetDevices(DllStructGetPtr($taPnPDeviceIDs), $SizeofArray)) < 0 Then Return 0
ReDim $aDevicesInfo[$SizeofArray][4]
Local $sString
For $i = 0 To $SizeofArray - 1
$tName = DllStructCreate("wchar[512]", DllStructGetData($taPnPDeviceIDs, 1, $i + 1))
$aDevicesInfo[$i][$eDevID] = DllStructGetData($tName, 1)
$oPortableDeviceManager.GetDeviceFriendlyName($aDevicesInfo[$i][$eDevID], $sString, 128)
$aDevicesInfo[$i][$eDevName] = $sString
$oPortableDeviceManager.GetDeviceManufacturer($aDevicesInfo[$i][$eDevID], $sString, 128)
$aDevicesInfo[$i][$eDevManufacturer] = $sString
$oPortableDeviceManager.GetDeviceDescription($aDevicesInfo[$i][$eDevID], $sString, 128)
$aDevicesInfo[$i][$eDevDescription] = $sString
$tName = 0
_WinAPI_CoTaskMemFree(DllStructGetData($taPnPDeviceIDs, 1, $i + 1))
Next
Return $aDevicesInfo
EndFunc ;==>GetPortableDevices
Alles anzeigen
Der Zugriff (darauf bezog sich deine Frage) passiert in Zeile 25. Es wird ein Objektinterface erstellt, aus CLSID und IID und der Struktur(Interfacebeschreibung) des PortableDeviceManager. Mit diesem Interface hast du dann Zugriff auf die Methoden.
Die Methoden konnt' ich schon mal ausfindig machen, aber keine Paramter.
Um Parameter zu finden, gehe ich immer so vor:
- Dll im DLL Export Viewer laden
- gewünschte Funktion markieren
- mit F7 Google-Suche zu dieser Funktion aufrufen
Also irgendwo muss die entschlüsselte Datei schon bereitgehalten werden, auf der Festplatte oder im RAM.
Was verstehst du unter "intern" entschlüsseln?
Funktioniert auf Win7 x64.
Installiert sind bei mir C++ Redistributables: 2005 (32/64), 2008 (32/64), 2013 (32)
Mein Bild hat hiermit 103217 Farben (1298x887 px) , Zeit: 184.53 ms.
Laut Bildbetrachter XnView sind es 103240 Farben - ein bischen Schwund ist immer ![]()
EDIT:
Habe jetzt mal das Amselbild verwendet:
Zeitbedarf: 130.92 ms
Anzahl Farben: 99394 (in XnView: 99375)
XnView zählt mal mehr, mal weniger als diese Funktion. (Wer zählt von Hand nach?
)
Ich hatte ein ähnliches Problem an einem PC: Ursache war das Netzteil, das hat nicht abgeschaltet oder auch ungefragt einen Reboot inszeniert.
Ich versuche jetzt deinen Code zu verstehen und mit der Struct weiter zu arbeiten.
Wirf mal einen Blick in mein Tut, da habe ich das etwas mehr kommentiert: Dll-Tutorial
Schau dir mal den Parameter advanced an: https://autoit.de/onlinehilfe/functions/GUIGetMsg.htm
Da werde ich später nochmal drüber schauen, Dll ist meist mit etwas Probieren verbunden und wenn man dann nicht selbst auf die Dll zugreifen kann, weiß man auch nicht ob die Überlegungen in die richtige Richtung gehen.
Ich habe vor Jahren mal die Nutzung von Arraystrukturen bei Dll in eine kleine Funktionssammlung gepackt. Vielleicht kannst du damit etwas anfangen: Arrays als Dll-Elemente
EDIT
$sAC_Info = DllCall($g_hAccessBridgeDll, 'BOOL:cdecl', 'getAccessibleContextInfo','long', $vmId, 'long', $acElement, 'struct*', $tAccessibleContextInfo)
Funktioniert dieser Aufruf?
struct*, $tAccessibleContextInfo soll einen Pointer auf $tAccessibleContextInfo legen.
Falls der Aufruf nicht funktioniert kannst du auch probieren:
ptr, DllStructGetPtr($tAccessibleContextInfo)
EDIT-2
ich vermute mal, mit dem Byte-Array solltest du zum Ziel kommen, in etwa so:
Global Const $MAX_STRING_SIZE = 1024
Global Const $SHORT_STRING_SIZE = 256
Global Const $MAX_ACTION_INFO = 256
Global Const $MAX_ACTIONS_TO_DO = 32
Global $tagAccessibleActionInfo = 'wchar name[' & $SHORT_STRING_SIZE & ']'
; create Byte-Array "actionInfo"
Global $iSize = DllStructGetSize(DllStructCreate($tagAccessibleActionInfo, 1))
Global $a_actionInfo[$MAX_ACTION_INFO +1]
$a_actionInfo[0] = DllStructCreate('byte[' & $iSize *$MAX_ACTION_INFO & "]")
Global $ptr = DllStructGetPtr($a_actionInfo[0])
For $i = 0 To $MAX_ACTION_INFO -1
$a_actionInfo[$i+1] = DllStructCreate($tagAccessibleActionInfo, $ptr + $i*$iSize)
Next
; Dll-Call
DllCall($g_hAccessBridgeDll, 'BOOL:cdecl', 'getAccessibleActions','long', $vmId, 'long', $acButton, 'ptr', DllStructGetPtr($a_actionInfo))
; evtl. muss der Pointer auf das Element[0] verweisen
; DllCall($g_hAccessBridgeDll, 'BOOL:cdecl', 'getAccessibleActions','long', $vmId, 'long', $acButton, 'ptr', DllStructGetPtr($a_actionInfo[0]))
Alles anzeigen
Bei der dritten Struktur habe ich keinen Plan, was mit JOBJECT64 für ein Datentyp gemeint ist.
Anfangen würde ich so:
Global Const $MAX_STRING_SIZE = 1024
Global Const $SHORT_STRING_SIZE = 256
Global Const $MAX_ACTION_INFO = 256
Global Const $MAX_ACTIONS_TO_DO = 32
;~ typedef struct AccessibleActionInfoTag {
;~ wchar_t name[SHORT_STRING_SIZE]; // action name
;~ } AccessibleActionInfo;
Global $tAccessibleActionInfo = DllStructCreate('wchar name[' & $SHORT_STRING_SIZE & ']')
;~ typedef struct AccessibleActionsTag {
;~ jint actionsCount; // number of actions
;~ AccessibleActionInfo actionInfo[MAX_ACTION_INFO]; // the action information
;~ } AccessibleActions;
Global $tAccessibleActions = DllStructCreate('int actionsCount;' & DllStructGetPtr($tAccessibleActionInfo) & '[' & $MAX_ACTION_INFO & ']')
Alles anzeigen
Laut Definition ist actionInfo ein Array von Pointern auf die Struktur AccessibleActionInfo, ich hoffe das klappt so.
Dort dann bei "_ClipBoard_GetData" $CF_UNICODETEXT eintragen und zurück in die Zwischenablage. Fertig!
Das hatte ich auch schon überlegt, allerdings habe ich da einen weniger aufwändigen und flexibleren Weg gewählt.
- Hotkey um nur bei Bedarf den Inhalt der Zwischenablage in pur Text zu wandeln
- Einfügen mit normal CTRL+V
#include <Clipboard.au3>
HotKeySet('^u', '_Clipboard_AsTextOnly') ; Ctrl+U
HotKeySet('^+e', '_exit') ; Ctrl+Shift+E
Func _Clipboard_AsTextOnly()
_ClipBoard_SetData(ClipGet(), $CF_UNICODETEXT)
EndFunc
Func _exit()
Exit
EndFunc
While True
Sleep(10)
WEnd
Alles anzeigen
Ich werde dann wohl die Variante belassen, ein Hotkey mehr zum Ausführen bringt mich nicht um. ![]()
Grundsätzlich funktioniert es damit.
Bei mir wird aber bei jedem Zeilenumbruch ein Seitenumbruch eingefügt. Ich muss dort ControlSend($hChild, '', '', StringReplace($sClip, @CRLF, @CR) , $SEND_RAW) verwenden.
Ich lass es mal noch offen, vielleicht gibt es noch andere Ideen.