- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的理解是,一般来说,当您向剪贴板添加句柄时,剪贴板就拥有该句柄,您不负责删除它,也不应该删除它。这就是这里所说的:https://msdn.microsoft.com/en-us/library/windows/desktop/ms649051%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
If SetClipboardData succeeds, the system owns the object identified by the hMem parameter. The application may not write to or free the data once ownership has been transferred to the system, but it can lock and read from the data until the CloseClipboard function is called. (The memory must be unlocked before the Clipboard is closed.) If the hMem parameter identifies a memory object, the object must have been allocated using the function with the GMEM_MOVEABLE flag.
事实上,我看到很多例子,人们调用 GlobalAlloc(),在全局句柄中放入一些文本,调用 SetClipboardData(),然后不释放全局句柄,因为剪贴板拥有它。
但对于通过 SetClipboardData(CF_BITMAP, hBitmap) 添加的 HBITMAP 数据
,我看到了很多这样的示例:
https://stackoverflow.com/a/7292773/384670
https://stackoverflow.com/a/28248531/384670
在这些情况下,代码在将 HBITMAP 添加到剪贴板后确实将其删除。
对于剪贴板而言,HBITMAP 句柄和 GlobalAlloc() 句柄之间有区别吗? CF_BITMAP 是否有什么特殊之处,是规则的异常(exception),并且剪贴板复制句柄而不是拥有它?您能给我指出解释差异的官方 (MSDN) 文档吗?
编辑:
这是在一篇文章中涉及两种类型句柄的另一个示例:http://www.codeproject.com/Articles/42/All-you-ever-wanted-to-know-about-the-Clipboard
请注意,对于位图,作者特别指出:
//copy has been made on clipboard so we can delete
最佳答案
以下是乔纳森·波特鼓励的实验结果。有问题的句柄位于变量 HBITMAP hbmScreen 中。这个实验的结果是,我可以在所有检查点(1)到(4)中访问hbmScreen,并且可以在最后保存正确的图像。所以这告诉我这个 handle 仍然是我可以使用的。正如我所说,我认为这并不能明确表明句柄不属于剪贴板。但由于在所有这些之后调用 DeleteObject( hbmScreen )
似乎也没有问题,所以我将继续这样做。
if ( OpenClipboard( NULL ) && EmptyClipboard() )
{
BITMAPINFOHEADER bi = { 0 };
bi.biSize = sizeof( BITMAPINFOHEADER );
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biWidth = rcClient.right - rcClient.left;
bi.biHeight = rcClient.bottom - rcClient.top;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0; // 3 * ScreenX * ScreenY;
BYTE *lpbitmap = (BYTE *)malloc( bi.biWidth * bi.biHeight * 4 );
// (1) call to make sure we can access hbmScreen here
memset( lpbitmap, 0, bi.biWidth * bi.biHeight * 4 );
GetDIBits( hdcScreen, hbmScreen, 0, (UINT)bi.biHeight, lpbitmap, (BITMAPINFO *)&bi, DIB_RGB_COLORS );
HANDLE hResult = SetClipboardData( CF_BITMAP, hbmScreen );
CloseClipboard();
// (2) call to check if we can access hbmScreen here
memset( lpbitmap, 0, bi.biWidth * bi.biHeight * 4 );
GetDIBits( hdcScreen, hbmScreen, 0, (UINT)bi.biHeight, lpbitmap, (BITMAPINFO *)&bi, DIB_RGB_COLORS );
OpenClipboard( NULL );
EmptyClipboard();
CloseClipboard();
// (3) call to check if we can access hbmScreen here
memset( lpbitmap, 0, bi.biWidth * bi.biHeight * 4 );
GetDIBits( hdcMemDC, hbmScreen, 0, (UINT)bi.biHeight, lpbitmap, (BITMAPINFO *)&bi, DIB_RGB_COLORS );
// (4) actually use the data from hbmScreen
std::vector<unsigned char> image;
int n = bi.biWidth * bi.biHeight * 4;
image.resize( n );
int i = 0;
for ( int y = bi.biHeight - 1 ; y >= 0 ; y-- )
{
for ( int x = 0 ; x < bi.biWidth ; x++ )
{
int base = ( y * bi.biWidth + x ) * 4;
image[ i++ ] = lpbitmap[ base + 2 ]; // r
image[ i++ ] = lpbitmap[ base + 1 ]; // g
image[ i++ ] = lpbitmap[ base ]; // b
image[ i++ ] = lpbitmap[ base + 3 ]; // a
}
}
free( lpbitmap );
unsigned error = lodepng::encode( "C:/a.png", image, bi.biWidth, bi.biHeight );
}
关于winapi - 谁在 SetClipboardData(CF_BITMAP, HBITMAP) 中释放句柄?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32086618/
我认为标题非常具有解释性,但这里更详细地说明了我正在尝试做的事情。基本上就是说我在内存中加载了一个BITMAP。 我想从中提取 BITMAPINFOHEADER 并将其添加到我的数据包结构中,该结构将
例如,如果我使用 LoadImage() 从线程 A 中的文件加载位图,我可以在线程 B 中使用返回的 HBITMAP 吗? 最佳答案 是的,可以,但请记住,一次只能将位图选择到一个 DC 中。如果您
我将桌面屏幕截图创建为位图文件。 在 win32 C 中降低这个大图像文件(~3 MB)的分辨率的最佳方法是什么? 我想通过网络发送它,所以文件应该更小。 最佳答案 使用StretchBlt调整位图大
无论我多么努力地寻找和尝试,我都找不到这段代码泄漏的原因。实际上,我不确定泄漏,但每次使用这段代码时 GDI 对象的数量都会增加。 HBITMAP hBmp; hBmp = CreateDIBitma
我有一个 ID 为 PNG 文件的资源 ID_IMAGES。该资源是一个图像数组,大小相同 (16x16)。我想弄清楚是否可以提取这些图像中的任何一张并从中生成 HBITMAP。 我在网上四处寻找,但
我想使用 CreateBitmap() 从一个简单的 unsigned char 像素缓冲区(每个像素 3 个字节)创建一个 HBITMAP 对象这…… HBITMAP hbm = CreateBit
我需要 C++ 代码从一侧获取 HBITMAP 并通过套接字发送它,在另一侧接收并再次使其成为 HBITMAP。 必须快速有效 如果更舒服,用GDI+位图 最佳答案 那是行不通的! 您需要做的是使用
我有一个像素数组,我需要将其转换为 HBITMAP 以便在窗口中显示它。我尝试使用 CreateDIBitmap() 但我没有 BMP header 。我尝试根据 MSDN 文档手动构建它们,但这没有
我有一个应用程序可以从数据库中加载一些 blob 数据,这些数据可以表示各种位图和图标的 png 格式或原始二进制数据。这被存储在 std::vector 我正在使用 CImageList 对象在 T
如果我有一个名为 bitmap 的 BITMAP,如何将其转换为 HBITMAP? 到目前为止我已经尝试过: HBITMAP hbm = (HBITMAP)&bitmap; //doesn't wor
在大快捷方式中,我正在尝试编写程序,该程序通过 NamedPipe 位图从另一个应用程序接收到的位图绘制位图。 我将分别发送 BITMAPINFO 结构和从 GetBitmapBits 函数获得的位图
我先道歉;我是 c 的新手,我真的不知道自己在做什么。 我正在尝试使用 Windows 7 和 c 捕获和显示屏幕截图。我知道这听起来很愚蠢,最终我会在不同的程序中需要这些功能中的每一个,捕获屏幕的那
如果给定了 HBITMAP 指针,并且我的应用程序是控制台应用程序,我如何从 hbitmap 获取图像字节。 我尝试使用需要诸如 HDC 之类的参数的 GetDIBits,但我无法获得。 编辑: 我从
我在屏幕上显示位图时遇到问题。当我编译并运行不显示任何内容时,尝试逐步调试,发现下面的代码是问题所在。 HBITMAP hbm = (HBITMAP)LoadImage(hInstance,
我正在尝试为给定的 jpg 图像创建一个 avi 文件。我正在使用库读取 jpg 并为其准备 hbitmap。最后我添加它来创建 avi 文件。但我最终的 avi 文件包含倒置图像。我在 bitmap
我正在创建一个实用程序,它使用全局 Hook 将一些(用户可自定义的)图标绘制到桌面上的其他窗口上。由于位图对象是特定于进程的,因此在绘制它们之前,我在每个进程中为这些图标创建了单独的 HBITMAP
我有一个加载具有透明背景的图像的应用程序,然后我使用 StretchBlt 将其调整为所需的大小,使用 SetStretchBltMode 设置 HALFTONE (我尝试使用其他模式,在保持透明度不
您好 Stack Overflow 用户。看来我没有在以下代码中正确使用 CreateCompatibleBitmap(): #include using namespace std; int ma
我的环境: win32 视觉 C++ directx 我需要将另一个应用程序的面部映射到我的应用程序的纹理。 例如,我的 Internet Explorer 屏幕出现在我的 DirectX Cube
我有一个 HBITMAP,它是使用 Excel Interop 的 CopyPicture 方法创建的。出于某种原因,这会在图像的顶部和左侧边缘放置一个灰色边框,即使它们不是电子表格的一部分。有人能告
我是一名优秀的程序员,十分优秀!