私は通常このように描かれるレイヤードウィンドウを持っています:
private void SelectBitmap(Bitmap bitmap)
{
IntPtr screenDc = GetDC(IntPtr.Zero);
IntPtr memDc = CreateCompatibleDC(screenDc);
IntPtr hBitmap = IntPtr.Zero;
IntPtr hOldBitmap = IntPtr.Zero;
try
{
hBitmap = bitmap.GetHbitmap(Color.FromArgb(0));
hOldBitmap = SelectObject(memDc, hBitmap);
POINT sourceLocation = new POINT(0, 0);
BLENDFUNCTION blend = new BLENDFUNCTION();
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = 255;
blend.AlphaFormat = AC_SRC_ALPHA;
SIZE newSize = new SIZE(bitmap.Width, bitmap.Height);
POINT newLocation = new POINT(Location.X, Location.Y);
UpdateLayeredWindow(Handle, screenDc,
ref newLocation, ref newSize,
memDc,
ref sourceLocation, 0,
ref blend,
ULW_ALPHA);
}
finally
{
ReleaseDC(IntPtr.Zero, screenDc);
if (hBitmap != IntPtr.Zero)
{
SelectObject(memDc, hOldBitmap);
DeleteObject(hBitmap);
}
DeleteDC(memDc);
}
}
ただし、これは明らかに、呼び出されるたびにウィンドウ全体を再描画します。これは、大きなウィンドウではかなりのパフォーマンス低下になります。(私の最上位のPCでも、Win2Kで人々がそれをどのように処理できるのか疑問に思います)
レイヤードウィンドウに関するMicrosoftの論文を読むと、次のように書かれています。UpdateLayeredWindowは常にウィンドウ全体を更新します。ウィンドウの一部を更新するには、従来のWM_PAINTを使用し、SetLayeredWindowAttributesを使用してブレンド値を設定します。
上記が理解できません。WM_PAINTは、レイヤードウィンドウビットマップにアクセスし、その一部のみをウィンドウに再描画するためにどのように想定されていますか?私が理解したところによると、階層化されたウィンドウは単にWM_PAINTメッセージを無効にし、ユーザーが自分でウィンドウを描画することを期待しています。完了したカスタム描画にWM_PAINTをバインドする方法は明らかにありません。
私は非常に明白な何かを逃していますか?