Skip to content

Commit c06d22c

Browse files
authored
Merge pull request #12972 from JeremyKuhne/movebitmapcopy
Move bitmap copy code to HBITMAP
2 parents 4a6bc3a + 4ac0308 commit c06d22c

File tree

2 files changed

+34
-34
lines changed

2 files changed

+34
-34
lines changed

src/System.Private.Windows.Core/src/Windows/Win32/Graphics/Gdi/HBITMAP.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,35 @@ public void Dispose()
1212
PInvokeCore.DeleteObject(this);
1313
}
1414
}
15+
16+
/// <summary>
17+
/// Creates a compatible bitmap copying the content of the current bitmap.
18+
/// </summary>
19+
public HBITMAP CreateCompatibleBitmap(int width, int height)
20+
{
21+
using var screenDC = GetDcScope.ScreenDC;
22+
23+
// Create a compatible DC to render the source bitmap.
24+
using CreateDcScope sourceDC = new(screenDC);
25+
using SelectObjectScope sourceBitmapSelection = new(sourceDC, this);
26+
27+
// Create a compatible DC and a new compatible bitmap.
28+
using CreateDcScope destinationDC = new(screenDC);
29+
HBITMAP compatibleBitmap = PInvokeCore.CreateCompatibleBitmap(screenDC, width, height);
30+
31+
// Select the new bitmap into a compatible DC and blit in the original bitmap.
32+
using SelectObjectScope destinationBitmapSelection = new(destinationDC, compatibleBitmap);
33+
PInvokeCore.BitBlt(
34+
destinationDC,
35+
0,
36+
0,
37+
width,
38+
height,
39+
sourceDC,
40+
0,
41+
0,
42+
ROP_CODE.SRCCOPY);
43+
44+
return compatibleBitmap;
45+
}
1546
}

src/System.Windows.Forms/src/System/Windows/Forms/OLE/WinFormsOleServices.cs

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -46,46 +46,15 @@ static unsafe HRESULT IOleServices.GetDataHere(string format, object data, FORMA
4646
{
4747
if (format.Equals(DataFormatNames.Bitmap) && data is Bitmap bitmap)
4848
{
49-
// Save bitmap
50-
pmedium->u.hBitmap = GetCompatibleBitmap(bitmap);
49+
// GDI+ returns a DIBSECTION based HBITMAP. The clipboard only deals well with bitmaps created using
50+
// CreateCompatibleBitmap(). So, we convert the DIBSECTION into a compatible bitmap.
51+
pmedium->u.hBitmap = bitmap.GetHBITMAP().CreateCompatibleBitmap(bitmap.Width, bitmap.Height);
5152
}
5253

5354
return HRESULT.S_OK;
5455
}
5556

5657
return HRESULT.DV_E_TYMED;
57-
58-
static HBITMAP GetCompatibleBitmap(Bitmap bitmap)
59-
{
60-
using var screenDC = GetDcScope.ScreenDC;
61-
62-
// GDI+ returns a DIBSECTION based HBITMAP. The clipboard only deals well with bitmaps created using
63-
// CreateCompatibleBitmap(). So, we convert the DIBSECTION into a compatible bitmap.
64-
HBITMAP hbitmap = bitmap.GetHBITMAP();
65-
66-
// Create a compatible DC to render the source bitmap.
67-
using CreateDcScope sourceDC = new(screenDC);
68-
using SelectObjectScope sourceBitmapSelection = new(sourceDC, hbitmap);
69-
70-
// Create a compatible DC and a new compatible bitmap.
71-
using CreateDcScope destinationDC = new(screenDC);
72-
HBITMAP compatibleBitmap = PInvokeCore.CreateCompatibleBitmap(screenDC, bitmap.Size.Width, bitmap.Size.Height);
73-
74-
// Select the new bitmap into a compatible DC and render the blt the original bitmap.
75-
using SelectObjectScope destinationBitmapSelection = new(destinationDC, compatibleBitmap);
76-
PInvokeCore.BitBlt(
77-
destinationDC,
78-
0,
79-
0,
80-
bitmap.Size.Width,
81-
bitmap.Size.Height,
82-
sourceDC,
83-
0,
84-
0,
85-
ROP_CODE.SRCCOPY);
86-
87-
return compatibleBitmap;
88-
}
8958
}
9059

9160
static unsafe bool IOleServices.TryGetBitmapFromDataObject<T>(Com.IDataObject* dataObject, [NotNullWhen(true)] out T data)

0 commit comments

Comments
 (0)