gpt4 book ai didi

winapi - 谁在 SetClipboardData(CF_BITMAP, HBITMAP) 中释放句柄?

转载 作者:行者123 更新时间:2023-12-02 09:53:19 25 4
gpt4 key购买 nike

我的理解是,一般来说,当您向剪贴板添加句柄时,剪贴板就拥有该句柄,您不负责删除它,也不应该删除它。这就是这里所说的: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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com