https://bugs.documentfoundation.org/show_bug.cgi?id=155855

--- Comment #2 from Mike Kaganski <[email protected]> ---
When pasting an older using Windows' Clipboard history manager (WinLogo+V), the
clipboard contents is replaced with the following three item types (seen with
NirSoft' InsideClipboard):

name                                             size
CF_BITMAP (id=2)                                 0
ExcludeClipboardContentFromMonitorProcessing     90
ClipboardHistoryItemId                           76

The second is likely internal, to avoid capturing it second time, so
uninteresting.

OTOH, [Print Screen] button puts these to the clipboard:

name                                             size
CF_BITMAP (id=2)                                 0
CF_DIB                                           8 294 452
CF_DIBV5                                         8 294 452

The interesting work happens in CDOTransferable::getClipboardData, which is
called to obtain a bitmap, and requests a CF_DIB. We could consider a fallback
to also request CF_BITMAP when DIB fails, but - read below. Also, it tries to
obtain the data from the IDataObject. It needs a proper tymed; and in this
specific case, the tymed that works is TYMED_GDI, so we could try to fallback
to it, but - read below.

Now for funny things.
Even when implementing these ideas, the paste would fail, because
WinBITMAPToOOBMP (that is called eventually for CF_BITMAP) would fail in a call
to GetDIBits (after a "succeeded" call to GetBitmapDimensionEx, which gave [0,
0] size). OK, we can replace GetBitmapDimensionEx with GetObjectW(aHBMP,
sizeof(BITMAP), &aBITMAP), giving the correct info ... but GetDIBits will fail
anyway with GetLastInfo() giving 87 (the parameter is incorrect).

But the best thing here is the Microsoft documentation for "Clipboard Formats"
[1]. It tells in Synthesized Clipboard Formats:

> The system implicitly converts data between certain clipboard formats: if a
> window requests data in a format that is not on the clipboard, the system
> converts an available format to the requested format.
> ...
> Clipboard Format    Conversion Format
> CF_BITMAP           CF_DIB
> ...
> When copying bitmaps, it is best to place the CF_DIB or CF_DIBV5 format on the
> clipboard. This is because the colors in a device-dependent bitmap (CF_BITMAP)
> are relative to the system palette, which may change before the bitmap is 
> pasted.
> ...
> If you place the CF_BITMAP format on the clipboard (and not CF_DIB), the 
> system
> renders the CF_DIB or CF_DIBV5 clipboard format as soon as the clipboard is
> closed. This ensures that the correct palette is used to generate the DIB.

So many things *not* happening as documented, when using the MS tool named
"Clipboard history"! They do not put CF_DIB to the clipboard (even though the
original clipboard content included that); the system does not create a CF_DIB
at the time they put the CF_BITMAP to the clipboard; and they do not create it
even when asked for this format explicitly. And finally, they refuse to create
a DIB from the HBITMAP, using the API.

If someone intends to work on this, the proper way seems to be like what is
used in WinSalBitmap::ImplCopyDIBOrDDB - use the HBITMAP to draw to our buffer,
and then maybe output the  bitmap to DIB using WriteDIBBitmapEx
(vcl/dibtools.hxx)?

[1]
https://learn.microsoft.com/en-us/windows/win32/dataxchg/clipboard-formats#synthesized-clipboard-formats

-- 
You are receiving this mail because:
You are the assignee for the bug.

Reply via email to