⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dissodlg.cpp

📁 C:Documents and SettingsAdministrator桌面VC++多媒体特效制作百例CHAR06DISSOLVE
💻 CPP
字号:
// dissodlg.cpp : implementation file
//

#include "stdafx.h"
#include "math.h"
#include "dissolve.h"
#include "dissodlg.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDissolveDlg dialog

CDissolveDlg::CDissolveDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDissolveDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDissolveDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CDissolveDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDissolveDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CDissolveDlg, CDialog)
	//{{AFX_MSG_MAP(CDissolveDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_KEYDOWN()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDissolveDlg message handlers

BOOL CDissolveDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	////
	//Load the 1st bitmap.
	//Create a CFile object for the DIB file.
	CFile dibFile1("housrock.bmp", CFile::modeRead);

	//Read the DIB file into memory. 
	m_hdib1 = ::ReadDIBFile(dibFile1);
	if (!m_hdib1)
		{
		MessageBox("Error reading DIB file.", MB_OK, NULL);
		return TRUE;
		}

	//Close the file.
	dibFile1.Close();
	
	//Create a CFile object for the 2nd DIB file.
	CFile dibFile2("kaibab.bmp", CFile::modeRead);

	//Read the DIB file into memory. 
	m_hdib2 = ::ReadDIBFile(dibFile2);
	if (!m_hdib2)
		{
		MessageBox("Error reading DIB file.", MB_OK, NULL);
		return TRUE;
		}

	dibFile2.Close();


	//Create logical palettes from the DIB file palettes.
	m_palette[0] = new CPalette;
	m_palette[NUM_STEPS-1] = new CPalette;
	if (m_palette[0] == NULL || m_palette[NUM_STEPS-1] == NULL)
	{
		//If we can't create both CPalette objects,
		//we must be really low on memory.
		::GlobalFree((HGLOBAL) m_hdib1);
		::GlobalFree((HGLOBAL) m_hdib2);
		m_hdib1 = m_hdib2 = NULL;
		MessageBox("Not enough memory for palettes.");
	}

	if (::CreateDIBPalette(m_hdib1, m_palette[0]) == NULL)
		MessageBox("Error creating palette from DIB.");

	if (::CreateDIBPalette(m_hdib2, m_palette[NUM_STEPS-1]) == NULL)
		MessageBox("Error creating palette from DIB.");
	
	//Get the bitmap sizes.
	LPSTR lpDIB1 = (LPSTR) ::GlobalLock((HGLOBAL) m_hdib1);
	LPSTR lpDIB2 = (LPSTR) ::GlobalLock((HGLOBAL) m_hdib2);
	m_bm1size = new CSize((int)::DIBWidth(lpDIB1),(int)::DIBHeight(lpDIB1));
	m_bm2size = new CSize((int)::DIBWidth(lpDIB2),(int)::DIBHeight(lpDIB2));
	::GlobalUnlock((HGLOBAL) m_hdib1);
	::GlobalUnlock((HGLOBAL) m_hdib2);

	//Make the window height and width equal to the
	//larger bitmap dimensions.
	int cxDIB, cyDIB;
	if (m_bm1size->cx > m_bm2size->cx)
		cxDIB = m_bm1size->cx;
	else
		cxDIB = m_bm2size->cx;

	if (m_bm1size->cy > m_bm2size->cy)
		cyDIB = m_bm1size->cy;
	else
		cyDIB = m_bm2size->cy;

	SetWindowPos(&wndTop, 0, 0, cxDIB, cyDIB, SWP_NOMOVE);
	CenterWindow();

	//"Display" each bitmap in its memory device context.
	CDC* pDC = GetDC();
	m_pDisplayMemDC1 = new CDC;
	m_pDisplayMemDC2 = new CDC;
	m_pDisplayMemDC1->CreateCompatibleDC(pDC);
	m_pDisplayMemDC2->CreateCompatibleDC(pDC);
				
	//Select and realize the palettes.
	m_pDisplayMemDC1->SelectPalette(m_palette[0], FALSE);
	m_pDisplayMemDC1->RealizePalette();
	m_pDisplayMemDC2->SelectPalette(m_palette[NUM_STEPS-1], FALSE);
	m_pDisplayMemDC2->RealizePalette();

	CBitmap dummy1, dummy2;
	if (!dummy1.CreateBitmap(m_bm1size->cx, m_bm1size->cy, 1, 8, NULL))
		MessageBox("Error creating bitmap.");
	if (!dummy2.CreateBitmap(m_bm2size->cx, m_bm2size->cy, 1, 8, NULL))
		MessageBox("Error creating bitmap.");
	m_pDisplayMemDC1->SelectObject(&dummy1);
	m_pDisplayMemDC2->SelectObject(&dummy2);

	//"Display" the bitmaps.
	CRect DIBRect1(0,0,m_bm1size->cx, m_bm1size->cy);
	CRect DIBRect2(0,0,m_bm2size->cx, m_bm2size->cy);
	if (::PaintDIB(m_pDisplayMemDC1->m_hDC, &DIBRect1, m_hdib1, &DIBRect1, m_palette[0]) == FALSE)
		MessageBox("Error painting DIB");
	if (::PaintDIB(m_pDisplayMemDC2->m_hDC, &DIBRect2, m_hdib2, &DIBRect2, m_palette[NUM_STEPS-1]) == FALSE)
		MessageBox("Error painting DIB");

	//Create the array of dissolve brushes.
	CreatePixelSetSequence();
	CreateDissolveBrushArray();

	//Create the dissolve palettes.
	if (!CreateDissolvePalettes())
		MessageBox("Palette creation failed.");

	//Set the flag.
	m_flag = FALSE;

	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CDissolveDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CPaintDC dc(this); // device context for painting

		//Get the client area dimensions.
		CRect rect;
		GetClientRect(&rect);

		if (m_flag)
		{
			//Dissolve the first picture into the display.
			if (dc.SelectPalette(m_palette[0], FALSE) == NULL)
				MessageBox("Error selecting palette.");
			dc.RealizePalette();
			for (int i = 0; i < NUM_STEPS; i++)
			{
				//Get the current dissolve brush.
				HANDLE oldBrush = dc.SelectObject(&m_newBrush[i]);
				if (!dc.BitBlt((rect.Width() - m_bm1size->cx) / 2,
					(rect.Height() - m_bm1size->cy) / 2,
					m_bm1size->cx,
					m_bm1size->cy,
					m_pDisplayMemDC1,
					0,0,0x00AC0744L))
						MessageBox("Error blitting bitmap");
				dc.SelectObject(oldBrush);
			}
		}
			else
			{
			//Dissolve the second picture into the display.
			for (int i = 0; i < NUM_STEPS ; i++)
				{
				//Select the dissolve palette corresponding to the
				//current dissolve step.
				dc.SelectPalette(m_palette[i], FALSE);
				dc.RealizePalette();
				
				//Get the current dissolve brush.
				HANDLE oldBrush = dc.SelectObject(&m_newBrush[i]);
				if (!dc.BitBlt((rect.Width() - m_bm2size->cx) / 2,
					(rect.Height() - m_bm2size->cy) / 2,
					m_bm2size->cx,
					m_bm2size->cy,
					m_pDisplayMemDC2,
					0,0,0x00AC0744L))
						MessageBox("Error blitting bitmap");
				dc.SelectObject(oldBrush);
				}
			}
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CDissolveDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CDissolveDlg::CreatePixelSetSequence(void)
{
//Reads dissolve brush pixel patterns from
//the text file PIXELLST.TXT.

	char buf[5];
	FILE *pixels = fopen("PIXELLST.TXT", "r");
	if (pixels == NULL)
		{
		MessageBox("Error opening PIXELLST.TXT");
		return;
		}
		
	for (int count = 1; count < 65; count++)
		{
		fgets(buf, 5, pixels);
		m_PixelSetSequence[count] = atoi(buf);
 		}
 
	fclose(pixels);
}

void CDissolveDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	//Toggle the flag and force repainting
	//of the entire window.

	m_flag = !m_flag;
	InvalidateRect(NULL,FALSE);
}

void CDissolveDlg::CreateDissolveBrushArray(void)
{
//Initializes the array of brushes with the 8
//gradations of dissolve brush.

	//Byte array for pixel values.
	BYTE pixels[16];
	int row, col, counter, dissolveStep;
	CBitmap* bitmap;

	for (dissolveStep = 0; dissolveStep < NUM_STEPS; dissolveStep++)
	{	
	//If we're at the last dissolve step we need a
	//solid black brush.

	if (dissolveStep == NUM_STEPS - 1)
		{
		m_newBrush[dissolveStep].CreateSolidBrush(RGB(0,0,0));
		return;
		}

	//If we're at an intermediate dissolve step
	//we must generate the brush.	
	//Initialize the array.
	for (counter = 0; counter < 8; counter++)
		pixels[counter * 2] = 0xFF;  	//Binary 11111111.

	//Set bits representing black pixels to 0,
	//based on data in the PixelSetSequence[] array.
	int x;
	for (counter = 1; counter <= (dissolveStep * (64 / NUM_STEPS)); counter++)
		{
		x = m_PixelSetSequence[counter];
		row = (m_PixelSetSequence[counter] - 1) / 8;
		col = (m_PixelSetSequence[counter] - 1) % 8;
		pixels[row * 2] = pixels[row * 2] & (~(BYTE)pow(2,col));
		}

	//Create a bitmap from the array.
	bitmap = new CBitmap;
	if (!bitmap->CreateBitmap(8, 8, 1, 1, pixels))
		{
		MessageBox("Error creating bitmap");
		return;
		}

	//Create a brush from the bitmap.
	if (!m_newBrush[dissolveStep].CreatePatternBrush(bitmap))
		{
		MessageBox("Could not create brush.");
		return;
		}
	delete bitmap;
	}
}

