VC 在桌面窗口显示图片,之前显示的图片不消失

jerrywky 2021-02-09 06:25:54
想做一个软件启动画,就是在程序窗口显示之前,先显示几张(比如3张)图片。使用CImage类,显示的图片格式为PNG。
希望得到的效果是:第一张显示,延时,消失;显示第二张,延时,再消失。显示第3张,延时,再消失。
可实际效果是:前面显示的图片总是存在,不消失。
第一张显示正常,后面的图片显示时,之前显示的图片却依然存在,不消失。所以,最终显示到第3张的时候,就相当在桌面上同时显示了3张图片重叠在一起。

望有高手能够指点一下,问题出在了哪里。非常感谢!


主要的代码如下:

void welcomestart(const float &secondsTimeout = 1)
{
//float secondsTimeout:每周图片显示的时长。单位:s

CWindowDC dc(CWnd::GetDesktopWindow());
//得到屏幕的尺寸,
int cx = GetSystemMetrics(SM_CXSCREEN);
int cy = GetSystemMetrics(SM_CYSCREEN);
// //资源句柄
HRSRC hRsrc = NULL;
//显示的图片数量,每次要显示3张图片
int cout_show = 0;
while (cout_show < 3)
{
//计数加1
cout_show++;
int temp_i = 0;
temp_i = cout_show %2;
//根据得到随机数,加载不同的图片资源
BOOL res1 = FALSE;
switch (temp_i)
{
case 0:
{
//加载第1张图片
hRsrc = ::FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_PNG1), _T("PNG"));
break;
}
case 1:
{
//加载第2张图片
hRsrc = ::FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_PNG2), _T("PNG"));
break;
}
case 2:
{
//加载第3张图片
hRsrc = ::FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_PNG1), _T("PNG"));
break;
}
}
// 查找资源
if (hRsrc == NULL)
return;
// 加载资源
HGLOBAL hImgData = ::LoadResource(AfxGetResourceHandle(), hRsrc);
if (hImgData == NULL)
{
::FreeResource(hImgData);
return;
}
// 锁定内存中的指定资源
LPVOID lpVoid = ::LockResource(hImgData);
DWORD dwSize = ::SizeofResource(AfxGetResourceHandle(), hRsrc);
HGLOBAL hNew = ::GlobalAlloc(GHND, dwSize);
LPBYTE lpByte = (LPBYTE)::GlobalLock(hNew);
::memcpy(lpByte, lpVoid, dwSize);
// 解除内存中的指定资源
::GlobalUnlock(hNew);
LPSTREAM pStream = nullptr;
CImage image2Display;
// 从指定内存创建流对象
HRESULT ht = ::CreateStreamOnHGlobal(hNew, TRUE, &pStream);
if (ht != S_OK)
{
GlobalFree(hNew);
}
else
{
// 加载图片
image2Display.Load(pStream);
GlobalFree(hNew);
}
// 释放资源
::FreeResource(hImgData);
//////////////////////////////////////////////////////
if (image2Display.GetBPP() == 32) //确认该图像包含Alpha通道
{
int i;
int j;
for (i = 0; i < image2Display.GetWidth(); i++)
{
for (j = 0; j < image2Display.GetHeight(); j++)
{
byte *pByte = (byte *)image2Display.GetPixelAddress(i, j);
pByte[0] = pByte[0] * pByte[3] / 255;
pByte[1] = pByte[1] * pByte[3] / 255;
pByte[2] = pByte[2] * pByte[3] / 255;
pByte = nullptr;
}
}
}
if (!image2Display.IsNull())
{

//得到图片尺寸,以便居中显示
int image_width = image2Display.GetWidth();
int image_height = image2Display.GetHeight();
//透明显示图片
image2Display.AlphaBlend(dc.m_hDC, (cx - image_width) / 2, (cy - image_height) / 2);
int nElapse = secondsTimeout * 1000;
//图片显示时长:单位:ms
Sleep(nElapse);
CRect rectPic((cx - image_width) / 2, (cy - image_height) / 2, (cx + image_width) / 2, (cy + image_height) / 2);
//################################################################################
//$$$$$$$$$$$$$下面的这3行代码,都不能使已经显示的图片消失$$$$$$$$$$$$$$$$$$$$$$$
//::InvalidateRect(GetDesktopWindow(), rectPic, TRUE);
//::RedrawWindow(GetDesktopWindow(), &rectPic, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_NOCHILDREN);
//::UpdateWindow(GetDesktopWindow());
//###################################################################################
}
//销毁图片
image2Display.Destroy();
hRsrc = NULL;
hImgData = NULL;
lpVoid = nullptr;
hNew = NULL;
lpByte = nullptr;
pStream = nullptr;
}
}
...全文
536 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
jerrywky 2021-03-09
  • 打赏
  • 举报
回复
@把海弄干的鱼歌者 不好意思,最近太忙了,回复晚了。后来我也是这样解决的。谢谢你!
[PE]经典八炮 2021-02-20
  • 打赏
  • 举报
回复
这样直接Invalidate就行了
[PE]经典八炮 2021-02-20
  • 打赏
  • 举报
回复
可以换个思路,在主窗口显示之前创建一个没有标题栏的窗口,在上面绘制图片,这样还可以拖动。VS2019的启动界面就是类似的,也是一个窗口,不信可以用系统截图工具的“窗口截图”功能,能捕获到启动画面。
schlafenhamster 2021-02-11
  • 打赏
  • 举报
回复
需要先擦除背景

19,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