Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
Hello;
I was just looking into the clipboard functions and found that the specialized function CopyBitmapToClipboard requires a CLIPBOARDOWNER.
CopyBitmapToClipboard
CLIPBOARDOWNER
I assume this has to do with delay-rendering of clipboard content and the WM_RENDERFORMAT message under Windows - no idea how the clipboard works under Mac... Wasn't actually aware that C4D uses that mechanism at all, but that's how it looks.
WM_RENDERFORMAT
So, if I use CopyBitmapToClipboard in a script or plugin of my own, I wouldn't delay-render the bitmap, so I'd use neither the CLIPBOARDOWNER_BODYPAINT nor the CLIPBOARDOWNER_PICTUREVIEWER constants, which (I assume) would cause the clipboard to send WM_RENDERFORMAT to either window instead of my script. Of course, these are the only constants available, and the function description does not offer anything else.
CLIPBOARDOWNER_BODYPAINT
CLIPBOARDOWNER_PICTUREVIEWER
When getting a bitmap from the system, GetC4DClipboardOwner returns 0, so I assume I can pass 0 safely too in calls to CopyBitmapToClipboard? Or am I overlooking some larger context here? As I am neither BodyPaint nor the PictureViewer, I would never want to use these constants anyway. But there is no speaking constant for 0, and CopyBitmapToClipboard makes it even a mandatory parameter?
GetC4DClipboardOwner
Can I crash C4D by using one of the two CLIPBOARDOWNER constants in a script (while not implementing a delay-render to clipboard at all which C4D doesn't even offer)?
GetC4DClipboardOwner allows me to retrieve the clipboard owner, but under what circumstances would I want to know that? If this is only for the delayed retrieval of clipboard content, then this should work fully transparently (?)
(Edit: Does look better with less formatting now?)
Hello @cairyn,
Thank you for reaching out to us. I see you saw my post yesterday before I hid it. I was not implying that you should change the existing one, and more meant that you should try to reduce the complexity of presentation and content of future requests, as at least I often struggle with both of in your topics.
The reason I hid my posting was that I was a bit lazy yesterday and accidentally looked at the Linux implementation of the clipboard. So, for Windows, the backend implementation of GetC4DClipboardOwner() looks like this:
GetC4DClipboardOwner()
Int32 ClipBoard::GetC4DOwner() { if (!_GeClippboardWindow || _GeClippboardWindow != GetClipboardOwner()) return 0; return m_ownerid; }
And this seems to be never to be able to get past the conditional expression in the first line, at least I never managed to do so. GetClipboardOwner() is a Windows function, and _GeClippboardWindow is a window handle (HWND) our clipboard is storing, the two simply never match up.
GetClipboardOwner()
_GeClippboardWindow
HWND
When writing a bitmap to the clipboard, and setting the owner identifier manually, the outcome is never what one would expect.
>>> bmp = c4d.bitmaps.BaseBitmap() >>> c4d.CopyBitmapToClipboard(bmp, c4d.CLIPBOARDOWNER_PICTUREVIEWER) >>> c4d.GetC4DClipboardOwner() 0 >>> c4d.CopyBitmapToClipboard(bmp, 12345678) >>> c4d.GetC4DClipboardOwner() 0
The reason is that the field m_ownerid is never actually written when the backend function which is invoked by CopyBitmapToClipboard() is being called. The reason is again here that something with window handles is going wrong, causing m_ownerid always being 0.
m_ownerid
CopyBitmapToClipboard()
0
So, to summarize:
ownerid
Int32
I am not sure yet how we will deal with this. It could for example be that the Windows API we are relying on has changed. It seems likely that we will simply make the argument ownerid and the concept of owners private, i.e., hide them in the C++ and Python docs, as this all is quite minor.
Thank you for pointing this out.
Cheers, Ferdinand
Hmm, there seem to be recent changes in that functionality. When I try to copy a newly rendered image from the PictureViewer, the owner actually seems to be set fine in the R23.110:
>>> c4d.GetC4DClipboardOwner() 200000244
(I assume that Python cannot do anything that C++ would not support...)
On the other hand, your other code indeed returns 0 so maybe the functionality wasn't consistent in R23 anyway.
Thanks, I will go with an ownerid of 0 for now... as there are no callbacks targeting my script, it can't hurt anyway.
Hey @cairyn,
yeah, you are right. @m_adam already pointed this out too. I screwed up and overwrote my clipboard when I tried this out. I have edited my initial posting, to not confuse future readers.
GetC4DClipboardOwner works fine in regards to the Picture Viewer and Bodypaint, but the argument ownerid of CopyBitmapToClipboard is effectively meaningless in the public API, as it lacks the window handle context to actually cause the ownerid to be stored. The owner id will always be set to 0.
And to underline the answer to your major question: It seems very unlikely that you could crash Cinema 4D with writing a made-up owner id into the clipboard (in the case the function would work properly and actually store the id). It is hard to give here absolute answers, as there is a lot of code in our code base. In the context of the clipboard alone, crashing can be excluded, but there could be other parts of Cinema 4D which make assumptions based on the owner id. Which is why I would recommend not using the predefined ones (which is rather theoretical due to said limitations of CopyBitmapToClipboard).