展示截图(略大,4.24M):

这些把位图加载到内存DC上的代码需要重复使用,于是定义成宏:
#define READY_CODE
CGditestDlg *pMainDlg = (CGditestDlg *)pParam;
CDC *pDC = pMainDlg->GetDC();
CBitmap bmp;
if (1 == pMainDlg->m_counter)
{
bmp.LoadBitmap(IDB_BITMAP1);
pMainDlg->m_counter = 2;
}
else if (2 == pMainDlg->m_counter)
{
bmp.LoadBitmap(IDB_BITMAP2);
pMainDlg->m_counter = 3;
}
else
{
bmp.LoadBitmap(IDB_BITMAP3);
pMainDlg->m_counter = 1;
}
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);
dcMem.SelectObject(&bmp);
BITMAP bm;
bmp.GetBitmap(&bm);
pMainDlg->Invalidate();
EnumChildWindows(pMainDlg->GetSafeHwnd(),
EnumChildProc, 0L);
#define CLEAN_CODE
dcMem.DeleteDC();
bmp.DeleteObject();
EnumChildWindows(
pMainDlg->GetSafeHwnd(),
EnumChildProc, 1L);
#define PI 3.14
//弧度 = 2π * 角度 / 360
#define RADIAN(degree) ((float)((2 * PI * degree) / 360))
/*从上飞入*/
UINT CGditestDlg::FlyIntoFromTop(LPVOID pParam)
{
READY_CODE
for (int ySrc = bm.bmHeight; ySrc >= 0; ySrc -= 10)
{
pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcMem, 0, ySrc, SRCCOPY);
Sleep(1);
}
CLEAN_CODE
return 0;
}
/*从左飞入*/
UINT CGditestDlg::FlyIntoFromLeft(LPVOID pParam)
{
READY_CODE
for (int xSrc = bm.bmWidth; xSrc >= 0; xSrc -= 10)
{
pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcMem, xSrc, 0, SRCCOPY);
Sleep(1);
}
CLEAN_CODE
return 0;
}
/*从上展开*/
UINT CGditestDlg::UnfoldFromTop(LPVOID pParam)
{
READY_CODE
for (int htDes = 0; htDes <= bm.bmHeight; htDes += 10)
{
pDC->BitBlt(0, 0, bm.bmWidth, htDes, &dcMem, 0, 0, SRCCOPY);
Sleep(1);
}
CLEAN_CODE
return 0;
}
/*从左展开*/
UINT CGditestDlg::UnfoldFromLeft(LPVOID pParam)
{
READY_CODE
for (int wtDes = 0; wtDes <= bm.bmWidth; wtDes += 10)
{
pDC->BitBlt(0, 0, wtDes, bm.bmHeight, &dcMem, 0, 0, SRCCOPY);
Sleep(1);
}
CLEAN_CODE
return 0;
}
百叶窗就是把位图分块同步显示,原理比较简单。
/*水平百叶窗*/
UINT CGditestDlg::HorizontalWindow(LPVOID pParam)
{
READY_CODE
int n = bm.bmHeight / 8;
for (int htDes = 0; htDes <= n; htDes += 1)
{
for (int i = 0; i < 8; i++)
{
pDC->BitBlt(0, n * i, bm.bmWidth, htDes, &dcMem, 0, n * i, SRCCOPY);
}
Sleep(10);
}
CLEAN_CODE
return 0;
}
/*垂直百叶窗*/
UINT CGditestDlg::VerticalWindow(LPVOID pParam)
{
READY_CODE
int n = bm.bmWidth / 8;
for (int wtDes = 0; wtDes <= n; wtDes += 1)
{
for (int i = 0; i < 8; i++)
{
pDC->BitBlt(n * i, 0, wtDes, bm.bmHeight, &dcMem, n * i, 0, SRCCOPY);
}
Sleep(10);
}
CLEAN_CODE
return 0;
}
拉直其实和百叶窗相差不了多少,也是分块同步显示,但是每一块是慢慢变大的。
/*往下拉直*/
UINT CGditestDlg::StraightenToBottom(LPVOID pParam)
{
READY_CODE
int n = bm.bmHeight / 8;
for (int htDes = 0; htDes <= n; htDes += 1)
{
for (int i = 0; i < 8; i++)
{
pDC->BitBlt(0, htDes * i, bm.bmWidth, htDes, &dcMem, 0, n * i, SRCCOPY);
}
Sleep(10);
}
CLEAN_CODE
return 0;
}
/*往右拉直*/
UINT CGditestDlg::StraightenToRight(LPVOID pParam)
{
READY_CODE
int n = bm.bmWidth / 8;
for (int wtDes = 0; wtDes <= n; wtDes += 1)
{
for (int i = 0; i < 8; i++)
{
pDC->BitBlt(wtDes * i, 0, wtDes, bm.bmHeight, &dcMem, n * i, 0, SRCCOPY);
}
Sleep(10);
}
CLEAN_CODE
return 0;
}
由小变大主要是要保存图像比例和算位图从在哪个坐标显示,图像大小发生变化,坐标随之变化。可以先确定图像的宽,然后 长=宽*(高/2);x坐标=位图实际的宽/2-当前的宽/2,y坐标=位图实际的高/2-当前的高/2。
/*由小变大*/
UINT CGditestDlg::SmallToLarge(LPVOID pParam)
{
READY_CODE
float x, y, w, h;
float base = 0;
pDC->SetStretchBltMode(HALFTONE);
while ((int)(base += 10) <= bm.bmWidth)
{
w = base;
h = base * ((float)bm.bmHeight / (float)bm.bmWidth);
x = (float)bm.bmWidth / 2 - w / 2;
y = (float)bm.bmHeight / 2 - h / 2;
pDC->StretchBlt((int