1268 lines
30 KiB
C++
1268 lines
30 KiB
C++
// HoursCtl.cpp : Implementation of the CHoursCtrl OLE control class.
|
|
|
|
#include "stdafx.h"
|
|
#include "Hours.h"
|
|
#include "HoursCtl.h"
|
|
#include "HoursPpg.h"
|
|
|
|
#include <time.h>
|
|
#include <sys\timeb.h>
|
|
|
|
#ifdef _DEBUG
|
|
//#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
IMPLEMENT_DYNCREATE(CHoursCtrl, COleControl)
|
|
|
|
//#ifdef DBCS
|
|
// For localization
|
|
// We hate hardcord resource
|
|
// V-HIDEKK 1996.09.23
|
|
USHORT CONTROL_WIDTH = 375;
|
|
USHORT CONTROL_HEIGHT = 163;
|
|
USHORT DAY_BUTTON_WIDTH = 83;
|
|
USHORT HOUR_BUTTON_HEIGHT = 20;
|
|
|
|
USHORT CELL_WIDTH = ((CONTROL_WIDTH - DAY_BUTTON_WIDTH) / 24);
|
|
USHORT CELL_HEIGHT = ((CONTROL_HEIGHT - HOUR_BUTTON_HEIGHT) / 7);
|
|
/*
|
|
#else
|
|
const USHORT CONTROL_WIDTH = 375;
|
|
const USHORT CONTROL_HEIGHT = 163;
|
|
const USHORT DAY_BUTTON_WIDTH = 83;
|
|
const USHORT HOUR_BUTTON_HEIGHT = 20;
|
|
|
|
const USHORT CELL_WIDTH = ((CONTROL_WIDTH - DAY_BUTTON_WIDTH) / 24);
|
|
const USHORT CELL_HEIGHT = ((CONTROL_HEIGHT - HOUR_BUTTON_HEIGHT) / 7);
|
|
#endif
|
|
*/
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Message map
|
|
|
|
BEGIN_MESSAGE_MAP(CHoursCtrl, COleControl)
|
|
//{{AFX_MSG_MAP(CHoursCtrl)
|
|
ON_WM_CREATE()
|
|
ON_WM_SETCURSOR()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_LBUTTONUP()
|
|
ON_WM_MOUSEMOVE()
|
|
//}}AFX_MSG_MAP
|
|
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Dispatch map VT_ARRAY
|
|
|
|
BEGIN_DISPATCH_MAP(CHoursCtrl, COleControl)
|
|
//{{AFX_DISPATCH_MAP(CHoursCtrl)
|
|
DISP_PROPERTY_NOTIFY(CHoursCtrl, "crPermitColor", m_crPermitColor, OnCrPermitColorChanged, VT_COLOR)
|
|
DISP_PROPERTY_NOTIFY(CHoursCtrl, "crDenyColor", m_crDenyColor, OnCrDenyColorChanged, VT_COLOR)
|
|
DISP_PROPERTY_EX(CHoursCtrl, "DateData", GetDateData, SetDateData, VT_VARIANT)
|
|
//}}AFX_DISPATCH_MAP
|
|
END_DISPATCH_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Event map
|
|
|
|
BEGIN_EVENT_MAP(CHoursCtrl, COleControl)
|
|
//{{AFX_EVENT_MAP(CHoursCtrl)
|
|
//}}AFX_EVENT_MAP
|
|
END_EVENT_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Property pages
|
|
|
|
BEGIN_PROPPAGEIDS(CHoursCtrl, 1)
|
|
PROPPAGEID(CHoursPropPage::guid)
|
|
END_PROPPAGEIDS(CHoursCtrl)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Initialize class factory and guid
|
|
|
|
IMPLEMENT_OLECREATE_EX(CHoursCtrl, "HOURS.HoursCtrl.1",
|
|
0xa44ea7ad, 0x9d58, 0x11cf, 0xa3, 0x5f, 0, 0xaa, 0, 0xb6, 0x74, 0x3b)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Type library ID and version
|
|
|
|
IMPLEMENT_OLETYPELIB(CHoursCtrl, _tlid, _wVerMajor, _wVerMinor)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Interface IDs
|
|
|
|
const IID BASED_CODE IID_DHours =
|
|
{ 0xa44ea7ab, 0x9d58, 0x11cf, { 0xa3, 0x5f, 0, 0xaa, 0, 0xb6, 0x74, 0x3b } };
|
|
const IID BASED_CODE IID_DHoursEvents =
|
|
{ 0xa44ea7ac, 0x9d58, 0x11cf, { 0xa3, 0x5f, 0, 0xaa, 0, 0xb6, 0x74, 0x3b } };
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Control type information
|
|
|
|
static const DWORD BASED_CODE _dwHoursOleMisc =
|
|
OLEMISC_ACTIVATEWHENVISIBLE |
|
|
OLEMISC_SETCLIENTSITEFIRST |
|
|
OLEMISC_INSIDEOUT |
|
|
OLEMISC_CANTLINKINSIDE |
|
|
OLEMISC_RECOMPOSEONRESIZE;
|
|
|
|
IMPLEMENT_OLECTLTYPE(CHoursCtrl, IDS_HOURS, _dwHoursOleMisc)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CHoursCtrl::CHoursCtrlFactory::UpdateRegistry -
|
|
// Adds or removes system registry entries for CHoursCtrl
|
|
|
|
BOOL CHoursCtrl::CHoursCtrlFactory::UpdateRegistry(BOOL bRegister)
|
|
{
|
|
// TODO: Verify that your control follows apartment-model threading rules.
|
|
// Refer to MFC TechNote 64 for more information.
|
|
// If your control does not conform to the apartment-model rules, then
|
|
// you must modify the code below, changing the 6th parameter from
|
|
// afxRegApartmentThreading to 0.
|
|
|
|
if (bRegister)
|
|
return AfxOleRegisterControlClass(
|
|
AfxGetInstanceHandle(),
|
|
m_clsid,
|
|
m_lpszProgID,
|
|
IDS_HOURS,
|
|
IDB_HOURS,
|
|
/* afxRegApartmentThreading, */0,
|
|
_dwHoursOleMisc,
|
|
_tlid,
|
|
_wVerMajor,
|
|
_wVerMinor);
|
|
else
|
|
return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CHoursCtrl::CHoursCtrl - Constructor
|
|
|
|
CHoursCtrl::CHoursCtrl()
|
|
{
|
|
InitializeIIDs(&IID_DHours, &IID_DHoursEvents);
|
|
|
|
// regular font
|
|
m_pFont = new CFont;
|
|
LOGFONT lf;
|
|
|
|
memset(&lf, 0, sizeof(LOGFONT)); // Clear out structure.
|
|
|
|
//#ifdef DBCS
|
|
// for localize
|
|
// V-HIDEKK 1996.09.23
|
|
CString csFontName,csFontSize;
|
|
csFontName.LoadString(IDS_STR_FONTNAME);
|
|
csFontSize.LoadString(IDS_STR_FONTSIZE);
|
|
lf.lfHeight = _ttoi(csFontSize.GetBuffer(0));
|
|
_tcscpy(lf.lfFaceName, csFontName.GetBuffer(0));
|
|
/*
|
|
#else
|
|
lf.lfHeight = 15;
|
|
_tcscpy(lf.lfFaceName, TEXT("Arial"));
|
|
#endif
|
|
*/
|
|
lf.lfWeight = 100;
|
|
m_pFont->CreateFontIndirect(&lf); // Create the font.
|
|
|
|
// create the individual 'cells' (m_sCells)
|
|
USHORT x, y;
|
|
x = HOUR_BUTTON_HEIGHT;
|
|
y = DAY_BUTTON_WIDTH;
|
|
|
|
CRect crOuter;
|
|
USHORT sCount = 1;
|
|
USHORT sRow = 1;
|
|
USHORT sCol = 1;
|
|
|
|
for (x = DAY_BUTTON_WIDTH; (x + CELL_WIDTH) < CONTROL_WIDTH; x += CELL_WIDTH)
|
|
{
|
|
for (y = HOUR_BUTTON_HEIGHT; (y + CELL_HEIGHT) < CONTROL_HEIGHT; y += CELL_HEIGHT)
|
|
{
|
|
m_sCell[sCount].x = x;
|
|
m_sCell[sCount].y = y;
|
|
m_sCell[sCount].cx = x + CELL_WIDTH + 1;
|
|
m_sCell[sCount].cy = y + CELL_HEIGHT + 1;
|
|
|
|
m_sCell[sCount].bVal = TRUE;
|
|
m_sCell[sCount].row = sRow;
|
|
m_sCell[sCount].col = sCol;
|
|
m_sCell[sCount].bSelected = FALSE;
|
|
sCount++;
|
|
sRow++;
|
|
}
|
|
sRow = 1;
|
|
sCol++;
|
|
}
|
|
|
|
// create the buttons
|
|
// start with the days
|
|
y = HOUR_BUTTON_HEIGHT;
|
|
sRow = 0;
|
|
|
|
while (sCount < 176)
|
|
{
|
|
m_sCell[sCount].x = 2;
|
|
m_sCell[sCount].y = y;
|
|
m_sCell[sCount].cx = m_sCell[sCount].x + DAY_BUTTON_WIDTH;
|
|
m_sCell[sCount].cy = y + CELL_HEIGHT;
|
|
m_sCell[sCount].bVal = TRUE;
|
|
m_sCell[sCount].row = sRow;
|
|
m_sCell[sCount].col = 0;
|
|
m_sCell[sCount].bSelected = FALSE;
|
|
|
|
sCount++;
|
|
sRow++;
|
|
//#ifdef DBCS
|
|
// This is right!
|
|
// V-HIDEKK 1996.09.23
|
|
y += CELL_HEIGHT;
|
|
/*
|
|
#else
|
|
y += HOUR_BUTTON_HEIGHT;
|
|
#endif
|
|
*/
|
|
}
|
|
|
|
// 'select all' button
|
|
m_sCell[sCount].x = 2;
|
|
m_sCell[sCount].y = 2;
|
|
m_sCell[sCount].cx = m_sCell[sCount].x + DAY_BUTTON_WIDTH;
|
|
//#ifdef DBCS
|
|
// This is right!
|
|
// V-HIDEKK 1996.09.23
|
|
m_sCell[sCount].cy = m_sCell[sCount].y + HOUR_BUTTON_HEIGHT;
|
|
/*
|
|
#else
|
|
m_sCell[sCount].cy = m_sCell[sCount].y + CELL_HEIGHT;
|
|
#endif
|
|
*/
|
|
m_sCell[sCount].bVal = TRUE;
|
|
m_sCell[sCount].row = 0;
|
|
m_sCell[sCount].col = 0;
|
|
m_sCell[sCount].bSelected = FALSE;
|
|
|
|
//#ifdef DBCS
|
|
// This is right!
|
|
// V-HIDEKK 1996.09.23
|
|
x = DAY_BUTTON_WIDTH;
|
|
/*
|
|
#else
|
|
x = 83;
|
|
#endif
|
|
*/
|
|
sCount++;
|
|
while (sCount < 201)
|
|
{
|
|
m_sCell[sCount].x = x;
|
|
m_sCell[sCount].y = 2;
|
|
m_sCell[sCount].cx = x + CELL_WIDTH;
|
|
//#ifdef DBCS
|
|
// This is right!
|
|
// V-HIDEKK 1996.09.23
|
|
m_sCell[sCount].cy = m_sCell[sCount].y + HOUR_BUTTON_HEIGHT;
|
|
/*
|
|
#else
|
|
m_sCell[sCount].cy = m_sCell[sCount].y + CELL_HEIGHT;
|
|
#endif
|
|
*/
|
|
|
|
m_sCell[sCount].bVal = TRUE;
|
|
m_sCell[sCount].row = sRow;
|
|
m_sCell[sCount].col = 0;
|
|
m_sCell[sCount].bSelected = FALSE;
|
|
|
|
sCount++;
|
|
sRow++;
|
|
x += CELL_WIDTH;
|
|
}
|
|
|
|
m_sCurrentRow = 1;
|
|
m_sCurrentCol = 1;
|
|
|
|
bToggle = TRUE;
|
|
|
|
// set default color values
|
|
m_crPermitColor = GetSysColor(COLOR_ACTIVECAPTION);
|
|
m_crDenyColor = GetSysColor(COLOR_CAPTIONTEXT);
|
|
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CHoursCtrl::~CHoursCtrl - Destructor
|
|
|
|
CHoursCtrl::~CHoursCtrl()
|
|
{
|
|
// remove button CFont*
|
|
if (m_pFont != NULL) delete m_pFont;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CHoursCtrl::OnDraw - Drawing function
|
|
|
|
void CHoursCtrl::OnDraw(
|
|
CDC* pDC, const CRect& rcBounds, const CRect& rcInvalid)
|
|
{
|
|
// create pen for the grid lines
|
|
CPen pBlackPen(PS_SOLID, 1, RGB(0,0,0));
|
|
CPen* pOriginalPen = (CPen*)pDC->SelectObject(pBlackPen);
|
|
|
|
// create the two brushes for allowed color and denied color
|
|
CBrush* pAllowedBrush = new CBrush;
|
|
pAllowedBrush->CreateSolidBrush(m_crPermitColor);
|
|
|
|
CBrush* pDeniedBrush = new CBrush;
|
|
pDeniedBrush->CreateSolidBrush(m_crDenyColor);
|
|
|
|
CBrush* pDragBrush = new CBrush;
|
|
pDragBrush->CreateHatchBrush(HS_BDIAGONAL, GetSysColor(COLOR_ACTIVECAPTION));
|
|
|
|
USHORT sCount = 1;
|
|
CRect crOuter;
|
|
|
|
pDC->SetBkColor(GetSysColor(COLOR_BTNFACE));
|
|
|
|
// draw the grid
|
|
while (sCount < 169)
|
|
{
|
|
crOuter = CRect(m_sCell[sCount].x,
|
|
m_sCell[sCount].y,
|
|
m_sCell[sCount].cx,
|
|
m_sCell[sCount].cy);
|
|
|
|
CRect crInterSect = (rcInvalid & crOuter);
|
|
if (!crInterSect.IsRectNull())
|
|
{
|
|
pDC->Rectangle(&crOuter);
|
|
crOuter.DeflateRect(1, 1);
|
|
|
|
if (m_sCell[sCount].bSelected) pDC->FillRect(&crOuter, pDragBrush);
|
|
else pDC->FillRect(&crOuter, (m_sCell[sCount].bVal ? pAllowedBrush : pDeniedBrush));
|
|
|
|
if ((m_sCurrentRow && m_sCurrentCol) && (sCount == m_sCurrentLoc())) // is this the 'selected' cell?
|
|
{
|
|
crOuter.DeflateRect(2, 4);
|
|
pDC->DrawFocusRect(&crOuter);
|
|
}
|
|
}
|
|
|
|
sCount++;
|
|
}
|
|
|
|
delete pAllowedBrush;
|
|
delete pDeniedBrush;
|
|
delete pDragBrush;
|
|
|
|
|
|
// draw the surrounding buttons
|
|
CBrush* pButtonBrush = new CBrush;
|
|
pButtonBrush->CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
|
|
|
|
CPen pWhitePen(PS_SOLID, 1, RGB(255, 255, 255));
|
|
pOriginalPen = (CPen*)pDC->SelectObject(pWhitePen);
|
|
|
|
CPen pDkGreyPen(PS_SOLID, 1, RGB(128, 128, 128));
|
|
CPen pLtGreyPen(PS_SOLID, 1, RGB(196, 196, 196));
|
|
|
|
CFont* pOldFont = pDC->SelectObject(m_pFont);
|
|
|
|
while (sCount < 176) // start with the days of the week
|
|
{
|
|
crOuter = CRect(m_sCell[sCount].x,
|
|
m_sCell[sCount].y,
|
|
m_sCell[sCount].cx,
|
|
m_sCell[sCount].cy);
|
|
|
|
CRect crInterSect = (rcInvalid & crOuter);
|
|
if (!crInterSect.IsRectNull())
|
|
{
|
|
crOuter.DeflateRect(1, 1);
|
|
pDC->FillRect(&crOuter, pButtonBrush);
|
|
if (m_sCell[sCount].bVal)
|
|
{
|
|
pDC->SelectObject(pWhitePen);
|
|
pDC->MoveTo(m_sCell[sCount].x, m_sCell[sCount].cy - 1);
|
|
pDC->LineTo(m_sCell[sCount].x, m_sCell[sCount].y + 1);
|
|
pDC->LineTo(m_sCell[sCount].cx - 2, m_sCell[sCount].y + 1);
|
|
|
|
pDC->SelectObject(pBlackPen);
|
|
pDC->LineTo(m_sCell[sCount].cx - 2, m_sCell[sCount].cy);
|
|
pDC->LineTo(m_sCell[sCount].x - 1, m_sCell[sCount].cy);
|
|
|
|
pDC->SelectObject(pDkGreyPen);
|
|
pDC->MoveTo(m_sCell[sCount].cx - 3, m_sCell[sCount].y + 2);
|
|
pDC->LineTo(m_sCell[sCount].cx - 3, m_sCell[sCount].cy - 1);
|
|
pDC->LineTo(m_sCell[sCount].x, m_sCell[sCount].cy - 1);
|
|
}
|
|
else
|
|
{
|
|
pDC->SelectObject(pBlackPen);
|
|
pDC->MoveTo(m_sCell[sCount].x, m_sCell[sCount].cy - 1);
|
|
pDC->LineTo(m_sCell[sCount].x, m_sCell[sCount].y + 1);
|
|
pDC->LineTo(m_sCell[sCount].cx - 2, m_sCell[sCount].y + 1);
|
|
|
|
pDC->SelectObject(pWhitePen);
|
|
pDC->MoveTo(m_sCell[sCount].cx - 2, m_sCell[sCount].cy);
|
|
pDC->LineTo(m_sCell[sCount].x - 1, m_sCell[sCount].cy);
|
|
|
|
pDC->SelectObject(pLtGreyPen);
|
|
pDC->MoveTo(m_sCell[sCount].cx - 3, m_sCell[sCount].y + 2);
|
|
pDC->LineTo(m_sCell[sCount].cx - 3, m_sCell[sCount].cy - 1);
|
|
pDC->LineTo(m_sCell[sCount].x, m_sCell[sCount].cy - 1);
|
|
}
|
|
|
|
pDC->SetBkMode(TRANSPARENT);
|
|
crOuter.DeflateRect(3, 2);
|
|
if (m_sCell[sCount].bVal)
|
|
pDC->DrawText(csDay[sCount - 169],
|
|
&crOuter,
|
|
DT_CENTER);
|
|
else
|
|
{
|
|
crOuter.OffsetRect(1, 1);
|
|
pDC->DrawText(csDay[sCount - 169],
|
|
&crOuter,
|
|
DT_CENTER);
|
|
}
|
|
// current selection?
|
|
if ((m_sCurrentCol == 0) && (m_sCurrentRow == sCount - 168))
|
|
{
|
|
CRect crSelection = CRect(m_sCell[sCount].x,
|
|
m_sCell[sCount].y,
|
|
m_sCell[sCount].cx,
|
|
m_sCell[sCount].cy);
|
|
|
|
crSelection.DeflateRect(5, 5);
|
|
pDC->DrawFocusRect(&crSelection);
|
|
}
|
|
}
|
|
sCount++;
|
|
}
|
|
|
|
// 'select all' button
|
|
crOuter = CRect(m_sCell[sCount].x,
|
|
m_sCell[sCount].y,
|
|
m_sCell[sCount].cx + 1,
|
|
m_sCell[sCount].cy + 1);
|
|
|
|
CRect crInterSect = (rcInvalid & crOuter);
|
|
if (!crInterSect.IsRectNull())
|
|
{
|
|
crOuter.DeflateRect(1, 1);
|
|
|
|
pDC->FillRect(&crOuter, pButtonBrush);
|
|
|
|
if (m_sCell[sCount].bVal)
|
|
{
|
|
pDC->SelectObject(pWhitePen);
|
|
pDC->MoveTo(m_sCell[sCount].x, m_sCell[sCount].cy - 1);
|
|
pDC->LineTo(m_sCell[sCount].x, m_sCell[sCount].y);
|
|
pDC->LineTo(m_sCell[sCount].cx - 2, m_sCell[sCount].y);
|
|
|
|
pDC->SelectObject(pBlackPen);
|
|
pDC->LineTo(m_sCell[sCount].cx - 2, m_sCell[sCount].cy - 2);
|
|
pDC->LineTo(m_sCell[sCount].x - 1, m_sCell[sCount].cy - 2);
|
|
|
|
pDC->SelectObject(pDkGreyPen);
|
|
pDC->MoveTo(m_sCell[sCount].cx - 3, m_sCell[sCount].y + 1);
|
|
pDC->LineTo(m_sCell[sCount].cx - 3, m_sCell[sCount].cy - 3);
|
|
pDC->LineTo(m_sCell[sCount].x, m_sCell[sCount].cy - 3);
|
|
}
|
|
else
|
|
{
|
|
pDC->SelectObject(pBlackPen);
|
|
pDC->MoveTo(m_sCell[sCount].x, m_sCell[sCount].cy - 1);
|
|
pDC->LineTo(m_sCell[sCount].x, m_sCell[sCount].y);
|
|
pDC->LineTo(m_sCell[sCount].cx - 2, m_sCell[sCount].y);
|
|
|
|
pDC->SelectObject(pWhitePen);
|
|
pDC->LineTo(m_sCell[sCount].cx - 2, m_sCell[sCount].cy - 2);
|
|
pDC->LineTo(m_sCell[sCount].x - 1, m_sCell[sCount].cy - 2);
|
|
|
|
pDC->SelectObject(pLtGreyPen);
|
|
pDC->MoveTo(m_sCell[sCount].cx - 3, m_sCell[sCount].y + 1);
|
|
pDC->LineTo(m_sCell[sCount].cx - 3, m_sCell[sCount].cy - 3);
|
|
pDC->LineTo(m_sCell[sCount].x, m_sCell[sCount].cy - 3);
|
|
}
|
|
|
|
// current selection?
|
|
if ((m_sCurrentCol == 0) && (m_sCurrentRow == 0))
|
|
{
|
|
CRect crSelection = CRect(m_sCell[sCount].x,
|
|
m_sCell[sCount].y,
|
|
m_sCell[sCount].cx,
|
|
m_sCell[sCount].cy);
|
|
|
|
crSelection.DeflateRect(5, 5);
|
|
pDC->DrawFocusRect(&crSelection);
|
|
}
|
|
|
|
}
|
|
|
|
sCount++;
|
|
// finish with col headers
|
|
while (sCount < 201)
|
|
{
|
|
crOuter = CRect(m_sCell[sCount].x,
|
|
m_sCell[sCount].y,
|
|
m_sCell[sCount].cx,
|
|
m_sCell[sCount].cy);
|
|
|
|
CRect crInterSect = (rcInvalid & crOuter);
|
|
if (!crInterSect.IsRectNull())
|
|
{
|
|
crOuter.DeflateRect(1, 1);
|
|
|
|
pDC->FillRect(&crOuter, pButtonBrush);
|
|
|
|
if (m_sCell[sCount].bVal)
|
|
{
|
|
pDC->SelectObject(pWhitePen);
|
|
pDC->MoveTo(m_sCell[sCount].x + 1, m_sCell[sCount].cy - 2);
|
|
pDC->LineTo(m_sCell[sCount].x + 1, m_sCell[sCount].y);
|
|
pDC->LineTo(m_sCell[sCount].cx, m_sCell[sCount].y);
|
|
|
|
pDC->SelectObject(pBlackPen);
|
|
pDC->LineTo(m_sCell[sCount].cx, m_sCell[sCount].cy - 2);
|
|
pDC->LineTo(m_sCell[sCount].x - 1, m_sCell[sCount].cy - 2);
|
|
|
|
pDC->SelectObject(pDkGreyPen);
|
|
pDC->MoveTo(m_sCell[sCount].cx - 1, m_sCell[sCount].y + 1);
|
|
pDC->LineTo(m_sCell[sCount].cx - 1, m_sCell[sCount].cy - 3);
|
|
pDC->LineTo(m_sCell[sCount].x, m_sCell[sCount].cy - 3);
|
|
}
|
|
else
|
|
{
|
|
pDC->SelectObject(pBlackPen);
|
|
pDC->MoveTo(m_sCell[sCount].x + 1, m_sCell[sCount].cy - 2);
|
|
pDC->LineTo(m_sCell[sCount].x + 1, m_sCell[sCount].y);
|
|
pDC->LineTo(m_sCell[sCount].cx, m_sCell[sCount].y);
|
|
|
|
pDC->SelectObject(pWhitePen);
|
|
pDC->LineTo(m_sCell[sCount].cx, m_sCell[sCount].cy - 2);
|
|
pDC->LineTo(m_sCell[sCount].x - 1, m_sCell[sCount].cy - 2);
|
|
|
|
pDC->SelectObject(pLtGreyPen);
|
|
pDC->MoveTo(m_sCell[sCount].cx - 1, m_sCell[sCount].y + 1);
|
|
pDC->LineTo(m_sCell[sCount].cx - 1, m_sCell[sCount].cy - 3);
|
|
pDC->LineTo(m_sCell[sCount].x, m_sCell[sCount].cy - 3);
|
|
}
|
|
|
|
// current selection?
|
|
if ((m_sCurrentCol == sCount - 176) && (m_sCurrentRow == 0))
|
|
{
|
|
CRect crSelection = CRect(m_sCell[sCount].x,
|
|
m_sCell[sCount].y,
|
|
m_sCell[sCount].cx,
|
|
m_sCell[sCount].cy);
|
|
|
|
crSelection.DeflateRect(3, 3);
|
|
pDC->DrawFocusRect(&crSelection);
|
|
}
|
|
|
|
}
|
|
sCount++;
|
|
}
|
|
|
|
delete pButtonBrush;
|
|
pDC->SelectObject(pOldFont);
|
|
|
|
// draw the border
|
|
pDC->SelectObject(pBlackPen);
|
|
pDC->MoveTo(1, rcBounds.BottomRight().y - 1);
|
|
pDC->LineTo(rcBounds.TopLeft().x + 1, rcBounds.TopLeft().y + 1);
|
|
pDC->LineTo(rcBounds.BottomRight().x + 1, 1);
|
|
|
|
pDC->SelectObject(pDkGreyPen);
|
|
pDC->MoveTo(0, rcBounds.BottomRight().y);
|
|
pDC->LineTo(rcBounds.TopLeft().x, rcBounds.TopLeft().y);
|
|
pDC->LineTo(rcBounds.BottomRight().x, 0);
|
|
|
|
pDC->SelectObject(pWhitePen);
|
|
pDC->MoveTo(1, rcBounds.BottomRight().y - 1);
|
|
pDC->LineTo(rcBounds.BottomRight().x - 1, rcBounds.BottomRight().y - 1);
|
|
pDC->LineTo(rcBounds.BottomRight().x - 1, 0);
|
|
|
|
pDC->SelectObject(pLtGreyPen);
|
|
pDC->MoveTo(2, rcBounds.BottomRight().y - 2);
|
|
pDC->LineTo(rcBounds.BottomRight().x - 2, rcBounds.BottomRight().y - 2);
|
|
pDC->LineTo(rcBounds.BottomRight().x - 2, 2);
|
|
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CHoursCtrl::DoPropExchange - Persistence support
|
|
|
|
void CHoursCtrl::DoPropExchange(CPropExchange* pPX)
|
|
{
|
|
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
|
|
COleControl::DoPropExchange(pPX);
|
|
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CHoursCtrl::OnResetState - Reset control to default state
|
|
|
|
void CHoursCtrl::OnResetState()
|
|
{
|
|
COleControl::OnResetState(); // Resets defaults found in DoPropExchange
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CHoursCtrl message handlers
|
|
|
|
int CHoursCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
|
|
//#ifdef DBCS
|
|
// for debug and localize
|
|
// We need this code. because dialog-size changed for RL (addusrw.exe)
|
|
// HardCord size mismatched
|
|
// V-HIDEKK 1996.09.23
|
|
|
|
CString csButtonWidth;
|
|
csButtonWidth.LoadString(IDS_STR_BUTTONWIDTH);
|
|
DAY_BUTTON_WIDTH = (USHORT)_ttoi(csButtonWidth.GetBuffer(0));
|
|
|
|
CONTROL_WIDTH = (USHORT)lpCreateStruct->cx;
|
|
CONTROL_HEIGHT = (USHORT)lpCreateStruct->cy;
|
|
HOUR_BUTTON_HEIGHT = CONTROL_HEIGHT/8 + CONTROL_HEIGHT%8 - 3;
|
|
CELL_WIDTH = ((CONTROL_WIDTH - DAY_BUTTON_WIDTH) / 24);
|
|
CELL_HEIGHT = ((CONTROL_HEIGHT - HOUR_BUTTON_HEIGHT) / 7);
|
|
|
|
// create the individual 'cells' (m_sCells)
|
|
USHORT x, y;
|
|
x = HOUR_BUTTON_HEIGHT;
|
|
y = DAY_BUTTON_WIDTH;
|
|
|
|
CRect crOuter;
|
|
USHORT sCount = 1;
|
|
USHORT sRow = 1;
|
|
USHORT sCol = 1;
|
|
|
|
for (x = DAY_BUTTON_WIDTH; (x + CELL_WIDTH) < CONTROL_WIDTH; x += CELL_WIDTH)
|
|
{
|
|
for (y = HOUR_BUTTON_HEIGHT; (y + CELL_HEIGHT) < CONTROL_HEIGHT; y += CELL_HEIGHT)
|
|
{
|
|
m_sCell[sCount].x = x;
|
|
m_sCell[sCount].y = y;
|
|
m_sCell[sCount].cx = x + CELL_WIDTH + 1;
|
|
m_sCell[sCount].cy = y + CELL_HEIGHT + 1;
|
|
|
|
m_sCell[sCount].bVal = TRUE;
|
|
m_sCell[sCount].row = sRow;
|
|
m_sCell[sCount].col = sCol;
|
|
m_sCell[sCount].bSelected = FALSE;
|
|
sCount++;
|
|
sRow++;
|
|
}
|
|
sRow = 1;
|
|
sCol++;
|
|
}
|
|
|
|
// create the buttons
|
|
// start with the days
|
|
y = HOUR_BUTTON_HEIGHT;
|
|
sRow = 0;
|
|
|
|
while (sCount < 176)
|
|
{
|
|
m_sCell[sCount].x = 2;
|
|
m_sCell[sCount].y = y;
|
|
m_sCell[sCount].cx = m_sCell[sCount].x + DAY_BUTTON_WIDTH;
|
|
m_sCell[sCount].cy = y + CELL_HEIGHT;
|
|
m_sCell[sCount].bVal = TRUE;
|
|
m_sCell[sCount].row = sRow;
|
|
m_sCell[sCount].col = 0;
|
|
m_sCell[sCount].bSelected = FALSE;
|
|
|
|
sCount++;
|
|
sRow++;
|
|
y += CELL_HEIGHT;
|
|
}
|
|
|
|
// 'select all' button
|
|
m_sCell[sCount].x = 2;
|
|
m_sCell[sCount].y = 2;
|
|
m_sCell[sCount].cx = m_sCell[sCount].x + DAY_BUTTON_WIDTH;
|
|
m_sCell[sCount].cy = m_sCell[sCount].y + HOUR_BUTTON_HEIGHT;
|
|
m_sCell[sCount].bVal = TRUE;
|
|
m_sCell[sCount].row = 0;
|
|
m_sCell[sCount].col = 0;
|
|
m_sCell[sCount].bSelected = FALSE;
|
|
|
|
x = DAY_BUTTON_WIDTH;
|
|
sCount++;
|
|
while (sCount < 201)
|
|
{
|
|
m_sCell[sCount].x = x;
|
|
m_sCell[sCount].y = 2;
|
|
m_sCell[sCount].cx = x + CELL_WIDTH;
|
|
m_sCell[sCount].cy = m_sCell[sCount].y + HOUR_BUTTON_HEIGHT;
|
|
|
|
m_sCell[sCount].bVal = TRUE;
|
|
m_sCell[sCount].row = sRow;
|
|
m_sCell[sCount].col = 0;
|
|
m_sCell[sCount].bSelected = FALSE;
|
|
|
|
sCount++;
|
|
sRow++;
|
|
x += CELL_WIDTH;
|
|
}
|
|
|
|
//#endif
|
|
|
|
if (COleControl::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
|
|
// load the text for the day buttons
|
|
csDay[0].LoadString(IDS_SUNDAY);
|
|
csDay[1].LoadString(IDS_MONDAY);
|
|
csDay[2].LoadString(IDS_TUESDAY);
|
|
csDay[3].LoadString(IDS_WEDNESDAY);
|
|
csDay[4].LoadString(IDS_THURSDAY);
|
|
csDay[5].LoadString(IDS_FRIDAY);
|
|
csDay[6].LoadString(IDS_SATURDAY);
|
|
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
// make the cursor over the control into the '+' sign
|
|
BOOL CHoursCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
|
|
{
|
|
::SetCursor(::LoadCursor(NULL, IDC_CROSS));
|
|
return TRUE;
|
|
}
|
|
|
|
// trap lButton clicks to toggle single cells
|
|
void CHoursCtrl::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
// invalidate the previous selection
|
|
InvalidateCell(m_sCurrentLoc());
|
|
|
|
Click(point);
|
|
pointDrag = point;
|
|
|
|
USHORT sCount = 1;
|
|
// clear out the old drag selection(s)
|
|
while (sCount < 168)
|
|
{
|
|
if (m_sCell[sCount].bSelected)
|
|
{
|
|
m_sCell[sCount].bSelected = FALSE;
|
|
|
|
InvalidateCell(sCount);
|
|
}
|
|
|
|
sCount++;
|
|
}
|
|
|
|
// COleControl::OnLButtonDown(nFlags, point);
|
|
}
|
|
|
|
|
|
void CHoursCtrl::InvalidateCell(USHORT sCellID)
|
|
{
|
|
CRect crCell = CRect(m_sCell[sCellID].x,
|
|
m_sCell[sCellID].y,
|
|
m_sCell[sCellID].cx,
|
|
m_sCell[sCellID].cy);
|
|
InvalidateRect(crCell);
|
|
}
|
|
|
|
void CHoursCtrl::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
if (nFlags == MK_LBUTTON)
|
|
{
|
|
USHORT sEndCell = GetCellID(point);
|
|
USHORT sStartCell = GetCellID(pointDrag);
|
|
//#ifdef DBCS
|
|
// If sEndCell==0, this cell is invalid
|
|
// It seems this like better!
|
|
// V-HIDEKK 1996.09.23
|
|
if (sStartCell == sEndCell || !sEndCell ) return;
|
|
/*
|
|
#else
|
|
if (sStartCell == sEndCell) return;
|
|
#endif
|
|
*/
|
|
|
|
CRect crSelected = CRect(min(m_sCell[sStartCell].x, m_sCell[sEndCell].x),
|
|
min(m_sCell[sStartCell].y, m_sCell[sEndCell].y),
|
|
max(m_sCell[sStartCell].x, m_sCell[sEndCell].x) + CELL_WIDTH,
|
|
max(m_sCell[sStartCell].y, m_sCell[sEndCell].y) + CELL_HEIGHT);
|
|
|
|
USHORT sCount = 0;
|
|
// clear out the old selection
|
|
while (sCount < 169)
|
|
{
|
|
if (!crSelected.PtInRect(CPoint(m_sCell[sCount].x + 1, m_sCell[sCount].y + 1)))
|
|
{
|
|
if (m_sCell[sCount].bSelected)
|
|
{
|
|
m_sCell[sCount].bSelected = FALSE;
|
|
|
|
InvalidateCell(sCount);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!m_sCell[sCount].bSelected)
|
|
{
|
|
m_sCell[sCount].bSelected = TRUE;
|
|
InvalidateCell(sCount);
|
|
}
|
|
}
|
|
|
|
sCount++;
|
|
}
|
|
}
|
|
|
|
COleControl::OnMouseMove(nFlags, point);
|
|
}
|
|
|
|
void CHoursCtrl::OnLButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
USHORT sEndCell = GetCellID(point);
|
|
USHORT sStartCell = GetCellID(pointDrag);
|
|
//#ifdef DBCS
|
|
// If sEndCell==0, this cell is invalid
|
|
// It seems this like better!
|
|
// V-HIDEKK 1996.09.23
|
|
if (sStartCell == sEndCell || !sEndCell ) return;
|
|
/*
|
|
#else
|
|
if (sStartCell == sEndCell) return;
|
|
#endif
|
|
*/
|
|
|
|
CRect crSelected = CRect(min(m_sCell[sStartCell].x, m_sCell[sEndCell].x),
|
|
min(m_sCell[sStartCell].y, m_sCell[sEndCell].y),
|
|
max(m_sCell[sStartCell].x, m_sCell[sEndCell].x) + CELL_WIDTH,
|
|
max(m_sCell[sStartCell].y, m_sCell[sEndCell].y) + CELL_HEIGHT);
|
|
|
|
// first get the avg
|
|
short sTmp = 0;
|
|
USHORT sCount = 0;
|
|
while (sCount < 169)
|
|
{
|
|
if (crSelected.PtInRect(CPoint(m_sCell[sCount].x + 1, m_sCell[sCount].y + 1)))
|
|
{
|
|
if (m_sCell[sCount].bVal) sTmp++;
|
|
else sTmp--;
|
|
}
|
|
|
|
sCount++;
|
|
}
|
|
|
|
BOOL bNewVal;
|
|
if (sTmp >= 0) bNewVal = FALSE;
|
|
else bNewVal = TRUE;
|
|
sCount = 0;
|
|
// now change them all to be !the average
|
|
// first get the avg
|
|
while (sCount < 169)
|
|
{
|
|
if (crSelected.PtInRect(CPoint(m_sCell[sCount].x + 1, m_sCell[sCount].y + 1)))
|
|
{
|
|
m_sCell[sCount].bVal = bNewVal;
|
|
m_sCell[sCount].bSelected = FALSE;
|
|
InvalidateCell(sCount);
|
|
}
|
|
|
|
sCount++;
|
|
}
|
|
|
|
COleControl::OnLButtonUp(nFlags, point);
|
|
}
|
|
|
|
USHORT CHoursCtrl::GetCellID(CPoint point)
|
|
{
|
|
USHORT sCount = 1;
|
|
|
|
// big grid?
|
|
CRect crOuter;
|
|
while (sCount < 169)
|
|
{
|
|
crOuter = CRect(m_sCell[sCount].x,
|
|
m_sCell[sCount].y,
|
|
m_sCell[sCount].x + CELL_WIDTH + 1,
|
|
m_sCell[sCount].y + CELL_HEIGHT + 1);
|
|
if (crOuter.PtInRect(point)) return sCount;
|
|
|
|
sCount++;
|
|
}
|
|
|
|
// day button?
|
|
while (sCount < 176)
|
|
{
|
|
crOuter = CRect(m_sCell[sCount].x,
|
|
m_sCell[sCount].y,
|
|
m_sCell[sCount].x + DAY_BUTTON_WIDTH + 1,
|
|
m_sCell[sCount].y + CELL_HEIGHT + 1);
|
|
if (crOuter.PtInRect(point)) return sCount;
|
|
|
|
sCount++;
|
|
}
|
|
|
|
// big button?
|
|
crOuter = CRect(m_sCell[sCount].x,
|
|
m_sCell[sCount].y,
|
|
m_sCell[sCount].x + DAY_BUTTON_WIDTH + 1,
|
|
//#ifdef DBCS
|
|
// It seems this is right!
|
|
// V-HIDEKK 1996.09.23
|
|
m_sCell[sCount].y + HOUR_BUTTON_HEIGHT + 1 ); //CELL_HEIGHT + 1);
|
|
/*
|
|
#else
|
|
m_sCell[sCount].y + CELL_HEIGHT + 1);
|
|
#endif
|
|
*/
|
|
if (crOuter.PtInRect(point)) return sCount;
|
|
|
|
// column button?
|
|
while (sCount < 201)
|
|
{
|
|
crOuter = CRect(m_sCell[sCount].x,
|
|
m_sCell[sCount].y,
|
|
m_sCell[sCount].x + CELL_WIDTH + 1,
|
|
//#ifdef DBCS
|
|
// It seems this is right!
|
|
// V-HIDEKK 1996.09.23
|
|
m_sCell[sCount].y + HOUR_BUTTON_HEIGHT + 1 ); //CELL_HEIGHT + 1);
|
|
/*
|
|
#else
|
|
m_sCell[sCount].y + CELL_HEIGHT + 1);
|
|
#endif
|
|
*/
|
|
if (crOuter.PtInRect(point)) return sCount;
|
|
|
|
sCount++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CHoursCtrl::Click(CPoint point)
|
|
{
|
|
USHORT sCount = 0;
|
|
CRect crOuter;
|
|
|
|
USHORT sCell = GetCellID(point);
|
|
|
|
//#ifdef DBCS
|
|
// Fix: Invalid Area clicked, then AV occurred.
|
|
// sCell==0 is Invalid Cell
|
|
// V-HIDEKK 1996.09.23
|
|
if( !sCell )
|
|
return;
|
|
|
|
//#endif
|
|
m_sCurrentRow = m_sCell[sCell].row;
|
|
m_sCurrentCol = m_sCell[sCell].col;
|
|
|
|
//#ifdef DBCS
|
|
// Fix: most right-bottom area can not selected
|
|
// Where is sCell==168 ?
|
|
// This is RIGHT!
|
|
// V-HIDEKK 1996.09.23
|
|
if (sCell < 169) m_sCell[sCell].bVal = !m_sCell[sCell].bVal;
|
|
/*
|
|
#else
|
|
if (sCell < 168) m_sCell[sCell].bVal = !m_sCell[sCell].bVal;
|
|
#endif
|
|
*/
|
|
InvalidateCell(sCell);
|
|
|
|
// if we clicked on a button toggle its value and redraw
|
|
if (sCell > 168)
|
|
{
|
|
if ((sCell > 168) && (sCell < 176)) // day button
|
|
ToggleDay(sCell - 168);
|
|
|
|
else if (sCell == 176) // toggle all
|
|
OnBigButton();
|
|
|
|
else // column header
|
|
ToggleCol(sCell - 177);
|
|
}
|
|
|
|
}
|
|
|
|
// toggle the values of a row (by day)
|
|
void CHoursCtrl::ToggleDay(UINT nID)
|
|
{
|
|
USHORT sCount;
|
|
CRect crOuter;
|
|
|
|
for (sCount = (USHORT)nID; sCount < 169; sCount += 7)
|
|
{
|
|
m_sCell[sCount].bVal = !m_sCell[nID + 168].bVal;
|
|
InvalidateCell(sCount);
|
|
}
|
|
m_sCell[nID + 168].bVal = !m_sCell[nID + 168].bVal;
|
|
m_sCurrentRow = (USHORT)nID;
|
|
m_sCurrentCol = 0;
|
|
|
|
}
|
|
|
|
// toggle the values of a column
|
|
void CHoursCtrl::ToggleCol(UINT nID)
|
|
{
|
|
USHORT sCount;
|
|
CRect crOuter;
|
|
|
|
m_sCurrentRow = 0;
|
|
m_sCurrentCol = nID + 1;
|
|
|
|
USHORT sVal = nID + 177;
|
|
nID *= 7;
|
|
|
|
for (sCount = 1; sCount < 8; sCount += 1)
|
|
{
|
|
m_sCell[sCount + nID].bVal = !m_sCell[sVal].bVal;
|
|
InvalidateCell(sCount + nID);
|
|
}
|
|
m_sCell[sVal].bVal = !m_sCell[sVal].bVal;
|
|
|
|
}
|
|
|
|
// toggle the whole page
|
|
void CHoursCtrl::OnBigButton()
|
|
{
|
|
USHORT sCount;
|
|
CRect crOuter;
|
|
|
|
m_sCurrentRow = 0;
|
|
m_sCurrentCol = 0;
|
|
|
|
for (sCount = 1; sCount < 169; sCount ++)
|
|
{
|
|
m_sCell[sCount].bVal = !m_sCell[176].bVal;
|
|
InvalidateCell(sCount);
|
|
}
|
|
|
|
m_sCell[176].bVal = !m_sCell[176].bVal;
|
|
|
|
}
|
|
|
|
BOOL CHoursCtrl::PreTranslateMessage(LPMSG lpmsg)
|
|
{
|
|
BOOL bHandleNow = FALSE;
|
|
CRect crOld, crNew;
|
|
|
|
switch (lpmsg->message)
|
|
{
|
|
case WM_KEYDOWN:
|
|
switch (lpmsg->wParam)
|
|
{
|
|
case VK_SPACE: // toggle the cell under the dot
|
|
{
|
|
short sOldCell = m_sCurrentLoc();
|
|
//#ifdef DBCS
|
|
// FIX: most left hours button can not selected.
|
|
// It seems rectangle mismatched.
|
|
// V-HIDEKK 1996.09.23
|
|
Click(CPoint(m_sCell[sOldCell].x + 5, m_sCell[sOldCell].y + 5));
|
|
/*
|
|
#else
|
|
Click(CPoint(m_sCell[sOldCell].x + 1, m_sCell[sOldCell].y + 1));
|
|
#endif
|
|
*/
|
|
bHandleNow = TRUE;
|
|
break;
|
|
}
|
|
|
|
case VK_UP:
|
|
{
|
|
// first store the old cell pos so we can erase it
|
|
short sOldCell = m_sCurrentLoc();
|
|
|
|
// move the carat to the new cell
|
|
m_sCurrentRow--;
|
|
if (m_sCurrentRow < 0) m_sCurrentRow = 7;
|
|
|
|
// now draw the new cell
|
|
short sNewCell = m_sCurrentLoc();
|
|
InvalidateCell(sOldCell);
|
|
InvalidateCell(sNewCell);
|
|
bHandleNow = TRUE;
|
|
break;
|
|
}
|
|
|
|
case VK_DOWN:
|
|
{
|
|
short sOldCell = m_sCurrentLoc();
|
|
|
|
m_sCurrentRow++;
|
|
if (m_sCurrentRow > 7) m_sCurrentRow = 0;
|
|
|
|
short sNewCell = m_sCurrentLoc();
|
|
InvalidateCell(sOldCell);
|
|
InvalidateCell(sNewCell);
|
|
bHandleNow = TRUE;
|
|
break;
|
|
}
|
|
|
|
case VK_LEFT:
|
|
{
|
|
short sOldCell = m_sCurrentLoc();
|
|
m_sCurrentCol--;
|
|
if (m_sCurrentCol < 0) m_sCurrentCol = 24;
|
|
|
|
short sNewCell = m_sCurrentLoc();
|
|
InvalidateCell(sOldCell);
|
|
InvalidateCell(sNewCell);
|
|
bHandleNow = TRUE;
|
|
break;
|
|
}
|
|
|
|
case VK_RIGHT:
|
|
{
|
|
short sOldCell = m_sCurrentLoc();
|
|
m_sCurrentCol++;
|
|
if (m_sCurrentCol > 24) m_sCurrentCol = 0;
|
|
|
|
short sNewCell = m_sCurrentLoc();
|
|
InvalidateCell(sOldCell);
|
|
InvalidateCell(sNewCell);
|
|
bHandleNow = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return bHandleNow;
|
|
}
|
|
|
|
|
|
short CHoursCtrl::m_sCurrentLoc()
|
|
{
|
|
if (!m_sCurrentCol && !m_sCurrentRow) // select all button
|
|
return 176;
|
|
|
|
else if (!m_sCurrentCol)
|
|
return m_sCurrentRow + 168;
|
|
|
|
else if (!m_sCurrentRow)
|
|
return m_sCurrentCol + 176;
|
|
|
|
return ((max(m_sCurrentCol - 1, 0) * 7) + m_sCurrentRow);
|
|
}
|
|
|
|
// these are triggered when the client app changes one of the exported properties
|
|
void CHoursCtrl::OnCrPermitColorChanged()
|
|
{
|
|
Invalidate();
|
|
|
|
SetModifiedFlag();
|
|
}
|
|
|
|
void CHoursCtrl::OnCrDenyColorChanged()
|
|
{
|
|
Invalidate();
|
|
|
|
SetModifiedFlag();
|
|
}
|
|
|
|
VARIANT CHoursCtrl::GetDateData()
|
|
{
|
|
VARIANT vaResult;
|
|
VariantInit(&vaResult);
|
|
|
|
vaResult.vt = VT_ARRAY | VT_UI1;
|
|
|
|
SAFEARRAYBOUND sab[1];
|
|
sab[0].cElements = 21;
|
|
sab[0].lLbound = 0;
|
|
|
|
vaResult.parray = SafeArrayCreate(VT_UI1, 1, sab);
|
|
|
|
// load constant offsets into an array
|
|
DWORD dwOffset[8];
|
|
USHORT sCount;
|
|
short sVal = 1;
|
|
for (sCount = 0; sCount < 8; sCount++)
|
|
{
|
|
dwOffset[sCount] = sVal;
|
|
sVal = sVal << 1;
|
|
}
|
|
|
|
// find the diff between current time and GMT (UTC)
|
|
struct _timeb tstruct;
|
|
_tzset();
|
|
_ftime( &tstruct );
|
|
|
|
// time difference in "seconds moving westward" - this is the amount of hours to add to the
|
|
// listbox values to get GMT
|
|
short sHourDiff = tstruct.timezone / 60;
|
|
|
|
sCount = 0;
|
|
short sOffset = 0;
|
|
|
|
// adjust for GMT
|
|
if (sHourDiff != 0)
|
|
{
|
|
sOffset += (sHourDiff % 8);
|
|
sCount = (int)(sHourDiff / 8);
|
|
}
|
|
|
|
USHORT sCount2 = 1; // address 0 is used elsewhere
|
|
USHORT sBase;
|
|
BYTE bRet[21];
|
|
ZeroMemory(bRet, 21);
|
|
|
|
for (sBase = 1; sBase < 8; sBase++)
|
|
{
|
|
sCount2 = sBase;
|
|
while (sCount2 < 169)
|
|
{
|
|
if (m_sCell[sCount2].bVal) // 1 = marked
|
|
bRet[sCount] |= dwOffset[sOffset];
|
|
|
|
sOffset++;
|
|
if (sOffset > 7)
|
|
{
|
|
sOffset = 0;
|
|
sCount++;
|
|
if (sCount > 20) sCount = 0;
|
|
}
|
|
sCount2+=7;
|
|
}
|
|
}
|
|
|
|
|
|
long index[1];
|
|
for (index[0] = 0; index[0] < 21; index[0]++)
|
|
SafeArrayPutElement(vaResult.parray, &index[0], &bRet[index[0]]);
|
|
|
|
return vaResult;
|
|
}
|
|
|
|
void CHoursCtrl::SetDateData(const VARIANT FAR& newValue)
|
|
{
|
|
// TODO: Add your property handler here
|
|
|
|
SetModifiedFlag();
|
|
}
|