Leaderboard
Popular Content
Showing content with the highest reputation on 02/02/2019 in all areas
-
Display message box while in progress of copying
caramen and 2 others reacted to pixelsearch for a topic
Hi all Just to share with you the simplest way to copy a folder into another one, displaying Windows native progress bar at same time : #include <AutoItConstants.au3> #include <WinAPIShellEx.au3> SplashTextOn("", "Installation in progress...", _ 250, 50, -1, 220, $DLG_NOTITLE + $DLG_TEXTVCENTER) _WinAPI_ShellFileOperation("C:\From Folder\*.*", "C:\To Folder", _ $FO_COPY, $FOF_SIMPLEPROGRESS) SplashOff()3 points -
It turns out that I lacked basic understanding of how handles work... and that they are duplicated when passed through CreateProcess, so you need to close your own copies of the handles in order for the pipe to properly close when the program exits. I also discovered that inheritence is a bit more complicated, as both handles (each for an end of the pipe) are marked as inheritable by the CreatePipe function during creation... this causes problems yet again by passively duplicating the handles which were not even passed to CreateProcess, you can prevent this by using the SetHandleInformation function. Here is the working code: bool allium_start(struct TorInstance *instance, char *config, allium_pipe *output_pipes) { // Prepare startup info with appropriate information SecureZeroMemory(&instance->startup_info, sizeof instance->startup_info); instance->startup_info.dwFlags = STARTF_USESTDHANDLES; SECURITY_ATTRIBUTES pipe_secu_attribs = {sizeof(SECURITY_ATTRIBUTES), NULL, true}; HANDLE pipes[2]; if (output_pipes == NULL) { CreatePipe(&pipes[0], &pipes[1], &pipe_secu_attribs, 0); output_pipes = pipes; } SetHandleInformation(output_pipes[0], HANDLE_FLAG_INHERIT, 0); instance->startup_info.hStdOutput = output_pipes[1]; instance->startup_info.hStdError = output_pipes[1]; instance->stdout_pipe = output_pipes[0]; // Stored for internal reference // Create the process bool success = CreateProcessA( NULL, cmd, NULL, NULL, config ? true : false, 0, NULL, NULL, &instance->startup_info, SecureZeroMemory(&instance->process, sizeof instance->process) ); // Close the write end of our stdout handle CloseHandle(output_pipes[1]); // Return on failure if (!success) return false; } You can refer to the accepted answer in my StackOverflow question for more details, many thanks to Remy Lebeau and RbMm for answering my questions there.2 points
-
francesca515, Sending me an abusive PM wishing me harm is really not the way to go. Account banned. M232 points
-
As the WebDriver UDF - Help & Support thread has grown too big, I started a new one. The prior thread can be found here.1 point
-
If Windows is a 64 bit version the examples must be run as 64 bit code.1 point
-
Vector to yaw and pitch - Google Earth Pro - camera control
FrancescoDiMuro reacted to Xandy for a topic
I'm just happy I learned to pronounce 'quaternions'.1 point -
Display message box while in progress of copying
gahhon reacted to pixelsearch for a topic
@gahhon : as your concern is to control what may happen if the folders/files already exist, then the only 2 flags that should be important to you are $FOF_NOCONFIRMMKDIR and $FOF_NOCONFIRMATION What follows works fine for me, so I suggest you to test it just like I just did : * Create a folder named C:\Test on your drive, with a couple of subfolders in it, then add a few files in C:\Test and its subfolders. Change the properties of 2-3 files to "read-only" * Launch this basic script #1 : _WinAPI_ShellFileOperation("C:\Test\*.*", "C:\Test2", _ $FO_COPY, $FOF_SIMPLEPROGRESS) * A window will appear, telling you that "folder Test2 doesn't exist, do you want to create it ?" Answer No and the script ends. Now we know that script #1 warns us when a folder doesn't exist. Let's find a way for not being warned in this case : * Add the flag $FOF_NOCONFIRMMKDIR ("don't confirm the creation of directories/folders") and run this modified script #2 : _WinAPI_ShellFileOperation("C:\Test\*.*", "C:\Test2", _ $FO_COPY, BitOr($FOF_SIMPLEPROGRESS, $FOF_NOCONFIRMMKDIR)) * No warning appears, everything is created/copied, which means that $FOF_NOCONFIRMMKDIR did the job concerning the warning of folders creation. You have now a new folder C:\Test2 on your drive, fully filled. Keep it. * Now let's run again script #2 to see what happens when all folders/files already exist. A warning appears that "a file (book2.xls in my case) already exists. Do you want to overwrite it ?" And the 4 usual buttons are here : "Yes", "All", "No", "Cancel" Answer Cancel and the script ends. Now we know that script #2 warns us when a file already exists. Let's find a way for not being warned in this case : * Add the flag $FOF_NOCONFIRMATION and run this modified script #3 : _WinAPI_ShellFileOperation("C:\Test\*.*", "C:\Test2", _ $FO_COPY, BitOr($FOF_SIMPLEPROGRESS, $FOF_NOCONFIRMMKDIR, $FOF_NOCONFIRMATION)) * No warning appears, everything is overwritten, which means that $FOF_NOCONFIRMATION did the job concerning the warning of "files already existing" That's it, with these 2 flags you can control all possibilities. I notice that it's important to indicate C:\Test\*.* (and not C:\Test) if you don't want the whole directory C:\Test to be copied as a subfolder inside C:\Temp2 The exact meaning of the other flags ? The answer should probably be found at MSDN, but if you're fully satisfied with the precedent tests, I suggest you don't waste your time with them. As I'm curious, I just tested $FOF_NORECURSION, it doesn't copy what's inside of the subfolders (though it creates the empty subfolders) Have a great week-end1 point -
Well i finish. I did it. Here is the new UDF, You just have to edit 2 $var it's simple. Func _CopyDirWithProgress($sOriginalDir, $sDestDir) ;$sOriginalDir and $sDestDir are quite selfexplanatory... ;This func returns: ; -1 in case of critical error, bad original or destination dir ; 0 if everything went all right ; >0 is the number of file not copied and it makes a log file ; if in the log appear as error message '0 file copied' it is a bug of some windows' copy command that does not redirect output... If StringRight($sOriginalDir, 1) <> '\' Then $sOriginalDir = $sOriginalDir & '\' If StringRight($sDestDir, 1) <> '\' Then $sDestDir = $sDestDir & '\' If $sOriginalDir = $sDestDir Then Return -1 ;ProgressOn('Copie en cours...', 'Liste les fichiers...' & @LF & @LF, '', -1, -1, 18) ;$ProgressOn ;$ProgressOnLabel1 Local $aFileList = _FileSearch($sOriginalDir) If $aFileList[0] = 0 Then ;ProgressOff() _Metro_SetProgress($Progress , 1 ) SetError(1) Return -1 EndIf If FileExists($sDestDir) Then If Not StringInStr(FileGetAttrib($sDestDir), 'd') Then ;ProgressOff() _Metro_SetProgress($Progress , 1 ) SetError(2) Return -1 EndIf Else DirCreate($sDestDir) If Not FileExists($sDestDir) Then ;ProgressOff() _Metro_SetProgress($Progress , 1 ) SetError(2) Return -1 EndIf EndIf Local $iDirSize, $iCopiedSize = 0, $fProgress = 0 Local $c, $FileName, $iOutPut = 0, $sLost = '', $sError Local $Sl = StringLen($sOriginalDir) _Quick_Sort($aFileList, 1, $aFileList[0]) $iDirSize = Int(DirGetSize($sOriginalDir) / 1024) ;ProgressSet(Int($fProgress * 100), $aFileList[$c], 'Copie des fichiers:') _Metro_SetProgress($ProgressOn , Int ($fProgress * 100) ) For $c = 1 To $aFileList[0] $FileName = StringTrimLeft($aFileList[$c], $Sl) _Metro_SetProgress($ProgressOn , Int ($fProgress * 100) ) GUICtrlSetData ( $ProgressOnLabel1 , "Copying: File "&$c&" / "&$aFileList[0]) If StringInStr(FileGetAttrib($aFileList[$c]), 'd') Then DirCreate($sDestDir & $FileName) Else If Not FileCopy($aFileList[$c], $sDestDir & $FileName, 1) Then If Not FileCopy($aFileList[$c], $sDestDir & $FileName, 1) Then;Tries a second time If RunWait(@ComSpec & ' /c copy /y "' & $aFileList[$c] & '" "' & $sDestDir & $FileName & '">' & @TempDir & '\o.tmp', '', @SW_HIDE)=1 Then;and a third time, but this time it takes the error message $sError = FileReadLine(@TempDir & '\o.tmp',1) $iOutPut = $iOutPut + 1 $sLost = $sLost & $aFileList[$c] & ' ' & $sError & @CRLF EndIf FileDelete(@TempDir & '\o.tmp') EndIf EndIf FileSetAttrib($sDestDir & $FileName, "+A-RSH");<- Comment this line if you do not want attribs reset. $iCopiedSize = $iCopiedSize + Int(FileGetSize($aFileList[$c]) / 1024) $fProgress = $iCopiedSize / $iDirSize EndIf Next ;ProgressOff() _Metro_SetProgress($Progress , 1 ) If $sLost <> '' Then;tries to write the log somewhere. If FileWrite($sDestDir & 'notcopied.txt',$sLost) = 0 Then If FileWrite($sOriginalDir & 'notcopied.txt',$sLost) = 0 Then FileWrite(@WorkingDir & '\notcopied.txt',$sLost) EndIf EndIf EndIf Return $iOutPut EndFunc ;==>_CopyDirWithProgress Func _FileSearch($sIstr, $bSF = 1) ; $bSF = 1 means looking in subfolders ; $sSF = 0 means looking only in the current folder. ; An array is returned with the full path of all files found. The pos [0] keeps the number of elements. Local $sCriteria, $sBuffer, $iH, $iH2, $sCS, $sCF, $sCF2, $sCP, $sFP, $sOutPut = '', $aNull[1] ;, $sIstr, $bSF $sCP = StringLeft($sIstr, StringInStr($sIstr, '\', 0, -1)) If $sCP = '' Then $sCP = @WorkingDir & '\' $sCriteria = StringTrimLeft($sIstr, StringInStr($sIstr, '\', 0, -1)) If $sCriteria = '' Then $sCriteria = '*.*' ;To begin we seek in the starting path. $sCS = FileFindFirstFile($sCP & $sCriteria) If $sCS <> - 1 Then Do $sCF = FileFindNextFile($sCS) If @error Then FileClose($sCS) ExitLoop EndIf If $sCF = '.' Or $sCF = '..' Then ContinueLoop $sOutPut = $sOutPut & $sCP & $sCF & @LF Until 0 EndIf ;And after, if needed, in the rest of the folders. If $bSF = 1 Then $sBuffer = @CR & $sCP & '*' & @LF;The buffer is set for keeping the given path plus a *. Do $sCS = StringTrimLeft(StringLeft($sBuffer, StringInStr($sBuffer, @LF, 0, 1) - 1), 1);current search. $sCP = StringLeft($sCS, StringInStr($sCS, '\', 0, -1));Current search path. $iH = FileFindFirstFile($sCS) If $iH <> - 1 Then Do $sCF = FileFindNextFile($iH) If @error Then FileClose($iH) ExitLoop EndIf If $sCF = '.' Or $sCF = '..' Then ContinueLoop If StringInStr(FileGetAttrib($sCP & $sCF), 'd') Then $sBuffer = @CR & $sCP & $sCF & '\*' & @LF & $sBuffer;Every folder found is added in the begin of buffer $sFP = $sCP & $sCF & '\'; for future searches $iH2 = FileFindFirstFile($sFP & $sCriteria); and checked with the criteria. If $iH2 <> - 1 Then Do $sCF2 = FileFindNextFile($iH2) If @error Then FileClose($iH2) ExitLoop EndIf If $sCF2 = '.' Or $sCF2 = '..' Then ContinueLoop $sOutPut = $sOutPut & $sFP & $sCF2 & @LF;Found items are put in the Output. Until 0 EndIf EndIf Until 0 EndIf $sBuffer = StringReplace($sBuffer, @CR & $sCS & @LF, '') Until $sBuffer = '' EndIf If $sOutPut = '' Then $aNull[0] = 0 Return $aNull Else Return StringSplit(StringTrimRight($sOutPut, 1), @LF) EndIf EndFunc ;==>_FileSearch Func _Quick_Sort(ByRef $SortArray, $First, $Last);Larry's code Dim $Low, $High Dim $Temp, $List_Separator $Low = $First $High = $Last $List_Separator = StringLen($SortArray[ ($First + $Last) / 2]) Do While (StringLen($SortArray[$Low]) < $List_Separator) $Low = $Low + 1 WEnd While (StringLen($SortArray[$High]) > $List_Separator) $High = $High - 1 WEnd If ($Low <= $High) Then $Temp = $SortArray[$Low] $SortArray[$Low] = $SortArray[$High] $SortArray[$High] = $Temp $Low = $Low + 1 $High = $High - 1 EndIf Until $Low > $High If ($First < $High) Then _Quick_Sort($SortArray, $First, $High) If ($Low < $Last) Then _Quick_Sort($SortArray, $Low, $Last) EndFunc ;==>_Quick_Sort Step 1: You copy past this into your script. Step 2: You make a MetroProgress named $ProgressOn Step 2.2 : Then You set it at 100% with _Metro_SetProgress($ProgressOn , 100 ) Step 3: You make a label named $ProgressOnLabel1 If you use the _CopyDirWithProgress($sOriginalDir, $sDestDir) it will update the progress bar named : $ProgressOn &the label named: $ProgressOnLabel1 Without file names. Only displaying : "Copying : */x" You can make them into custome external gui metro windows Pheww! You are pretty lucky i was working on somthing similar so i ll use it ============================================== If you want external windows : Name your Gui $hGui Or rename $hGUI this udf: Func _CopyDirWithProgress($sOriginalDir, $sDestDir) ;$sOriginalDir and $sDestDir are quite selfexplanatory... ;This func returns: ; -1 in case of critical error, bad original or destination dir ; 0 if everything went all right ; >0 is the number of file not copied and it makes a log file ; if in the log appear as error message '0 file copied' it is a bug of some windows' copy command that does not redirect output... $hGUI2 = _Metro_CreateGUI ( "ITMigra2", 200 , 200 , -1, -1, False , $hGUI ) $Control_Buttons2 = _Metro_AddControlButtons(True, False, True, False, True) ;CloseBtn = True, MaximizeBtn = True, MinimizeBtn = True, FullscreenBtn = True, MenuBtn = True $ProgressOn = _Metro_CreateProgress (25, 55 , 150, 30) $ProgressOnLabel1 = GUICtrlCreateLabel(" copy ? ",40, 95 , 120, 40) GUICtrlSetColor($ProgressOnLabel1, 0xFB1924) _Metro_SetProgress($ProgressOn , 100 ) GUISetState( @SW_HIDE , $hGUI2 ) If StringRight($sOriginalDir, 1) <> '\' Then $sOriginalDir = $sOriginalDir & '\' If StringRight($sDestDir, 1) <> '\' Then $sDestDir = $sDestDir & '\' If $sOriginalDir = $sDestDir Then Return -1 ;ProgressOn('Copie en cours...', 'Liste les fichiers...' & @LF & @LF, '', -1, -1, 18) ;$ProgressOn ;$ProgressOnLabel1 Local $aFileList = _FileSearch($sOriginalDir) If $aFileList[0] = 0 Then ;ProgressOff() _Metro_SetProgress($Progress , 1 ) SetError(1) Return -1 EndIf If FileExists($sDestDir) Then If Not StringInStr(FileGetAttrib($sDestDir), 'd') Then ;ProgressOff() _Metro_SetProgress($Progress , 1 ) SetError(2) Return -1 EndIf Else DirCreate($sDestDir) If Not FileExists($sDestDir) Then ;ProgressOff() _Metro_SetProgress($Progress , 1 ) SetError(2) Return -1 EndIf EndIf Local $iDirSize, $iCopiedSize = 0, $fProgress = 0 Local $c, $FileName, $iOutPut = 0, $sLost = '', $sError Local $Sl = StringLen($sOriginalDir) _Quick_Sort($aFileList, 1, $aFileList[0]) $iDirSize = Int(DirGetSize($sOriginalDir) / 1024) ProgressSet(Int($fProgress * 100), $aFileList[$c], 'Copie des fichiers:') For $c = 1 To $aFileList[0] $FileName = StringTrimLeft($aFileList[$c], $Sl) GUISetState( @SW_SHOW , $hGUI2 ) _Metro_SetProgress($ProgressOn , Int ($fProgress * 100) ) GUICtrlSetData ( $ProgressOnLabel1 , "Copying: File "&$c&" / "&$aFileList[0]) If StringInStr(FileGetAttrib($aFileList[$c]), 'd') Then DirCreate($sDestDir & $FileName) Else If Not FileCopy($aFileList[$c], $sDestDir & $FileName, 1) Then If Not FileCopy($aFileList[$c], $sDestDir & $FileName, 1) Then;Tries a second time If RunWait(@ComSpec & ' /c copy /y "' & $aFileList[$c] & '" "' & $sDestDir & $FileName & '">' & @TempDir & '\o.tmp', '', @SW_HIDE)=1 Then;and a third time, but this time it takes the error message $sError = FileReadLine(@TempDir & '\o.tmp',1) $iOutPut = $iOutPut + 1 $sLost = $sLost & $aFileList[$c] & ' ' & $sError & @CRLF EndIf FileDelete(@TempDir & '\o.tmp') EndIf EndIf FileSetAttrib($sDestDir & $FileName, "+A-RSH");<- Comment this line if you do not want attribs reset. $iCopiedSize = $iCopiedSize + Int(FileGetSize($aFileList[$c]) / 1024) $fProgress = $iCopiedSize / $iDirSize EndIf Next ;ProgressOff() _Metro_SetProgress($Progress , 1 ) If $sLost <> '' Then;tries to write the log somewhere. If FileWrite($sDestDir & 'notcopied.txt',$sLost) = 0 Then If FileWrite($sOriginalDir & 'notcopied.txt',$sLost) = 0 Then FileWrite(@WorkingDir & '\notcopied.txt',$sLost) EndIf EndIf EndIf _Metro_GUIDelete ( $hGui2 ) Return $iOutPut EndFunc ;==>_CopyDirWithProgress Func _FileSearch($sIstr, $bSF = 1) ; $bSF = 1 means looking in subfolders ; $sSF = 0 means looking only in the current folder. ; An array is returned with the full path of all files found. The pos [0] keeps the number of elements. Local $sCriteria, $sBuffer, $iH, $iH2, $sCS, $sCF, $sCF2, $sCP, $sFP, $sOutPut = '', $aNull[1] ;, $sIstr, $bSF $sCP = StringLeft($sIstr, StringInStr($sIstr, '\', 0, -1)) If $sCP = '' Then $sCP = @WorkingDir & '\' $sCriteria = StringTrimLeft($sIstr, StringInStr($sIstr, '\', 0, -1)) If $sCriteria = '' Then $sCriteria = '*.*' ;To begin we seek in the starting path. $sCS = FileFindFirstFile($sCP & $sCriteria) If $sCS <> - 1 Then Do $sCF = FileFindNextFile($sCS) If @error Then FileClose($sCS) ExitLoop EndIf If $sCF = '.' Or $sCF = '..' Then ContinueLoop $sOutPut = $sOutPut & $sCP & $sCF & @LF Until 0 EndIf ;And after, if needed, in the rest of the folders. If $bSF = 1 Then $sBuffer = @CR & $sCP & '*' & @LF;The buffer is set for keeping the given path plus a *. Do $sCS = StringTrimLeft(StringLeft($sBuffer, StringInStr($sBuffer, @LF, 0, 1) - 1), 1);current search. $sCP = StringLeft($sCS, StringInStr($sCS, '\', 0, -1));Current search path. $iH = FileFindFirstFile($sCS) If $iH <> - 1 Then Do $sCF = FileFindNextFile($iH) If @error Then FileClose($iH) ExitLoop EndIf If $sCF = '.' Or $sCF = '..' Then ContinueLoop If StringInStr(FileGetAttrib($sCP & $sCF), 'd') Then $sBuffer = @CR & $sCP & $sCF & '\*' & @LF & $sBuffer;Every folder found is added in the begin of buffer $sFP = $sCP & $sCF & '\'; for future searches $iH2 = FileFindFirstFile($sFP & $sCriteria); and checked with the criteria. If $iH2 <> - 1 Then Do $sCF2 = FileFindNextFile($iH2) If @error Then FileClose($iH2) ExitLoop EndIf If $sCF2 = '.' Or $sCF2 = '..' Then ContinueLoop $sOutPut = $sOutPut & $sFP & $sCF2 & @LF;Found items are put in the Output. Until 0 EndIf EndIf Until 0 EndIf $sBuffer = StringReplace($sBuffer, @CR & $sCS & @LF, '') Until $sBuffer = '' EndIf If $sOutPut = '' Then $aNull[0] = 0 Return $aNull Else Return StringSplit(StringTrimRight($sOutPut, 1), @LF) EndIf EndFunc ;==>_FileSearch Func _Quick_Sort(ByRef $SortArray, $First, $Last);Larry's code Dim $Low, $High Dim $Temp, $List_Separator $Low = $First $High = $Last $List_Separator = StringLen($SortArray[ ($First + $Last) / 2]) Do While (StringLen($SortArray[$Low]) < $List_Separator) $Low = $Low + 1 WEnd While (StringLen($SortArray[$High]) > $List_Separator) $High = $High - 1 WEnd If ($Low <= $High) Then $Temp = $SortArray[$Low] $SortArray[$Low] = $SortArray[$High] $SortArray[$High] = $Temp $Low = $Low + 1 $High = $High - 1 EndIf Until $Low > $High If ($First < $High) Then _Quick_Sort($SortArray, $First, $High) If ($Low < $Last) Then _Quick_Sort($SortArray, $Low, $Last) EndFunc ;==>_Quick_Sort Personaly i use the external windows it's pretty cool.1 point
-
AutoPM, If you do not show us some code which can reproduce the behaviour you describe then I am afraid we cannot help you. I have never heard of an AutoIt compiled exe which continues running after closure - and certainly not after a machine reboot. So either you have done something within the code which causes this behaviour (which is why we need to see a reproducer script) or there is something else going on with your machine - which I consider the most likely explanation. So over to you - if you want help then show some code. M23 P.S. And I would strongly counsel against opening other accounts - we do not permit that here.1 point
-
Script Keeps Running Even After Closing.
FrancescoDiMuro reacted to Subz for a topic
Fair enough, it appears their is something wrong with your script, so you need to fix it... problem solved.1 point -
Vector to yaw and pitch - Google Earth Pro - camera control
user4157124 reacted to RTFC for a topic
Hello. Sorry to rain on your parade, but your approach simply won't work, as you're bound to run into gimbal lock issues in Euler space. What you need to do is convert your Euler angles to quaternions, rotate in complex space, then convert back to Euler angles.1 point -
Script Keeps Running Even After Closing.
FrancescoDiMuro reacted to Subz for a topic
Are you going to post the script or do we have to organize a medium to look into a crystal ball?1 point -
@ManualIT The ProcessGetStats() function returns an array. In your check() function, you are referencing $memory (the array) when you should be referencing $memory[0] / 1024. The script below does basically the same thing as what your script was doing, with the correction that I pointed out and a some remarks to help make it clear. Also note the @error checking. Coding defensively, in order to catch and handle errors when they occur, will save you a lot of headaches when your scripts get longer and more complex. If you start the script without MSPaint running, you will get an error message. Your original script would not have recognized that mspaint wasn't running and just continued on. #include <Constants.au3> Global $aMemStats Global $nMemKB While 1 ;Get process' memory stats $aMemStats = ProcessGetStats("mspaint.exe") If @error Then MsgBox($MB_ICONERROR, "ERROR", "Unable to get process stats. Check to make sure mspaint is running.") Exit EndIf ;Convert bytes to kilobytes $nMemKB = $aMemStats[0] / 1024 ;If threshhold exceeded If $nMemKB > 30000 Then ;Display message and exit MsgBox($MB_ICONWARNING, "WARNING", "MSPaint memory limit exceeded!" & @CRLF & "Working set = " & $nMemKB) Exit EndIf ;Wait a second Sleep(1000) WEnd1 point
-
Parsing a file ... but starting at the middle?
FrancescoDiMuro reacted to BrewManNH for a topic
Your code makes no sense as written, how about helping us help you by including where you're getting the $param defined, what you're using the loop for (because you're not using the $i variable anywhere in it in the code), and any other pertinent code that would show us what it is you're trying to accomplish.1 point -
Restart a program when it reaches above 1GB of memory
ManualIT reacted to argumentum for a topic
https://www.autoitscript.com/forum/topic/197259-memory-leak-script-stopper-or-not/?tab=comments#comment-14147541 point -
look at ProcessGetStats () function1 point
-
@Skysnake suggestion is good.1 point
-
create a context menu to listView
GoogleDude reacted to Bilgus for a topic
There is the bare minimum for what you want #include <Misc.au3> #include <ListViewConstants.au3> #include <GUIConstants.au3> #include <GuiMenu.au3> Global $GUI = GUICreate("test") Global $g_iTemp Global $g_hList1 = GUICtrlCreateListView("#|x|y", 5, 24, 161, 70, $LVS_SHOWSELALWAYS Or $LVS_SINGLESEL) GUICtrlCreateListViewItem("text", $g_hList1) Global $g_hList1_LVN = GUICtrlCreateDummy() Global $context = GUICtrlCreateContextMenu($g_hList1) GUICtrlCreateMenuItem("1", $context) GUICtrlCreateMenuItem("2", $context) Global $g_hList2 = GUICtrlCreateListView("#|x|y", 5, 100, 161, 70, $LVS_SHOWSELALWAYS Or $LVS_SINGLESEL) GUICtrlCreateListViewItem("text", $g_hList2) Global $g_hList2_LVN = GUICtrlCreateDummy() Global $context2 = GUICtrlCreateContextMenu($g_hList2) GUICtrlCreateMenuItem("3", $context2) GUICtrlCreateMenuItem("4", $context2) GUISetState() GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") While 1 Switch GUIGetMsg() Case $gui_event_close Exit Case $g_hList1_LVN ;This is just a dummy it only recieves events ConsoleWrite("LV1 EVENT" & @CRLF) $g_iTemp = GUICtrlRead($g_hList1_LVN) ;Retrieve the code that WM_NOTIFY SENT If $g_iTemp = $LVN_KEYDOWN Then If _IsPressed("79") And (_IsPressed("A0") Or _IsPressed("A1")) Then ;Right/ Left Shift & F10 ShowMenu($GUI, $g_hList1, $context) Else ConsoleWrite("Some Other Keys" & @CRLF) EndIf Else ConsoleWrite("Some Other Event" & @CRLF) EndIf Case $g_hList2_LVN ConsoleWrite("LV2 EVENT" & @CRLF) $g_iTemp = GUICtrlRead($g_hList1_LVN) If $g_iTemp = $LVN_KEYDOWN Then If _IsPressed("79") And (_IsPressed("A0") Or _IsPressed("A1")) Then ;Right/ Left Shift & F10 ShowMenu($GUI, $g_hList2, $context2) EndIf EndIf EndSwitch WEnd Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $tNMHDR, $iCode ; Switch $wParam Case $g_hList1 $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $iCode = DllStructGetData($tNMHDR, "Code") Switch $iCode Case $LVN_KEYDOWN, $NM_CLICK GUICtrlSendToDummy($g_hList1_LVN, $iCode) ;send the code back to be processed by the dummy EndSwitch Case $g_hList2 $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $iCode = DllStructGetData($tNMHDR, "Code") Switch $iCode Case $LVN_KEYDOWN, $NM_CLICK GUICtrlSendToDummy($g_hList2_LVN, $iCode) EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func ShowMenu($hWnd, $idCtrl, $idContext) Local $aPos, $x, $y Local $hMenu = GUICtrlGetHandle($idContext) $aPos = ControlGetPos($hWnd, "", $idCtrl) $x = $aPos[0] $y = $aPos[1] + $aPos[3] ClientToScreen($hWnd, $x, $y) TrackPopupMenu($hWnd, $hMenu, $x, $y) EndFunc ;==>ShowMenu ; Convert the client (GUI) coordinates to screen (desktop) coordinates Func ClientToScreen($hWnd, ByRef $x, ByRef $y) Local $tPoint = DllStructCreate("int;int") DllStructSetData($tPoint, 1, $x) DllStructSetData($tPoint, 2, $y) DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "struct*", $tPoint) $x = DllStructGetData($tPoint, 1) $y = DllStructGetData($tPoint, 2) ; release Struct not really needed as it is a local $tPoint = 0 EndFunc ;==>ClientToScreen ; Show at the given coordinates (x, y) the popup menu (hMenu) which belongs to a given GUI window (hWnd) Func TrackPopupMenu($hWnd, $hMenu, $x, $y) ;DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0) _GUICtrlMenu_TrackPopupMenu($hMenu, $hWnd, $x, $y) EndFunc ;==>TrackPopupMenu1 point -
Why not a 'classic' way ? (the code below is for concept only because I don't really understand the last requirements) #include <Array.au3> Local $test[15] = [1, 1, 1, 1, 3, 4, 6, 6, 8, 8, 0, 8, 5, 9, 9] ;Local $test[14] = [1, 1, 1, 1, 3, 4, 6, 6, 8, 8, 0, 8, 5, 9] _ArraySort($test) _ArrayDisplay($test) Local $n = UBound($test), $res[$n], $r = 0, $dup For $i = 1 to $n-1 If $test[$i] = $test[$i-1] Then $res[$r] = $test[$i-1] $r += 1 $dup = 1 Else If $dup = 1 Then $res[$r] = $test[$i-1] $r += 1 $dup = 0 EndIf EndIf If $i = $n-1 and $dup = 1 Then $res[$r] = $test[$i] $r += 1 EndIf Next Redim $res[$r] _ArrayDisplay($res, "Only multiples")1 point
-
Right click on ListView
GoogleDude reacted to Tvern for a topic
You can use this as a basis for experimentation. You might want to switch to a UDF listview if you're going to rely on more UDF functions though. #include <GuiConstantsEx.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> ;basic GUI Global $GUI = GUICreate("", 300, 450) Global $hListView = GUICtrlCreateListView("A|B|C|D|E|F|G", 25, 25, 250, 400) For $i = 0 To 20 GUICtrlCreateListViewItem("A" & $i & "|B" & $i & "|C" & $i & "|D" & $i & "|E" & $i & "|F" & $i & "|G" & $i, $hListView) Next ;Context Menu Global $hCMenu = GUICtrlCreateContextMenu($hListView) ;add a context menu to the listview. I don't think you can add a seperate one to each item unless you write your own function. Global $hCMenuText = GUICtrlCreateMenuItem("Get Text", $hCMenu) ;add the get text option to the menu. Global $sItemText ;this will store the text of the last right-clicked item. GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ;This intercepts the Notification windows sends your GUI when you right click the listview (and many others) amd sends it to the "WM_NOTIFY" function. GUISetState() While 1 Switch GUIGetMsg() Case -3 Exit Case $hCMenuText _ShowText() EndSwitch WEnd ;All Notify messages for your GUI will be send to this function. Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $iwParam Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView) ;$ilParam is a pointer. This reads what's at that adress. (not sure why the name suggests its an int) $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom ;Check what control triggered the msg Case $hWndListView ;If it was the listview... Switch $iCode ;Check what action triggered the msg Case $NM_RCLICK ;If it was a right click... $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam) ;get the information about the item clicked. $sItemText = _GUICtrlListView_GetItemText($hWndListView, DllStructGetData($tInfo, "Index"), DllStructGetData($tInfo, "SubItem")) ;store the item text in a global variable in case the get text option is clicked. ;You could also just store the Index and SubItem values, the entire $tInfo struct, or whatever works best for you. ;Uncomment the next part to get more information about your click. ;~ _DebugPrint("$NM_RCLICK" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _ ;~ "-->IDFrom:" & @TAB & $iIDFrom & @LF & _ ;~ "-->Code:" & @TAB & $iCode & @LF & _ ;~ "-->Index:" & @TAB & DllStructGetData($tInfo, "Index") & @LF & _ ;~ "-->SubItem:" & @TAB & DllStructGetData($tInfo, "SubItem") & @LF & _ ;~ "-->NewState:" & @TAB & DllStructGetData($tInfo, "NewState") & @LF & _ ;~ "-->OldState:" & @TAB & DllStructGetData($tInfo, "OldState") & @LF & _ ;~ "-->Changed:" & @TAB & DllStructGetData($tInfo, "Changed") & @LF & _ ;~ "-->ActionX:" & @TAB & DllStructGetData($tInfo, "ActionX") & @LF & _ ;~ "-->ActionY:" & @TAB & DllStructGetData($tInfo, "ActionY") & @LF & _ ;~ "-->lParam:" & @TAB & DllStructGetData($tInfo, "lParam") & @LF & _ ;~ "-->KeyFlags:" & @TAB & DllStructGetData($tInfo, "KeyFlags")) EndSwitch EndSwitch ;Returning this allows the GUI to handle the messages in the usual way once you're done. Returning anything else will block default behavior. (giving you a largely unresponsive GUI) Return $GUI_RUNDEFMSG EndFunc Func _ShowText() MsgBox(0,"Test",$sItemText) EndFunc Func _DebugPrint($s_text, $line = @ScriptLineNumber) ConsoleWrite( _ "!===========================================================" & @LF & _ "+======================================================" & @LF & _ "-->Line(" & StringFormat("%04d", $line) & "):" & @TAB & $s_text & @LF & _ "+======================================================" & @LF) EndFunc1 point -
AlchemistZim, Welcome to the AutoIt forum. The infinite progress you are looking for is known as a "marquee" progress and is created thus: #include <GUIConstantsEx.au3> #include <ProgressConstants.au3> #include <SendMessage.au3> $hGUI = GUICreate("Test", 500, 500) GUICtrlCreateProgress(10, 10, 400, 20, $PBS_MARQUEE) _SendMessage(GUICtrlGetHandle(-1), $PBM_SETMARQUEE, True, 50) ; final parameter is update time in ms GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch WEndAs to the list of steps, take a look at GUICtrlCreateList in the Help file - it should do just what you need. If you are new to scripting, then reading the Help file (at least the first few sections - Using AutoIt, Tutorials and the first couple of References) will help you enormously. You should also look at the excellent tutorials that you will find here and here - you will find other tutorials in the Wiki (the link is at the top of the page). There are even video tutorials on YouTube if you prefer watching to reading. I know you want to start coding NOW, but a little study will save you a lot of trouble later on, believe me. Give it a go yourself - you know where we are if you run into diffculties. M231 point