Page 1 of 1

Clipboard persistence

Posted: Mon Jul 23, 2018 3:47 pm
by wombats
Hi,

I am trying to add cut/copy/paste to my program...which is going to be interesting for macOS and Linux/Qt, certainly. I'm not even sure I'll be able to do what I need to with Qt, but anyway, I digress.

On Windows, I am able to copy a structure to the clipboard and paste it back. However, if you try to paste when the program is restarted, it crashes. How can I ensure the data remains on the clipboard after the program ends, or at least ensure the pasted data is valid so it doesn't crash?

(Clipboard functions by Danilo: viewtopic.php?p=395527#p395527)

Code: Select all

Procedure SetClipboardData(Type.s, *theData, theDataLen)
  If OpenClipboard_(0)
    format = RegisterClipboardFormat_(@Type)
    If format
      hMem = GlobalAlloc_(#GMEM_MOVEABLE|#GMEM_DDESHARE,theDataLen)
      If hMem
        mem = GlobalLock_(hMem)
        If mem
          CopyMemory(*theData,mem,theDataLen)
          If SetClipboardData_(format,hMem)
            result = format
          EndIf
          GlobalUnlock_(hMem)
        EndIf
      EndIf
    EndIf
    CloseClipboard_()
  EndIf
  ProcedureReturn result
EndProcedure

Procedure GetClipboardFormat(Type.s)
  ProcedureReturn RegisterClipboardFormat_(@Type)
EndProcedure

Procedure GetClipboardData(format)
  If OpenClipboard_(0)
    hMem = GetClipboardData_(format)
    If hMem
      dataSize = GlobalSize_(hMem)
      src = GlobalLock_(hMem)
      If src
        mem = AllocateMemory( dataSize )
        If mem
          CopyMemory(src,mem,dataSize)
        EndIf
        GlobalUnlock_(hMem)
      EndIf
    EndIf
    CloseClipboard_()
  EndIf
  ProcedureReturn mem
EndProcedure

Structure test
  name.s
EndStructure

format = GetClipboardFormat("MyClipboardFormat")

OpenWindow(0, 0, 0, 500, 400, "", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered)

ButtonGadget(0, 10, 10, 96, 25, "Copy")
ButtonGadget(1, 10, 40, 96, 25, "Paste")

Repeat
  
  event = WaitWindowEvent()
  
  Select event
      
    Case #PB_Event_Gadget
      
      Select EventGadget()
          
        Case 0
          Define *data.Test = AllocateStructure(Test)
          *data\name = "Hello"
          SetClipboardData("MyClipboardFormat", *data, SizeOf(Test))
          
        Case 1
          If OpenClipboard_(0)
            If IsClipboardFormatAvailable_(format)
              Define *clipData.Test = GetClipboardData(format)
              Debug *clipData\name
            EndIf
          EndIf
          
      EndSelect
      
    EndSelect
  
Until event = #PB_Event_CloseWindow

Re: Clipboard persistence

Posted: Mon Jul 23, 2018 4:27 pm
by ccode
Hello wombats,

you don't like the standard clipboard features of PureBasic ?
wombats wrote:On Windows, I am able to copy a structure to the clipboard and paste it back. However, if you try to paste when the program is restarted, it crashes. How can I ensure the data remains on the clipboard after the program ends, or at least ensure the pasted data is valid so it doesn't crash?
Save it to a file, not Clipboard.

Everything else just makes unnecessary trouble.

Re: Clipboard persistence

Posted: Mon Jul 23, 2018 4:29 pm
by Mijikai
U could use a hash - why not just save the data?

Re: Clipboard persistence

Posted: Mon Jul 23, 2018 4:36 pm
by wombats
ccode wrote:Hello wombats,

you don't like the standard clipboard features of PureBasic ?
wombats wrote:On Windows, I am able to copy a structure to the clipboard and paste it back. However, if you try to paste when the program is restarted, it crashes. How can I ensure the data remains on the clipboard after the program ends, or at least ensure the pasted data is valid so it doesn't crash?
Save it to a file, not Clipboard.

Everything else just makes unnecessary trouble.
The Clipboard library in PureBasic only handles text and images. I need to copy and paste complex structures containing strings, images, lists, etc. I have asked for this functionality to be added to PureBasic, but unfortunately it was never commented on by the developers, so I assume they didn't see the worth in it.
Mijikai wrote:U could use a hash - why not just save the data?
I am trying to provide copy and paste functionality to my users, like in any professional program. It is reasonable to expect clipboard data to remain on the clipboard after the program has ended, and also for the paste function to not make the program crash.

Re: Clipboard persistence

Posted: Mon Jul 23, 2018 4:44 pm
by Trond
wombats wrote:It is reasonable to expect clipboard data to remain on the clipboard after the program has ended
Yes, but at least on Linux, this simply isn't how the clipboard works. You, as an app developer, can't get around it.

Edit: Anyway, would converting your data to JSON and using the normal text clipboard functions work?

Re: Clipboard persistence

Posted: Mon Jul 23, 2018 4:48 pm
by wombats
Trond wrote:
wombats wrote:It is reasonable to expect clipboard data to remain on the clipboard after the program has ended
Yes, but at least on Linux, this simply isn't how the clipboard works. You, as an app developer, can't get around it.

Edit: Anyway, would converting your data to JSON and using the normal text clipboard functions work?
That's fine for Linux if that's the expected functionality.

I don't think JSON would be an option as some of the structures hold images. If it could be done, it wouldn't be my preferred way as I want my program to act like others on each OS, but at least it would avoid me having to figure out how to do it on each platform!

Re: Clipboard persistence

Posted: Mon Jul 23, 2018 5:23 pm
by ccode
Reply to: wombats

Save your structures in a database and read them back. Of course, appropriate read-in and read-out functions must be programmed for this purpose.

But that would be the usual way.

.......

If you have only small pictures you can pass them as Base64.
And the other values ​​must be passed as formatted text.

(Only an insignificant opinion)

Why does it have to be saved via the clipboard?

Re: Clipboard persistence

Posted: Mon Jul 23, 2018 5:30 pm
by wombats
ccode wrote:Reply to: wombats

Save your structures in a database and read them back. Of course, appropriate read-in and read-out functions must be programmed for this purpose.

But that would be the usual way.

.......

If you have only small pictures you can pass them as Base64.
And the other values ​​must be passed as formatted text.

(Only an insignificant opinion)

Why does it have to be saved via the clipboard?
It's not to save the program data; I already have saving and loading implemented. This functionality is to allow users to copy parts of their project and paste it...such as duplicating items or copying them to another project. The clipboard is the expected way to do this.

Is an image in Base64 larger than it would be in its image form? Is there a limit to the image size?

Re: Clipboard persistence

Posted: Mon Jul 23, 2018 5:55 pm
by Mijikai
Store a hash and the datasize in the clipboard to check and verify your data later.

Re: Clipboard persistence

Posted: Mon Jul 23, 2018 6:08 pm
by wombats
Mijikai wrote:Store a hash and the datasize in the clipboard to check and verify your data later.
I can do that, but it doesn’t solve my problem of the clipboard data being lost when the program ends.

Re: Clipboard persistence

Posted: Mon Jul 23, 2018 6:20 pm
by ccode
Answer:
Does your program need to be stopped when you replace the clipboard?
Otherwise you have to save persistently via a file. The clipboard will certainly also temporarily write to ROM memory and not work in RAM.

Re: Clipboard persistence

Posted: Wed Jul 25, 2018 1:48 pm
by wombats
I've decided to just store the data on the clipboard in a JSON string. I've realised some benefits this provides, including not needing to worry about having to figure out how to use the clipboard on each platform.

Regarding images, I was able to store a large-ish image...about 1800x600 pixels successfully in Base64. Is there a limit to the image size at all?

Re: Clipboard persistence

Posted: Tue Jul 31, 2018 3:23 pm
by dagcrack
There shouldn't be a limit, just your available memory and processing time. Which in all regards means you should impose a limit - Restrictions allow for less issues down the road, generally speaking.

If serializing / deserializing through the available JSON functions becomes slow you'll have to write the binary data yourself, possibly the images as raw data referenced by a hash or just an ID.

Base64 encoding of images is common practice in web dev these days (has been for a while), with async applications and "all that". :lol: