Nikolas92 Posted December 28, 2016 Share Posted December 28, 2016 (edited) I am trying to make gui to automate saving selected files and folders from CD, but for some reason when CD is ejected, then button disappears from gui and treeview items dont get removed. I think that problem is with GuiRegisterMsg. Anyone can help me how to fix it? expandcollapse popup#NoTrayIcon #RequireAdmin #include <GUIConstants.au3> #include <GUIConstantsEx.au3> #include <TreeViewConstants.au3> #include <WindowsConstants.au3> #Include <GuiTreeView.au3> #Include <File.au3> #include <WinAPIFiles.au3> #include <WinAPI.au3> Opt("WinWaitDelay", 0) Opt("MouseClickDelay", 0) Opt("MouseClickDownDelay", 0) Opt("MouseClickDragDelay", 0) Opt("SendKeyDelay", 0) Opt("SendKeyDownDelay", 0) Opt("WinTitleMatchMode", 3) Opt('GUIOnEventMode', 1) Opt('GUICloseOnEsc' , 1) FileDelete (@ScriptDir & "\Unstoppable.ucb") Global $CheckBoxCount = 0 Global $CheckedItems = '' Global Const $DBT_DEVICEARRIVAL = 0x00008000 Global Const $DBT_DEVICECOMPLETEREMOVAL = 0x00008004 Global Const $DBT_DEVTYP_VOLUME = 0x00000002 Global $hGUI = GUICreate("Waiting for disc...", 530, 400, -1, -1) Global $hTreeView = _GUICtrlTreeView_Create($hGUI, 0, 0, 530, 370, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_CHECKBOXES)) Global $recover = GUICtrlCreateButton("Recover", 0, 370, 80, 30, $SS_Center) GUISetBkColor(0xCECECE) GUICtrlSetOnEvent($recover, '_Recover') GUISetOnEvent($GUI_EVENT_CLOSE, '_AllExit') $hImage = _GUIImageList_Create(16, 16, 5, 2) _GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 4) _GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 54) _GUICtrlTreeView_SetNormalImageList($hTreeView, $hImage) GUIRegisterMsg($WM_DEVICECHANGE, "DeviceChange") GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUISetState(@SW_SHOW, $hGUI) $Temp = DriveGetDrive("CDROM") If IsArray($Temp) Then For $j = 1 to $Temp[0] If DriveStatus($Temp[$j]) = 'READY' Then $hItem = _GUICtrlTreeView_AddChild($hTreeView, '', StringUpper($Temp[$j]), 0) _GUICtrlTreeView_SetChildren($hTreeView, $hItem, True) WinSetTitle($hGUI, WinGetTitle($hGUI), 'Select files and folders to recover:') EndIf Next EndIf While 1 Sleep(1000) WEnd Func _AllExit() GUIDelete($hGUI) Exit EndFunc Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hTreeView Switch $iCode Case $NM_CLICK $aPos = GUIGetCursorInfo($hGUI) $ObjectClicked = _GUICtrlTreeView_HitTest($hTreeView, $aPos[0], $aPos[1]) $cItem = _GUICtrlTreeView_HitTestItem($hTreeView, $aPos[0], $aPos[1]) If $ObjectClicked = '16' Then If _GUICtrlTreeView_GetExpanded($hTreeView, $cItem) = True Then ControlTreeView($hGUI, "", $hTreeView, "Collapse", $cItem) Else $sSelectedPath = StringReplace(_GUICtrlTreeView_GetTree($hTreeView, $cItem), "|", "\") If _GUICtrlTreeView_GetChildCount($hTreeView, $cItem) <= 0 Then _SearchFolder($cItem, $sSelectedPath) EndIf EndIf ElseIf $ObjectClicked = '64' Then If _GUICtrlTreeView_GetChecked($hTreeView, $cItem) = False Then ; checked $CheckBoxCount = $CheckBoxCount + 1 $sSelectedPath = StringReplace(_GUICtrlTreeView_GetTree($hTreeView, $cItem), "|", "\") If not StringInStr($sSelectedPath, '\') Then $sSelectedPath = $sSelectedPath & '\' $CheckedItems = $CheckedItems & $sSelectedPath & @CRLF Else ; unchecked $CheckBoxCount = $CheckBoxCount - 1 $sSelectedPath = StringReplace(_GUICtrlTreeView_GetTree($hTreeView, $cItem), "|", "\") If not StringInStr($sSelectedPath, '\') Then $sSelectedPath = $sSelectedPath & '\' $CheckedItems = StringReplace($CheckedItems, $sSelectedPath & @CRLF, '') EndIf EndIf Case $NM_DBLCLK $aPos = GUIGetCursorInfo($hGUI) $ObjectClicked = _GUICtrlTreeView_HitTest($hTreeView, $aPos[0], $aPos[1]) $cItem = _GUICtrlTreeView_HitTestItem($hTreeView, $aPos[0], $aPos[1]) If $ObjectClicked = '2' or $ObjectClicked = '4' Then If _GUICtrlTreeView_GetExpanded($hTreeView, $cItem) = True Then ControlTreeView($hGUI, "", $hTreeView, "Collapse", $cItem) Else $sSelectedPath = StringReplace(_GUICtrlTreeView_GetTree($hTreeView, $cItem), "|", "\") If _GUICtrlTreeView_GetChildCount($hTreeView, $cItem) <= 0 Then _SearchFolder($cItem, $sSelectedPath) EndIf EndIf EndIf Case $TVN_SELCHANGINGA, $TVN_SELCHANGINGW Return 1 Case $NM_SETFOCUS Return 1 EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc Func _SearchFolder($cParent, $sPath) $aFolderList = _FileListToArray($sPath, "*", $FLTA_FOLDERS) If IsArray($aFolderList) Then For $i = 1 To $aFolderList[0] $hItem = _GUICtrlTreeView_AddChild($hTreeView, $cParent, $aFolderList[$i], 0) _GUICtrlTreeView_SetChildren($hTreeView, $hItem, True) Next EndIf $aFileList = _FileListToArray($sPath, "*", $FLTA_FILES) If IsArray($aFileList) Then For $i = 1 To $aFileList[0] _GUICtrlTreeView_AddChild($hTreeView, $cParent, $aFileList[$i], 1, 1) Next EndIf If _GUICtrlTreeView_GetChildCount($hTreeView, $cParent) <= 0 Then _GUICtrlTreeView_SetChildren($hTreeView, $cParent, False) EndIf EndFunc Func DeviceChange($hWndGUI, $msg, $wParam, $lParam) Local $DriveLetter Local Const $DeviceType = GetDeviceType($lParam) If $DeviceType = $DBT_DEVTYP_VOLUME Then Local Const $UnitMask = GetUnitMask($lParam) $DriveLetter = GetDriveLetterFromUnitMask($UnitMask) & ":" EndIf Switch $wParam Case $DBT_DEVICECOMPLETEREMOVAL If DriveGetType($DriveLetter) = "CDROM" Then $hItem = _GUICtrlTreeView_FindItem($hTreeView, $DriveLetter) If $hItem <> '0' Then _GUICtrlTreeView_Delete($hTreeView, $hItem) $Temp = DriveGetDrive("CDROM") If IsArray($Temp) Then $ready = 'no' For $j = 1 to $Temp[0] If DriveStatus($Temp[$j]) = 'READY' Then $ready = 'yes' ExitLoop EndIf Next EndIf If $ready = 'yes' Then $RecoverList = StringSplit($CheckedItems, @LF) If IsArray($RecoverList) Then For $i = 1 to $RecoverList[0] - 1 If StringInStr($RecoverList[$i], $DriveLetter & '\') Then $CheckBoxCount = $CheckBoxCount - 1 $CheckedItems = StringReplace($CheckedItems, $RecoverList[$i] & @LF, '') EndIf Next EndIf Else $CheckBoxCount = 0 $CheckedItems = '' WinSetTitle($hGUI, WinGetTitle($hGUI), 'Waiting for disc...') EndIf EndIf Case $DBT_DEVICEARRIVAL If DriveGetType($DriveLetter) = "CDROM" Then $hItem = _GUICtrlTreeView_FindItem($hTreeView, $DriveLetter) If $hItem <> '0' Then _GUICtrlTreeView_Delete($hTreeView, $hItem) $hItem = _GUICtrlTreeView_AddChild($hTreeView, '', $DriveLetter, 0) _GUICtrlTreeView_SetChildren($hTreeView, $hItem, True) WinSetTitle($hGUI, WinGetTitle($hGUI), 'Select files and folders to recover:') EndIf EndSwitch Return EndFunc;==DeviceChange Func GetUnitMask($lParam) ; Create a struct from $lParam which contains a pointer to a Windows-created struct. Local Const $tagDEV_BROADCAST_VOLUME = "dword dbcv_size; dword dbcv_devicetype; dword dbcv_reserved; dword dbcv_unitmask; word dbcv_flags" Local Const $DEV_BROADCAST_VOLUME = DllStructCreate($tagDEV_BROADCAST_VOLUME, $lParam) Local Const $UnitMask = DllStructGetData($DEV_BROADCAST_VOLUME, "dbcv_unitmask") Return $UnitMask EndFunc ;==>GetUnitMask Func GetDeviceType($lParam) ; Create a struct from $lParam which contains a pointer to a Windows-created struct. Local Const $tagDEV_BROADCAST_VOLUME = "dword dbcv_size; dword dbcv_devicetype; dword dbcv_reserved; dword dbcv_unitmask; word dbcv_flags" Local Const $DEV_BROADCAST_VOLUME = DllStructCreate($tagDEV_BROADCAST_VOLUME, $lParam) Local Const $DeviceType = DllStructGetData($DEV_BROADCAST_VOLUME, "dbcv_devicetype") Return $DeviceType EndFunc ;==>GetDeviceType Func GetDriveLetterFromUnitMask($UnitMask) Local Const $Drives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" Local $Count = 0 Local $Pom = $UnitMask While $Pom <> 0 $Pom = BitShift($Pom, 1) $Count += 1 WEnd If $Count >= 1 And $Count <= 26 Then Return StringMid($Drives, $Count, 1) Else Return SetError(1, 0, '?') EndIf EndFunc ;==>GetDriveLetterFromUnitMask Func _Recover() Local $sRetFolder, $sRetFile, $path, $sDrive, $sDir, $sFolderName, $sExtension, $CDROM If $CheckBoxCount = '0' Then MsgBox(0, '', 'You have to check at least 1 file or folder before clicking Recover.') Return Else Local $ProgressGui = GUICreate('', 220, 39, (@DesktopWidth-220)/2-35, 0, $WS_CAPTION) Local $CurrentActivity = GUICtrlCreateLabel('', 3, 1, 213, 35, $SS_CENTER) GUICtrlSetFont($CurrentActivity, 11, 0, 0, "Verdana") GUISetState(@SW_HIDE, $hGUI) GUISetState(@SW_SHOW, $ProgressGui) GUICtrlSetData($CurrentActivity, "Recovering files and folders...") $sRetFile = '' $sRetFolder = '' $RecoverList = StringSplit($CheckedItems, @LF) _PathSplit(StringStripCR($RecoverList[1]), $sDrive, $sDir, $sFolderName, $sExtension) $CDROM = $sDrive For $i = 1 to $RecoverList[0] - 1 $path = StringStripCR($RecoverList[$i]) If StringInStr(FileGetAttrib($path), "D") = 0 Then ; File $sRetFile = $sRetFile & $path & '|' & @DesktopDir & '\Recovered' & @CRLF Else ; Folder _PathSplit($path, $sDrive, $sDir, $sFolderName, $sExtension) $sRetFolder = $sRetFolder & $path & '|' & @DesktopDir & '\Recovered\' & $sFolderName & $sExtension & @CRLF EndIf Next FileOpen(@ScriptDir & "\Unstoppable.ucb", $FO_UTF8 + $FO_APPEND) FileWrite(@ScriptDir & "\Unstoppable.ucb", @CRLF) FileWrite(@ScriptDir & "\Unstoppable.ucb", $sRetFolder) FileWrite(@ScriptDir & "\Unstoppable.ucb", $sRetFile) RegDelete('HKCU\Software\Roadkil') RegWrite('HKCU\Software\Roadkil', 'Lic_Unstp','REG_BINARY', Binary('0x31')) RegWrite('HKCU\Software\Roadkil', 'Settings_Unstp', 'REG_BINARY', Binary('0x0f27050000000000')) RunWait(@ScriptDir & '\UnstoppableCopier.exe' & ' +urateiwfz "' & @ScriptDir & '\Unstoppable.ucb' & '"') GUICtrlSetData($CurrentActivity, "Recovering finished. Ejecting disc...") FileDelete (@ScriptDir & "\Unstoppable.ucb") $hItem = _GUICtrlTreeView_FindItem($hTreeView, $CDROM) _GUICtrlTreeView_Delete($hTreeView, $hItem) WinSetTitle($hGUI, WinGetTitle($hGUI), 'Waiting for disc...') $CheckBoxCount = 0 $CheckedItems = '' $hVolume = _WinAPI_CreateFile('\\.\' & $CDROM, 2, 2, 6) _WinAPI_DeviceIoControl($hVolume, $FSCTL_DISMOUNT_VOLUME) _WinAPI_DeviceIoControl($hVolume, $IOCTL_STORAGE_EJECT_MEDIA) _WinAPI_CloseHandle($hVolume) GUISetState(@SW_HIDE, $ProgressGui) GUISetState(@SW_SHOW, $hGUI) GUIDelete($ProgressGui) Return EndIf EndFunc Edited December 29, 2016 by Nikolas92 Link to comment Share on other sites More sharing options...
Nikolas92 Posted December 28, 2016 Author Share Posted December 28, 2016 This is how error looks, it appears when I eject CD without checking anything or clicking on button. Link to comment Share on other sites More sharing options...
careca Posted December 29, 2016 Share Posted December 29, 2016 (edited) Well i dont have a cdrom so i had to test with DriveGetDrive("FIXED") but its really an external hd, and after i eject it, the only thing that happens is the tree no longer can go recursive/show more files or folders (for this Hdd but for the others works as normal) Button stays there anyway. As i couldn't reproduce the problem, im not going to be of much help. Edited December 29, 2016 by careca Spoiler Renamer - Rename files and folders, remove portions of text from the filename etc. GPO Tool - Export/Import Group policy settings. MirrorDir - Synchronize/Backup/Mirror Folders BeatsPlayer - Music player. Params Tool - Right click an exe to see it's parameters or execute them. String Trigger - Triggers pasting text or applications or internet links on specific strings. Inconspicuous - Hide files in plain sight, not fully encrypted. Regedit Control - Registry browsing history, quickly jump into any saved key. Time4Shutdown - Write the time for shutdown in minutes. Power Profiles Tool - Set a profile as active, delete, duplicate, export and import. Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes. NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s. IUIAutomation - Topic with framework and examples Au3Record.exe Link to comment Share on other sites More sharing options...
Nikolas92 Posted December 29, 2016 Author Share Posted December 29, 2016 when drive is ejected, then its tree should also be removed, but that doesnt happen for me in case when button disappears (then tree doesnt get removed) Link to comment Share on other sites More sharing options...
Nikolas92 Posted December 29, 2016 Author Share Posted December 29, 2016 Anyone have idea why randomly when $DBT_DEVICECOMPLETEREMOVAL is triggered function _GUICtrlTreeView_Delete($hTreeView, $hItem) fails and button gets deleted? Link to comment Share on other sites More sharing options...
Nikolas92 Posted December 30, 2016 Author Share Posted December 30, 2016 Problem "solved" by adding this under Case $DBT_DEVICECOMPLETEREMOVAL: If GUICtrlGetState($recover) = -1 Then ShellExecute(@ScriptFullPath) _AllExit() EndIf careca 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now