mirror of
https://github.com/reactos/reactos.git
synced 2025-01-05 22:12:46 +00:00
[CLIPBRD]
Fix the computation of where bitmap pixels start, depending on whether we are dealing with DIBs or DIBs version 5+ (depending on the header BITMAPINFOHEADER or BITMAPV5HEADER etc...). I also noticed a bug in Windows that few other people already discovered, related to the automatic conversion of CF_DIBV5/CF_BITMAP to CF_DIB clipboard format. See the comment in the code. CORE-10679 svn path=/trunk/; revision=70349
This commit is contained in:
parent
830c4ee4a0
commit
e0b85f16d3
1 changed files with 86 additions and 7 deletions
|
@ -16,7 +16,7 @@ void ShowLastWin32Error(HWND hwndParent)
|
|||
dwError = GetLastError();
|
||||
|
||||
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL, dwError, 0, (LPWSTR)&lpMsgBuf, 0, NULL);
|
||||
NULL, dwError, 0, (LPWSTR)&lpMsgBuf, 0, NULL);
|
||||
MessageBoxW(hwndParent, lpMsgBuf, NULL, MB_OK | MB_ICONERROR);
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
|
@ -102,8 +102,9 @@ void SetDIBitsToDeviceFromClipboard(UINT uFormat, HDC hdc, int XDest, int YDest,
|
|||
{
|
||||
LPBITMAPINFOHEADER lpInfoHeader;
|
||||
LPBYTE lpBits;
|
||||
LONG bmWidth, bmHeight;
|
||||
DWORD dwPalSize = 0;
|
||||
HGLOBAL hGlobal;
|
||||
INT iPalSize;
|
||||
|
||||
hGlobal = GetClipboardData(uFormat);
|
||||
if (!hGlobal)
|
||||
|
@ -113,18 +114,96 @@ void SetDIBitsToDeviceFromClipboard(UINT uFormat, HDC hdc, int XDest, int YDest,
|
|||
if (!lpInfoHeader)
|
||||
return;
|
||||
|
||||
if (lpInfoHeader->biBitCount < 16)
|
||||
if (lpInfoHeader->biSize == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
iPalSize = (1 << lpInfoHeader->biBitCount) * 4;
|
||||
LPBITMAPCOREHEADER lpCoreHeader = (LPBITMAPCOREHEADER)lpInfoHeader;
|
||||
|
||||
dwPalSize = 0;
|
||||
|
||||
if (lpCoreHeader->bcBitCount <= 8)
|
||||
{
|
||||
dwPalSize = (1 << lpCoreHeader->bcBitCount);
|
||||
|
||||
if (fuColorUse == DIB_RGB_COLORS)
|
||||
dwPalSize *= sizeof(RGBTRIPLE);
|
||||
else
|
||||
dwPalSize *= sizeof(WORD);
|
||||
}
|
||||
|
||||
bmWidth = lpCoreHeader->bcWidth;
|
||||
bmHeight = lpCoreHeader->bcHeight;
|
||||
}
|
||||
else if ((lpInfoHeader->biSize == sizeof(BITMAPINFOHEADER)) ||
|
||||
(lpInfoHeader->biSize == sizeof(BITMAPV4HEADER)) ||
|
||||
(lpInfoHeader->biSize == sizeof(BITMAPV5HEADER)))
|
||||
{
|
||||
dwPalSize = lpInfoHeader->biClrUsed;
|
||||
|
||||
if ((dwPalSize == 0) && (lpInfoHeader->biBitCount <= 8))
|
||||
dwPalSize = (1 << lpInfoHeader->biBitCount);
|
||||
|
||||
if (fuColorUse == DIB_RGB_COLORS)
|
||||
dwPalSize *= sizeof(RGBQUAD);
|
||||
else
|
||||
dwPalSize *= sizeof(WORD);
|
||||
|
||||
if (/*(lpInfoHeader->biSize == sizeof(BITMAPINFOHEADER)) &&*/
|
||||
(lpInfoHeader->biCompression == BI_BITFIELDS))
|
||||
{
|
||||
dwPalSize += 3 * sizeof(DWORD);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a (disabled) hack for Windows, when uFormat == CF_DIB
|
||||
* it needs yet another extra 3 DWORDs, in addition to the
|
||||
* ones already taken into account in via the compression.
|
||||
* This problem doesn't happen when uFormat == CF_DIBV5
|
||||
* (in that case, when compression is taken into account,
|
||||
* everything is nice).
|
||||
*
|
||||
* NOTE 1: This fix is only for us, because when one pastes DIBs
|
||||
* directly in apps, the bitmap offset problem is still present.
|
||||
*
|
||||
* NOTE 2: The problem can be seen with Windows' clipbrd.exe if
|
||||
* one copies a CF_DIB image in the clipboard. By default Windows'
|
||||
* clipbrd.exe works with CF_DIBV5 and CF_BITMAP, so the problem
|
||||
* is unseen, and the clipboard doesn't have to convert to CF_DIB.
|
||||
*
|
||||
* FIXME: investigate!!
|
||||
* ANSWER: this is a Windows bug; part of the answer is there:
|
||||
* http://go4answers.webhost4life.com/Help/bug-clipboard-format-conversions-28724.aspx
|
||||
* May be related:
|
||||
* http://blog.talosintel.com/2015/10/dangerous-clipboard.html
|
||||
*/
|
||||
#if 0
|
||||
if ((lpInfoHeader->biSize == sizeof(BITMAPINFOHEADER)) &&
|
||||
(lpInfoHeader->biCompression == BI_BITFIELDS))
|
||||
{
|
||||
dwPalSize += 3 * sizeof(DWORD);
|
||||
}
|
||||
#endif
|
||||
|
||||
bmWidth = lpInfoHeader->biWidth;
|
||||
bmHeight = lpInfoHeader->biHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
iPalSize = 0;
|
||||
/* Invalid format */
|
||||
GlobalUnlock(hGlobal);
|
||||
return;
|
||||
}
|
||||
|
||||
lpBits = (LPBYTE)lpInfoHeader + lpInfoHeader->biSize + iPalSize;
|
||||
lpBits = (LPBYTE)lpInfoHeader + lpInfoHeader->biSize + dwPalSize;
|
||||
|
||||
SetDIBitsToDevice(hdc, XDest, YDest, lpInfoHeader->biWidth, lpInfoHeader->biHeight, XSrc, YSrc, uStartScan, lpInfoHeader->biHeight, lpBits, (LPBITMAPINFO)lpInfoHeader, fuColorUse);
|
||||
SetDIBitsToDevice(hdc,
|
||||
XDest, YDest,
|
||||
bmWidth, bmHeight,
|
||||
XSrc, YSrc,
|
||||
uStartScan,
|
||||
bmHeight,
|
||||
lpBits,
|
||||
(LPBITMAPINFO)lpInfoHeader,
|
||||
fuColorUse);
|
||||
|
||||
GlobalUnlock(hGlobal);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue