- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我发现(至少)Win10 在通过 Alt-PrtScrn(可能是合成格式)创建的 CF_DIBV5 上调用 ::GetClipboardData()
会导致图像被修改(并且基本上被破坏).
例如,在 ON_WM_CLIPBOARDUPDATE()
的处理程序上,下面的简单循环将导致损坏(请注意,您需要使用 Debug模式,这样::GetClipboardData() 就不会被优化掉)。
要进行测试,首先不要运行处理剪贴板的应用,使用 Alt-PrntScrn 捕获数据,然后将其粘贴到画图。现在运行处理剪贴板的应用程序(下面的示例)。重复 Alt-PrntScrn 过程,您会发现捕获窗口的右侧在左侧结束而不是在该区域居中的地方有所不同。
void CMainFrame::OnClipboardUpdate()
if (::OpenClipboard(AfxGetMainWnd()->m_hWnd)) {
UINT uformat=0;
while ((uformat=::EnumClipboardFormats(uformat))!=0) {
if (uformat==CF_DIBV5) {
// get the data - run in debug mode so not optimized out
HGLOBAL hglobal=::GetClipboardData(uformat);
}
}
// clean up
::CloseClipboard();
}
}
要启用处理程序,您需要调用 AddClipboardFormatListener(GetSafeHwnd());
类似 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
然后 RemoveClipboardFormatListener( GetSafeHwnd());
在 void CMainFrame::OnDestroy()
那么这是 Win10(和其他 Windows 版本)中的错误,还是我应该做一些示例没有做的其他事情? (我知道存在其他格式,但 CF_DBIV5 是我想要的)。
我使用的是版本 1903(操作系统内部版本 18362.838)
请注意示例图片左侧有右侧项目,左下角有一些垃圾像素。我在应用程序运行时按 alt-prtscrn,粘贴在画图中。
我的分辨率是 2560x1600。
这是一个会导致问题的项目的链接:
最佳答案
您可以在 documentation 中找到以下说明:
The red, green, and blue bitfield masks for
BI_BITFIELD
bitmaps immediately follow theBITMAPINFOHEADER
,BITMAPV4HEADER
, andBITMAPV5HEADER
structures. TheBITMAPV4HEADER
andBITMAPV5HEADER
structures contain additional members for red, green, and blue masks as follows.
当 BITMAPINFOHEADER
的 biCompression
成员设置为 BI_BITFIELDS
并且函数接收类型为 LPBITMAPINFO
的参数时, 颜色 mask 将紧随标题。颜色表(如果存在)将遵循颜色掩码。 BITMAPCOREHEADER
位图不支持颜色 mask 。
当您正确处理 CF_DIBV5
时,您将成功绘制图像。以下是Win32 C++的例子,您可以引用:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static UINT uFormat = (UINT) -1;
HDC hdcMem = NULL;
RECT rc = {0};
BYTE * pData = NULL;
BITMAPV5HEADER *pDibv5Info = NULL;
switch (message)
{
case WM_CLIPBOARDUPDATE:
{
if (IsClipboardFormatAvailable(CF_DIBV5))
{
uFormat = CF_DIBV5;
::CloseClipboard();
GetClientRect(hWnd, &rc);
InvalidateRect(hWnd, &rc, TRUE);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
switch (uFormat)
{
case CF_DIBV5:
hdcMem = CreateCompatibleDC(hdc);
if (hdcMem != NULL)
{
if (::OpenClipboard(hWnd)) {
HANDLE hglobal = ::GetClipboardData(uFormat);
pData = (BYTE*)GlobalLock(hglobal);
if (pData)
{
pDibv5Info = (BITMAPV5HEADER *)pData;
int offset = pDibv5Info->bV5Size + pDibv5Info->bV5ClrUsed * sizeof(RGBQUAD);
if (pDibv5Info->bV5Compression == BI_BITFIELDS)
offset += 3 * sizeof(DWORD); //three DWORD color masks that specify the red, green, and blue components
pData += offset;
SetDIBitsToDevice(hdc, 20, 20, pDibv5Info->bV5Width, pDibv5Info->bV5Height, 0, 0, 0, pDibv5Info->bV5Height, pData, (BITMAPINFO *)pDibv5Info, 0);
}
GlobalUnlock(hglobal);
::CloseClipboard();
}
}
break;
}
EndPaint(hWnd, &ps);
}
break;
}
在我的应用程序窗口中绘制的正确图像:
我可以在没有代码的情况下重现同样的问题:
if (pDibv5Info->bV5Compression == BI_BITFIELDS)
offset += 3 * sizeof(DWORD);
损坏的图像:
关于winapi - Windows clipboard::GetClipboardData() for CF_DIBV5 导致剪贴板上的图像被修改和损坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61788908/
我正在开发一个小软件来通知用户在未经授权的应用程序中粘贴内容,我挂接了 GetClipboardData 来执行此操作。几乎一切正常,但是当我从 Word 复制内容时,例如,我单击 InternetE
当 GetClipboardData()用于访问剪贴板捕获的数据,是否有 API 调用或标志来区分复制操作 (CTRL+C) 和剪切操作 (CTRL+X)? 最佳答案 没有通用的方法可以知道数据是否由
我有一个 MFC 应用程序可以在剪贴板中查找文件,它在复制文件时工作正常但在剪切和粘贴操作期间失败。当我实时调试时,它显示 GetClipboardData(CF_HDROP) 失败并返回错误号 14
我有这个断断续续的问题,让我发疯了很长时间:在我的一个程序中,获取剪贴板数据(CF_TEXT) 90%(左右)的时间成功,但每隔一段时间它就会返回 NULL。 尽管 OpenClipboard() 在
我发现(至少)Win10 在通过 Alt-PrtScrn(可能是合成格式)创建的 CF_DIBV5 上调用 ::GetClipboardData() 会导致图像被修改(并且基本上被破坏). 例如,在
我是一名优秀的程序员,十分优秀!