📄 dissodlg.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 + -