Getting File Dragged to Icon

Mac OSX specific forum
skape
User
User
Posts: 17
Joined: Mon Nov 18, 2013 7:24 am

Getting File Dragged to Icon

Post 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...
WilliamL
Addict
Addict
Posts: 1252
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: Getting File Dragged to Icon

Post 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>
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
skape
User
User
Posts: 17
Joined: Mon Nov 18, 2013 7:24 am

Re: Getting File Dragged to Icon

Post 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!
skape
User
User
Posts: 17
Joined: Mon Nov 18, 2013 7:24 am

Re: Getting File Dragged to Icon

Post 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.)
WilliamL
Addict
Addict
Posts: 1252
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: Getting File Dragged to Icon

Post 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.
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
skape
User
User
Posts: 17
Joined: Mon Nov 18, 2013 7:24 am

Re: Getting File Dragged to Icon

Post 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
Last edited by skape on Mon Jan 26, 2015 4:24 am, edited 1 time in total.
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Getting File Dragged to Icon

Post 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?
skape
User
User
Posts: 17
Joined: Mon Nov 18, 2013 7:24 am

Re: Getting File Dragged to Icon

Post 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! :)
skape
User
User
Posts: 17
Joined: Mon Nov 18, 2013 7:24 am

Re: Getting File Dragged to Icon

Post 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...... :shock:

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?
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Getting File Dragged to Icon

Post 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. ;)
skape
User
User
Posts: 17
Joined: Mon Nov 18, 2013 7:24 am

Re: Getting File Dragged to Icon

Post by skape »

Alright, thanks Danilo. :)

I didn't know about the PostEvent(#CustomEvent) ability. Neat. :)
Post Reply