I have the following code in the DropObject event handler of a desktop app main window:
Do
If obj.FolderItemAvailable Then
If obj.FolderItem.Type <> "" Then
MediaForUse = InStr(AllAvailExt, obj.FolderItem.Type) /// determine whether the droped file extension is in my 'to use' list
Select Case MediaForUse
Case 117 To 254 /// it's a video ext.
vFullPath = obj.FolderItem.NativePath
vname_no_ext = Replace(obj.FolderItem.Name, obj.FolderItem.Type , "")
vext = obj.FolderItem.Type
vdir = obj.FolderItem.Parent.NativePath
#If TargetMacOS Then vdir = vdir + "/"
vname_with_ext = obj.FolderItem.Name
ProcessMedia /// Go to process the media (may take a while)
Case 0 To 116 /// it's an audio ext.
Continue
End Select
End If
End If
Loop Until Not obj.NextItem
It works great on both Mac and Windows as long as I drag all media files in one go, but, and here is the tricky part, in case you have one video file in one folder and another in a different folder you can’t drag them together right, so you drag one and it starts to process (may take even an hour) and as long as the process is running you can’t add more files to the Cue.
So I tried to release the blockage by creating TheCue() As FolderItem
[code]Do
If obj.FolderItemAvailable Then
If obj.FolderItem.Type <> “” Then
MediaForUse = InStr(AllAvailExt, obj.FolderItem.Type) /// determine whether the droped file is in the ‘AllAvailExt’ Array
Select Case MediaForUse
Case 117 To 254 /// it’s a video ext.
TheCue.Append(obj.FolderItem)
Case 0 To 116 /// it’s an audio ext.
Continue
End Select
End If
End If
Loop Until Not obj.NextItem
If CueNotRunning Then
RenderCue
End If[/code]
RenderCue Method:
[code]For i As Integer = 0 To UBound(TheCue)
If TheCue(i).Exists Then
If TheCue(i).Type <> “” Then
MediaForUse = InStr(AllAvailExt, TheCue(i).Type) /// determine whether the droped file is in the ‘AllAvailExt’ Array
Select Case MediaForUse
Case 117 To 254 /// it’s a video ext.
vFullPath = TheCue(i).NativePath
vname_no_ext = Replace(TheCue(i).Name, TheCue(i).Type , “”)
vext = TheCue(i).Type
vdir = TheCue(i).Parent.NativePath #If TargetMacOS Then vdir = vdir + “/”
vname_with_ext = TheCue(i).Name
ProcessMedia /// Go to process the media (may take a while)
Case 0 To 116 /// it's an audio ext.
Continue
End Select
End If
End If
Next[/code]
Now it kinda lets me drag more objects but instead of adding them to the list it doubles the items that have been in the original drag and I can’t seem to add the new once.
All I want is to be able to drag/add more items to the process cue list while process is still running, any idea ?
Finder and the file are both locked during the DropObject event.
The only thing you should be doing in this event is creating a FolderItem reference to the dropped file. Processing the file should be threaded or delayed until the next event loop with a Timer.
That is annoyingly true, didn’t bother to mention that really unwanted behavior but that is the least of you problems because it doesn’t lock other Finder windows and my users want to add files from other location so they only bothered by the fact that once the process starts and as I mentioned can last up to an hour per file, you can’t add more files to the list until it is all done.
If you have any idea how to add files to the Initial cue list once it started I’ll be thrilled to see a small example. I thought creating a FolderItem Array and using it in a separate method or timer would solve the problem but I can’t seem to get it to work properly for some reason.
Set the view to “by list”, click in the two folder black triangles to open both folders and you can select the two files located in two different folder.
I hope this is clear.
I do not know how this can help you, but I prefer to tells you.
have the dropObject method place a reference in a queue, and start a threaded method if not already running
that threaded method processes only one of the files… when it is done it checks if there is another, or it terminates, once it terminates the act of dropping a new file will restart it
That way the user can drop files at any time, and they are queued up without any timers or other such overhead
[quote=433759:@Dave S]1) have the dropObject method place a reference in a queue, and start a threaded method if not already running
2) that threaded method processes only one of the files… when it is done it checks if there is another, or it terminates, once it terminates the act of dropping a new file will restart it
That way the user can drop files at any time, and they are queued up without any timers or other such overhead[/quote]
Hi Dave, that is exactly what I’ve been trying to do but don’t know how to accomplish, as I was saying I created a FolderItem Array trying to buffer that queue and use it in a separate method but it seems my coding knowledge insufficient to achieve that goal
If you can be kind enough to guide me with some code example I’ll be more than grateful.
since this is a window then the easiest is to put a thread object ON the widow by dragging one from the control palette to the window - it will be named Thread1 which is fine
then in your window you have a property, theCue() as folderitem and in the drop object event you just add to theCue
Do
If obj.FolderItemAvailable Then
If obj.FolderItem.Type <> "" Then
MediaForUse = InStr(AllAvailExt, obj.FolderItem.Type) /// determine whether the droped file is in the 'AllAvailExt' Array
Select Case MediaForUse
Case 117 To 254 /// it's a video ext.
TheCue.Append(obj.FolderItem)
Case 0 To 116 /// it's an audio ext.
Continue
End Select
End If
End If
Loop Until Not obj.NextItem
If Thread1.State <> Thread.Running Then
Thread1.Run
End If
Then add the RUN event handler to thread1 and put this code in it
This should be workable - but its all written in a forum post so its may only be close
While UBound(TheCue) >= 0
If TheCue(0).Exists Then
If TheCue(0).Type <> "" Then
MediaForUse = InStr(AllAvailExt, TheCue(0).Type) /// determine whether the droped file is in the 'AllAvailExt' Array
Select Case MediaForUse
Case 117 To 254 /// it's a video ext.
vFullPath = TheCue(0).NativePath
vname_no_ext = Replace(TheCue(0).Name, TheCue(0).Type , "")
vext = TheCue(0).Type
vdir = TheCue(0).Parent.NativePath
#If TargetMacOS Then vdir = vdir + "/"
vname_with_ext = TheCue(0).Name
ProcessMedia /// Go to process the media (may take a while)
Case 0 To 116 /// it's an audio ext.
Continue
End Select
End If
End If
theCue.remove 0
wend
by putting the processing of each media item into the threads run event the UI should remain responsive
I just took your code and split it into “the piece that does the processing” and made that a thread
and the rest of the drag handling is mostly the same
Yes I see that, I almost believed that the missing link had been found, but after I made the change I get this exception:
Maybe I should have mentioned I have quite extensive GUI textual Communications on the main window plus progress bar update all the way through plus Shell.Execute (mode 2) all happening in the [quote]ProcessMedia[/quote] method that I call now from within thread1 and It seems to be forbidden
well the thread cannot directly manipulate the UI
Period
But what you can do in the thread is have properties for progress etc and then as part of the thread have it run a timer and that timers action can
or if you put the thread directly on the form as I suggested have the thread set properties on the form and then a timer takes those properties and updates the UI
[quote=433776:@Norman Palardy]well the thread cannot directly manipulate the UI
Period
But what you can do in the thread is have properties for progress etc and then as part of the thread have it run a timer and that timers action can
or if you put the thread directly on the form as I suggested have the thread set properties on the form and then a timer takes those properties and updates the UI[/quote]
Haha should be interesting @Norman Palardy
So I Can set in the thread:
[code]ProcessIsRunning = True
ProcessHandleTimer.Mode = 2
While ProcessIsRunning
Wend[/code]
And in the Timer call the ProcessMedia method and when it’s done stop the timer and set ProcessIsRunning to False that will break the loop in the thread and let it continue to the next item ?
Oh I see, cool @Norman Palardy
Although this is getting a bit complicated because I have tons of UI updates within the process like progress bar status update, progress percentage visual display on the main window UI etc.
I’ll do my best to crack this Catch 22 conundrum, should be fun
basically when you want the ui to remain responsive you need to shove the processing into a thread as that can/will yield time back to the main thread of the application which handles UI updates etc
and then the trick is to figure out how to communicate the progress back to the UI with something NOT in the thread itself
all modern OS UI Kits basically require this - they didnt all used to