我需要在WS_OVERLAPPED窗口中制作鸟动画(如下图所示)。动画由8幅图像表示:

图像中的蓝色(即RGB(0, 255, 255))必须是透明的(见下面的屏幕快照)。
我想使用CreateWindowEx() (用分层窗口表示鸟)和WS_EX_LAYERED参数来完成这个任务。不幸的是,鸟一定是WS_CHILD。WS_EX_LAYERED | WS_CHILD 不合法在Windows 7中的混合
WS_EX_LAYERED样式支持顶层窗口和子窗口.以前的windows版本只支持顶层窗口的WS_EX_LAYERED。
最后的效果应该是这样的(我已经绘制了窗口的背景-唯一的问题是鸟):

我怎样才能达到这个效果?如何在父窗口中激活鸟?
如果您知道如何实现透明背景色的鸟类动画,请分享。
发布于 2013-03-11 22:35:07
我终于知道该怎么做了。这很棘手。
解决方案的完整描述可以在这里获得- Wing.org/教程/transparency.html。
波兰读者请听伟大的翻译的报道。
简单的想法:
给出位图的外观有透明的部分是相当简单的,并涉及使用黑白面具图像除了的彩色图像,我们想要看透明的。要使效果正常工作,需要满足以下条件:首先,彩色图像必须在我们希望显示为透明的所有区域都是黑色的。其次,--在我们想要透明的区域,面具图像必须是白色的,而在其他地方,则必须是黑色的。颜色和掩模图像显示为本页示例图片中最左边的两个图像。
简单的解决方案:
#define TRANSPARENCY_COLOR RGB(0, 255, 255)
birdBmp = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
hbmpMask = CreateBitmapMask(birdBmp, TRANSPARENCY_COLOR);绘画:
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
HDC birdMaskHdc = CreateCompatibleDC(hdc);
BITMAP bmInfo;
GetObject(birdBmp, sizeof(bmInfo), &bmInfo);
HBITMAP hbmpOld = (HBITMAP) SelectObject(birdMaskHdc, hbmpMask);
BitBlt(hdc, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight, birdMaskHdc, 0, 0, SRCAND);
SelectObject(birdMaskHdc, birdBmp);
BitBlt(hdc, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight, birdMaskHdc, 0, 0, SRCPAINT);
SelectObject(birdMaskHdc, hbmpOld);
DeleteDC(birdMaskHdc);
EndPaint(hWnd, &ps);
break;
}清洁:
case WM_DESTROY:
{
DeleteObject(hbmpMask);
DeleteObject(birdBmp);
PostQuitMessage(0);
break;
}函数,该函数负责创建位图掩码:
HBITMAP CreateBitmapMask(HBITMAP hbmColour, COLORREF crTransparent)
{
HDC hdcMem, hdcMem2;
HBITMAP hbmMask, hbmOld, hbmOld2;
BITMAP bm;
GetObject( hbmColour, sizeof( BITMAP ), & bm );
hbmMask = CreateBitmap( bm.bmWidth, bm.bmHeight, 1, 1, NULL );
hdcMem = CreateCompatibleDC( NULL );
hdcMem2 = CreateCompatibleDC( NULL );
hbmOld =( HBITMAP ) SelectObject( hdcMem, hbmColour );
hbmOld2 =( HBITMAP ) SelectObject( hdcMem2, hbmMask );
SetBkColor( hdcMem, crTransparent );
BitBlt( hdcMem2, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY );
BitBlt( hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem2, 0, 0, SRCINVERT );
SelectObject( hdcMem, hbmOld );
SelectObject( hdcMem2, hbmOld2 );
DeleteDC( hdcMem );
DeleteDC( hdcMem2 );
return hbmMask;
}发布于 2013-03-10 19:56:33
由于动画是在没有与窗口交互的情况下完成的,所以我们需要一个计时器:
case WM_CREATE:
// load resources
SetTimer(hwnd, 0, 250, NULL); // set timer to 250 ms
return 0;
...
case WM_DESTROY:
KillTimer(hwnd, 0);
// release the resources
return 0;我们可以使每个计时器勾选的整个窗口失效,但最好只重画所需的部分。我们还将在这里更新当前的帧号:
case WM_TIMER:
frame_number++;
if (frame_number >= 8)
frame_number = 0;
RECT rc = { 30, 30, 80, 80 }; // a rectangle from (30,30) to (80,80)
InvalidateRect(hwnd, &rc, FALSE);
return 0;然后,在WM_PAINT处理程序中绘制当前帧:
case WM_PAINT:
// draw the sky
SelectObject(hDCMem, hBird);
TransparentBlt(hDC, 30, 30, 50, 50, hDCMem, frame_number * 51, 0, 50, 50, RGB(0, 255, 255)); // 51 is 50 (side of a bird frame) + 1 (gap between the frames)
// draw the rest
return 0;https://stackoverflow.com/questions/15324807
复制相似问题