[VC6] 在对话框上实现LOGO图片的渐变性切换效果

    一个比较简单的效果。在对话框上放几个单项选择,当用户改变选择时,在对话框上有一个LOGO性质的图片进行渐变性的切换,已反应当前的选择。实现的代码量很小。我从网络上下载了三个足球俱乐部LOGO的壁纸图片,首先把它们缩放到同样的尺寸,然后添加为图片资源。在程序运行时,随着选择的改变,从当前图片逐渐过渡到另一张图片。

    开发工具:VC6.0;

    相关API: GetDIBs, SetDIBitsToDevice;

    运行效果如下:

    

    主题代码量很小,所以可以完整列出如下:

CODE_ImgSwitch
#include "stdafx.h"
#include 
<stdlib.h>
#include 
"resource.h"

#define ID_TIMER    1 

HINSTANCE hInst;

//global variables
BYTE* lpCurBits; //当前显示用的
BYTE* lpCacheBits; //DIB临时存储区
//三幅图片
BYTE* lpBits[3];

//信息头
BITMAPINFO bminfo;

//图片所在矩形~
RECT rcImg;

//functions;
//准备工作
void DoPrepare(HWND hDlg);
LRESULT CALLBACK MyDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
void GetNextDIB(int percent, int iSel);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     
int       nCmdShow)
{
     
// TODO: Place code here.
    hInst = hInstance;
    DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL,
        (DLGPROC)MyDlgProc, 
0);
    
return 0;
}

//准备工作
void DoPrepare(HWND hDlg)
{
    HBITMAP hBitmap;
    BITMAP bm;
    
int i, stride;    
    HDC hdc 
= GetDC(hDlg);
    
//HDC hMemDC = CreateCompatibleDC(hdc);
    
//ReleaseDC(hDlg, hdc);
    
    
for(i=0; i<3; i++)
    {
        hBitmap 
= LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1 + i));
        
if(i == 0)
        {
            GetObject(hBitmap, 
sizeof(BITMAP), &bm);
            
//图片所在客户区矩形
            rcImg.left = 0;
            rcImg.top 
= 0;
            rcImg.right 
= bm.bmWidth;
            rcImg.bottom 
= bm.bmHeight;
            
//bminfo
            
//扫描行宽度(实际上图片大小一致)
            stride = (bm.bmWidth * 24 + 31/ 32 * 4;
            bminfo.bmiHeader.biSize 
= sizeof(BITMAPINFOHEADER);
            bminfo.bmiHeader.biPlanes 
= 1;
            bminfo.bmiHeader.biBitCount 
= 24;
            bminfo.bmiHeader.biWidth 
= bm.bmWidth;
            bminfo.bmiHeader.biHeight 
= bm.bmHeight;
            bminfo.bmiHeader.biSizeImage 
= bm.bmHeight * stride;                
        }
        
//lpBits[i] = (BYTE*)bm.bmBits;
        lpBits[i] = (BYTE*)malloc(bminfo.bmiHeader.biSizeImage);
        GetDIBits(hdc, hBitmap, 
0, bminfo.bmiHeader.biHeight, lpBits[i], &bminfo, DIB_RGB_COLORS);

        DeleteObject(hBitmap);
    }
    ReleaseDC(hDlg, hdc);
    
//DeleteDC(hMemDC);
    
//创建当前显示的DIB
    lpCurBits = (BYTE*)malloc(bminfo.bmiHeader.biSizeImage);
    memcpy(lpCurBits, lpBits[
0], bminfo.bmiHeader.biSizeImage);
    lpCacheBits 
= (BYTE*)malloc(bminfo.bmiHeader.biSizeImage);
}

//the dlg's window procedure
LRESULT CALLBACK MyDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    
static int iSel;
    
//当前百分比(当为100时,停止计时器)
    static int percent;
    
switch (message)
    {
        
case WM_INITDIALOG:
            {
                DoPrepare(hDlg);
                
//默认选中第一个选项
                CheckDlgButton(hDlg, IDC_RADIO1, BST_CHECKED);
                iSel 
= 0;
                percent 
= 0;
                
return TRUE;
            }
            
break;

        
case WM_COMMAND:
            
switch(LOWORD(wParam))
            {
            
case IDOK:
            
case IDCANCEL:
                EndDialog(hDlg, LOWORD(wParam));                
                
break;

            
case IDC_RADIO1:
            
case IDC_RADIO2:
            
case IDC_RADIO3:
                iSel 
= LOWORD(wParam) - IDC_RADIO1;
                percent 
= 100;
                
//把当前位图拷贝到缓冲区
                memcpy(lpCacheBits, lpCurBits, bminfo.bmiHeader.biSizeImage);
                SetTimer(hDlg, ID_TIMER, 
20, NULL);
                
break;
            }
            
break;

        
case WM_PAINT:
            {
                PAINTSTRUCT ps;
                HDC hdc 
= BeginPaint(hDlg, &ps);
                SetDIBitsToDevice(hdc, 
                    
00, rcImg.right, rcImg.bottom,
                    
00
                    
0, bminfo.bmiHeader.biHeight,
                    lpCurBits,
                    
&bminfo,
                    DIB_RGB_COLORS);

                EndPaint(hDlg, 
&ps);
            }
            
break;

        
case WM_TIMER:
            {
                
if(percent <= 0)
                {
                    KillTimer(hDlg, ID_TIMER);
                    
return TRUE;
                }
                percent 
-= 5;
                GetNextDIB(percent, iSel);
                InvalidateRect(hDlg, 
&rcImg, FALSE);
                
return TRUE;
            }
            
break;

        
case WM_DESTROY:
            {
                
int i;
                
for(i=0; i<3; i++)
                {
                    free(lpBits[i]);
                }
                free(lpCurBits);
                free(lpCacheBits);
            }
            
return TRUE;
    }
    
return FALSE;
}

//已当前百分比进行混合图像
//                            100                  0
//percent: 混合百分比  当前图片|------------------>|目标图片
//                             |---percent-->| 
//destDIB: 目标DIB
void GetNextDIB(int percent, int iSel)
{
    unsigned 
int i;
    
int x1, x2;
    
for(i=0; i<bminfo.bmiHeader.biSizeImage; i++)
    {
        x1 
= lpCacheBits[i];
        x2 
= lpBits[iSel][i];
        lpCurBits[i] 
= (BYTE)((x1*percent + x2*(100-percent) )/100);
    }
}

  

    源代码下载链接:

    https://files.cnblogs.com/hoodlum1980/ImgSwitch.rar    

原文地址:https://www.cnblogs.com/hoodlum1980/p/1787349.html