教學軟體、遊戲、多媒體課件中,位圖顯示特效(推拉、交錯、雨滴、百葉窗、隨機積木)能大幅提升吸引力。本文探討 VC++ 6.0 實作各種顯示技巧的原理與方法。
// 載入資源
m_Bitmap.LoadBitmap(IDB_BITMAP1);
// 建立記憶體 DC
CDC MemDC;
MemDC.CreateCompatibleDC(NULL);
MemDC.SelectObject(&m_Bitmap);
// 顯示
CClientDC ClientDC(this);
BITMAP BM;
m_Bitmap.GetObject(sizeof(BM), &BM);
ClientDC.BitBlt(x, y, BM.bmWidth, BM.bmHeight, &MemDC, 0, 0, SRCCOPY);
優點:速度快;缺點:執行檔膨脹、靈活度低。
HBITMAP hBitmap;
BITMAP BM;
CDC MemDC, ClientDC(this);
MemDC.CreateCompatibleDC(&ClientDC);
hBitmap = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),
_T("demo1.bmp"), IMAGE_BITMAP,
0, 0, LR_LOADFROMFILE);
MemDC.SelectObject(hBitmap);
::GetObject(hBitmap, sizeof(BM), &BM);
ClientDC.BitBlt(x, y, BM.bmWidth, BM.bmHeight, &MemDC, 0, 0, SRCCOPY);
優點:檔案獨立、無需重新編譯、執行檔較小;缺點:速度稍慢。
BITMAP m_Bm; // 位圖尺寸資訊
HBITMAP m_hBitmap; // 位圖句柄
CDC m_MemDC; // 記憶體 DC
// 建構函數初始化
m_MemDC.CreateCompatibleDC(NULL);
m_hBitmap = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),
_T("demo1.bmp"), IMAGE_BITMAP,
0, 0, LR_LOADFROMFILE);
m_MemDC.SelectObject(m_hBitmap);
::GetObject(m_hBitmap, sizeof(m_Bm), &m_Bm);
原理:將位圖掃描線分為奇/偶兩組,奇數行由上往下,偶數行由下往上同時展開。
CClientDC ClientDC(this);
for (int i = 0; i <= m_Bm.bmHeight; i += 2) {
int j = i;
while (j > 0) {
// 奇數行:上往下
ClientDC.StretchBlt(0, j-1, m_Bm.bmWidth, 1,
&m_MemDC, 0, m_Bm.bmHeight - (i - j - 1),
m_Bm.bmWidth, 1, SRCCOPY);
// 偶數行:下往上
ClientDC.StretchBlt(0, m_Bm.bmHeight - j, m_Bm.bmWidth, 1,
&m_MemDC, 0, i - j,
m_Bm.bmWidth, 1, SRCCOPY);
j -= 2;
}
Sleep(10); // 控制動畫速度
}
原理:最後一條掃描線從頂部移動到底部並保留軌跡,接著倒數第二條,以此類推,形成雨滴落下視覺。
// 程式碼略,核心邏輯:
// for 每條掃描線 (從最後一條到第一條)
// for 目標位置從 0 到 bmHeight
// StretchBlt 繪製單條掃描線到目標位置
// Sleep 控制速度
原理:將位圖分為 N 條水平條帶,每條條帶以隨機延遲或順序由左/右/中間展開/收合。
原理:將位圖切割為 M×N 小塊,按隨機順序在目標位置逐個貼上,形成積木堆疊動畫。
BOOL StretchBlt(
int x, int y, // 目標左上角
int nWidth, int nHeight,// 目標寬高
CDC* pSrcDC, // 來源 DC
int xSrc, int ySrc, // 來源左上角
int nSrcWidth, int nSrcHeight, // 來源寬高
DWORD dwRop); // SRCCOPY 等
特效核心在於動態計算來源/目標矩形,配合 Sleep 控制幀率。
StretchBlt 縮放繪製單行/單塊,避免逐像素操作。BitBlt 到螢幕,消除閃爍。Graphics::DrawImage 獲得更好縮放品質與 Alpha 混合支援。掌握 StretchBlt 矩形映射邏輯,配合迴圈與延遲,即可實作豐富多樣的位圖顯示特效。這些技巧不僅適用於 VC++ 6.0,同樣適用於現代 MFC/GDI+ 專案。建議封裝為 CBitmapEffect 類別,提供 PlayInterlace()、PlayRaindrop() 等統一介面,提升專案複用性。