// PrintCircleDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "PrintCircle.h"
#include "PrintCircleDlg.h"
#include "time.h"
#include "RainbowColour.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define RANDOM_COLOR RGB(rand()%155+100,rand()%155+100,rand()%155+100)
// CPrintCircleDlg 对话框
//unsigned srand(time(NULL));
//重新定义线程函数,在线程函数中等待事件对象
unsigned long __stdcall DrawCircle(LPVOID pThreadParam)
{
CPrintCircleDlg* pDlg = (CPrintCircleDlg*)pThreadParam;
WaitForSingleObject(pDlg->m_hEvent, 100 /*INFINITE*/);
CDC *pDC = pDlg->GetDC();
HDC hDC = pDC->GetSafeHdc();
CRect clientRC;
pDlg->GetClientRect(clientRC);
CPen mypen,bkpen;
CPen *oldpen;
CPoint pt = pDlg->m_Circle;
CPoint lastPtLeft; //记录圆最后的点,左上
CPoint lastPtRight; //记录圆最后的点,左上
if (clientRC.PtInRect(pt))
{
srand( pDlg->m_Seed );
/*COLORREF PenColor = RANDOM_COLOR;*/
RainbowColour myRainbowColour;
COLORREF PenColor = RGB(RainbowColour::nRed[pDlg->m_Seed],
RainbowColour::nGreen[pDlg->m_Seed],
RainbowColour::nBlue[pDlg->m_Seed]);
const int radius = 1;
int RandChange = rand()%50+30;
int MaxRange = RandChange; //记录圆的最大变化
for (int i= 0; i<RandChange; i++) //圆渐大
{
mypen.CreatePen(PS_SOLID,3,PenColor); //空心圆的画笔
bkpen.CreatePen(PS_SOLID,3,RGB(93,93,93)); //背景色的画笔
oldpen=pDC->SelectObject(&mypen);
MoveToEx(hDC, pt.x+radius+i, pt.y, NULL );
AngleArc(hDC, pt.x, pt.y, radius+i , 0, 360);
pDC->SelectObject(oldpen);
mypen.DeleteObject();
oldpen=pDC->SelectObject(&bkpen);
MoveToEx(hDC, pt.x+radius+i-3, pt.y, NULL );
AngleArc(hDC, pt.x, pt.y, radius+i-3, 0, 360);
pDC->SelectObject(oldpen);
bkpen.DeleteObject();
Sleep(50);
}
int RandSleepTime = rand()%3000+500;
Sleep(RandSleepTime);
for (int i= 0; i<RandChange+5; i++) //圆渐小
{
mypen.CreatePen(PS_SOLID,3,PenColor); //空心圆的画笔
bkpen.CreatePen(PS_SOLID,3,RGB(93,93,93)); //背景色的画笔
oldpen=pDC->SelectObject(&bkpen);
MoveToEx(hDC, pt.x+radius+MaxRange-i+3, pt.y, NULL );
AngleArc(hDC, pt.x, pt.y, MaxRange+radius-i+3, 0, 360);
pDC->SelectObject(oldpen);
bkpen.DeleteObject();
oldpen=pDC->SelectObject(&mypen);
MoveToEx(hDC, pt.x+MaxRange+radius-i, pt.y, NULL);
AngleArc(hDC, pt.x, pt.y, MaxRange+radius-i , 0, 360);
pDC->SelectObject(oldpen);
mypen.DeleteObject();
Sleep(20);
}
}
pDlg->ReleaseDC(pDC);
SetEvent(pDlg->m_hEvent);
return 0;
}
CPrintCircleDlg::CPrintCircleDlg(CWnd* pParent /*=NULL*/)
: CDialog(CPrintCircleDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_Seed = 0;
m_SuspendTimes = 0;
}
void CPrintCircleDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CPrintCircleDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_WM_LBUTTONDBLCLK()
ON_WM_LBUTTONDOWN()
ON_WM_ERASEBKGND()
ON_WM_RBUTTONDOWN()
END_MESSAGE_MAP()
// CPrintCircleDlg 消息处理程序
BOOL CPrintCircleDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CPrintCircleDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(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
{
CDC *pDC = GetDC();
CRect clientRC;
GetClientRect(clientRC);
pDC->FillSolidRect(clientRC, /*::GetSysColor*/RGB(93,93,93));
CDialog::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CPrintCircleDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CPrintCircleDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{
//PauseTask();
}
void CPrintCircleDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_Circle = point;
if (m_Seed==239) //跟RainbowColour::MAXSIZE相关链
m_Seed=0;
m_Seed++; //每次开启新线程发不同的种子
HANDLE hDrawCircle = CreateThread(NULL, 0, DrawCircle, this, 0, NULL); //创建一个画圆线程
HANDLE* phDrawCircle = new HANDLE(hDrawCircle);
m_ThreadList.push_back(*phDrawCircle); //线程指针放入容器
delete phDrawCircle;
ContinueTask(m_SuspendTimes);
CDialog::OnLButtonDown(nFlags, point);
}
BOOL CPrintCircleDlg::OnEraseBkgnd(CDC* pDC)
{
return TRUE; //解决刷新闪烁问题
//return CDialog::OnEraseBkgnd(pDC);
}
void CPrintCircleDlg::PauseTask()
{
for (size_t i=0; i<m_ThreadList.size(); i++)
{
DWORD exitCode = 0;
GetExitCodeThread(m_ThreadList[i], &exitCode);
if (exitCode != STILL_ACTIVE && m_ThreadList[i] != NULL)
{
m_ThreadList[i] = NULL;
CloseHandle(m_ThreadList[i]);
}
else if (exitCode == STILL_ACTIVE)
{
SuspendThread( m_ThreadList[i] );
}
}
}
int CPrintCircleDlg::ContinueTask(int times)
{
for (std::vector<HANDLE>::iterator iter = m_ThreadList.begin(); iter!=m_ThreadList.end(); iter++)
{
for (int i=0; i<times; i++)
{
ResumeThread( *iter );
}
}
DeleteNULLPointer(m_ThreadList);
return 0;
}
void CPrintCircleDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
PauseTask();
m_SuspendTimes++;
CDialog::OnRButtonDown(nFlags, point);
}
void CPrintCircleDlg::DeleteNULLPointer(std::vector<HANDLE> &vect)
{
for (std::vector<HANDLE>::iterator iter = vect.begin(); iter!=vect.end(); iter++)
{
if (*iter == NULL)
{
vect.erase(iter);
iter = vect.begin();
continue;
}
}
}