Dem Manne kann geholfen werden ![]()
ListView - SubItem einzeln färben/formatieren, Finale Version!
Dem Manne kann geholfen werden ![]()
ListView - SubItem einzeln färben/formatieren, Finale Version!
Wenn das Programm beim Installieren eine "uninstall.exe" angelegt hat, brauchst du diese nur mit AutoIt aufrufen.
Falls du willst, dass das angeklickte (oder per Tastatur angewählte) TabItem erst nach erfolgreicher Passwortabfrage gezeigt wird, muß man Maus- und Tastatur per Hook abfangen.
Ich habe auch mal dieses Bsp. erstellt:
#include <GuiConstantsEx.au3>
#include <GuiTab.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>
Global Const $HC_ACTION = 0
Global Const $WM_LBUTTONDOWN = 0x201
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 = 0
Global $Passwort = 'pass', $passItem = 2 ; <== Index des PW-geschützten TabItems
$Form1_1 = GUICreate("Testfenster", 297, 341, 210, 144)
$Programme = GUICtrlCreateTab(8, 8, 280, 304)
$hTab = GUICtrlGetHandle($Programme)
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_1, $hookID = $Programme
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]While 1
If $checkPass Then _CheckPass()
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Programme
Switch GUICtrlRead($Programme)
Case 0
;~ MsgBox(0, '', 'Tab1 aktiviert')
Case 1
;~ MsgBox(0, '', 'Tab2 aktiviert')
Case 2
;~ MsgBox(0, '', 'Tab3 aktiviert')
Case 3
;~ MsgBox(0, '', 'Tab4 aktiviert')
EndSwitch
EndSwitch
WEnd
Func _MouseProc($nCode, $wParam, $lParam)
If $nCode < 0 Or (Not _MouseOverTabItem($hookGUI, $hTab, $passItem)) Then
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndIf
If $nCode = $HC_ACTION And $wParam = $WM_LBUTTONDOWN Then
$checkPass = 1 ; Überprüfung aktivieren
Return -1 ; Mausklick wird ignoriert ==> TabItem noch nicht aktiviert
EndIf
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc
Func _CheckPass()
If InputBox('Passwort', 'Bitte Passwort eingeben:') == $Passwort Then
_GUICtrlTab_SetCurSel($hTab, $passItem)
Else
MsgBox(0, 'Fehler', 'Falsches Passwort!')
EndIf
$checkPass = 0
EndFunc
Func _MouseOverTabItem($GUI, $hWnd, $iTabItem)
If Not BitAND(WinGetState($GUI),
Then Return False
Local $old = Opt('MouseCoordMode', 2)
Local $posM = MouseGetPos()
Opt('MouseCoordMode', $old)
Local $posC = _GUICtrlTab_GetItemRect($hWnd, $iTabItem)
If ($posM[0] >= $posC[0] And $posM[0] <= $posC[2]) And _
($posM[1] >= $posC[1] And $posM[1] <= $posC[3]) Then
Return True
Else
Return False
EndIf
EndFunc
Func _KeyProc($nCode, $wParam, $lParam)
Local $tKEYHOOKS, $vkCode, $ret, $curPos, $curItem
$ret = DllCall("user32.dll","long","GetKeyState","long", 0x14)
If $ret[0] Then $isCapsLock = 1
$tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
$curPos = GUIGetCursorInfo($hookGUI) ; <== check, welche ID aktiv
If $nCode < 0 Or $curPos[4] <> $hookID 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 = 1
Return -1
EndIf
Case 0x27 ; ==> Pfeil re.
If GUICtrlRead($hookID) +1 = $passItem Then
$checkPass = 1
Return -1
EndIf
EndSwitch
EndIf
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc
Func OnAutoItExit()
_WinAPI_UnhookWindowsHookEx($hHook)
DllCallbackFree($hStub_MouseProc)
_WinAPI_UnhookWindowsHookEx($hHook2)
DllCallbackFree($hStub_KeyProc)
EndFunc ;==>OnAutoItExit
Edit: Hatte grad noch einen Fehler beim Positionsvergleich der Maus entdeckt - nun passt es. ![]()
Das geht so (statt MsgBox dann dein Code):
#include <GUIConstants.au3>
$Form1_1 = GUICreate("Testfenster", 297, 341, 210, 144)
$Programme = 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)
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Programme
Switch GUICtrlRead($Programme)
Case 0
MsgBox(0, '', 'Tab1 aktiviert')
Case 1
MsgBox(0, '', 'Tab2 aktiviert')
Case 2
MsgBox(0, '', 'Tab3 aktiviert')
Case 3
MsgBox(0, '', 'Tab4 aktiviert')
EndSwitch
EndSwitch
WEnd
Habt Ihr eventuell ein Beispiel?
Bsp. gibt es viele, da du aber noch in den Anfängen steckst, wird dir ein RegExp-Bsp. vermutlich nicht allzuviel bringen, da die Lösung sich immer exakt an der konkreten Aufgabenstellung orientiert.
Insofern ist es schon notwendig, zu sehen, wie der String aufgebaut ist und welche Daten du separieren möchtest.
Für Bsp. schau mal in die Hilfe zu StringRegExp.
Ich hab mal progandys Hinweis eingearbeitet. Das ergibt dann schonmal eine saubere Übersicht.
Da meine CFG sich deutlich von deiner unterscheidet, mußt du die weitere Bearbeitung individuell vornehmen. Meine Ansätze treffen bei dir nicht zu.
$path = 'C:\GDILine\BDE\idapi32.cfg'
$path = '..\BDE\idapi32.cfg'
$fh = FileOpen($path, 16)
$read = StringTrimLeft(FileRead($fh), 2)
FileClose($fh)
$text = ''
For $i = 1 to StringLen($read)-2 Step 2
$tmp = Dec(StringMid($read, $i, 2))
Switch $tmp
Case 0, 1
$tmp = 32 ; Leerzeichen
Case 2
ContinueLoop
Case 3
$tmp = 13 ; Zeilenumbruch
Case 4
$tmp = 61 ; =
EndSwitch
$text &= Chr($tmp)
Next
ConsoleWrite($text & @CRLF)
So sieht es z.B. bei mir aus:
.
DRIVERS
PARADOX
INIT
NET DIR = C:\
DATABASES
DBDEMOS
DB INFO
TYPE = STANDARD
PATH = C:\Program Files\Common Files\Borland Shared\Data
ENABLE BCD = FALSE
DEFAULT DRIVER = PARADOX
IBLocal
DB INFO
TYPE = INTRBASE
PATH =
DB OPEN
SERVER NAME = C:\Program Files\Common Files\Borland Shared\Data\employee.gdb
USER NAME = SYSDBA
OPEN MODE = READ/WRITE
SCHEMA CACHE SIZE = 8
LANGDRIVER =
SQLQRYMODE =
SQLPASSTHRU MODE = SHARED AUTOCOMMIT
SCHEMA CACHE TIME = -1
MAX ROWS = -1
BATCH COUNT = 200
ENABLE SCHEMA CACHE = FALSE
SCHEMA CACHE DIR =
ENABLE BCD = FALSE
BLOBS TO CACHE = 64
BLOB SIZE = 32
DefaultDD
DB INFO
TYPE = STANDARD
PATH = C:\Program Files\Common Files\Borland Shared\SampleDictionary
ENABLE BCD = FALSE
DEFAULT DRIVER = PARADOX
Microsoft Access-Datenbank
DB OPEN
DATABASE NAME =
USER NAME =
ODBC DSN = Microsoft Access-Datenbank
OPEN MODE = READ/WRITE
SCHEMA CACHE SIZE = 8
SQLQRYMODE =
LANGDRIVER =
SQLPASSTHRU MODE = SHARED AUTOCOMMIT
SCHEMA CACHE TIME = -1
MAX ROWS = -1
BATCH COUNT = 200
ENABLE SCHEMA CACHE = FALSE
SCHEMA CACHE DIR =
ENABLE BCD = FALSE
ROWSET SIZE = 20
BLOBS TO CACHE = 64
DB INFO
TYPE = Microsoft Access-Treiber (*.mdb)
PATH =
dBASE-Dateien
DB OPEN
DATABASE NAME =
USER NAME =
ODBC DSN = dBASE-Dateien
OPEN MODE = READ/WRITE
SCHEMA CACHE SIZE = 8
SQLQRYMODE =
LANGDRIVER =
SQLPASSTHRU MODE = SHARED AUTOCOMMIT
SCHEMA CACHE TIME = -1
MAX ROWS = -1
BATCH COUNT = 200
ENABLE SCHEMA CACHE = FALSE
SCHEMA CACHE DIR =
ENABLE BCD = FALSE
ROWSET SIZE = 20
BLOBS TO CACHE = 64
DB INFO
TYPE = Microsoft dBase-Treiber (*.dbf)
PATH =
Excel-Dateien
DB OPEN
DATABASE NAME =
USER NAME =
ODBC DSN = Excel-Dateien
OPEN MODE = READ/WRITE
SCHEMA CACHE SIZE = 8
SQLQRYMODE =
LANGDRIVER =
SQLPASSTHRU MODE = SHARED AUTOCOMMIT
SCHEMA CACHE TIME = -1
MAX ROWS = -1
BATCH COUNT = 200
ENABLE SCHEMA CACHE = FALSE
SCHEMA CACHE DIR =
ENABLE BCD = FALSE
ROWSET SIZE = 20
BLOBS TO CACHE = 64
DB INFO
TYPE = Microsoft Excel-Treiber (*.xls)
PATH =
LTDB
DB INFO
TYPE = STANDARD
PATH = C:\Programme\Sunrise\CPAP\Data
ENABLE BCD = FALSE
DEFAULT DRIVER = PARADOX
Alles anzeigen
Ich meine nicht jeder User guckt sich alle Zeilen bei einem Script an und führt das stattdessen sofort aus.
Aber in einer EXE kannst du sie nicht mal angucken. ![]()
ungetestet:
[autoit]Local $INIread = 'logs.ini'
Local $INIwrite = 'gefunden.ini'
Local $arINI = IniReadSection($INIread, 'nummer')
Local $arFile
For $i = 1 To UBound($arINI) -1
_FileReadToArray(@ScriptDir & '\' & $arINI[$i][1], $arFile)
If @error Then
ConsoleWrite('@error: ' & @error & @TAB & $arINI[$i][1] & @CRLF)
ContinueLoop
EndIf
For $j = 1 To UBound($arFile) -1
If StringInStr($arFile[$j], 'SUCHE') Then
IniWrite($INIwrite, 'found', $arINI[$i][0], $arINI[$i][0])
EndIf
Next
Next
Ja, die IDAPI32.CFG ist schon eklig.
Ich hab das mit den mir vorliegenden cfg's getestet. Bei denen waren zumindest logische Gruppierungen immer ab 'TYPE'.
Intern ist auch kein Konzept ersichtlich. Die (Nicht-Text-) Zeichen 01, 02, 03, 04 überspringe ich, da sonst eine Textausgabe nicht möglich wär. Das sind u.A. Markierungen für Start of Text / End of Text - aber ohne logisch erkennbare Zusammenhänge zu den einzelnen Aliases.
Wenn du bei dir konstante Längen zwischen den Elementen findest, kannst du diese zum Splitten verwenden. Eine andere Möglichkeit sehe ich nicht.
Ich habe um Splitten zu können die ersten 3 Leerzeichen im String gebraucht (Alias-3 Leerzeichen-Restinfo). Da aber auch größere Lücken im String sind, würde mit StringSplit an allen diesen Stellen gesplittet werden. Somit habe ich StringReplace genutzt, da ich dort festlegen kann, dass nur das erste Vorkommen eines Strings verwendet wird. Also habe ich 3 Leerzeichen durch 3 Sternchen ersetzt und dann an den Sternchen gesplittet. ![]()
Auch von mir ein Welcome. Wir können bald eine "Graue AutoIt-Fraktion" bilden. ![]()
Dann treten wir zur nächsten Wahl an. ![]()
GUICtrlSetState(controlID, state) ; state = $GUI_ENABLE / $GUI_DISABLE
[/autoit]Global $count = 0, $max = 20 ; $max ist die maximale Anzahl der Durchläufe (Aufrufe)
AdlibEnable('_msg', 1000) ; alle 1000 ms wird das Programm aufgerufen
HotKeySet('!e', '_ende') ; Hotkey zum vorzeitigen Beenden: ALT + e
While 1
Sleep(100)
WEnd
Func _msg()
$count += 1
ConsoleWrite('Message #' & $count & @CRLF)
If $count = $max Then
AdlibDisable()
Exit
EndIf
EndFunc
Func _ende()
ConsoleWrite("vorzeitig beendet" & @CRLF)
AdlibDisable()
Exit
EndFunc
Schau dir mal _IECreateEmbedded an.
Da wir im Talk sind, können wir das ja etwas breiter diskutieren. ![]()
Ich bin der Meinung, das Sicherheitsempfinden sollte bei jedem weit höher angesetzt werden. Ob ich jemandem vertraue ist doch völlig nebensächlich - es kann sein, dass z.B. gerade ein neuer Virus aktiv wurde, dessen Signatur nicht erkannt wurde. Ungewollt schickt ein User das (seiner Meinung nach saubere) Programm in die Welt. Und nur weil er Vertrauen genießt, verbreitet sich so der Virus dankend weiter.
Wenn schon fremde EXE, erst scannen und dann in der Sandbox starten.
..aber das bedeutet auch das auf jedem rechner auf dem meine exe funktionieren soll auch autoit installiert sein muss?
Nein, die Includes werden beim Kompilieren in dein Skript eingebunden und stehen dann in der EXE zur Verfügung.
Da fehlt das Include
#Include <Timers.au3>
Schau dir mal "OrganizeIncludes" von Xenobiologist an, damit kannst du die Includes automatisch organisieren.
Ist nicht so schwer:
[autoit]$maxIdle_min = 5 ; <== Minuten für Nixtun
$pid = Run("C:\meine.exe")
Do
Sleep(100)
Until _Timer_GetIdleTime() > $maxIdle_min*60*1000 ; da Rückgabe in ms: min * 60(s) * 1000 (ms)
ProcessClose ($pid)
Ich habe bestimmt 12 programme die ablaufen sollen in einem script dann?
Ja und? Das gehört sowieso in ein Array um es in einer Schleife abzuarbeiten (alles andere wäre ineffektiv).
Vor der Installation legst du einen Eintrag für dein Installprogramm in RunOnce an.
Das Programm muß mit Parameter gestartet werden (Index Installationsschritt), per default also 0 oder 1, je nachdem, wie du dein Array aufbaust.
Also schreibst du vor jedem Installationsschritt den aktuellen Startparameter (Indexwert des Arrays) in die Registry und nach erfolgreicher Installation löschst du ihn sofort wieder.
Inaktivität kannst du mit _Timer_GetIdleTime prüfen.
Das Programm am Besten mit Run starten, dann bekommst du die PID zurück und kannst damit das Programm auch Beenden (ProcessClose).