C++ 如何制作缩小位图的动画并摆脱“;阴影&x201D;在OnEraseBkgnd()中使用StretchBlt围绕它?(MFC)
我想在C++ 如何制作缩小位图的动画并摆脱“;阴影&x201D;在OnEraseBkgnd()中使用StretchBlt围绕它?(MFC),c++,mfc,C++,Mfc,我想在OnEraseBkgnd()中使用StretchBlt制作缩小位图的动画 这是我的密码: BOOL CMainDlg::OnEraseBkgnd(CDC* pDC) { double rat = 1; //ratio double width, height, x, y, time=0; CBitmap Background; BITMAP bm; CDC dcMemory; Background.LoadBitmap(IDB_CO
OnEraseBkgnd()
中使用StretchBlt
制作缩小位图的动画
这是我的密码:
BOOL CMainDlg::OnEraseBkgnd(CDC* pDC)
{
double rat = 1; //ratio
double width, height, x, y, time=0;
CBitmap Background;
BITMAP bm;
CDC dcMemory;
Background.LoadBitmap(IDB_COVER); //Load Bitmap
Background.GetBitmap(&bm); //Load Bitmap into handle
dcMemory.CreateCompatibleDC(pDC);
dcMemory.SelectObject(&Background);
pDC->SetStretchBltMode(HALFTONE);
while(time <= 300){
width = 800 * rat;
height = 600 * rat;
x = (800 - width) / 2;
y = (600 - height) / 2;
pDC->StretchBlt((int)x, (int)y, (int)width, (int)height, &dcMemory, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
rat = easeOutExpo(time,1,-0.5,300);
time+=5;
Sleep(5); //Delay 5 millisecond
}
return TRUE;
}
double CMainDlg::easeOutExpo(double e,double t,double u,double a){
return (e==a)?t+u:u*(-pow(2,-10*e/a)+1)+t;
}
EDIT2:
我忘了说,
IDD_load
的对话框边框是NONE代码正在原始图像上绘制越来越小的图像。每次都必须重新绘制背景,然后绘制新的较小图像。例如:
pDC->FillSolidRect(&rect, GetSysColor(COLOR_3DFACE));
pDC->StretchBlt(x, y, width, height, &dcMemory, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
但是,必须使用双缓冲来避免闪烁
首先,创建一个与前面创建的类似的内存dc(buffer\u dc
)和一个内存位图(buffer\u bitmap
)
在每个过程中,使用FillSolidRect
填充buffer\u dc
的背景。在缓冲区\u dc
上绘制图像。最后,BitBlt
所有内容到pDC
:
BOOL CMainDlg::OnEraseBkgnd(CDC* pDC)
{
CRect rect;
GetClientRect(&rect);
CDC buffer_dc;
buffer_dc.CreateCompatibleDC(pDC);
CBitmap buffer_bitmap;
buffer_bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
CBitmap *buffer_oldbmp = buffer_dc.SelectObject(&buffer_bitmap);
...
while(time <= 300)
{
...
buffer_dc.FillSolidRect(&rect, GetSysColor(COLOR_3DFACE));
buffer_dc.StretchBlt((int)x, (int)y, (int)width, (int)height, &dcMemory, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &buffer_dc, 0, 0, SRCCOPY);
Sleep(5);
...
}
buffer_dc.SelectObject(buffer_oldbmp);
return TRUE;
}
谢谢但我在位图下有另一个背景图像。这意味着我不能使用
FillSolidRect
来填充“阴影”。那么,有什么方法可以调用OnEraseBkgnd()?或者用其他方法来解决这个问题?顺便说一下,闪烁问题仍然存在。我不知道问题出在哪里…你在哪里画背景图像?显示OnPaint
,OnEraseBkgnd
中的所有绘画代码……实际上,我所说的不是“真实的”背景图像。我只是想说背景不是单色的。我最初的想法是直接在“屏幕”上显示位图。(不在对话框上)因此“背景(对话框外)”不是纯色。有关如何处理无效
,请参阅编辑。对话框可以使自身失效,但它不能像您在另一个主题中尝试的那样,从OnInitDialog
执行该操作。
BOOL CMainDlg::OnEraseBkgnd(CDC* pDC)
{
CRect rect;
GetClientRect(&rect);
CDC buffer_dc;
buffer_dc.CreateCompatibleDC(pDC);
CBitmap buffer_bitmap;
buffer_bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
CBitmap *buffer_oldbmp = buffer_dc.SelectObject(&buffer_bitmap);
...
while(time <= 300)
{
...
buffer_dc.FillSolidRect(&rect, GetSysColor(COLOR_3DFACE));
buffer_dc.StretchBlt((int)x, (int)y, (int)width, (int)height, &dcMemory, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &buffer_dc, 0, 0, SRCCOPY);
Sleep(5);
...
}
buffer_dc.SelectObject(buffer_oldbmp);
return TRUE;
}
class CSpashDlg : public CDialog
{
public:
CSpashDlg(CWnd *wnd = NULL):CDialog(IDD_SPLASH, wnd){}
private:
CBitmap m_bitmap;
int m_width, m_height;
BOOL OnInitDialog()
{
CDialog::OnInitDialog();
HBITMAP hbitmap = (HBITMAP)LoadImage(0, L"test.bmp",
IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if(!hbitmap)
{
AfxMessageBox(L"bitmap file not found\n");
return TRUE;
}
m_bitmap.Attach(hbitmap);
BITMAP bm;
m_bitmap.GetBitmap(&bm);
m_width = bm.bmWidth;
m_height = bm.bmHeight;
SetWindowPos(0, 100, 100, m_width, m_height, SWP_NOREDRAW);
SetTimer(1, 1, 0);
return TRUE;
}
void OnTimer(UINT_PTR timer)
{
if(timer != 1)
return;
CRect rc;
GetWindowRect(&rc);
if(rc.Width() < 10 || rc.Height() < 10)
{
KillTimer(1);
PostMessage(WM_COMMAND, IDCANCEL);
return;
}
rc.InflateRect(-1, -1);
SetWindowPos(0, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOREDRAW);
Invalidate(FALSE);
}
void OnPaint()
{
CPaintDC dc(this);
CRect rc;
GetClientRect(&rc);
CDC memdc;
memdc.CreateCompatibleDC(0);
memdc.SelectObject(&m_bitmap);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, rc.Width(), rc.Height(),
&memdc, 0, 0, m_width, m_height, SRCCOPY);
}
BOOL OnEraseBkgnd(CDC*)
{
return TRUE;
}
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CSpashDlg, CDialog)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_TIMER()
END_MESSAGE_MAP()
class MyApp : public CWinApp
{
public:
BOOL InitInstance()
{
CWinApp::InitInstance();
CSpashDlg splash;
splash.DoModal();
CDialog dlg(IDD_DIALOG1);
dlg.DoModal();
return FALSE;
}
} a_app;