eXCalendar - FAQ
Exontrol.COM Software - Frequently Asked Questions - ExCalendar Component
1:
The control's release notes can be found on our web site, looking for the Release Notes column in the control's main page. Click here for direct link.
2:
The idea of adding recurring events to eXCalendar consists in:
  • Handle the DateChanged event of the eXCalendar component
  • Collects the occurrences of the recurrence expression between FirstVisibleDate, LastVisibleDate properties of the eXCalendar component, using the RecurRange method of the eXICalendar library
  • For each occurrence found, add a new events using the Add method of the Events collection of  eXCalendar component

The following VB sample adds recurring events to eXCalendar :

Private Sub Calendar1_DateChanged()
    DoEvents
    With Calendar1
        .BeginUpdate
        Dim o As Variant
        For Each o In CreateObject("Exontrol.ICalendar").RecurRange("DTSTART=20151201;FREQ=WEEKLY;BYDAY=FR", .FirstVisibleDate, .LastVisibleDate)
            .Events.Add(o).Marker = True
        Next
        .EndUpdate
    End With
End Sub
Private Sub Form_Load()
    With Calendar1
        .FirstDay = Monday
        .AlignmentDay = CenterAlignment
        .GridLineColor = RGB(128, 128, 128)
        Calendar1_DateChanged
    End With
End Sub

and you should get:

The same sample in C++, should look such as:

void C...Dlg::DateChangedCalendar1()
{
	DoEvents();
	EXCALENDARLib::ICalendarPtr spCalendar1 = GetDlgItem(IDC_CALENDAR1)->GetControlUnknown();
	if ( spCalendar1 != NULL )
	{
		EXCALENDARLib::IEventsPtr spEvents = spCalendar1->Events;
		spCalendar1->BeginUpdate();
		EXICALENDARLib::IICalendarPtr spICal = ::CreateObject(L"Exontrol.ICalendar");
		if ( spICal != NULL )
		{
			_variant_t vtRecurRange = spICal->GetRecurRange(L"DTSTART=20151201;FREQ=WEEKLY;BYDAY=FR",spCalendar1->FirstVisibleDate,spCalendar1->LastVisibleDate);
			if ( V_VT( &vtRecurRange ) == ( VT_ARRAY | VT_DATE ) )
			{
				SAFEARRAY* pArray = V_ARRAY( &vtRecurRange );
				DATE* pData = NULL;
				if ( SUCCEEDED( SafeArrayAccessData( pArray, (LPVOID*)&pData ) ) )
				{
					long lowerBound = 0, upperBound = 0;
					SafeArrayGetLBound(pArray, 1 , &lowerBound);
					SafeArrayGetUBound(pArray, 1, &upperBound);
					long nCount = upperBound - lowerBound + 1; 
					SafeArrayUnaccessData( pArray );
					for ( long i = 0; i < nCount; i++, pData++ )  // iterate through returned values
						spEvents->Add( *pData )->Marker = VARIANT_TRUE;
				}
			}
		}
		spCalendar1->EndUpdate();
	}
}
BOOL C...Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	...
	EXCALENDARLib::ICalendarPtr spCalendar1 = GetDlgItem(IDC_CALENDAR1)->GetControlUnknown();
	if ( spCalendar1 != NULL )
	{
		spCalendar1->PutAlignmentDay(EXCALENDARLib::CenterAlignment);
		spCalendar1->PutFirstDay(EXCALENDARLib::Monday);
		spCalendar1->PutGridLineColor(RGB(128,128,128));
		DateChangedCalendar1();
	}
	return TRUE;  // return TRUE  unless you set the focus to a control
}

where the definitions for CreateObject, DoEvents is:

#include <comdef.h>
IUnknownPtr CreateObject( BSTR Object )
{
	IUnknownPtr spResult;
	spResult.CreateInstance( Object );
	return spResult;
};
void DoEvents()
{
	MSG m = {0};
	while ( PeekMessage( &m, NULL, NULL, NULL, PM_REMOVE ) )
	{
		TranslateMessage( &m );
		DispatchMessage( &m );
	}
}

The same sample in C#, should look such as:

private void axCalendar1_DateChanged(object sender, EventArgs e)
{
    Application.DoEvents();
    if (iCal != null)
    {
        axCalendar1.BeginUpdate();
        axCalendar1.Events.Clear();
        foreach (System.DateTime d in ( iCal.get_RecurRange("DTSTART=20151201;FREQ=WEEKLY;BYDAY=FR", axCalendar1.FirstVisibleDate, axCalendar1.LastVisibleDate) as Array ))
            axCalendar1.Events.Add(d).Marker = true;
        axCalendar1.EndUpdate();
    }
}
EXICALENDARLib.ICalendar iCal = null;
        private void Form1_Load(object sender, EventArgs e)
        {
            iCal = new EXICALENDARLib.ICalendar();
            axCalendar1.Appearance = EXCALENDARLib.AppearanceEnum.None2;
            axCalendar1.ShowWeeks = true;
            axCalendar1.Date = Convert.ToDateTime("1/1/2015",System.Globalization.CultureInfo.GetCultureInfo("en-US"));
            axCalendar1.ShowNonMonthDays = false;
            axCalendar1.ShowMonthSelector = false;
            axCalendar1.FirstDay = EXCALENDARLib.WeekDayEnum.Monday;
            axCalendar1.AlignmentDay = EXCALENDARLib.AlignmentEnum.CenterAlignment;
            axCalendar1.GridLineColor = Color.Gray;
        }
3:

The control provides events like Click or DblClick that notifies once the user clicks / double clicks the control. The control's DateFromPoint(-1,-1) property determines the date from the current cursor position. The Item property of the Events collection can be of Date type, which indicates that you can check if there is any event associated with the date.

The following VB sample displays the date being clicked:

Private Sub Calendar1_Click()
	Dim d As Date
	With Calendar1
		d = .DateFromPoint(-1, -1)
		If Not (d = 0) Then
			MsgBox "You have clicked: " & d
		End If
	End With
End Sub

The following VB sample displays the date being clicked, including the associated event:

Private Sub Calendar1_Click()
	Dim d As Date, s As String
	With Calendar1.Object
		d = .DateFromPoint(-1, -1)
		If Not (d = 0) Then
			s = "You have clicked: " & d
			Dim e As EXCALENDARLibCtl.Event
			Set e = .Events.Item(CDate(d))
			If Not e Is Nothing Then
				s = s + vbCrLf + "The date has associated an event"
			End If
		End If
	End With
	If (Len(s) > 0) Then
		MsgBox s
	End If
End Sub

In VBA/MSAccess, you need to replace the EXCALENDARLibCtl with EXCALENDARLib, else you will be prompted for a compiler error: "Can't find project or library"

How-To Questions
General Questions