Page 1 of 1
Getting File Dragged to Icon
Posted: Fri Jan 23, 2015 6:05 pm
by skape
Hello,
Using the code posted by WilliamL (originally Fred) in the Cocoa tips and tricks thread, I created a test app as such:
Code: Select all
ImportC ""
PB_Gadget_SetOpenFinderFiles(Callback)
EndImport
IsGadget(0) ; Ensures the gadget lib is linked as this command is in it
Procedure OpenFinderFilesCallback(*Utf8Files)
Protected filecnt,filesin$,filename$
filesin$ = PeekS(*Utf8Files, -1, #PB_UTF8) ; Each file is separated by a 'tab'
MessageRequester("",filesin$)
If Len(filesin$) ; Here you have the filename to open
MessageRequester("Raw Load...",filesin$+" filecount="+Str(CountString(filesin$,Chr(9)))) ; Use StringField() to iterate easily
For filecnt=1 To CountString(filesin$,Chr(9))+1
filename$=StringField(filesin$,filecnt,Chr(9))
filepath$=GetPathPart(filename$)
filename$=GetFilePart(filename$)
MessageRequester("Loading file...",filePath$+Chr(13)+filename$)
Next
EndIf
EndProcedure
OpenWindow(0, 0, 0, 300, 300, "Accept Files Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
PB_Gadget_SetOpenFinderFiles(@OpenFinderFilesCallback()); should be put very early in the code, before any event loop
;MessageRequester("Done","Done")
Repeat
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
End
Case #Null
Break
EndSelect
ForEver
ForEver
The app does not receive a call back when opened by double clicking a registered file, or by dragging a file to the icon. HOWEVER, if the app is already open, it WILL receive the notification that a file has been double clicked, etc. Any thoughts on how to make this work for the first event? I have tried to call the "registering callback" before opening the window and get no different results...
Re: Getting File Dragged to Icon
Posted: Fri Jan 23, 2015 6:51 pm
by WilliamL
I haven't looked at your code but one thought is that you haven't updated your Info.plist file.
Adding something like this to alert the system to your files/app relationship.
<key>CFBundleTypeExtensions</key>
<array>
<string>BKS</string>
</array>
Re: Getting File Dragged to Icon
Posted: Fri Jan 23, 2015 7:40 pm
by skape
Hi,
Thanks for your reply! I had already updated the plist with an entry that enables the dragging of any type of file:
Code: Select all
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>*</string>
</array>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
</array>
I have also tried it using a more restrictive entry, no joy. This is, however, how I am able to drag files to the app icon AFTER it is already open and it works. Also, it works to do "Open With..." AFTER the app is open. My question is regarding catching the initial event that is triggered when first opening the app with one of these methods.
Thanks!
Re: Getting File Dragged to Icon
Posted: Sun Jan 25, 2015 4:32 pm
by skape
It'd be awesome if someone could try this out. I've been bashing my head against it for the last couple of days and can't get it to register the initial event when the app is opened... Thanks!
This is pretty essential for any app that opens documents (or potentially for easy file processing w/ drag to icon.)
Re: Getting File Dragged to Icon
Posted: Mon Jan 26, 2015 2:11 am
by WilliamL
I'm sorry you haven't gotten any other suggestions. It can be very frustrating when it doesn't work without any feedback.
I've been using the code for quite a while now in several apps and never had a problem but that doesn't help you much. You have to create an executable to test the file opening ability and when you create an executable a new Index.plist file is created so you will have to replace that with your modified plist every time. There is a way around that but lets not go into that now. I always use exclusive extensions like .bks or .pchart or .inv. So put in the code, create and executable, update the plist, create a text file with the correct extension and you should be good to go.
I'm using 10.95 and don't know if it works with Yosemite.
Re: Getting File Dragged to Icon
Posted: Mon Jan 26, 2015 3:48 am
by skape
Thanks WilliamL, your reply is helpful. Seems to me that it may be a problem with Yosemite. I have tried many combinations of specific extensions and generic ones, and I replace the plist every time I compile an executable... The registering IS WORKING, just only when the app is already open.
I'm not positive it is a problem with Yosemite, as unless I am mistaken, the PB IDE uses this precise method for opening documents. The IDE works just fine for opening documents via double click or drag when it isn't already open...
Is there any way that you could send me a working (on Mavericks) example using this method that I could test here?
[EDIT:]
Okay, turns out that I had to add an interface element to the window for it to work?! I don't get it, but it's working now...
Thanks again WilliamL!
Code: Select all
ImportC ""
PB_Gadget_SetOpenFinderFiles(Callback)
EndImport
Declare ButtonHandler()
IsGadget(0) ; Ensures the gadget lib is linked as this command is in it
Procedure OpenFinderFilesCallback(*Utf8Files)
Protected filecnt,filesin$,filename$
filesin$ = PeekS(*Utf8Files, -1, #PB_UTF8) ; Each file is separated by a 'tab'
MessageRequester("",filesin$)
If Len(filesin$) ; Here you have the filename to open
MessageRequester("Raw Load...",filesin$+" filecount="+Str(CountString(filesin$,Chr(9)))) ; Use StringField() to iterate easily
For filecnt=1 To CountString(filesin$,Chr(9))+1
filename$=StringField(filesin$,filecnt,Chr(9))
filepath$=GetPathPart(filename$)
filename$=GetFilePart(filename$)
MessageRequester("Loading file...",filePath$+Chr(13)+filename$)
Next
EndIf
EndProcedure
OpenWindow(0, 0, 0, 300, 300, "Accept Files Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
PB_Gadget_SetOpenFinderFiles(@OpenFinderFilesCallback()); should be put very early in the code, before any event loop
ButtonGadget(0,10,10,70,27,"Dummy")
BindGadgetEvent(0,@ButtonHandler())
Repeat
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
End
Case #Null
Break
EndSelect
ForEver
ForEver
Procedure ButtonHandler()
MessageRequester("Good Job.", "You pressed a button. Yay. -_-")
EndProcedure
Re: Getting File Dragged to Icon
Posted: Mon Jan 26, 2015 4:09 am
by Danilo
Did you try to move 'PB_Gadget_SetOpenFinderFiles' before the OpenWindow() command?
This works for me:
Code: Select all
#My_Event_NewFiles = #PB_Event_FirstCustomValue
Global FileIn$ = ""
ImportC ""
PB_Gadget_SetOpenFinderFiles(Callback)
EndImport
IsGadget(0)
ProcedureC OpenFinderFilesCallback(*Utf8Files)
FileIn$ = PeekS(*Utf8Files, -1, #PB_UTF8)
PostEvent(#MY_EVENT_NEWFILES)
EndProcedure
PB_Gadget_SetOpenFinderFiles(@OpenFinderFilesCallback())
OpenWindow(0,0,0,200,200,"OpenFinderFilesCallback",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow : End
Case #My_Event_NewFiles : MessageRequester("Result", FileIn$)
EndSelect
ForEver
Shouldn't you change 'Procedure' to 'ProcedureC' for the handler callback?
Re: Getting File Dragged to Icon
Posted: Mon Jan 26, 2015 4:28 am
by skape
Danilo wrote:Did you try to move 'PB_Gadget_SetOpenFinderFiles' before the OpenWindow() command?
Yes, I did try that and it made no difference for me. In fact, that is what I tried first.
Danilo wrote:Shouldn't you change 'Procedure' to 'ProcedureC' for the handler callback?
Hmm, not sure about that one. Seems to work in standard mode for me, but it very well may be supposed be otherwise...
Thanks Danilo, I'll investigate a bit more!

Re: Getting File Dragged to Icon
Posted: Mon Jan 26, 2015 4:35 am
by skape
Now I'm really befuddled. It seems to be working now for all combinations of
Procedure vs.
ProcedureC and PB_Gadget_SetOpenFinderFiles()
before vs
after OpenWindow(). Suddenly it doesn't matter......
Maybe I'm using a slightly different plist??
As a side note: I mostly understand (some) of the differences between a standard call and CDecl convention, but, practically speaking, how do you know which to make? I'm somewhat new to this.

I guess stdcall and CDecl both push parameters onto the stack in the same order, so that works both ways, but if you do one when the other is expected, you may corrupt the registers, or leak memory?
Re: Getting File Dragged to Icon
Posted: Mon Jan 26, 2015 5:10 am
by Danilo
skape wrote:As a side note: I mostly understand (some) of the differences between a standard call and CDecl convention, but, practically speaking, how do you know which to make? I'm somewhat new to this.

In 64-bit mode it shouldn't make a difference. If Fred says PB_Gadget_SetOpenFinderFiles() takes a ProcedureC function pointer as argument, I'm using this.

Re: Getting File Dragged to Icon
Posted: Mon Jan 26, 2015 5:26 am
by skape
Alright, thanks Danilo.
I didn't know about the PostEvent(#CustomEvent) ability. Neat.
