Что нового

переключение режима "read only" по комбинации клавиш

Alexey

Новичок
Сообщения
171
Репутация
0
Версия AutoIt: 3.3.0.0 (win xp pro sp 2 ru)

Описание:
при нажатии на Alt+F7 все файлы текущей папки лишаются атрибута "только чтение"
при нажатии на Alt+F8 все файлы текущей папки приобретают атрибут "только чтение"

Примечания:
нашёл в справке подходящую страницу, немного подстроил пример под себя:

Код:
;mark all files in current directory as read only
If Not FileSetAttrib("*.*", "+R") Then
    MsgBox(4096,"Error", "Problem setting attributes.")
EndIf


но символов +R недостаточно. правильным ли будет изменение на +R-R ?
чтобы работало, что нужно добавить/исправить ?
 

Nik_rus

Python The Snake.
Сообщения
214
Репутация
62
Я как понял, FileSetAttrib не сработает, если аттрибут R уже поставлен. Т.е. в принципе можно сделать в условии ветку Else и туда пихать код снятия аттрибута.
 
Автор
A

Alexey

Новичок
Сообщения
171
Репутация
0
примерно так ? :
Код:
$attrib = FileGetAttrib("*.*")
If @error Then
    MsgBox(4096,"Error", "Could not obtain  attributes")
    Exit
Else
    If StringInStr($attrib, "R") Then
    FileSetAttrib("*.*", "-R")
    EndIf
EndIf

не знаю, что указывать в кавычках в первой строке - путь-то всегда разный будет

впрочем, пока что даже предыдущий кусочек кода не работает - в том числе если все файлы без атрибута
(атрибут, кстати, проставляется в файлах, его не имевших, и лежащих в одной папке с запускаемым au3-файлом. но ведь это совсем не то)
 

Nik_rus

Python The Snake.
Сообщения
214
Репутация
62
Где-то на форуме я видел как доставать из работающего explorer'а рабочюю папку. Думаю решение именно там.
 
Автор
A

Alexey

Новичок
Сообщения
171
Репутация
0
как я понимаю, вот это имеется в виду:
Код:
; ==================================================================================================
; Func _GetWindowsExplorerPath($hWnd)
;
; Function to get the path currently being explored by a Windows Explorer window
;
; $hWnd = Handle to the Windows Explorer window
;
; Returns:
;   Success: String - Path being explored by this window
;   Failure: "" empty string, with @error set:
;      @error = 1 = This is not a valid explorer window
;      @error = 2 = DLL call error, use _WinAPI_GetLastError()
;
; Author: WideBoyDixon
; ==================================================================================================
Func _GetWindowsExplorerPath($hWnd)
    Local $pv, $pidl, $return = "", $ret, $hMem, $pid, $folderPath = DllStructCreate("char[260]"), $className
    Local $bPIDL = False
    Local Const $CWM_GETPATH = 0x400 + 12;

    ; Check the classname of the window first
    $className = DllCall("user32.dll", "int", "GetClassName", "hwnd", $hWnd, "str", "", "int", 4096)
    If @error Then Return SetError(2, 0, "")
    If ($className[2] <> "ExploreWClass" And $className[2] <> "CabinetWClass") Then Return SetError(1, 0, "")
    
    ; Retrieve the process ID for our process
    $pid = DllCall("kernel32.dll", "int", "GetCurrentProcessId")
    If @error Then Return SetError(2, 0, "")

    ; Send the CWM_GETPATH message to the window
    $hMem = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hWnd, "int", $CWM_GETPATH, "wparam", $pid[0], "lparam", 0) 
    If @error Then Return SetError(2, 0, "")
    If $hMem[0] = 0 Then Return SetError(1, 0, "")
    
    ; Lock the shared memory
    $pv = DllCall("shell32.dll", "ptr", "SHLockShared", "uint", $hMem[0], "uint", $pid[0])
    If @error Then Return SetError(2, 0, "")
    If $pv[0] Then
        $pidl = DllCall("shell32.dll", "ptr", "ILClone", "uint", $pv[0]) ; Clone the PIDL
        If @error Then Return SetError(2, 0, "")
        $bPIDL = True
        DllCall("shell32.dll", "int", "SHUnlockShared", "uint", $pv) ; Unlock the shared memory
    EndIf
    DllCall("shell32.dll", "int", "SHFreeShared", "uint", $hMem, "uint", $pid) ; Free the shared memory
    
    If $bPIDL Then
        ; Retrieve the path from the PIDL
        $ret = DllCall("shell32.dll", "int", "SHGetPathFromIDList", "ptr", $pidl[0], "ptr", DllStructGetPtr($folderPath))
        If (@error = 0) And ($ret[0] <> 0) Then $return = DllStructGetData($folderPath, 1) ; Retrieve the value
        DllCall("shell32.dll", "none", "ILFree", "ptr", $pidl[0]) ; Free up the PIDL that we cloned
        Return SetError(0, 0, $return) ; Success
    EndIf
    
    Return SetError(2, 0, "") ; Failed a WinAPI call
EndFunc

данный код я ужé пробовал добавлять, но безуспешно
 

dwerf

Использует ArchLinux
Сообщения
478
Репутация
218
Код:
HotKeySet('!{F7}', '_NotReadOnly') ;при нажатии Alt+F7 вызывается функция _NotReadOnly
HotKeySet('!{F8}', '_ReadOnly') ;при нажатии Alt+F8 вызывается функция _ReadOnly

While 1 ;Бесконечный цикл, висим в трее, ждём нажатия клавиш
	Sleep(25)
WEnd

Func _NotReadOnly()
	Local $hActiveWindow = WinGetHandle('[ACTIVE]') ;Получаем handle (идентификатор) активного окна
	Local $sPath = _GetWindowsExplorerPath($hActiveWindow) ;Получаем путь к открытой в этом окне папке (если окно не Explorer'а, а другой программы, получаем ошибку)
	If Not @error Then FileSetAttrib($sPath & '\*', '-R') ;Если при получении не было ошибок, устанавлеваем аттрибут для файлов лежащих по этому пути
EndFunc

Func _ReadOnly()
	Local $hActiveWindow = WinGetHandle('[ACTIVE]')
	Local $sPath = _GetWindowsExplorerPath($hActiveWindow)
	If Not @error Then FileSetAttrib($sPath & '\*', '+R')
EndFunc

; ==================================================================================================
; Func _GetWindowsExplorerPath($hWnd)
;
; Function to get the path currently being explored by a Windows Explorer window
;
; $hWnd = Handle to the Windows Explorer window
;
; Returns:
;   Success: String - Path being explored by this window
;   Failure: "" empty string, with @error set:
;      @error = 1 = This is not a valid explorer window
;      @error = 2 = DLL call error, use _WinAPI_GetLastError()
;
; Author: WideBoyDixon
; ==================================================================================================
Func _GetWindowsExplorerPath($hWnd)
    Local $pv, $pidl, $return = "", $ret, $hMem, $pid, $folderPath = DllStructCreate("char[260]"), $className
    Local $bPIDL = False
    Local Const $CWM_GETPATH = 0x400 + 12;

    ; Check the classname of the window first
    $className = DllCall("user32.dll", "int", "GetClassName", "hwnd", $hWnd, "str", "", "int", 4096)
    If @error Then Return SetError(2, 0, "")
    If ($className[2] <> "ExploreWClass" And $className[2] <> "CabinetWClass") Then Return SetError(1, 0, "")

    ; Retrieve the process ID for our process
    $pid = DllCall("kernel32.dll", "int", "GetCurrentProcessId")
    If @error Then Return SetError(2, 0, "")

    ; Send the CWM_GETPATH message to the window
    $hMem = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hWnd, "int", $CWM_GETPATH, "wparam", $pid[0], "lparam", 0)
    If @error Then Return SetError(2, 0, "")
    If $hMem[0] = 0 Then Return SetError(1, 0, "")

    ; Lock the shared memory
    $pv = DllCall("shell32.dll", "ptr", "SHLockShared", "uint", $hMem[0], "uint", $pid[0])
    If @error Then Return SetError(2, 0, "")
    If $pv[0] Then
        $pidl = DllCall("shell32.dll", "ptr", "ILClone", "uint", $pv[0]) ; Clone the PIDL
        If @error Then Return SetError(2, 0, "")
        $bPIDL = True
        DllCall("shell32.dll", "int", "SHUnlockShared", "uint", $pv) ; Unlock the shared memory
    EndIf
    DllCall("shell32.dll", "int", "SHFreeShared", "uint", $hMem, "uint", $pid) ; Free the shared memory

    If $bPIDL Then
        ; Retrieve the path from the PIDL
        $ret = DllCall("shell32.dll", "int", "SHGetPathFromIDList", "ptr", $pidl[0], "ptr", DllStructGetPtr($folderPath))
        If (@error = 0) And ($ret[0] <> 0) Then $return = DllStructGetData($folderPath, 1) ; Retrieve the value
        DllCall("shell32.dll", "none", "ILFree", "ptr", $pidl[0]) ; Free up the PIDL that we cloned
        Return SetError(0, 0, $return) ; Success
    EndIf

    Return SetError(2, 0, "") ; Failed a WinAPI call
EndFunc
 
Автор
A

Alexey

Новичок
Сообщения
171
Репутация
0
dwerf
работает, спасибо. решил только заменить alt+F7 и alt+F8 на win+9 и win+0, так как очень напрягает переход фокуса со списка файлов на главное меню окнá - и это при том, что в данном случае не только одна alt нажимается

хочу уточнить. что именно означает Sleep(25) ? чтó происходит каждую сороковую часть секунды ?

и ещё довольно общий вопрос. как вообще принято организовывать результаты таких вот тем, как эта ? допустим, у кого-то накапливается 3-4 подобных рабочих скрипта, но неужели exe-файлы из них всегда все обречены висеть в памяти ? а если таких скриптов 10-20 ? правильно ли предполагаю, что в итоге все эти небольшие скрипты как-то сводят в один большой, чтобы всегда загружен был только он один ?
спрашиваю интереса ради - у меня это всего второй exe (полученный из au3), который будет всегда загружен
 

dwerf

Использует ArchLinux
Сообщения
478
Репутация
218
Alexey [?]
хочу уточнить. что именно означает Sleep(25) ? чтó происходит каждую сороковую часть секунды ?
Ничего не происходит. Просто совсем пустой цикл сильно загружает процессор.

правильно ли предполагаю, что в итоге все эти небольшие скрипты как-то сводят в один большой, чтобы всегда загружен был только он один ?
Я бы свёл.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 471
Репутация
2 401
Alexey [?]
как вообще принято организовывать результаты таких вот тем, как эта ? допустим, у кого-то накапливается 3-4 подобных рабочих скрипта, но неужели exe-файлы из них всегда все обречены висеть в памяти ?
У меня подобных “удобняшек” тоже есть несколько (около 5-ти), я их соеденил в один скрипт, и назвал SystemHelper.exe :smile:
 
Верх