Das Tool hilft mir nur bedingt, da ich inzwischen mehr Externe Datenträger (teils auch partitioniert) besitze, als Laufwerksbuchstaben zur Verfügung stehen.
Beiträge von BugFix
-
-
Hi,
ich nehme an, bei euch sieht es ähnlich aus:
Immer mehrere USB-Sticks angestöpselt, davon sind welche identisches Fabrikat und bekommen deshalb auch keine festen Laufwerksbuchstaben, sondern mal hat der eine G:, dann der andere.
Um nun nicht immer zu gucken, welche Laufwerksnummern belegt und dann nach einem Ordner zu suchen, habe ich diese Funktion erstellt. Es wird der Pfad ohne Laufwerk angegeben. Die Funktion sucht in allen Laufwerken auf Existenz dieses Pfades und prüft auf Schreibrechte (Read-Only oder nicht), standardmäßig beschreibbar. Wobei mir aufgefallen ist, dass das Setzen von Read-Only per Skript erfolgen muss - im Explorer lassen sich nur die Rechte für die enthaltenen Dateien setzen.
Die Funktion gibt die vollen Pfade von allen Treffern zurück.
Vielleicht könnt ihr es brauchen.AutoIt
Alles anzeigen; #FUNCTION# ==================================================================================================================== ; Name ..........: _DriveGetFolderExists ; Description ...: Searches a given path on all drives. You can search for writable (default) or read-only pathes. ; Syntax ........: _DriveGetFolderExists($sFolder[, $bWriteable = True]) ; Parameters ....: $sFolder - Folder path without drive. ; $bWriteable - [optional] Searched path is (not) writeable. Default is True. ; Return values .: Success Array with full pathes of all matches. Count of matches in $array[0] ; Failure @error=1, $array[0]=0 - no matches ; Author ........: BugFix ; =============================================================================================================================== Func _DriveGetFolderExists($sFolder, $bWriteable=True) Local $aD = DriveGetDrive('all') Local $aExists[$aD[0]+1] = [0] Local $sPath, $iErr = 0 $sFolder = StringRegExpReplace($sFolder, '^(\\+)|(\\+)$', '') For $i = 1 To $aD[0] $sPath = StringFormat('%s\%s', $aD[$i], $sFolder) If FileExists($sPath) And ((StringInStr(FileGetAttrib($sPath), 'R') = 0) = $bWriteable) Then $aExists[0] += 1 $aExists[$aExists[0]] = $sPath EndIf Next ReDim $aExists[$aExists[0]+1] If $aExists[0] = 0 Then $iErr = 1 Return SetError($iErr,0,$aExists) EndFunc ;==>_DriveGetFolderExists -
@Bitnugger
Hast du Recht, war noch nicht "durchkomponiert"
- so ist es vollständig:AutoIt
Alles anzeigen; Rückgabe Handle des geklickten Item (-1 und @error=1, wenn unter letztem Item geklickt) ; oder Array mit Item-Handle und Hittest-Value Func _GUICtrlTreeView_GetItemClicked($hGui, $hTreeview, $bRetArray=False) Local $tPOINT = _WinAPI_GetMousePos(True, $hGui) Local $aPos = ControlGetPos($hGui, "", $hTreeview) Local $iX = DllStructGetData($tPOINT, "X") - $aPos[0] Local $iY = DllStructGetData($tPOINT, "Y") - $aPos[1] Local $iHittest = _GUICtrlTreeView_HitTest($hTreeview, $iX, $iY) Local $hItem = _GUICtrlTreeView_HitTestItem($hTreeview, $iX, $iY) Local $iErr = 0 If $iHittest = 1 Then $iErr = 1 $hItem = -1 EndIf If $bRetArray Then Local $aRet[2] = [$hItem, $iHittest] ; [Handle-Item, Value-Hittest] -> Values: https://www.autoitscript.com/autoit3/docs/libfunctions/_GUICtrlTreeView_HitTest.htm Return SetError($iErr,0,$aRet) EndIf Return SetError($iErr,0,$hItem) EndFunc -
Die PW sind seit jeher mit "läuft nie ab" erstellt.
Die WaWi ist nicht auf DOS-Basis und heißt GDILine.
Die Links sind alle per Hand angelegt. Bei nur 10 Usern rolle ich nichts aus, sondern installiere Notwendiges immer einzeln per Hand.
Der Server hat seinen letzten Neustart Anfang April, ich boote in etwa alle ein oder zwei Monate neu.Übrigens hatte ich doch mal das Problem mit dem Fehler 3034 geschildert. Der Fehler taucht seit einigen Wochen nicht mehr auf. Steht aber nicht in einem erkennbaren zeitlichen Zusammenhang mit dem vorab geschilderten Problem.
Windows ist und bleibt eine Wunderkiste. Oder um es mit Forrest Gump zu sagen: "Windows ist wie eine Schachtel Pralinen - man weiß nie, was man kriegt."
-
EDIT: Hatte eben erst gelesen, dass auch mehrere Treffer möglich sind. Hier mal als Muster:
EDIT 2: Habe das mal noch in Funktionen gegossen.
Eines muß noch erwähnt werden: Die Verwendung von _GUICtrlTreeView_SetItemParam darf nicht erfolgen, wenn die TreeviewItem mit den nativen Funktionen erstellt werden (GUICtrlCreateTreeViewItem). In diesem Fall wird in ItemParam die Ctrl-ID gespeichert. Ein Überschreiben dieses Wertes würde also das Treeview zerlegen, da den Item falsche ID zugeordnet würden.
Also auschließlich die UDF verwenden.AutoIt
Alles anzeigen#include <TreeViewConstants.au3> #include <StructureConstants.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <FontConstants.au3> #include <GuiTreeView.au3> $hGui = GUICreate('Test') GUISetBkColor(0x003463) $idTree = GUICtrlCreateTreeView(10, 10, 180, 250) $hTreeview = GUICtrlGetHandle($idTree) _GUICtrlTreeView_SetBkColor($hTreeview, 0x003463) _GUICtrlTreeView_SetTextColor($hTreeview, 0xE0E0E0) _GUICtrlTreeView_SetLineColor($hTreeview, 0xBACEFF) For $i = 1 To 20 $hwndItem = _GUICtrlTreeView_Add($hTreeview, 0, 'Item ' & Random(1,20,1)) If StringInStr(' 2 5 7 12 13 18 ', ' ' & String($i) & ' ') Then For $j = 1 To 4 _GUICtrlTreeView_AddChild($hTreeview, $hwndItem, 'Item ' & Random(1,4,1)) Next EndIf Next $idIn = GUICtrlCreateInput('Item ' & Random(1,10,1), 210, 40, 90, 20) $btSearch = GUICtrlCreateButton('Suche', 210, 10, 90, 20) GUISetState() GuiRegisterMsg($WM_NOTIFY, 'WM_NOTIFY') Global $aLastMatch[1] = [0] Global $__TVITEMFOUND = 2000 ; Wert für ItemParam um Item als gefunden zu markieren _GUICtrlTreeView_Expand($hTreeview) _GUICtrlTreeView_EnsureVisible($hTreeview, 0) While 1 Switch GUIGetMsg() Case -3 Exit Case $btSearch Local $aItem = _GUICtrlTreeView_FindItemAll($hTreeview, GUICtrlRead($idIn), 2) ; für gefundene Item ItemParam setzen If Not @error Then _GUICtrlTreeView_SetItemParamEx($hTreeview, $aItem, $__TVITEMFOUND) ; für Item aus vorigem Suchergebnis ItemParam zurücksetzen _GUICtrlTreeView_ResetItemParam($hTreeview, $aLastMatch) _WinAPI_RedrawWindow($hTreeview) $aLastMatch = $aItem EndSwitch WEnd ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GUICtrlTreeView_FindItemAll ; Description ...: Searches all Item none-/sensitive and/or by full/partial string ; Syntax ........: _GUICtrlTreeView_FindItemAll($hWnd, $sSearch[, $iFlag = 0]) ; Parameters ....: $hWnd - The Treeview handle. ; $sSearch - The search string. ; $iFlag - [optional] Default is 0 (none sensitiv, full string). Combine with BitOr: 1=sensitive, 2=partial string ; Return values .: Success Array with the found item. Count of matches on $array[0] ; Failure No item found. set @error=1, $array[1]=0 ; Author ........: BugFix ; =============================================================================================================================== Func _GUICtrlTreeView_FindItemAll($hWnd, $sSearch, $iFlag=0) If $iFlag = -1 Or $iFlag = Default Then $iFlag = 0 Local $bSense = (BitAND($iFlag, 1) = 1), $bPart = (BitAND($iFlag, 2) = 2) Local $aMatch[1] = [0], $sText, $iErr = 0, $bMatch Local $hItem = _GUICtrlTreeView_GetFirstItem($hWnd) While $hItem <> 0 $sText = _GUICtrlTreeView_GetText($hWnd, $hItem) $bMatch = False If $bPart Then ; partial If StringInStr($sText, $sSearch, BitAND($iFlag, 1)) Then $bMatch = True Else ; full text If $bSense Then $bMatch = ($sText == $sSearch) Else $bMatch = ($sText = $sSearch) EndIf EndIf If $bMatch Then $aMatch[0] += 1 ReDim $aMatch[$aMatch[0]+1] $aMatch[$aMatch[0]] = $hItem EndIf $hItem = _GUICtrlTreeView_GetNext($hWnd, $hItem) WEnd If $aMatch[0] = 0 Then $iErr = 1 Return SetError($iErr,0,$aMatch) EndFunc ;==>_GUICtrlTreeView_FindItemAll Func _GUICtrlTreeView_SetItemParamEx($hWnd, ByRef $aItem, $iParam=2000) For $i = 1 To $aItem[0] _GUICtrlTreeView_SetItemParam($hWnd, $aItem[$i], $iParam) Next _GUICtrlTreeView_EnsureVisible($hWnd, $aItem[1]) EndFunc ;==>_GUICtrlTreeView_SetItemParamEx Func _GUICtrlTreeView_ResetItemParam($hWnd, ByRef $aItem) If $aItem[0] <> 0 Then For $i = 1 To $aItem[0] _GUICtrlTreeView_SetItemParam($hWnd, $aItem[$i], 0) Next EndIf EndFunc ;==>_GUICtrlTreeView_ResetItemParam Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndTreeview = $hTreeview $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hWndTreeview Switch $iCode Case $NM_CUSTOMDRAW Local $iDrawStage, $iItem, $tItemSpec, $iParam, $hDC, $hFont, $tCustDraw = DllStructCreate($tagNMTVCUSTOMDRAW, $lParam) $iDrawStage = DllStructGetData($tCustDraw, 'DrawStage') Local $aDefFont[14] = [15,0,0,0,$FW_NORMAL,False,False,False, _ $DEFAULT_CHARSET,$OUT_DEFAULT_PRECIS,$CLIP_DEFAULT_PRECIS,$DEFAULT_QUALITY,0,'Arial'] If $iDrawStage = $CDDS_ITEMPREPAINT Then $tItemSpec = DllStructCreate('dword', DllStructGetPtr($tCustDraw, 'ItemSpec')) $iItem = DllStructGetData($tItemSpec, 1) $iParam = _GUICtrlTreeView_GetItemParam($hWndTreeview, $iItem) If $iParam = $__TVITEMFOUND Then DllStructSetData($tCustDraw, 'ClrText', 0x9090FF) ; BGR DllStructSetData($tCustDraw, 'ClrTextBk', 0x633400) $hDC = DllStructGetData($tCustDraw, 'HDC') $hFont = _WinAPI_CreateFont($aDefFont[0],$aDefFont[1],$aDefFont[2],$aDefFont[3],$aDefFont[4],$aDefFont[5],$aDefFont[6], _ $aDefFont[7],$aDefFont[8],$aDefFont[9],$aDefFont[10],$aDefFont[11],$aDefFont[12],$aDefFont[13]) _WinAPI_SelectObject($hDC, $hFont) Return $CDRF_NEWFONT EndIf EndIf EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY -
Hallo Peter,
als ich den Thread eröffnete, wußte ich nicht: bei 2 Usern ist die Anmeldung normal möglich. Ein User mit Rechten "Benutzer" und einer mit Rechten "Admin" (der Chef
). Und diese User waren auch jeden Tag aktiv.
An den Rechten kann niemand rumspielen, anmelden am Server könnte sich ausser mir nur mein Chef und der läßt von allem die Finger.
Anmeldeskripte gibt es nicht, auf dem Server läuft die Warenwirtschaftssoftware und diese ist verlinkt auf jeden User-PC. User startet also nur den Link und muß sich dabei mit Usernamen und Pw identifizieren um auf den Server zu verbinden.
Auch die anderen Punkte treffen nicht zu.
Da ich nicht lange genug vor Ort bleiben konnte, läuft das System im Moment auf diesem Status. Ist nicht sehr dramatisch, da die Warenwirtschaft mit eigenem Rechtemanagement arbeitet. Beim nächsten mal werde ich dann testen, wie es mit neu angelegten Usern funktioniert. Könnte ich eigentlich einen gelöschten User mit demselben Namen wieder erstellen? Windows gab beim Löschen eines Users eine Meldung aus, dass man den User nicht wiederherstellen kann, da er über eine eindeutige Kennung identifiziert ist. Heißt das, ein bestehender User X an User-PC wird dann vom Server als gelöschter User X interpretiert, selbst wenn dieser erneut am Server angelegt wurde? -
Virus ist ausgeschlossen. Das ist ein Intranet, keinerlei Verbindung ins böse Web. Externe Datenträger werden auch nicht angeschlossen.
-
Hi,
seltsames Phänomen. In unserem Netzwerk (Arbeitsgruppen-Netzwerk mit Win2000-Server) können sich die User plötzlich nicht mehr anmelden. Der Server antwortet: Falsches Passwort.
Ich habe in der Userverwaltung die Pw neu gesetzt - unverändert. Per Zufall haben wir einen Workaround zum Anmelden gefunden:
- anmelden als:
Username: ein beliebiges Zeichen
Pw: leer lassenIst natürlich kein Dauerzustand, da alle Rechtevergaben nun in der Luft hängen.
Bevor ich irgendetwas anderes teste (meine Überlegung war die User kpl. zu löschen und neu anzulegen) wollte ich mal fragen, ob ihr sowas schon erlebt habt und die Ursache kennt. Und dran denken - es ist kein Domänennetzwerk. -
Danke, aber hooken wollte ich hierbei eigentlich nicht. Wäre nur die allerletzte Wahl.
Meines Erachtens muß es doch eine Notifikation geben, wenn die Checkbox per Leertaste un/checked wird. Leider habe ich in keiner der Strukturen und Messages bisher etwas passendes gefunden.Ich hoffe mal, jemand hat noch eine Idee.
-
In einem Treeview lassen sich die Checkboxen mit Mausklick oder durch Drücken der Leertaste un/checken. Ich möchte nun die Leertasten-Funktion verhindern.
Mein Gedanke war:
- TVN_KEYDOWN abfragen
- Prüfen ob Leertaste das Event ausgelöst hat - wenn ja: "Return 1" um Normalverhalten zu unterbinden.Aber leider reagiert die Checkbox trotzdem. Also ist das Event TVN_KEYDOWN wohl ungeeignet, da die Markierung der Checkbox scheinbar stattfindet ehe dieses Event ausgelöst wird.
Nun habe ich im Moment keine Idee, wie ich die Leertaste verhindern kann...AutoIt
Alles anzeigen#include <TreeViewConstants.au3> #include <StructureConstants.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> Global $hTreeview _Test() Func _Test() GUICreate('Test', 210, 210) Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES) Local $idTreeview = GUICtrlCreateTreeView(15, 15, 180, 180, $iStyle, $WS_EX_CLIENTEDGE) $hTreeview = GUICtrlGetHandle(-1) For $i = 0 To 9 GUICtrlCreateTreeViewItem('Item ' & $i, $idTreeview) Next GuiRegisterMsg($WM_NOTIFY, '_WM_NOTIFY') GUISetState() Do Until GUIGetMsg() = -3 EndFunc Func _WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $hWndFrom, $tNMHDR, $iCode $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hTreeview Switch $iCode Case $TVN_KEYDOWN Local $tagTVKEYDOWN = $tagNMHDR & ';WORD wVKey;UINT flags' Local $tTVKEYDOWN = DllStructCreate($tagTVKEYDOWN, $lParam) Local $vKey = DllStructGetData($tTVKEYDOWN, 'wVKey') ConsoleWrite("@@ Debug line" & @TAB & @ScriptLineNumber & " var: $vKey --> " & $vKey & @LF) If $vKey = 32 Then Return 1 ; Leertaste >> kein Normalverhalten gewünscht (Checkbox soll nicht reagieren) Case $TVN_SELCHANGEDA, $TVN_SELCHANGEDW Local $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $lParam) Switch DllStructGetData($tNMTREEVIEW, 'Action') Case $TVC_BYKEYBOARD ConsoleWrite('TVC_BYKEYBOARD' & @CRLF) Case $TVC_BYMOUSE ConsoleWrite('TVC_BYMOUSE' & @CRLF) Case $TVC_UNKNOWN ConsoleWrite('TVC_UNKNOWN' & @CRLF) EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc -
wenn ich für jeden einzlnen button jetzt eine GuiStartGroup erstelle, dann kann ich jeden einzelnen Checken, aber nicht wieder Unchecken.
Da hast du die falschen Controls gewählt. Für Un/Check mit mehreren Ctrl gleichzeitig verwende GUICtrlCreateCheckbox. Einfach ersetzen statt der Radios, alle Parameter kannst du lassen.
-
Ich habe auch mal mit diskpart rumgegurgt. Aber, wie du richtig sagtest, kann man sehr schnell sehr viel falsch machen.
Ich habe dann mit verschiedenen Tools rumprobiert und mir persönlich gefällt Rufus recht gut. Klein und schnell, lädt ISO auf den Stick und macht ihn bootbar.
Für MultiBoot verwende ich RMPrepUSB. -
Ich habe freundlich gefragt und wünsche mir Freundlichkeit. Respektlosigkeit einem Anfänger gegenüber, ist mehr als unangebracht.
@Anagastes
Lies dir bitte noch mal genau Andy's Post durch und versuche dann Unfreundlichkeit oder Respektlosigkeit darin zu finden - es wird dir nicht gelingen.
Andy hat (eher völlig emotionslos) gefragt, warum du noch keine Fehlerbehandlung gemacht hast. Und das ist etwas, was wir eigentlich von jedem erwarten.
Findest du es unfreundlich und respektlos, wenn auf deine Fehler hingewiesen wird? Ich bin dankbar, wenn mir Fehler aufgezeigt werden, nur so kann man etwas lernen.
Vielleicht bist du nur etwas dünnhäutig? -
Kann man 3state für Checkboxen in Treeviews verwenden?
Ich würde sagen ja, wenn ich die möglichen Flags und Parameter der TV-Strukturen betrachte.
Werde das bei Gelegenheit mal näher anschauen.Edit:
Ja, es geht so:Zitat von MSDNA state image is displayed next to an item's icon to indicate an application-defined state. Specify the state image list by sending a TVM_SETIMAGELISTmessage. To set an item's state image, include the TVIS_STATEIMAGEMASK value in the stateMask member of the TVITEM structure. Bits 12 through 15 of the structure's state member specify the index in the state image list of the image to be drawn.
-
$sFilePath = $Combo
Falsch, so erhältst du nur die ID der Combo.
Du mußt zur Laufzeit den aktuellen Wert der Combo lesen: GuiCtrlRead($Combo) -
Habe die Lösung gefunden mit Hittest.
Spoiler anzeigen
AutoIt
Alles anzeigen#include <File.au3> #include <FileConstants.au3> #include <GUIConstantsEx.au3> #include <GuiTreeView.au3> #include <StructureConstants.au3> #include <TreeViewConstants.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> ; TEST-SEITE ; !!! Bitte einen existierenden Pfad zum Erstellen des Treeview angeben ; !!! NICHT C:\ nehmen - sonst crasht es wegen Überschreiten der Rekursionstiefe ;) Global $sPathRoot = 'C:\Code_Python' Global $aAllItem[1][4] = [[0]] Global $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES) Global $iStyleEx = BitOR($WS_EX_COMPOSITED, $WS_EX_CLIENTEDGE) $hGui = GUICreate('Test TV - Folderstruct') Global $cTreeview = GUICtrlCreateTreeView(20, 20, 300, 320, $iStyle, $iStyleEx) Global $hTreeview = GUICtrlGetHandle($cTreeview) _GUICtrlTreeView_SetBkColor($hTreeview, 0x003463) _GUICtrlTreeView_SetTextColor($hTreeview, 0xE0E0E0) _GUICtrlTreeView_SetLineColor($hTreeview, 0xBACEFF) GUISetState() GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") _GUICtrlTreeView_BeginUpdate($hTreeview) _FillTreeviewFromFolder($hTreeview, 0, $sPathRoot, $sPathRoot, True) _GUICtrlTreeView_EndUpdate($hTreeview) _GUICtrlTreeView_Expand($hTreeview) Do Until GUIGetMsg() = -3 Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndTreeview = $hTreeview, $fCheck, $hParent, $aItem, $iItem, $iHittest $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hWndTreeview Switch $iCode Case $NM_CLICK $aItem = _GUICtrlTreeView_GetItemClicked($hGui, $hWndTreeview, True) If @error Then Return $GUI_RUNDEFMSG $iItem = $aItem[0] $iHittest = $aItem[1] Switch $iHittest Case 4 ; Text - normales Verhalten unterbinden (kein Edit etc.) ConsoleWrite("!> TEXT CLICKED: " & _GUICtrlTreeView_GetText($hWndTreeview, $iItem) & @LF) Return 1 Case 16 ; Node - normales Verhalten ConsoleWrite("!> NODE CLICKED: " & _GUICtrlTreeView_GetText($hWndTreeview, $iItem) & @LF) Return $GUI_RUNDEFMSG Case 64 ; Checkbox - SubItem klicken ConsoleWrite("!> CHECKBOX CLICKED: " & _GUICtrlTreeView_GetText($hWndTreeview, $iItem) & @LF) $fCheck = Not _GUICtrlTreeView_GetChecked($hWndTreeview, $iItem) _CheckItemRec($hWndTreeview, $iItem, $fCheck) _GUICtrlTreeView_SetChecked($hWndTreeview, $iItem, $fCheck) ; wenn TRUE - sicher stellen, dass Parents auch gecheckt werden If $fCheck Then $hParent = _GUICtrlTreeView_GetParentHandle($hWndTreeview, $iItem) If $hParent Then Do _GUICtrlTreeView_SetChecked($hWndTreeview, $hParent, True) $hParent = _GUICtrlTreeView_GetParentHandle($hWndTreeview, $hParent) Until $hParent = 0 EndIf EndIf Return 1 ; nonzero to not allow the default processing EndSwitch Case $TVN_BEGINDRAGA, $TVN_BEGINDRAGW, $TVN_BEGINLABELEDITA, $TVN_BEGINLABELEDITW, $TVN_BEGINRDRAGA, $TVN_BEGINRDRAGW, _ $TVN_DELETEITEMA, $TVN_DELETEITEMW, $TVN_ENDLABELEDITA, $TVN_ENDLABELEDITW Return 1 EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY ; Treeview befüllen mit der Ordnerstruktur eines übergebenen Pfades Func _FillTreeviewFromFolder($hwnd, $hParent, $sPathParent, $sPathChild, $fCheckall=False) Local $aDir = _GetFolder($sPathChild), $hItem If $aDir[0] > 0 Then For $i = 1 To $aDir[0] $aAllItem[0][0] += 1 ReDim $aAllItem[$aAllItem[0][0]+1][4] $hItem = _GUICtrlTreeView_AddChild($hwnd, $hParent, _StripPath($aDir[$i])) If $fCheckall Then _GUICtrlTreeView_SetChecked($hwnd, $hItem) $aAllItem[$aAllItem[0][0]][0] = $hParent $aAllItem[$aAllItem[0][0]][1] = $hItem $aAllItem[$aAllItem[0][0]][2] = $sPathParent $aAllItem[$aAllItem[0][0]][3] = $aDir[$i] _FillTreeviewFromFolder($hwnd, $hItem, $aDir[$i], $aDir[$i], $fCheckall) Next EndIf EndFunc ; Rückgabe Array mit allen Pfaden der Ordner eines Verzeichnisses (nicht rekursiv) Func _GetFolder($sPath) Local $aFolder = _FileListToArrayRec($sPath, "*", $FLTAR_FOLDERS, $FLTAR_NORECUR, $FLTAR_SORT, $FLTAR_FULLPATH) If @error Then Local $aFolder[1] = [0] Return $aFolder EndFunc ; Rückgabe Ordnername oder Pfad ohne Ordnername Func _StripPath($sFullPath, $retPath=0) Local $i = StringInStr($sFullPath, '\', 0, -1) If $retPath = 1 Then Return StringLeft($sFullPath, $i-1) Return StringTrimLeft($sFullPath, $i) EndFunc ; Check eines Item und aller seiner Subitem, rekursiv Func _CheckItemRec($hwnd, $hItem, $fCheck=True) Local Static $fNext = False ; Item selbst un/checken If $fNext Then _GUICtrlTreeView_SetChecked($hwnd, $hItem, $fCheck) Else $fNext = True EndIf ; alle Childs und deren Childs ermitteln Local $aChild = _GuiCtrlTreeView_GetChildArray($hwnd, $hItem) If $aChild[0] > 0 Then For $i = 1 To $aChild[0] _CheckItemRec($hwnd, $aChild[$i], $fCheck) Next EndIf EndFunc ; Rückgabe Array mit allen Child-Item(Handle) eines Item Func _GuiCtrlTreeView_GetChildArray($hwnd, $hParent) Local $iChild = _GUICtrlTreeView_GetChildCount($hwnd, $hParent) Local $aChild[1] = [0], $hItem If $iChild = -1 Then Return $aChild $hItem = _GUICtrlTreeView_GetFirstChild($hwnd, $hParent) _ArrayAdd($aChild, $hItem) $aChild[0] += 1 $hItem = _GUICtrlTreeView_GetNextSibling($hwnd, $hItem) While $hItem <> 0 _ArrayAdd($aChild, $hItem) $aChild[0] += 1 $hItem = _GUICtrlTreeView_GetNextSibling($hwnd, $hItem) WEnd Return $aChild EndFunc ; Rückgabe Handle des geklickten Item (-1 wenn unter letztem Item geklickt) Func _GUICtrlTreeView_GetItemClicked($hGui, $hTreeview, $bRetArray=False) Local $tPOINT = _WinAPI_GetMousePos(True, $hGui) Local $aPos = ControlGetPos($hGui, "", $hTreeview) Local $iX = DllStructGetData($tPOINT, "X") - $aPos[0] Local $iY = DllStructGetData($tPOINT, "Y") - $aPos[1] Local $iHittest = _GUICtrlTreeView_HitTest($hTreeview, $iX, $iY) Local $hItem = _GUICtrlTreeView_HitTestItem($hTreeview, $iX, $iY) If $iHittest = 1 Then Return SetError(1, 0, -1) If $bRetArray Then Local $aRet[2] = [$hItem, $iHittest] Return $aRet EndIf Return $hItem EndFunc
UEZ: Das Problem war zu erkennen ob Node geklickt wird (dann soll natürlich NUR ein/ausgeklappt werden) oder ob Checkbox geklickt wird (NUR DANN soll auch rekursiv un/checked werden) oder Text.
Dank der Funktion _GUICtrlTreeView_HitTest habe ich jetzt alle erforderlichen Infos dafür.Trotzdem Danke fürs Mitdenken.
-
Das Thema klingt banal, ist programmtechnisch auch banal. Aber das Problem kommt beim Klick.
Im Normalfall wird beim Klick auf eine Checkbox nur diese un/checked. Im Treeview ist es natürlich sinnvoll dann auch alle untergeordneten Item zu un/checken.
Es gibt jedoch keine Möglichkeit abzufragen, ob auf die Checkbox geklickt wurde, weil das Event CLICK dem Event CHECK vorausgeht. Über die HitItem Funktion kann ich das Item welches geklickt wurde, ermitteln. Wenn ich die Funktion zweimal aufrufe mit unterschiedlichen Parametern, weiß ich auch, ob ich nicht auf den Text geklickt habe.
Aber ich kann dann trotzdem nicht unterscheiden, ob ich die Checkbox oder (wenn vorhanden) die Node geklickt habe. Da ich die normale Verarbeitung der Messages im TV unterbinden muß, kann ich zwar mein un/checken ausführen, aber das passiert auch beim Klick auf Node und die Funktion des Node geht verloren.
Belasse ich die Standardverarbeitung der Message, funktioniert Node (wird auch gleich als Klick auf die Checkbox gewertet) aber kein Klick auf die Checkbox selbst.Hier mal als Bsp., gebt bei $sPathRoot einen Pfad ein, der zum Lesen einer Ordnerstruktur verwendet werden soll.
AutoIt
Alles anzeigen#include <File.au3> #include <FileConstants.au3> #include <GUIConstantsEx.au3> #include <GuiTreeView.au3> #include <StructureConstants.au3> #include <TreeViewConstants.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> ; TEST-SEITE ; !!! Bitte einen existierenden Pfad zum Erstellen des Treeview angeben ; !!! NICHT C:\ nehmen - sonst crasht es wegen Überschreiten der Rekursionstiefe ;) Global $sPathRoot = 'C:\Code_Python' Global $aAllItem[1][4] = [[0]] Global $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES) Global $iStyleEx = BitOR($WS_EX_COMPOSITED, $WS_EX_CLIENTEDGE) $hGui = GUICreate('Test TV - Folderstruct') Global $cTreeview = GUICtrlCreateTreeView(20, 20, 300, 320, $iStyle, $iStyleEx) Global $hTreeview = GUICtrlGetHandle($cTreeview) _GUICtrlTreeView_SetBkColor($hTreeview, 0x003463) _GUICtrlTreeView_SetTextColor($hTreeview, 0xE0E0E0) _GUICtrlTreeView_SetLineColor($hTreeview, 0xBACEFF) GUISetState() GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") _GUICtrlTreeView_BeginUpdate($hTreeview) _FillTreeviewFromFolder($hTreeview, 0, $sPathRoot, $sPathRoot, True) _GUICtrlTreeView_EndUpdate($hTreeview) _GUICtrlTreeView_Expand($hTreeview) Do Until GUIGetMsg() = -3 Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndTreeview = $hTreeview, $fCheck, $hParent $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hWndTreeview Switch $iCode Case $NM_CLICK Local $iItem = _GUICtrlTreeView_GetItemClicked($hGui, $hWndTreeview) If @error Then Return $GUI_RUNDEFMSG ConsoleWrite("!> CLICKED: " & _GUICtrlTreeView_GetText($hWndTreeview, $iItem) & @LF) $fCheck = Not _GUICtrlTreeView_GetChecked($hWndTreeview, $iItem) _CheckItemRec($hWndTreeview, $iItem, $fCheck) _GUICtrlTreeView_SetChecked($hWndTreeview, $iItem, $fCheck) ;~ ; wenn TRUE - sicher stellen, dass Parents auch gecheckt werden If $fCheck Then $hParent = _GUICtrlTreeView_GetParentHandle($hWndTreeview, $iItem) If $hParent Then Do _GUICtrlTreeView_SetChecked($hWndTreeview, $hParent, True) $hParent = _GUICtrlTreeView_GetParentHandle($hWndTreeview, $hParent) Until $hParent = 0 EndIf EndIf ConsoleWrite('>> Un/Check ORDNER: ' & _GUICtrlTreeView_GetText($hWndTreeview, $iItem) & @CRLF) Return 1 ; nonzero to not allow the default processing ;~ Return $GUI_RUNDEFMSG Case $TVN_BEGINDRAGA, $TVN_BEGINDRAGW, $TVN_BEGINLABELEDITA, $TVN_BEGINLABELEDITW, $TVN_BEGINRDRAGA, $TVN_BEGINRDRAGW, _ $TVN_DELETEITEMA, $TVN_DELETEITEMW, $TVN_ENDLABELEDITA, $TVN_ENDLABELEDITW Return 1 EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY ; Treeview befüllen mit der Ordnerstruktur eines übergebenen Pfades Func _FillTreeviewFromFolder($hwnd, $hParent, $sPathParent, $sPathChild, $fCheckall=False) Local $aDir = _GetFolder($sPathChild), $hItem If $aDir[0] > 0 Then For $i = 1 To $aDir[0] $aAllItem[0][0] += 1 ReDim $aAllItem[$aAllItem[0][0]+1][4] $hItem = _GUICtrlTreeView_AddChild($hwnd, $hParent, _StripPath($aDir[$i])) If $fCheckall Then _GUICtrlTreeView_SetChecked($hwnd, $hItem) $aAllItem[$aAllItem[0][0]][0] = $hParent $aAllItem[$aAllItem[0][0]][1] = $hItem $aAllItem[$aAllItem[0][0]][2] = $sPathParent $aAllItem[$aAllItem[0][0]][3] = $aDir[$i] _FillTreeviewFromFolder($hwnd, $hItem, $aDir[$i], $aDir[$i], $fCheckall) Next EndIf EndFunc ; Rückgabe Array mit allen Pfaden der Ordner eines Verzeichnisses (nicht rekursiv) Func _GetFolder($sPath) Local $aFolder = _FileListToArrayRec($sPath, "*", $FLTAR_FOLDERS, $FLTAR_NORECUR, $FLTAR_SORT, $FLTAR_FULLPATH) If @error Then Local $aFolder[1] = [0] Return $aFolder EndFunc ; Rückgabe Ordnername oder Pfad ohne Ordnername Func _StripPath($sFullPath, $retPath=0) Local $i = StringInStr($sFullPath, '\', 0, -1) If $retPath = 1 Then Return StringLeft($sFullPath, $i-1) Return StringTrimLeft($sFullPath, $i) EndFunc ; Check eines Item und aller seiner Subitem, rekursiv Func _CheckItemRec($hwnd, $hItem, $fCheck=True) Local Static $fNext = False ; Item selbst un/checken If $fNext Then _GUICtrlTreeView_SetChecked($hwnd, $hItem, $fCheck) Else $fNext = True EndIf ; alle Childs und deren Childs ermitteln Local $aChild = _GuiCtrlTreeView_GetChildArray($hwnd, $hItem) If $aChild[0] > 0 Then For $i = 1 To $aChild[0] _CheckItemRec($hwnd, $aChild[$i], $fCheck) Next EndIf EndFunc ; Rückgabe Array mit allen Child-Item(Handle) eines Item Func _GuiCtrlTreeView_GetChildArray($hwnd, $hParent) Local $iChild = _GUICtrlTreeView_GetChildCount($hwnd, $hParent) Local $aChild[1] = [0], $hItem If $iChild = -1 Then Return $aChild $hItem = _GUICtrlTreeView_GetFirstChild($hwnd, $hParent) _ArrayAdd($aChild, $hItem) $aChild[0] += 1 $hItem = _GUICtrlTreeView_GetNextSibling($hwnd, $hItem) While $hItem <> 0 _ArrayAdd($aChild, $hItem) $aChild[0] += 1 $hItem = _GUICtrlTreeView_GetNextSibling($hwnd, $hItem) WEnd Return $aChild EndFunc ; Rückgabe Handle des geklickten Item (-1 wenn unter letztem Item geklickt) Func _GUICtrlTreeView_GetItemClicked($hGui, $hTreeview, $bTextOnly=False) Local $tPOINT = _WinAPI_GetMousePos(True, $hGui) Local $iX = DllStructGetData($tPOINT, "X") Local $iY = DllStructGetData($tPOINT, "Y") Local $aPos = ControlGetPos($hGui, "", $hTreeview) Local $hItem = _GUICtrlTreeView_HitTestItem($hTreeview, $iX - $aPos[0], $iY - $aPos[1]) ; Item-Rectangle abfragen, $hItem gibt 0 zurück bei Klick unter letztes Item. Wird von anderen Funkt. als Handle interpretiert ; aber DisplayRect gibt korrekterweise einen Fehler aus _GUICtrlTreeView_DisplayRect($hTreeview, $hItem, $bTextOnly) If Not @error Then Return $hItem Else Return SetError(1, 0, -1) EndIf EndFuncFalls ihr einen Workaround habt - nehme ich gern entgegen.
Edit:
Habe gerade gesehen, dass über Hittest noch brauchbare Infos kommen. Werde ich gleich mal umsetzen. Sieht vielversprechend aus. -
ist es möglich, mehrere Radio´s mit dem "for..to.."-befehl zu erstellen, wenn buchstaben UND zahlen in dem "namen" von dem radio enthalten sind ?
z.b. die ersten drei heißen: 1,2,3,a,b,cWenn die Namen keiner Logik folgen, was eine automatische Generierung ausschließt:
Du kannst entweder das $idRadios[7][3] von 3 auf 4 Spalten erweitern und in der 4.ten Spalte die Namen vorab eintragen um sie dann beim Erstellen zu nutzen.
Bevorzugen würde ich jedoch ein separates Array für die Namen, läßt sich schneller erstellen:AutoItLocal $sNamen = 'Name1,Name2,Name3,Name4,Name5,Name6,Name7' Local $aNamen = StringSplit($sNamen, ',', 2)Jetzt kannst du in deiner Schleife das $aNamen mit dem selben Index benutzen und daraus die Namen verwenden.
-
Ich hatte nach so etwas gesucht. Habe jetzt eine bessere Variante gefunden, die tatsächlich zur Zeit des Klicks das Item ermittelt. Was mir nicht gefällt, ist die Tatsache, dass jeder Klick in der Zeile des Item als Item-Klick gewertet wird. Also auch Klicks auf Ein/Ausklappsymbol und Chekcbox.
Aber sonst ganz brauchbar:
Edit:
Ich habe die Funktion jetzt erweitert.
Nun kann auch zurückgegeben werden, ob Klick auf Node, Checkbox oder Text (Ergebnis Hittest)AutoIt
Alles anzeigen; Rückgabe Handle des geklickten Item (-1 wenn unter letztem Item geklickt) ; oder Array mit Item-Handle und Hittest-Value Func _GUICtrlTreeView_GetItemClicked($hGui, $hTreeview, $bRetArray=False) Local $tPOINT = _WinAPI_GetMousePos(True, $hGui) Local $aPos = ControlGetPos($hGui, "", $hTreeview) Local $iX = DllStructGetData($tPOINT, "X") - $aPos[0] Local $iY = DllStructGetData($tPOINT, "Y") - $aPos[1] Local $iHittest = _GUICtrlTreeView_HitTest($hTreeview, $iX, $iY) Local $hItem = _GUICtrlTreeView_HitTestItem($hTreeview, $iX, $iY) If $iHittest = 1 Then Return SetError(1, 0, -1) If $bRetArray Then Local $aRet[2] = [$hItem, $iHittest] ; [Handle-Item, Value-Hittest] -> Values: https://www.autoitscript.com/autoit3/docs/libfunctions/_GUICtrlTreeView_HitTest.htm Return $aRet EndIf Return $hItem EndFunc -
[OT]
Ich habe gerade 30 Sekunden lang probiert, den Dreck auf dem Monitor wegzuwischen.
Da hatte ich zuviel Finger gleichzeitig auf der Tastatur - und schwupp-di-wupp war das Zirkumflex reingerutscht
[/OT]