2016-05-28 2 views
3

HBITMAPをクリップボードにコピーしようとするといくつかの問題があります。私のHBITMAPCOLORREF配列から作成され、正しく表示することができます。ここではそれが作成される方法です。WinAPI:HBITMAPをクリップボードに正しくコピーする

COLORREF* colors = new COLORREF[imageSize[0] * imageSize[1]]; 

for (int i = 0; i < imageSize[1]; i++) { 
    for (int j = 0; j < imageSize[0]; j++) { 
     colors[imageSize[0] * i + j] = RGB(/* ... */); 
    } 
} 

// Create bitmap 
HBITMAP hBitmap = CreateBitmap(imageSize[0], imageSize[1], 1, 32, (void*)colors); 

delete[] colors; 

クリップボードに私のビットマップをコピーするために、私はこのコードの小片を使用します。

OpenClipboard(hWnd); 
EmptyClipboard(); 

SetClipboardData(CF_BITMAP, hBitmap); 

CloseClipboard(); 

私は私のアプリを実行すると、私はコピーすることができていますそのビットマップを貼り付けて、たとえばMS Paintのどこかに貼り付けます。しかし、もう一度コピーしようとすると、上記のコードの最初の部分が再度実行されない限り、クリップボードの内容を貼り付けることはできません。 MSDN documentation

は、SetClipboardDataが成功した場合

は、システムはHMemのパラメータによって識別されるオブジェクトを所有していると言われています。

私はこれが何を意味するのか正確には分かりませんが、私の問題の原因だと思います。 hereが必要な機能を実行する例が見つかりましたが、同じ種類の変数は使用されていないようです。今回は文字列を使用したもう1つの例はhereです。

私はこの最後の例を私のケースにどのように翻訳するかについてはあまりよく分かりません。あなたは私を正しい方向に向けることができますか?

+0

「COLORREF」はRGBおよびRGBA画像用ですが、これは32ビットのグレースケール画像のようです。私はこれをやったので、それは長いです、そして、私はドキュメンテーションに明らかな警告を見ることができませんでした。 –

+0

@RemyLebeau興味深いことに、http://stackoverflow.com/questions/32086618/who-releases-handle-in-setclipboarddatacf-bitmap-hbitmapのOPテストの結果は明らかに、システムが実際にビットマップ。 –

+1

[クリップボード形式](https://msdn.microsoft.com/en-us/library/windows/desktop/ms649013.aspx)ドキュメントの 'CF_BITMAP'に関する注意を参照してください。 'CF_BITMAP'はDDBであり、そのまま保存することはできません。変換されてDIBとして保存されます。 –

答えて

0

削除されたコメントは私が答えを見つけるのを助けました。実際にHBITMAPを別のHBITMAPにコピーしてからSetClipboardDataを呼び出す必要があります。このようにして、コピーしたビットマップをクリップボードに送ることができ、元のビットマップは後で保存されます。

ビットマップをコピーするには、Copying a Bitmap to another Bitmapにあるコードを使用しました。私のコードでは、次のようになります:

// Create a new bitmap 
HBITMAP hBitmap_copy = CreateBitmap(imageSize[0], imageSize[1], 1, 32, NULL); 

// Copy the source bitmap to the new one  
HDC srcDC = CreateCompatibleDC(GetDC(NULL)); 
HDC newDC = CreateCompatibleDC(GetDC(NULL)); 

HBITMAP srcBitmap = (HBITMAP)SelectObject(srcDC, hBitmap); 
HBITMAP newBitmap = (HBITMAP)SelectObject(newDC, hBitmap_copy); 

BitBlt(newDC, 0, 0, imageSize[0], imageSize[1], srcDC, 0, 0, SRCCOPY); 

SelectObject(srcDC, srcBitmap); 
SelectObject(newDC, newBitmap); 

DeleteDC(srcDC); 
DeleteDC(newDC); 

// hBitmap_copy can now be copied to the clipboard 
OpenClipboard(hWnd); 
EmptyClipboard(); 

SetClipboardData(CF_BITMAP, hBitmap_copy); 

CloseClipboard(); 

これで、表示されたビットマップを何度でもコピーできます。

0
// You can't pass hBitmap to SetClipboardData directly 
OpenClipboard(NULL) 
HBITMAP hBitmap = getBit(); // From somewhere 

DIBSECTION ds; 
::GetObject(hBitmap, sizeof(DIBSECTION), &ds); 
//make sure compression is BI_RGB 
ds.dsBmih.biCompression = BI_RGB; 
HDC hdc = ::GetDC(NULL); 
HBITMAP hbitmap_ddb = ::CreateDIBitmap(
    hdc, &ds.dsBmih, CBM_INIT, ds.dsBm.bmBits, (BITMAPINFO*)&ds.dsBmih, DIB_RGB_COLORS); 
::ReleaseDC(NULL, hdc); 

EmptyClipboard(); 
SetClipboardData(CF_BITMAP, hbitmap_ddb); 
CloseClipboard(); 
関連する問題