📄 dslvedlg.cpp
字号:
// dslvedlg.cpp : implementation file
//
#include "stdafx.h"
#include "dslvexp.h"
#include "dslvedlg.h"
#include "math.h"
#include "dibapi.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
//The bitmap dimensions.
#define BM_WIDTH 320
#define BM_HEIGHT 240
//Total number of dissolve steps.
#define NUM_STEPS 8
/////////////////////////////////////////////////////////////////////////////
// CDslvexpDlg dialog
CDslvexpDlg::CDslvexpDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDslvexpDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CDslvexpDlg)
// 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 CDslvexpDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDslvexpDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDslvexpDlg, CDialog)
//{{AFX_MSG_MAP(CDslvexpDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_KEYDOWN()
ON_WM_LBUTTONDOWN()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDslvexpDlg message handlers
BOOL CDslvexpDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//Load the 2nd bitmap (the one we'll dissolve to).
//Create a CFile object for the DIB file.
CFile dibFile("hibisc2.bmp", CFile::modeRead);
//Read the DIB file into memory.
hdib = ::ReadDIBFile(dibFile);
if (!hdib)
{
MessageBox("Error reading DIB file.", MB_OK, NULL);
return TRUE;
}
//Close the file.
dibFile.Close();
//Create a logical palette from the DIB file's palette.
palette = new CPalette;
if (palette == NULL)
{
//If we can't create the CPalette object,
//we must be really low on memory.
::GlobalFree((HGLOBAL) hdib);
hdib = NULL;
AfxMessageBox("Not enough memory for palette.");
}
if (::CreateDIBPalette(hdib, palette) == NULL)
AfxMessageBox("Error creating palette from DIB.");
//Get the bitmap size.
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) hdib);
int cxDIB = (int) ::DIBWidth(lpDIB);
int cyDIB = (int) ::DIBHeight(lpDIB);
//Make the window the same size as the bitmap.
SetWindowPos(&wndTop, 0, 0, cxDIB, cyDIB, SWP_NOMOVE);
CenterWindow();
//"Display" the second bitmap (the one we'll
//dissolve to) in its memory device context.
pDC = GetDC();
pDisplayMemDC2 = new CDC;
pDisplayMemDC2->CreateCompatibleDC(pDC);
//Set the DIB rectangle sizes to be
//equal to the bitmap size.
CRect DIBRect;
DIBRect.left = DIBRect.top = 0;
DIBRect.right = (int) ::DIBWidth(lpDIB);
DIBRect.bottom = (int) ::DIBHeight(lpDIB);
::GlobalUnlock((HGLOBAL) hdib);
//Select and realize the palette.
pDisplayMemDC2->SelectPalette(palette, FALSE);
pDisplayMemDC2->RealizePalette();
CBitmap dummy;
if (!dummy.CreateBitmap(DIBRect.Width(), DIBRect.Height(), 1, 8, NULL))
MessageBox("Error creating bitmap.");
pDisplayMemDC2->SelectObject(&dummy);
//"Display" the bitmap.
if (::PaintDIB(pDisplayMemDC2->m_hDC, &DIBRect, hdib, &DIBRect, palette) == FALSE)
MessageBox("Error painting DIB");
//Load the first bitmap (the one we'll dissolve over).
pDisplayMemDC1 = new CDC;
CBitmap* pBitmap = new CBitmap;
pBitmap->LoadBitmap(IDB_BITMAP1);
pDisplayMemDC1->CreateCompatibleDC(pDC);
pDisplayMemDC1->SelectObject(pBitmap);
delete pBitmap;
//Load the dissolve brush pixel patterns.
CreatePixelSetSequence();
//We start at dissolve step 0;
m_dissolveStep = 0;
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 CDslvexpDlg::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 it's the first time thru, display the
//source bitmap and return.
if (m_dissolveStep == 0)
{
int x = (rect.Width() - BM_WIDTH) / 2;
int y = (rect.Height() - BM_HEIGHT) / 2;
if (!dc.BitBlt(x,y,BM_WIDTH,BM_HEIGHT,pDisplayMemDC1,0,0,SRCCOPY))
MessageBox("Error displaying bitmap.");
}
else
{
//Get the current dissolve brush.
CBrush* newBrush = CreateDissolveBrush(m_dissolveStep);
HANDLE oldBrush = dc.SelectObject(newBrush);
//Select and realize the palette.
dc.SelectPalette(palette, FALSE);
dc.RealizePalette();
if (!dc.BitBlt(0,0,rect.Width(),rect.Height(),pDisplayMemDC2,0,0,0x00AC0744L))
MessageBox("Error blitting bitmap");
dc.SelectObject(oldBrush);
delete newBrush;
}
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CDslvexpDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CDslvexpDlg::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);
PixelSetSequence[count] = atoi(buf);
}
fclose(pixels);
}
CBrush* CDslvexpDlg::CreateDissolveBrush(int dissolveStep)
{
//Create a dissolve brush for the
//current dissolve step.
CBrush* pBr = new CBrush;
//If we're at the last dissolve step we need a
//solid black brush.
if (dissolveStep == NUM_STEPS)
{
pBr->CreateSolidBrush(RGB(0,0,0));
return pBr;
}
//If we're at an intermediate dissolve step
//we must generate the brush.
CBitmap bitmap;
int row, col;
//Byte array for pixel values.
BYTE pixels[16];
//Initialize the array.
for (int 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.
for (counter = 1; counter <= (dissolveStep * (64 / NUM_STEPS)); counter++)
{
row = (PixelSetSequence[counter] - 1) / 8;
col = (PixelSetSequence[counter] - 1) % 8;
pixels[row * 2] = pixels[row * 2] & (~(BYTE)pow(2,col));
}
//Create a bitmap from the array.
if (!bitmap.CreateBitmap(8, 8, 1, 1, pixels))
{
MessageBox("Error creating bitmap");
return NULL;
}
//Create a brush from the bitmap.
if (!pBr->CreatePatternBrush(&bitmap))
{
MessageBox("Could not create brush.");
return NULL;
}
return pBr;
}
void CDslvexpDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
//When a key is pressed, go to the next
//dissolve step and repaint the window.
if (m_dissolveStep < NUM_STEPS)
{
m_dissolveStep++;
InvalidateRect(NULL, FALSE);
}
}
void CDslvexpDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
//Set a timer with a 100 millisecond interval.
int nTimer = SetTimer(1,100,NULL);
}
void CDslvexpDlg::OnTimer(UINT nIDEvent)
{
//When the timer counts down, go to the
//next dissolve step and repaint the display.
if (m_dissolveStep < NUM_STEPS)
{
m_dissolveStep++;
InvalidateRect(NULL, FALSE);
}
//If dissolve is complete, kill the timer.
else
KillTimer(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -