www.pudn.com > IFSEditor.rar > ProgressDlg.cpp


// ProgressDlg.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "IFSEditor.h" 
#include "ProgressDlg.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CProgressDlg dialog 
 
static long g_bShouldClose; 
static long g_bClosed; 
 
CProgressDlg::CProgressDlg(CWnd* pParent /*=NULL*/) 
	: CDialog(CProgressDlg::IDD, pParent) 
{ 
	//{{AFX_DATA_INIT(CProgressDlg) 
		// NOTE: the ClassWizard will add member initialization here 
	//}}AFX_DATA_INIT 
	m_pDoc = NULL; 
} 
 
 
void CProgressDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CProgressDlg) 
	DDX_Control(pDX, IDC_PROGRESS, m_Progress); 
	//}}AFX_DATA_MAP 
} 
 
 
BEGIN_MESSAGE_MAP(CProgressDlg, CDialog) 
	//{{AFX_MSG_MAP(CProgressDlg) 
	//}}AFX_MSG_MAP 
	ON_MESSAGE(WM_USER + 1, OnUserOne) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CProgressDlg message handlers 
 
void CProgressDlg::OnOK()  
{ 
	// TODO: Add extra validation here 
} 
 
void CProgressDlg::OnCancel()  
{ 
	// TODO: Add extra cleanup here 
	if(g_bClosed == 0) 
	{ 
		::InterlockedIncrement(&g_bShouldClose); 
		for(;g_bClosed == 0;)::Sleep(10); 
	} 
	CDialog::OnCancel(); 
} 
 
BOOL CProgressDlg::OnInitDialog()  
{ 
	CDialog::OnInitDialog(); 
	 
	// Start render thread 
	if(m_pDoc) 
	{ 
		// Create bitmap for display 
		CDC ScreenDC, memdc; 
		CBitmap *pOldBmp; 
		CBrush BackBrush; 
		CRect rt(0, 0, m_pDoc->m_dwWidth, m_pDoc->m_dwHeight); 
		for(;ScreenDC.CreateDC("DISPLAY", NULL, NULL, NULL) == FALSE;); 
		memdc.CreateCompatibleDC(&ScreenDC); 
		m_bmpRender.CreateCompatibleBitmap(&ScreenDC, m_pDoc->m_dwWidth, m_pDoc->m_dwHeight); 
		BackBrush.CreateSolidBrush(m_pDoc->m_clrBack); 
		pOldBmp = (CBitmap *)memdc.SelectObject(&m_bmpRender); 
		memdc.FillRect(rt, &BackBrush); 
		memdc.SelectObject(pOldBmp); 
		BackBrush.DeleteObject(); 
		memdc.DeleteDC(); 
		ScreenDC.DeleteDC(); 
 
		// Transfer variables 
		int ItemCount; 
		HBITMAP hRender = (HBITMAP)m_bmpRender.GetSafeHandle(); 
		HWND hWnd = GetSafeHwnd(); 
		BYTE *pMem = new BYTE[sizeof(COLORREF) * 2 +  
		sizeof(int) * 6 + sizeof(HBITMAP) + sizeof(long) * 2 + sizeof(HWND) + 
		sizeof(double) * 7 * (ItemCount = m_pDoc->m_IFSArray.GetSize())]; 
		BYTE *pMemSafe = pMem; 
		memcpy(pMem, &m_pDoc->m_clrBack, sizeof(COLORREF)); 
		pMem += sizeof(COLORREF); 
		memcpy(pMem, &m_pDoc->m_clrFore, sizeof(COLORREF)); 
		pMem += sizeof(COLORREF); 
		memcpy(pMem, &m_pDoc->m_dwWidth, sizeof(int)); 
		pMem += sizeof(int); 
		memcpy(pMem, &m_pDoc->m_dwHeight, sizeof(int)); 
		pMem += sizeof(int); 
		memcpy(pMem, &m_pDoc->m_dwUnitLenX, sizeof(int)); 
		pMem += sizeof(int); 
		memcpy(pMem, &m_pDoc->m_dwUnitLenY, sizeof(int)); 
		pMem += sizeof(int); 
		memcpy(pMem, &m_pDoc->m_ptStartPos.x, sizeof(long)); 
		pMem += sizeof(long); 
		memcpy(pMem, &m_pDoc->m_ptStartPos.y, sizeof(long)); 
		pMem += sizeof(long); 
		memcpy(pMem, &m_pDoc->m_dwN, sizeof(int)); 
		pMem += sizeof(int); 
		memcpy(pMem, &ItemCount, sizeof(int)); 
		pMem += sizeof(int); 
		memcpy(pMem, &hRender, sizeof(HBITMAP)); 
		pMem += sizeof(HBITMAP); 
		memcpy(pMem, &hWnd, sizeof(HWND)); 
		pMem += sizeof(HWND); 
		for(int i=0; im_IFSArray[i].m_a, sizeof(double)); 
			pMem += sizeof(double); 
			memcpy(pMem, &m_pDoc->m_IFSArray[i].m_b, sizeof(double)); 
			pMem += sizeof(double); 
			memcpy(pMem, &m_pDoc->m_IFSArray[i].m_c, sizeof(double)); 
			pMem += sizeof(double); 
			memcpy(pMem, &m_pDoc->m_IFSArray[i].m_d, sizeof(double)); 
			pMem += sizeof(double); 
			memcpy(pMem, &m_pDoc->m_IFSArray[i].m_e, sizeof(double)); 
			pMem += sizeof(double); 
			memcpy(pMem, &m_pDoc->m_IFSArray[i].m_f, sizeof(double)); 
			pMem += sizeof(double); 
			memcpy(pMem, &m_pDoc->m_IFSArray[i].m_pi, sizeof(double)); 
			pMem += sizeof(double); 
		} 
		g_bShouldClose = 0; 
		g_bClosed = 0; 
 
 
		// Begin Render Thread 
		m_Progress.SetRange(0, 1000); 
		DWORD ThreadId; 
		::CloseHandle(::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RenderThread, pMemSafe, 0, &ThreadId)); 
	} 
	 
	return TRUE;  // return TRUE unless you set the focus to a control 
	              // EXCEPTION: OCX Property Pages should return FALSE 
} 
 
DWORD WINAPI RenderThread(BYTE *pMem) 
{ 
	CArray IFSArray; 
	COLORREF clrFore; 
	COLORREF clrBack; 
	CPoint ptStartPos; 
	int dwN; 
	int dwUnitLenY; 
	int dwUnitLenX; 
	int dwHeight; 
	int dwWidth; 
	int ItemCount; 
	HBITMAP hRender; 
	HWND hWnd; 
	IFSArray.SetSize(0, 1); 
 
	// Get Variables 
	BYTE *pMemSafe = pMem; 
	memcpy(&clrBack, pMem, sizeof(COLORREF)); 
	pMem += sizeof(COLORREF); 
	memcpy(&clrFore, pMem, sizeof(COLORREF)); 
	pMem += sizeof(COLORREF); 
	memcpy(&dwWidth, pMem, sizeof(int)); 
	pMem += sizeof(int); 
	memcpy(&dwHeight, pMem, sizeof(int)); 
	pMem += sizeof(int); 
	memcpy(&dwUnitLenX, pMem, sizeof(int)); 
	pMem += sizeof(int); 
	memcpy(&dwUnitLenY, pMem, sizeof(int)); 
	pMem += sizeof(int); 
	memcpy(&ptStartPos.x, pMem, sizeof(long)); 
	pMem += sizeof(long); 
	memcpy(&ptStartPos.y, pMem, sizeof(long)); 
	pMem += sizeof(long); 
	memcpy(&dwN, pMem, sizeof(int)); 
	pMem += sizeof(int); 
	memcpy(&ItemCount, pMem, sizeof(int)); 
	pMem += sizeof(int); 
	memcpy(&hRender, pMem, sizeof(HBITMAP)); 
	pMem += sizeof(HBITMAP); 
	memcpy(&hWnd, pMem, sizeof(HWND)); 
	pMem += sizeof(HWND); 
	for(int i=0; i= LowBound && RandNum < HighBound) 
			{ 
				IFSArray[j].Calculate(x, y); 
				break; 
			} 
			LowBound += IFSArray[j].m_pi; 
		} 
		::SetPixel(memdc, 
			(int)(dwUnitLenX * x + ptStartPos.x + 0.5), 
			(int)(dwHeight - 1 - dwUnitLenY * y - ptStartPos.y + 0.5), 
			clrFore); 
		if(g_bShouldClose) 
		{ 
			break; 
		} 
		CurPos = (int)((i + 1.0) / dwN * 1000); 
		if(CurPos != FormerPos) 
		{ 
			::PostMessage(hWnd, WM_USER + 1, CurPos, 0); 
			FormerPos = CurPos; 
		} 
	} 
	if(i == dwN) 
	{ 
		::SelectObject(memdc, hOldBmp); 
		::DeleteDC(memdc); 
		::InterlockedIncrement(&g_bClosed); 
		::PostMessage(hWnd, WM_USER + 1, 0, 0); 
	} 
	else 
	{ 
		::InterlockedIncrement(&g_bClosed); 
	} 
	return 0; 
} 
 
LRESULT CProgressDlg::OnUserOne(WPARAM wParam, LPARAM lParam) 
{ 
	if(wParam == 0) 
	{ 
		CDialog::OnOK(); 
	} 
	else 
	{ 
		m_Progress.SetPos(wParam); 
	} 
	return 0; 
}