// SpecialFxDlg.cpp : 实现文件 // #include "stdafx.h" #include "SpecialFx.h" #include "SpecialFxDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CSpecialFxDlg 对话框 CSpecialFxDlg::CSpecialFxDlg(CWnd* pParent /*=NULL*/) : CDialog(CSpecialFxDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_bStop = FALSE; } void CSpecialFxDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_CHECKWATER, m_chkWater); DDX_Control(pDX, IDC_CHECKFIRE, m_chkFire); DDX_Control(pDX, IDC_CHECKPLASMA, m_chkPlasma); DDX_Control(pDX, IDC_SLIDERFIREALPHA, m_sldrFire); DDX_Control(pDX, IDC_SLIDERPLASMAALPHA, m_sldrPlasma); } BEGIN_MESSAGE_MAP(CSpecialFxDlg, CDialog) ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_WM_MOUSEMOVE() ON_WM_LBUTTONDOWN() ON_WM_TIMER() ON_BN_CLICKED(IDC_CHECKWATER, OnBnClickedCheckwater) ON_BN_CLICKED(IDC_CHECKFIRE, OnBnClickedCheckfire) ON_BN_CLICKED(IDC_CHECKPLASMA, OnBnClickedCheckplasma) ON_BN_CLICKED(IDC_BUTTONANIMATE, OnBnClickedButtonanimate) ON_BN_CLICKED(IDC_BUTTONSTOP, OnBnClickedButtonstop) ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDERFIREALPHA, OnNMCustomdrawSliderfirealpha) ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDERPLASMAALPHA, OnNMCustomdrawSliderplasmaalpha) END_MESSAGE_MAP() // CSpecialFxDlg 消息处理程序 BOOL CSpecialFxDlg::OnInitDialog() { CDialog::OnInitDialog(); // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 /************************************************************************/ CPictureHolder myTmpPicture; myTmpPicture.CreateFromBitmap(IDB_CODEPROJECTBMP); m_bmpRenderSource.Create32BitFromPicture(&myTmpPicture,402,120); m_bmpRenderTarget.Create32BitFromPicture(&myTmpPicture,402,120); // m_bmpRenderTarget.SetBitmap(IDB_CODEPROJECTBMP);// will be overwritten.... // create water object m_myWater.Create(402,120); // come on baby light my fire.. (ok create our fire object) m_myFire.m_iAlpha = 30;// want a 30% alpha m_myFire.m_iHeight = 120; m_myFire.m_iWidth = 402; m_myFire.InitFire(); m_sldrFire.SetRange(1,100,TRUE); m_sldrFire.SetPos(30); // finally the plasma m_myPlasma.Create(402,120); m_myPlasma.m_iAlpha = 30;// 30 % alpha m_sldrPlasma.SetRange(1,100,TRUE); m_sldrPlasma.SetPos(30); // set up the check boxes and our booleans m_bRunWater = TRUE; m_bRunFire = FALSE; m_bRunPlasma = FALSE; m_chkWater.SetCheck(TRUE); /************************************************************************/ return TRUE; // 除非设置了控件的焦点,否则返回 TRUE } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CSpecialFxDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); // 使图标在工作矩形中居中 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; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { CPaintDC dc(this); CPoint ptOrigin(15,20); m_bmpRenderTarget.Draw(&dc,ptOrigin); CDialog::OnPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标显示。 HCURSOR CSpecialFxDlg::OnQueryDragIcon() { return static_cast(m_hIcon); } void CSpecialFxDlg::OnMouseMove(UINT nFlags, CPoint point) { // see if its in our picture... // ScreenToClient(&point); if ( m_bStop ) return; CRect rcPicture; rcPicture.left = 15; rcPicture.top = 20; rcPicture.right = rcPicture.left + m_bmpRenderSource.GetWidth(); rcPicture.bottom = rcPicture.top + m_bmpRenderSource.GetHeight(); if(rcPicture.PtInRect(point) == TRUE) { // since dibs are drawn upside down we need to flip the y position (for it to look right) point.y -= 20;// offset from top of screen to image.. point.y = 120-point.y; m_myWater.HeightBlob(point.x -15,point.y,5,50,m_myWater.m_iHpage); } CDialog::OnMouseMove(nFlags, point); } void CSpecialFxDlg::OnLButtonDown(UINT nFlags, CPoint point) { if ( m_bStop ) return; CRect rcPicture; rcPicture.left = 15; rcPicture.top = 20; rcPicture.right = rcPicture.left + m_bmpRenderSource.GetWidth(); rcPicture.bottom = rcPicture.top + m_bmpRenderSource.GetHeight(); if(rcPicture.PtInRect(point) == TRUE) { // since dibs are drawn upside down we need to flip the y position (for it to look right) point.y -= 20;// offset from top of screen to image.. point.y = 120-point.y; // ; m_myWater.HeightBlob(point.x-15,point.y,50,500,m_myWater.m_iHpage); } CDialog::OnLButtonDown(nFlags, point); } // 如何使波纹不在OnTimer内实现; void CSpecialFxDlg::OnTimer(UINT nIDEvent) { if(nIDEvent == 1971) { // if ( m_bStop ) // return; if(!m_bRunWater) m_myWater.FlattenWater();// flatten it so it appears we turned it off... m_myWater.Render((DWORD*)m_bmpRenderSource.GetDIBits(),(DWORD*)m_bmpRenderTarget.GetDIBits()); if(m_bRunFire) m_myFire.Render((DWORD*)m_bmpRenderTarget.GetDIBits(),402,120); if(m_bRunPlasma) m_myPlasma.Render((DWORD*)m_bmpRenderTarget.GetDIBits(),402,120,402); CClientDC dc(this); CPoint ptOrigin(15,20); m_bmpRenderTarget.Draw(&dc,ptOrigin); } CDialog::OnTimer(nIDEvent); } void CSpecialFxDlg::OnBnClickedCheckwater() { m_bRunWater = m_chkWater.GetCheck(); } void CSpecialFxDlg::OnBnClickedCheckfire() { m_bRunFire = m_chkFire.GetCheck(); } void CSpecialFxDlg::OnBnClickedCheckplasma() { m_bRunPlasma = m_chkPlasma.GetCheck(); } void CSpecialFxDlg::OnBnClickedButtonanimate() { m_nTimer = SetTimer(1971,5,NULL); m_bStop = FALSE; } void CSpecialFxDlg::OnBnClickedButtonstop() { m_bStop = TRUE; //KillTimer(m_nTimer); } void CSpecialFxDlg::OnNMCustomdrawSliderfirealpha(NMHDR *pNMHDR, LRESULT *pResult) { LPNMCUSTOMDRAW pNMCD = reinterpret_cast(pNMHDR); m_myFire.m_iAlpha = m_sldrFire.GetPos(); *pResult = 0; } void CSpecialFxDlg::OnNMCustomdrawSliderplasmaalpha(NMHDR *pNMHDR, LRESULT *pResult) { LPNMCUSTOMDRAW pNMCD = reinterpret_cast(pNMHDR); m_myPlasma.m_iAlpha = m_sldrPlasma.GetPos(); *pResult = 0; } // // 内存泄漏,在KillTimer后,m_bmpRenderTarget // 和 m_bmpRenderSource仍在活动; // 内存DC一块没有清除完全; BOOL CSpecialFxDlg::DestroyWindow() { m_bStop = TRUE; KillTimer(m_nTimer); Sleep(500); #if 1 m_myWater.~CWaterRoutine(); m_myFire.~CFireRoutine(); m_myPlasma.~CPlasmaRoutine(); #endif m_bmpRenderTarget.DeleteObject(); m_bmpRenderSource.DeleteObject(); return CDialog::DestroyWindow(); }