Ähhm:
ZitatDienstag, 4. September 2007, 13:15
ZitatLetzte Aktivität
Samstag, 8. September 2012, 19:01
Du Leichenschänder ![]()
Ähhm:
ZitatDienstag, 4. September 2007, 13:15
ZitatLetzte Aktivität
Samstag, 8. September 2012, 19:01
Du Leichenschänder ![]()
Sollte so passen oder?
Ja, aber z.Zt. verwendest du das Mouse-Hook-Hwnd in deiner Key-Procedure. ![]()
Und die Passagen für den Mouse-Hook kannst du dann entfernen:
Global $hStub_MouseProc = DllCallbackRegister("_MouseProc", "long", "int;wparam;lparam")
Global $hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($hStub_MouseProc), $hmod)
; in Func OnAutoItExit()
_WinAPI_UnhookWindowsHookEx($hHook)
DllCallbackFree($hStub_MouseProc)
Würdest du WM_NOTIFY für die Mausklick weiterverwenden oder stattdessen _MouseProc
Würdest du diese Methode immer der ständigen Abfrage in der While-Schleife vorziehen
Wenn du nur auf den Klick reagieren mußt, bist du mit WM_NOTIFY bestens bedient. Wenn du jedoch den Klick unter Umständen nicht zulassen möchtest und auch zusätzliche Infos zur Maus benötigst ist der Mouse-Hook die bessere Wahl.
Die Pfeiltasten mußt du dir über einen Keyhook abfangen. Ich poste mal aus meiner Bsp.-Sammlung, wie ich es für ein Tab gelöst hatte. Auswahl der Tabs per Klick oder Pfeiltaste
#include <GuiConstantsEx.au3>
#include <GuiTab.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>
OnAutoItExitRegister('OnAutoItExit')
AdlibRegister('_CheckPass', 50)
Global Const $HC_ACTION = 0
[/autoit] [autoit][/autoit] [autoit]Global $hStub_MouseProc = DllCallbackRegister("_MouseProc", "long", "int;wparam;lparam")
Global $hStub_KeyProc = DllCallbackRegister("_KeyProc", "long", "int;wparam;lparam")
Global $hmod = _WinAPI_GetModuleHandle(0)
Global $hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($hStub_MouseProc), $hmod)
Global $hHook2 = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hStub_KeyProc), $hmod)
Global $hTab, $lastTab = 0, $checkPass = False
Global $Passwort = 'pass', $passItem = 2 ; <== 0-basierter Index des PW-geschützten TabItems
[/autoit] [autoit][/autoit] [autoit]$Form1 = GUICreate("Testfenster", 297, 341, 210, 144)
$Tab = GUICtrlCreateTab(8, 8, 280, 304)
GUICtrlSetResizing(-1, $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT)
$tab1 = GUICtrlCreateTabItem("Tab1")
$tab2 = GUICtrlCreateTabItem("Tab2")
$tab3 = GUICtrlCreateTabItem("Tab3")
$tab4 = GUICtrlCreateTabItem("Tab4")
GUICtrlCreateTabItem("")
GUISetState(@SW_SHOW)
Global $hookGUI = $Form1, $hookID = $Tab
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Tab
Switch GUICtrlRead($Tab)
Case 0
WinSetTitle($Form1, '', ' >> Tab1 aktiviert <<')
Case 1
WinSetTitle($Form1, '', ' >> Tab2 aktiviert <<')
Case 2
WinSetTitle($Form1, '', ' >> Tab3 aktiviert <<')
Case 3
WinSetTitle($Form1, '', ' >> Tab4 aktiviert <<')
EndSwitch
Sleep(1000)
WinSetTitle($Form1, '', 'Testfenster')
EndSwitch
WEnd
Func _MouseProc($nCode, $wParam, $lParam)
Select
Case $nCode < 0
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
Case Not _MouseOverTabItem($hookGUI, $hookID, $passItem)
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
Case $wParam = $WM_LBUTTONDOWN
If $nCode = $HC_ACTION Then
$checkPass = True ; Überprüfung aktivieren
Return -1 ; Mausklick wird ignoriert ==> TabItem noch nicht aktiviert
EndIf
EndSelect
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc ;==>_MouseProc
Func _KeyProc($nCode, $wParam, $lParam)
Local $tKEYHOOKS, $vkCode
$tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
If ControlGetFocus($Form1) <> 'SysTabControl321' Then Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
$vkCode = DllStructGetData($tKEYHOOKS, "vkCode")
If $wParam = $WM_KEYDOWN Then
Switch $vkCode
Case 0x25 ; ==> Pfeil li.
If GUICtrlRead($hookID) - 1 = $passItem Then
$checkPass = True ; Überprüfung aktivieren
Return -1 ; Tastendruck wird ignoriert ==> TabItem noch nicht aktiviert
EndIf
Case 0x27 ; ==> Pfeil re.
If GUICtrlRead($hookID) + 1 = $passItem Then
$checkPass = True ; Überprüfung aktivieren
Return -1 ; Tastendruck wird ignoriert ==> TabItem noch nicht aktiviert
EndIf
EndSwitch
EndIf
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc ;==>_KeyProc
Func _CheckPass()
If Not $checkPass Then Return
If InputBox('Passwort', 'Bitte Passwort eingeben:') == $Passwort Then
_GUICtrlTab_SetCurSel(GUICtrlGetHandle($Tab), $passItem)
Else
MsgBox(0, 'Fehler', 'Falsches Passwort!')
EndIf
$checkPass = 0
EndFunc ;==>_CheckPass
Func _MouseOverTabItem($GUI, $TabID, $iTabItem)
If Not BitAND(WinGetState($GUI),
Then Return False
Local $old = Opt('MouseCoordMode', 2)
Local $posM = MouseGetPos(), $tMouse = DllStructCreate($tagPOINT)
DllStructSetData($tMouse, 1, $posM[0])
DllStructSetData($tMouse, 2, $posM[1])
Opt('MouseCoordMode', $old)
Local $tTabItem = _GUICtrlTab_GetItemRectRelativ($GUI, $TabID, $iTabItem, 1)
If _WinAPI_PtInRect($tTabItem, $tMouse) Then
Return True
Else
Return False
EndIf
EndFunc ;==>_MouseOverTabItem
;===============================================================================
; Function Name: _GUICtrlTab_GetItemRectRelativ($GUI, $TabID, $iTabItem, $iReturnType=0)
; Description: Returns the co-ordinates of a TabItem relatively to the GUI co-ordinates
; Parameter(s): $GUI - window handle
; $TabID - Tab ID (not handle!)
; $iTabItem - TabItem index
; $iReturnType - Return type array=0 (default), RECT-structure=1
; Return Value(s): Array or structure with co-ordinates of a TabItem (left, top, right, bottom)
; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
;===============================================================================
Func _GUICtrlTab_GetItemRectRelativ($GUI, $TabID, $iTabItem, $iReturnType=0)
Local $hWnd = GUICtrlGetHandle($TabID)
Local $TabPos = ControlGetPos($GUI, '', $TabID)
Local $tRECT = DllStructCreate("int Left;int Top;int Right;int Bottom")
Local $pRect = DllStructGetPtr($tRECT)
GUICtrlSendMsg($TabID, $TCM_GETITEMRECT, $iTabItem, $pRect)
Local $posLeft = $TabPos[0]+2, $posTop = $TabPos[1]+2
Local $width = (DllStructGetData($tRECT,3) - DllStructGetData($tRECT,1))
Local $height = DllStructGetData($tRECT,4) - DllStructGetData($tRECT,2)
If $iTabItem > 0 Then
For $i = 0 To $iTabItem -1
GUICtrlSendMsg($TabID, $TCM_GETITEMRECT, $iTabItem, $pRect)
$posLeft += (DllStructGetData($tRECT,3) - DllStructGetData($tRECT,1))
Next
EndIf
If $iReturnType Then
DllCall("user32", 'long', 'SetRect', 'ptr', $pRECT, 'long', $posLeft, _
'long', $posTop, 'long', $posLeft+$width, 'long', $posTop +$height)
Return $tRECT
Else
Local $aOut[4] = [$posLeft, $posTop, $posLeft +$width, $posTop +$height]
Return $aOut
EndIf
EndFunc ;==>_GUICtrlTab_GetItemRectRelativ
Func OnAutoItExit()
_WinAPI_UnhookWindowsHookEx($hHook)
DllCallbackFree($hStub_MouseProc)
_WinAPI_UnhookWindowsHookEx($hHook2)
DllCallbackFree($hStub_KeyProc)
EndFunc ;==>OnAutoItExit
Die Plain-Text Variante habe ich jetzt noch um Eerkennung von Ordinalzahlen und Paragrafen erweitert. Die Standardtextfarbe habe ich jetzt auch etwas kräftiger gewählt.
Wie das funktioniert und aussieht könnt ihr dem Bild entnehmen:
Was ich nicht verstehe, warum fällt das EndIf weg wenn ich If und Then in einer Zeile schreibe?
Then steht immer in derselben Zeile wie If ![]()
Es gibt einzeilige Statements, wenn also nach dem Statement nur ein Befehl ausgeführt wird, dann kann das alles in einer Zeile erfolgen und ein EndIf ist nicht erforderlich.
[autoit]If $A = $B Then Return $C
[/autoit]Wenn mehrere Befehle nach dem Statement ausgeführt werden sollen muß der Befehlsblock durch EndIf beendet werden.
[autoit]If $A = $B Then
$C = 5
$D = 6
EndIf
Als kleines Nebenbei habe ich die Definitionen für die Textdatei erweitert und mal ordentlich aufgehübscht. ![]()
Aus dem Anhang:
"Text.zip" in den Ordner "..\Packages\Text\" entpacken (vorhandene "Plain text.tmLanguage" überschreiben)
"User.zip" in den Ordner "..Packages\User\" entpacken
Damit ein bestimmter Dateityp immer mit derselben Syntaxdatei angezeigt wird, wie folgt vorgehen:
- Datei öffnen
- In der Statusbar unten rechts ist die aktuell genutzte Syntax sichtbar
- Diesen Syntaxnamen anklicken
- ersten Menüpunkt wählen ("Open all with current extension as..")
- im Submenü "GEWÜNSCHTE_SYNTAX" auswählen
Nun wird jede Datei diesen Typs immer mit dieser Syntaxdefinition geöffnet
Damit zusätzlich auch mit einem Dateityp ein Schema automatisch verknüpft wird, so vorgehen:
- Datei erstellen (od. wenn vorhanden öffnen) "SUFFIX.sublime-settings"
- Inhalt:
Das wäre ein Standardthema
Für eigene Themes auf den Pfad verweisen, z.B. hier für Text
Die Settings-Datei für PlainText ist im Anhang bereits enthalten.
Und so kann Text dann aussehen:
Wie kann ich erreichen das nur die checked items in die Ini geschrieben werden?
Ist das überhaupt realisierbar?
![]()
Schau dir mal deine Code an: Du prüfst ob das Item gecheckt ist und setzt bei gecheckt $sOut2 auf den Itemwert.
Aber: Unabhängig von der Überprüfung schreibst du anschließend bei jedem Schleifendurchlauf in die INI! Das darf natürlich nur innerhalb des If-Statements passieren.
Hier nun die AutoIt-Version im Stil von SciTE-OldStyle und zusätzlicher Einzelfärbung für Hexzahlen und Klammern (dabei moch 2 kleine Bugs aus der im vorigen Post gepinnten Syntaxdefinition gefixed).
Damit ist jetzt erst mal der optische Grundstein gelegt. Nun gehts ans Eingemachte. ![]()
(Anhang in den Ordner "C:\Users\USERNAME\AppData\Roaming\Sublime Text 2\Packages\User\" entpacken)
Edit:
- Noch einen Fehler beim Com-Objects-Parsing gefixed.
- "AutoIt.sublime-settings" hinzugefügt
"AutoIt-Definition_plus_Theme-OldStyle.zip" enthält:
Ich habe inzwischen die "Scope Rules/ Naming Conventions" ausfindig gemacht und anhand dieser eine .tmLanguage erstellt, die somit auch bei vorhandenen Farbschemes genutzt werden kann.
Es gibt in diesen Regeln eine vordefinierte Struktur mit entsprechenden Begriffen.
Bsp.: Kommentarzeile
Scope (Basis) = "comment.line"
Es gibt bereits vordefinierte Sub-Scopes:
"comment.line.double-slash" — // Kommentar
"comment.line.double-dash" — -- Kommentar
"comment.line.number-sign" — # Kommentar
"comment.line.percentage" - % Kommentar
Da davon nichts für AutoIt zutrifft, wird der Sub-Scope:
"comment.line.character" verwendet.
Um doppelte Scope-Namen zu vermeiden, wird an den Scope immer die Syntaxbezeichnung angehängt, für uns also: ".autoit".
Im Gegensatz zum Highlighting mit Lexxer, wird hier die Farbgebung über Syntaxerkennung mittels der vergebenen Regex-Definition aus der .tmLanguage gesteuert.
Bei einem Match liest der Parser den Namen aus der .tmLanguage und sucht im aktuellen Farbschema nach größtmöglicher Übereinstimmung im Namen.
Bsp.:
Ich verwende im Muster eine Erkennung von Integer und separat von Hexadezimalzahlen. Dazu habe ich die Scopes
- "constant.numeric.hex.any" und
- "constant.numeric.number.any"
Beide Scopes kennt der Parser nicht, also wird jeweils von rechts eine Ebene nach vorn gegangen und erneut geprüft. Für beide Scopes findet der Parser dann mit
"constant.numeric"
eine Übereinstimmung. Es werden also beide Scopes mit den Font-/Farbanweisungen für diesen "Stamm" angezeigt.
In einem individuell erstellten Farbschema kann ich natürlich jeden vergebenen Scope auch einzeln ansprechen und nach meinem Geschmack formatieren.
Hier mal eine Auflistung der Scop-Namen in dieser Musterdatei mit Zuordnung der AutoIt-Syntax:
Den allgemeingültigen Scope (Root) habe ich zur Veranschaulichung zwischen 2 Pipes gesteckt.
• "|comment.line.character|.any" Einzeiliger Kommentar
• "|comment.block|.any" Kommentar-Block
• "|constant.numeric|.hex.any" Hexadezimalzahlen
• "|constant.numeric|.number.any" Integer
• "|entity.name.function|.native.any" Native Funktionen
• "|entity.name.tag|.macro.any" Makros
• "|constant.character|.preprocessor.any" Include(-Once)/NoTrayIcon/RequireAdmin
• "|string.quoted|.include.file.any" Dateiname hinter Include (als String markiert)
• "|constant.character|.preprocessor.any" End-/Region
• "|constant.language|.preprocessor.special.autoit" Preprozessor Anweisungen, Wrapper etc.
• "|keyword.control|.any" Keywords
• "|keyword.operator|.any" Operatoren
• "|keyword.other|.braces.any" Klammern
• "|string.quoted.single|.any" String, einfach quotiert
• "|string.quoted.double|.any" String, doppelt quotiert
• "|variable.parameter|.sentkey.any" SentKeys
• "|variable.language|.any" Variablen
• "|support.function|.udf.any" UDF-Funktionen
• "|support.class|.objects.any" Com Objects
Alles anzeigen
Im Anhang findet ihr die Musterdatei "Test.JSON-Language". Jetzt werden auch SentKeys korrekt erkannt.
Wenn ihr euch die *.tmTheme aus dem vorigen Beitrag zur Hand nehmt, sollte es kein Problem sein ein eigenes Farbschema zu erstellen.
Bevor ihr aus der .JSON-Language die .tmLanguage erstellt dann natürlich noch die ersten 3 Zeilen anpassen:
"Test" wird der Language-Name, der dann auch in der Syntaxübersicht erscheint (also z.B. AutoIt), "source.any" wird dann zu "source.autoit" und '[""]' zu '["au3"]'.
Um die Übersicht über Standard-Packages und eigene Werke zu behalten, empfiehlt es sich, eigene Definitionen unter:
"C:\Users\USERNAME\AppData\Roaming\Sublime Text 2\Packages\User\"
abzuspeichern.
Ein Hinweis noch: Falls ihr selbst an den Syntaxdefinitionen (Regex-Pattern) herumbasteln möchtet, probiert diese vorher ausserhalb des Editors aus. Die Regex-Syntax weicht gering von der uns bekannten ab. Sublime Text verwendet die Regex-Engine "Oniguruma".
Und nun viel Spaß damit.
So, ich habe nun mal wieder etwas Zeit gefunden an dieser Baustelle weiter zu basteln.
Ich habe jetzt eine "AutoIt.tmLanguage" erstellt und basierend auf dieser die "Default.au3.tmtheme".
Syntaxhighlighting funktioniert noch nicht für SentKeys aber dafür habe ich zusätzlich drin als eigene Typen mit separater Färbung:
• Klammern
• Hex-Zahlen
Einige UDF-Funktionsnamen sind noch nicht enthalten. Da muß ich mir noch eine Routine schreiben, die die JSON-Datei automatisch generiert. Aber für den Anfang gehts erst mal. ![]()
Im Anhang sind auch die "JSON"-Dateien enthalten. Wenn man etwas ändern möchte, muß es an diesen Dateien passieren. Anschließend werden daraus mit "F7" bei Einstellung Build-System "JSON to PropertyList" die .tmLanguage / .tmtheme erstellt.
Im Anhang:
• Ordner "AutoIt3" {AutoIt3.JSON-tmLanguage, AutoIt3.tmLanguage} ==> Ordner Speichern in "C:\Users\USERNAME\AppData\Roaming\Sublime Text 2\Packages\"
• Dateien {Default.au3.JSON-tmtheme, Default.au3.tmtheme} ==> Dateien Speichern in "C:\Users\USERNAME\AppData\Roaming\Sublime Text 2\Packages\Color Scheme - Default\"
Das ganze schaut dann so aus:
Stimmt ja - GDI+ Handle sind weder identifizier- noch validierbar. Ist ein String-Handle, dass auch nach dem Dispose unverändert von der Variable gehalten wird. Nur im internen GDI+ Management wird das Handle beim Dispose gelöscht.
Naja, dann eben einmal öfter disposen, falls schon im Skript getan. Schadet jedenfalls nicht. ![]()
3 Punkte:
• Du gehst in deinem Skript ausschließlich von Globalen Handles aus. Es gibt viele Fälle, in denen Handle Local in Funktionen erstellt werden und auch dort wieder sauber geclosed werden sollten. Eine entsprechende Unterscheidung wäre sinnvoll. Wie du Local von Global/Dim trennst, kannst du dir z.B. hier (ab Zeile 135) anschauen.
• Der Aufruf für die Dispose-Funktion wird ja vor einem (evtl. auch mehreren) Exit im Skript eingefügt. Ich finde aber in dem Skript nicht die Suche nach "Exit" -- oder habe ich was übersehen?
• Ich würde auf Nummer sicher gehen und jeden Dispose-Befehl nur ausführen, wenn das Handle auch noch existiert - also "If IsHwnd($Handle) Then ...". Damit sparst du dir auch vorab zu prüfen, ob schon ein Dispose-Befehl für das Handle existiert.
Inzwischen kommen immer mehr Dienste auf den Markt, die freien WebSpace anbieten.
ADrive und Mega mit je 50 GB Cloudspace sind da die absoluten Topscorer. Ob man Mega nutzen möchte.. nun ja, könnte sein dass Kim dot Com damit auch wieder baden geht und dann sind die Daten futsch. ![]()
Hier mal eine Auflistung von Anbietern
Volumen Dienst Web-Site WebDAV-Unterstützung max. Dateigröße Features/Besonderheiten
50 GB A Drive www.adrive.com X (nur Premium User $6,95 / Monat) 16 GB Online Edit Dokumente, Download aus Websites direkt in die Cloud
10 GB ++ Mediafire www.mediafire.com - 200 MB Online Edit Dokumente, Space kann bis 50 GB steigen
50 GB Mega mega.co.nz - unlimitiert API für Entwickler
7 / 25 GB Skydrive skydrive.live.com X 300 MB 7 GB f. Neukunden
25 GB Telekom Mediencenter mediencenter.telekom.de X 2 GB* *Browser, m. Mediencenter Software unbegrenzt ? nur für Telekom-Kunden ? https://webdav.mediencenter.t-online.de
10 GB ++ Goneo Multi-Cloud www.goneo.de/cloud/register - 2 GB Space kann bis 100 GB steigen
5 GB Box www.box.com X k.A.
5 GB Google Drive drive.google.com - 10 GB
5 GB Hidrive www.free-hidrive.com X k.A. Mailupload-Adresse für Freunde und Bekannte
5 GB ++ Ubuntu One one.ubuntu.com - k.A. Space kann bis 20 GB steigen
5 GB Wuala www.wuala.com - 40 GB Online Edit Dokumente
3 GB Cloud me www.cloudme.com X 150 MB
2 GB Cloud Safe secure.cloudsafe.com X k.A.
2 GB ++ Dropbox www.dropbox.com - (nur mit ext. Dienst DropDAV) 300 MB* *Browser, durch Einladungen/ App Download etc. erweiterbar
2 GB GMX Mediacenter www.gmx.de X 1,95 GB
2 GB Web.de Online-Speicher web.de X 1 GB
Alles anzeigen
Schick wäre es ja, wenn man über eine Oberfläche Zugriff auf alle Cloud-Dienste hätte. Das bietet allerdings keines der Tools, die ich gefunden habe. Die meisten Clouds lassen sich in Primadesk einbinden. Es bietet Zugriff auf die WebDAV-Schnittstelle und somit können alle Dienste, die damit arbeiten auch eingebunden werden. Aber einen großen Nachteil hat das Tool: Man kann darüber keine Daten uploaden, das muss man mit den jeweiligen Tools erledigen. Alles andere (Download, zwischen den Clouds Daten tauschen, Sharing) kann man aber darüber erledigen.
Gut gefällt mir iSpaces. Es bietet selbst 1 GB Free Space und verwaltet zusätzlich Dropbox und Box (somit min. 8 GB). Es versteht sich als eine Art Online-PC. Ein Office-Paket ist enthalten mit dem sich auch vernünftig arbeiten läßt. Weiterhin vorhanden ein integrierter Browser (Browser im Browser
-- ziemlich flott allerdings) und ein eigenes Telefonie-Modul (ähnlich wie Skype).
Andere MultiCloudManager sind in der Free-Version dermaßen limitiert, dass der eigentliche Zweck verloren geht. Falls ihr aber auf einen solchen stoßt, der etwa 10 Dienste freier Wahl kpl. managen kann, wäre ich sehr interessiert. ![]()
NB: Alle Dienste mit WebDAV-Funktionalität können direkt im Explorer eingebunden werden. Win 7 kann das zwar mit Bordmitteln (aber ohne Vergabe von Laufwerksbuchstaben), empfehlenswerter ist aber das Tool Netdrive von MacroData (Alternativ gibt es auch von Novell eine m.M. nach leichter konfigurierbare Version von Netdrive). Details zur Anwendung findet ihr im Dokument WebDAV Tipps und Tricks.
Edit:
Netdrive von MacroData ist etwas tricky in der Konfiguration:
Normalerweise werden WebDAV-Dienste über eine https-Adresse angesprochen (sollte sein). Dazu muß also die SSL-Verschlüsselung für die neu anzulegende Verbindung aktiviert werden. Der Parameter versteckt sich in der Dienste-Liste: Dienst markieren - Advanced klicken - Häkchen bei "SSL".
Bei den Zugangsdaten darauf achten: SSL-Port ist 443.
Wirklich geklappt hat das bei mir aber nur mit dem GMX-Mediacenter. Bei allen anderen Anwendungen konnte das Tool keine Verbindung herstellen. Die Netzverknüpfung im Windows Explorer funktionierte dagegen tadellos - aber leider eben ohne Möglichkeit Laufwerksbuchstaben zu verwenden.
Netdrive von Novell konnte ich nicht testen, da es einen "FSD-Service" starten will, der bei mir nicht existiert. :pinch:
Ein interessantes Tool habe ich noch entdeckt: BitKinex - ein All-in-One FTP/SFTP/WebDAV Client. Bis auf SkyDrive konnte ich damit alle meine WebDAV-Clouds einbinden.
Das Problem mit SkyDrive liegt in dessen Adressstruktur. Um die Adresse bilden zu können benötigt ihr die #cid eures Accounts. Dazu im Acc einloggen, links auf "Dateien" klicken. Jetzt wird in der Adresszeile des Browsers angezeigt https://skydrive.live.com/#cid=C166A3D817145BE4 <-- diese cid ist frei erfunden
Daraus ergibt sich die WebDAV-Adresse: \\d.docs.live.net@SSL\C166A3D817145BE4
Und dieses @SSL sorgt dafür, dass Adresse und Username verknüpft werden. Nach Eintrag der Adresse erscheint im User-Feld "d.docs.live.net". Ändert man dieses auf den richtigen Usernamen, wird der Teil wiederum im Adressfeld entfernt. Beide Felder sind durch das @ wechselseitig verknüpft und können somit nicht korrekt ausgefüllt werden.
BitKinex verlangt übrigens die Adresse ohne Protokoll, stattdessen mit angehängtem Port. Also statt z.B. "https://webdav.mc.gmx.net" -- "webdav.mc.gmx.net:443"
Soweit ich weiß, wird die gesamte DB für die Dauer eines Zugriffs (Schreib- oder Lesevorgang) gesperrt. Somit ist ein echtes paralleles Arbeiten mehrerer User nicht möglich.
Wenn die einzigen im Text enthaltenen Ziffern zur ID gehören, brauchst du gar nicht abfragen ob Text dabei ist - einfach nur die Ziffern rausfischen:
[autoit]$ret = StringRegExp(GUICtrlRead($input), '\d+', 1)
ConsoleWrite($ret[0] & @LF)
Man könnte mit IsString prüfen -- aber das Lesen eines Inputs ergibt einen String. Also müßte man vorher mit Number(GuiCtrlRead($input)) umwandeln.
Ich bevorzuge da eine RegEx-Abfrage:
$sRead = GUICtrlRead($input)
If Not StringRegExp($sRead, "^\d+$") Then ; .. Text enthalten
Also von der Android-App QR-Code Scan wird der Inhalt nach dem Lesen so im Anzeigefenster dargestellt:
Max Mustermann
Musterfirma
Musterstrasse 1 Musterstadt
11111 Germany
0211 111 111
0211 111 112
mustermann @musterdomain.de
http://www.musterdomain.de
Bei Übernahme in Kontakte sieht es dann so aus:
Vorname: Max Mustermann
Familienname: leer
Telefon1: 0211111111
Telefon2: 0211 111 112
eMail: mustermann@musterdomain.de
Postanschrift
___ Strasse: Musterstrasse 1 Musterstadt
__________11111 Germany
___Stadt: leer
___PLZ: leer
Organisation: Musterfirma
Webseite: leer
Die Zuordnung passt also vorne und hinten nicht. Mit vcf habe ich mich aber bisher nie beschäftigt und die Feldbeschreibung ergibt auf den ersten Blick nicht viel Sinn.
Die Zahl in Workbooks gibt die erste/zweite/dritte... Datei an, falls in Excel mehrere Dateien geöffnet sind.
Sheets ist das Tabellenblatt
Ich rate eigentlich davon ab, den Index zu verwenden ohne vorher zu prüfen ob er auch auf das gewünschte Workbook/Tabellenblatt verweist. Es kann ja jederzeiz z.B. die Reihenfolge der Tabellenblätter verändert werden.
Besser beim Workbook den Dateipfad und beim Tabellenblatt den Namen übergeben. Der Parameter läßt beides zu.