// ClockView.cpp : implementation of the CClockView class // #include "stdafx.h" #include #include #include "Clock.h" #include "ClockDoc.h" #include "ClockView.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif static CRITICAL_SECTION clockCriticalSection; static HWND hWindow = NULL; static HANDLE hThread = NULL; static UINT threadID = 0; static BOOL threadActive = FALSE; static BOOL terminateThread = FALSE; static unsigned __stdcall runThread(void* ArgList /* = NULL */); ///////////////////////////////////////////////////////////////////////////// // CClockView double CClockView::cosines[12]; double CClockView::sinuses[12]; BOOL CClockView::bCosinesCalculated = FALSE; IMPLEMENT_DYNCREATE(CClockView, CView) BEGIN_MESSAGE_MAP(CClockView, CView) //{{AFX_MSG_MAP(CClockView) ON_WM_ERASEBKGND() //}}AFX_MSG_MAP ON_MESSAGE(WM_USER, OnWMUser) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CClockView construction/destruction CClockView::CClockView(): clock_w(60), clock_h(60), clock_dx(5), clock_dy(5), font_size(14), m_Font(), m_Brush(RGB(210, 210, 210)), m_BluePen(PS_SOLID, 1, RGB(32, 32, 255)), m_BlackPen(PS_SOLID, 1, RGB(0, 0, 0)), m_RedPen(PS_SOLID, 1, RGB(255, 32, 32)) { // TODO: add construction code here } CClockView::~CClockView() { } BOOL CClockView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CClockView drawing void CClockView::OnDraw(CDC* pDC) { CClockDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here CRect clientRect; GetClientRect(&clientRect); pDC->FillRect(&clientRect, &m_Brush); pDC->SetBkMode(TRANSPARENT); CTime theTime = CTime::GetCurrentTime(); CString sTime = theTime.Format("%d %B %Y, %H:%M:%S"); // time == "19 March 1991" CPen* oldPen = pDC->SelectObject(&m_BlackPen); //... CBrush* oldBrush = pDC->SelectObject(&m_Brush); pDC->MoveTo(10, 10); pDC->LineTo(100, 100); pDC->SelectObject(&m_RedPen); pDC->MoveTo(100, 10); pDC->LineTo(10, 100); //... pDC->SelectObject(oldBrush); pDC->SelectObject(oldPen); pDC->DrawText( sTime, CRect(0, 0, 300, 20), DT_LEFT | DT_VCENTER ); } ///////////////////////////////////////////////////////////////////////////// // CClockView diagnostics #ifdef _DEBUG void CClockView::AssertValid() const { CView::AssertValid(); } void CClockView::Dump(CDumpContext& dc) const { CView::Dump(dc); } CClockDoc* CClockView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CClockDoc))); return (CClockDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CClockView message handlers LONG CClockView::OnWMUser(UINT message, LONG) { Invalidate(FALSE); return 0; } void CClockView::PostNcDestroy() { // TODO: Add your specialized code here and/or call the base class BOOL active; EnterCriticalSection(&clockCriticalSection); terminateThread = TRUE; active = threadActive; LeaveCriticalSection(&clockCriticalSection); CWaitCursor tmpCursor; while (active) { Sleep(200); EnterCriticalSection(&clockCriticalSection); active = threadActive; LeaveCriticalSection(&clockCriticalSection); } DeleteCriticalSection(&clockCriticalSection); CView::PostNcDestroy(); } void CClockView::OnInitialUpdate() { CView::OnInitialUpdate(); // TODO: Add your specialized code here and/or call the base class InitializeCriticalSection(&clockCriticalSection); // For clock face drawing: compute cos, sin of 5-minute angles double angle = 0., da = 3.14158 / 6.; for (int i = 0; i < 12; i++, angle += da) { cosines[i] = cos(angle); sinuses[i] = sin(angle); } hWindow = m_hWnd; terminateThread = FALSE; hThread = (HANDLE) _beginthreadex( NULL, // pointer to thread security attributes 0, // initial thread stack size, in bytes runThread, // pointer to thread function NULL, // argument for new thread 0, // creation flags &threadID // pointer to returned thread ID ); } BOOL CClockView::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default CRect clientRect; GetClientRect(&clientRect); pDC->FillRect(&clientRect, &m_Brush); // return CView::OnEraseBkgnd(pDC); return TRUE; } static unsigned __stdcall runThread(void* ArgList /* = NULL */) { threadActive = TRUE; while (!terminateThread) { Sleep(1000); PostMessage( hWindow, WM_USER, 0, 0 ); } EnterCriticalSection(&clockCriticalSection); terminateThread = FALSE; threadActive = FALSE; LeaveCriticalSection(&clockCriticalSection); return 0; }