BOOL CDissolveDlg::CreateDissolvePalettes(void)
{
//Creates 6 intermediate palettes to soften the
//dissolve from one bitmap to another. Returns TRUE
//on success, FALSE on error.

	BOOL result = TRUE;
	LOGPALETTE tempPal;
	PALETTEENTRY palStepArray[256], palTempArray[256];
	tempPal.palVersion = 0x300;
	tempPal.palNumEntries = 1;
		
	//Create uninitialized palettes for entries 2-7.
	for (int i = 1; i < (NUM_STEPS - 1); i++)
		{
		m_palette[i] = new CPalette;
		if (m_palette[i] == NULL)
			result = FALSE;
		if ((m_palette[i]->CreatePalette(&tempPal)) == 0)
			result = FALSE;
		}

	//Be sure all of our palettes have 256 entries.
	for (i = 0; i < NUM_STEPS; i++)
		{
		if ((m_palette[i]->ResizePalette(256)) == 0)
			result = FALSE;
		}

	if (result == FALSE)
		return result;

	//Fill in the array with the step values for
	//the three colors for each palette entry. Start
	//By loading the starting and ending palette
	//values into the two arrays
	m_palette[0]->GetPaletteEntries(0, 256, palStepArray);
	m_palette[NUM_STEPS-1]->GetPaletteEntries(0, 256, palTempArray);

	//Next make each entry in palTempArray equal to the "step" for
	//that color/palette entry combination. This is the difference 
	//between the the values in the two palettes divided by the number
	//of steps.
	for (i = 0; i < 256; i++)
		{
		palTempArray[i].peRed =
			 (palTempArray[i].peRed - palStepArray[i].peRed) / (NUM_STEPS - 1);
		palTempArray[i].peBlue =
			 (palTempArray[i].peBlue - palStepArray[i].peBlue) / (NUM_STEPS - 1);
		palTempArray[i].peGreen =
			 (palTempArray[i].peGreen - palStepArray[i].peGreen) / (NUM_STEPS - 1);
		}
		
	//Now we create each intermediate palette by taking the
	//values in the starting palette and adding or subtracting
	//the corresponding step value.
	for (i = 1; i < (NUM_STEPS - 2); i++)
		{
		for (int j = 0; j < 256; j++)
			{
			palStepArray[j].peRed = palStepArray[j].peRed + palTempArray[j].peRed;
			palStepArray[j].peBlue = palStepArray[j].peBlue + palTempArray[j].peBlue;
			palStepArray[j].peGreen = palStepArray[j].peGreen + palTempArray[j].peGreen;
			if ((j > 9) && (j < 246))
				palStepArray[j].peFlags = PC_RESERVED;
			}
		m_palette[i]->SetPaletteEntries(0,256,palStepArray);
		}

	return result;
}

void CDissolveDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	//Destroy the palette objects.
	for (int i = 0; i < NUM_STEPS; i++)
		delete m_palette[i];	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -