mirror of
https://github.com/reactos/reactos.git
synced 2024-10-05 00:43:21 +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
|
@ -16,7 +16,7 @@ void ShowLastWin32Error(HWND hwndParent)
|
||||||
dwError = GetLastError();
|
dwError = GetLastError();
|
||||||
|
|
||||||
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
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);
|
MessageBoxW(hwndParent, lpMsgBuf, NULL, MB_OK | MB_ICONERROR);
|
||||||
LocalFree(lpMsgBuf);
|
LocalFree(lpMsgBuf);
|
||||||
}
|
}
|
||||||
|
@ -102,8 +102,9 @@ void SetDIBitsToDeviceFromClipboard(UINT uFormat, HDC hdc, int XDest, int YDest,
|
||||||
{
|
{
|
||||||
LPBITMAPINFOHEADER lpInfoHeader;
|
LPBITMAPINFOHEADER lpInfoHeader;
|
||||||
LPBYTE lpBits;
|
LPBYTE lpBits;
|
||||||
|
LONG bmWidth, bmHeight;
|
||||||
|
DWORD dwPalSize = 0;
|
||||||
HGLOBAL hGlobal;
|
HGLOBAL hGlobal;
|
||||||
INT iPalSize;
|
|
||||||
|
|
||||||
hGlobal = GetClipboardData(uFormat);
|
hGlobal = GetClipboardData(uFormat);
|
||||||
if (!hGlobal)
|
if (!hGlobal)
|
||||||
|
@ -113,18 +114,96 @@ void SetDIBitsToDeviceFromClipboard(UINT uFormat, HDC hdc, int XDest, int YDest,
|
||||||
if (!lpInfoHeader)
|
if (!lpInfoHeader)
|
||||||
return;
|
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
|
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);
|
GlobalUnlock(hGlobal);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue