⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 schedulehandler.h

📁 Vc.Net入门与提高源码
💻 H
字号:
// ScheduleHandler.h : Defines the ATL Server request handler class
// (c) 2000 Microsoft Corporation
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Classes Reference and related electronic
// documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft C++ Libraries products.

#pragma once

#include "ScheduleDB.h"

#define START_TIME	8	// Start the schedule at 08:00 (8 A.M.)
#define END_TIME	20	// End the schedule at 19:00 (8 P.M.)

inline HRESULT AddNewAppointment(
		CDataConnection& DataConnection,
		long nMonth,
		long nDay,
		long nYear,
		long nTime,
		long nUserID,
		LPCTSTR szTitle,
		LPCTSTR szLocation,
		LPCTSTR szDetails)
	{
		CNewAppointment newAppointment;

		// Copy the data into the appointment
		sprintf(newAppointment.m_szDate, "%d/%d/%d", nMonth, nDay, nYear);
		lstrcpy(newAppointment.m_szTitle, szTitle);
        lstrcpy(newAppointment.m_szLocation, szLocation);
        lstrcpy(newAppointment.m_szDetails, szDetails);
		newAppointment.m_lTime = nTime;
		newAppointment.m_lUserID = nUserID;

		// Add the appointment into the database
		return newAppointment.OpenRowset(DataConnection, NULL);
	}


// class CScheduleHandler
// This handler is responsible for displaying the entire schedule grid for a given day
// Note: There is a tag {{SetTodays}} used by welcome.srf which switches a boolean on.
//       This boolean ignores the current hour member to display the entire schedule 
//       for the day in sequence, without attempting to fit the appointments in a grid
//       like in schedule.srf.
class CScheduleHandler
	: public CRequestHandlerT<CScheduleHandler>,
	  public CMantaWebBase<CScheduleHandler>
{
private:
	HRESULT				m_hRes;				// Member HRESULT for DB calls			
	COleDateTime		m_date;				// The date viewed by the schedule
	COleDateTime		m_datePrev;			// The previous day's date
	COleDateTime		m_dateNext;			// The next day's date
	CAppointmentList	m_appointmentList;	// Schedule DB object
	bool				m_bFailed;			// Boolean to determine failure
	int					m_iCurHour;			// Current hour viewed
	bool				m_bTodays;			// Boolean to determine if we're listing today's schedule (from welcome screen)
	CStringA			m_strTitle;			// Title of the new appointment
	CStringA			m_strLocation;		// Location of the new appointment
	CStringA			m_strDetails;		// Details of the new appointment
	LONG				m_lStart;			// Start of new appointment (in 24 hour format, duration is assumed to be 1 hour)
	
public:
	CScheduleHandler() : m_bFailed(false),
		                 m_iCurHour(START_TIME),
						 m_bTodays(false)
	{
		// Set the status to invalid
		m_date.SetStatus(COleDateTime::invalid);
	}

	HTTP_CODE ValidateAndExchange()
	{
		// Set the content type to html
		m_HttpResponse.SetContentType("text/html");

		// Validate the session
		if (!ValidateSession())
			return ValidationError();
			
		const CHttpRequestParams& QueryParams = m_HttpRequest.GetQueryParams();
		const CHttpRequestParams& FormFields = m_HttpRequest.GetFormVars();
		
		// Set the internal date to the one specified by query params
		// If its invalid, reset to today
		int year, month, day;
        QueryParams.Exchange("year", &year);
		QueryParams.Exchange("month", &month);
		QueryParams.Exchange("day", &day);
		m_date.SetDate(year, month, day);
		if (m_date.GetStatus() != COleDateTime::valid)
			m_date = COleDateTime::GetCurrentTime();

		// If this is a valid form submition
		if (FormFields.Lookup("title") != NULL &&
			FormFields.Lookup("start") != NULL &&
			FormFields.Lookup("duration") != NULL)
		{
			// Validate and add new appointment
			if (ValidateFormData(FormFields))
			{
				if (AddNewAppointment() != HTTP_SUCCESS)
					return HTTP_SUCCESS_NO_PROCESS;
			}
			else
				m_bFailed = true;	// Data was invalid
		}
		else
		{
			// Set the default values
			m_lStart = 8;
		}
		
		// Set the next and previous days
		m_datePrev = m_date - COleDateTimeSpan(1, 0, 0, 0);
		m_dateNext = m_date + COleDateTimeSpan(1, 0, 0, 0);

		// Open up the schedule for the internal date
		GetUserID(&m_appointmentList.m_lUserID);
		sprintf(m_appointmentList.m_szDate, "%d/%d/%d", m_date.GetMonth(), m_date.GetDay(), m_date.GetYear());

		m_hRes = m_appointmentList.OpenRowset(m_dataConnection, NULL);
		if (m_hRes != S_OK)
			return DatabaseError("CSchedule::OpenRowset()", m_hRes);
	
		m_hRes = m_appointmentList.MoveFirst();
		if (m_hRes != S_OK && m_hRes != DB_S_ENDOFROWSET)
			return DatabaseError("CSchedule::MoveFirst()", m_hRes);
	
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnNextDay()
	{
		// Respond with the next day's day
		m_HttpResponse << m_dateNext.GetDay();
		return HTTP_SUCCESS;
	}
	
	HTTP_CODE OnNextMonth()
	{
		// Respond with the next day's month
		m_HttpResponse << m_dateNext.GetMonth();
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnNextYear()
	{
		// Respond with the next day's year
		m_HttpResponse << m_dateNext.GetYear();
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnPrevDay()
	{
		// Respond with the previous day's day
		m_HttpResponse << m_datePrev.GetDay();
		return HTTP_SUCCESS;
	}
	
	HTTP_CODE OnPrevMonth()
	{
		// Respond with the previous day's month
		m_HttpResponse << m_datePrev.GetMonth();
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnPrevYear()
	{
		// Respond with the previous day's year	
		m_HttpResponse << m_datePrev.GetYear();
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnDate()
	{
		// Respond with the long date
		m_HttpResponse << m_date.Format("%A, %B %d, %Y");
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnSetTodays()
	{
		// Note: this is used in the welcome.srf to let us know that we want to ignore m_iCurHour
		// and list all the appoinments for today in order
		m_bTodays = true;
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnRowsLeft()
	{
		// Used in schedule.srf to run through all the rows
		ATLASSERT(m_iCurHour >= START_TIME && m_iCurHour <= END_TIME);
		return (m_iCurHour < END_TIME) ? HTTP_SUCCESS : HTTP_S_FALSE;
	}

	HTTP_CODE OnNextRow()
	{
		// Used in schedule.srf to increment to the next row
		ATLASSERT(m_iCurHour >= START_TIME && m_iCurHour < END_TIME);
		if (m_appointmentList.m_lTime == m_iCurHour)
			m_appointmentList.MoveNext();
		m_iCurHour++;
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnCellColor()
	{
		// Respond with the cell color
		// white - scheduled, yellowish - not scheduled
		if (m_appointmentList.m_lTime == m_iCurHour)
			m_HttpResponse << "#FFFFFF";
		else
			m_HttpResponse << "#FFFFCC";
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnStartTime()
	{
		// If listing today's, just output the appointment start time
		// Otherwise, use the current hour
		if (m_bTodays)
			m_HttpResponse << ((m_appointmentList.m_lTime > 12) ? (m_appointmentList.m_lTime - 12) : m_appointmentList.m_lTime);
		else
			m_HttpResponse << ((m_iCurHour > 12) ? (m_iCurHour - 12) : m_iCurHour);
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnStartAM()
	{
		// If listing today's, return HTTP_SUCCESS if the appointment start time is AM
		// Otherwise, use the current hour
		if (m_bTodays)
			return (m_appointmentList.m_lTime >= 12) ? HTTP_S_FALSE : HTTP_SUCCESS;
		else
			return (m_iCurHour >= 12) ? HTTP_S_FALSE : HTTP_SUCCESS;
	}

	HTTP_CODE OnEndTime()
	{
		// If listing today's, just output the appointment end time
		// Otherwise, use the current hour
		if (m_bTodays)
			m_HttpResponse << ((m_appointmentList.m_lTime > 11) ? (m_appointmentList.m_lTime - 11) : (m_appointmentList.m_lTime + 1));
		else
			m_HttpResponse << ((m_iCurHour > 11) ? (m_iCurHour - 11) : (m_iCurHour + 1));
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnEndAM()
	{
		// If listing today's, return HTTP_SUCCESS if the appointment end time is AM
		// Otherwise, use the current hour
		if (m_bTodays)
			return (m_appointmentList.m_lTime >= 11) ? HTTP_S_FALSE : HTTP_SUCCESS;
		else
			return (m_iCurHour >= 11) ? HTTP_S_FALSE : HTTP_SUCCESS;
	}

	HTTP_CODE OnAppointmentsLeft()
	{
		// Return HTTP_SUCCESS if there are appointments still left
		return (m_hRes != S_OK) ? HTTP_S_FALSE : HTTP_SUCCESS;
	}

	HTTP_CODE OnAppointmentID()
	{
		// Respond with the appointment id
		if ( (!m_bTodays && m_appointmentList.m_lTime == m_iCurHour) || m_bTodays)
			m_HttpResponse << m_appointmentList.m_lAppointmentID;
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnAppointmentTitle()
	{
		// Respond with the appointment title
		if ( (!m_bTodays && m_appointmentList.m_lTime == m_iCurHour) || m_bTodays)
		{
			m_HttpResponse << m_appointmentList.m_szTitle;
			if (lstrlen(m_appointmentList.m_szLocation) > 0)
				m_HttpResponse << " (" << m_appointmentList.m_szLocation << ")";
		}
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnNextAppointment()
	{
		// Used in welcome.srf to get the next appointment
		m_hRes = m_appointmentList.MoveNext();
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnFailure()
	{
		return (m_bFailed) ? HTTP_SUCCESS : HTTP_S_FALSE;
	}

	HTTP_CODE OnMaxStringLen()
	{
		// Respond with the max string len
		m_HttpResponse << DB_MAX_STRLEN;
		return HTTP_SUCCESS;
	}
	
	HTTP_CODE OnMaxDetailsLen()
	{
		// Respond with the max details len
		m_HttpResponse << DB_MAX_DETAILSLEN;
		return HTTP_SUCCESS;
	}
		
	HTTP_CODE OnTitleInput()
	{
		// Respond with the appointment title
		m_HttpResponse << m_strTitle;
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnLocationInput()
	{
		// Respond with the appointment location
		m_HttpResponse << m_strLocation;
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnDetailsInput()
	{
		// Respond with the appointment details
		m_HttpResponse << m_strDetails;
		return HTTP_SUCCESS;
	}

	HTTP_CODE OnTimeSelected(int *pTime)
	{
		ATLASSERT(pTime != NULL);

		// Respond with the selected time if it matches the start time
		if (*pTime == m_lStart)
			m_HttpResponse << "selected";
		return HTTP_SUCCESS;
	}

	// Replacement method map
	BEGIN_REPLACEMENT_METHOD_MAP(CScheduleHandler)
		REPLACEMENT_METHOD_ENTRY("NextDay", OnNextDay)
		REPLACEMENT_METHOD_ENTRY("NextMonth", OnNextMonth)
		REPLACEMENT_METHOD_ENTRY("NextYear", OnNextYear)
		REPLACEMENT_METHOD_ENTRY("PrevDay", OnPrevDay)
		REPLACEMENT_METHOD_ENTRY("PrevMonth", OnPrevMonth)
		REPLACEMENT_METHOD_ENTRY("PrevYear", OnPrevYear)
		REPLACEMENT_METHOD_ENTRY("SetTodays", OnSetTodays)
		REPLACEMENT_METHOD_ENTRY("RowsLeft", OnRowsLeft)
		REPLACEMENT_METHOD_ENTRY("NextRow", OnNextRow)
		REPLACEMENT_METHOD_ENTRY("CellColor", OnCellColor)
		REPLACEMENT_METHOD_ENTRY("StartTime", OnStartTime)
		REPLACEMENT_METHOD_ENTRY("StartAM", OnStartAM)
		REPLACEMENT_METHOD_ENTRY("EndTime", OnEndTime)
		REPLACEMENT_METHOD_ENTRY("EndAM", OnEndAM)
		REPLACEMENT_METHOD_ENTRY("AppointmentsLeft", OnAppointmentsLeft)
		REPLACEMENT_METHOD_ENTRY("AppointmentID", OnAppointmentID)
		REPLACEMENT_METHOD_ENTRY("AppointmentTitle", OnAppointmentTitle)
		REPLACEMENT_METHOD_ENTRY("NextAppointment", OnNextAppointment)
		REPLACEMENT_METHOD_ENTRY("Date", OnDate)
		REPLACEMENT_METHOD_ENTRY("Failure", OnFailure)
		REPLACEMENT_METHOD_ENTRY("MaxStringLen", OnMaxStringLen)
		REPLACEMENT_METHOD_ENTRY("MaxDetailsLen", OnMaxDetailsLen)
		REPLACEMENT_METHOD_ENTRY("TitleInput", OnTitleInput)
		REPLACEMENT_METHOD_ENTRY("LocationInput", OnLocationInput)
		REPLACEMENT_METHOD_ENTRY("DetailsInput", OnDetailsInput)
		REPLACEMENT_METHOD_ENTRY_EX("TimeSelected", OnTimeSelected, int, DefaultParseInt)
	END_REPLACEMENT_METHOD_MAP()

private:
	bool ValidateFormData(const CHttpRequestParams& FormFields)
	{
		DWORD dwRet;
		// Validate the form data
		if (FormFields.Validate("title", &m_strTitle, 1, DB_MAX_STRLEN) != VALIDATION_S_OK)
			return false;

		// Prepare for HTML
		HTMLPrepareString(m_strTitle);
		if (m_strTitle.GetLength() > DB_MAX_STRLEN)
			return false;
		
		dwRet = FormFields.Validate("location", &m_strLocation, 0, DB_MAX_STRLEN);
		if (dwRet != VALIDATION_S_OK && dwRet != VALIDATION_S_EMPTY)
			return false;

		// Prepare for HTML
		HTMLPrepareString(m_strLocation);
		if (m_strLocation.GetLength() > DB_MAX_STRLEN)
			return false;
		
		dwRet = FormFields.Validate("details", &m_strDetails, 0, DB_MAX_DETAILSLEN);
		if (dwRet != VALIDATION_S_OK && dwRet != VALIDATION_S_EMPTY)
			return false;

		// Prepare for HTML
		HTMLPrepareString(m_strDetails);
		if (m_strDetails.GetLength() > DB_MAX_DETAILSLEN)
			return false;

		if (FormFields.Validate("start", &m_lStart, START_TIME, END_TIME) != VALIDATION_S_OK)
			return false;

		// Find the appoinment in the database to ensure no duplicates
		CFindAppointment findAppointment;

		sprintf(findAppointment.m_szDate, "%d/%d/%d", m_date.GetMonth(), m_date.GetDay(), m_date.GetYear());
		findAppointment.m_lTime = m_lStart;
		GetUserID(&findAppointment.m_lUserID);
		
		if (findAppointment.OpenRowset(m_dataConnection, NULL) != S_OK)
			return false;

		HRESULT hr = findAppointment.MoveFirst();
		if (hr == DB_S_ENDOFROWSET)
			return true;	// Return true, no duplicate appointment

		// Duplicate found
		return false;
	}

	HTTP_CODE AddNewAppointment()
	{
		long lUserID = 0;
		GetUserID(&lUserID);

		// Add the appointment into the database
		HRESULT hr = ::AddNewAppointment(m_dataConnection,
									m_date.GetMonth(),
									m_date.GetDay(),
									m_date.GetYear(),
									m_lStart,
									lUserID,
									m_strTitle,
									m_strLocation,
									m_strDetails);

		if (hr != S_OK)
			return DatabaseError("CNewAppointment::OpenRowset()", hr);

		// Reset the member variables
		m_strTitle = "";
		m_strLocation = "";
		m_strDetails = "";
		m_lStart = 8;
		return HTTP_SUCCESS;
	}

}; // class CScheduleHandler

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -