|

(Download
Code) 

Part I
Lets see in some more detail the basic interaction
mechanism:

Weve seen that the VBCE WindowProc does not
provide functionality to react programmatically to WM_NOTIFY callbacks.
So, we would have to "Subclass" the VBCE window which
is nothing else than extending WindowProc with extra functionality
designed by the programmer.
To implement Subclassing, we would have to inform
the system that our WindowProc is somewhere else and return the
control to the original WindowProc once were done with the
callback:

And we came to another drawback on VBCE: the lack
of the AddressOf operator. Without AddressOf were not able
to inform the Month Calendar Control that we want its messages to
be sent to our own handler so were not able to implement this
mechanism.
In our case, it would be excellent to be informed
by the Month-Calendar control every time the user clicks on a date.
As we are unable to receive these messages, we have to implement
another approach: we show the calendar, wait for the user to click
an "OK" button, and then we send a message to the control
requesting the selected date.

On the example, our VBCE window calls just two functions
to use the Month-Calendar control.
First we load the calendar on the "Form_Load()"
event with:
'-- Insert Calendar Common
Control
MCalendar_Load Me.hwnd, App.hInstance, 8, 40
where the last two values are just the position (in
pixels) of the upper-left corner of the calendar, and we call:
'-- Get Calendar Date selected
mDate = MCalendar_Date
to get the date selected. All the Month-Calendar related
code is included on the "McalendarMod" module. We also
use the GetLocalTime and SetLocalTime API functions to retrieve
and set our system date but this is not directly related to the
Month-Calendar control (check the UDT demonstration code).

Before we can create or use any common controls, we
have to register them. There are actually two options available:
we either register the specific control we want to use or we register
all common controls at once. The MCalendar_Load sub uses the first
option by calling the InitCommonControlsEx API function with the
ICC_DATE_CLASSES parameter on its INITCOMMONCONTROLSEX udt.
Then we create the Month-Calendar window, CreateWindowEx,
with the desired profile. "dwStyle", the 4th call parameter
of CreateWindowEx, let us change the control style. Example: if
we add MCS_NOTODAY (&H10), the Month-Calendar control will not
display the "today" date at the bottom of the control:
Const MCS_NOTODAY = &H10
'-- Create the month calendar (resize it later)
MCalendar_hWnd = CreateWindowEx( _
0, MONTHCAL_CLASS, "", _
WS_BORDER + WS_CHILD + WS_VISIBLE + MCS_NOTODAY, _
0, 0, 0, 0, _
hwndOwner, vbNull, g_hinst, vbNull)
After creation well interact with the control
through messages. MCalendar_Load uses two messages: first it uses
the MCM_GETMINREQRECT message to get the required width and height
to show an entire month. These values will be used further on by
the SetWindowPos API function. Then it uses the MCM_SETCOLOR with
the MCSC_MONTHBK parameter to set the background color (RGB) to
light yellow.

This function just sends a MCM_GETCURSEL message to
get the currently selected date on a SYSTEMTIME udt and returns
it. The time part is extracted because its irrelevant on a
Month-Calendar control.
Written on: 27/Oct/99
By: Antonio Paneiro
ComMEDIA,Lda.
apaneiro@commedia.pt
http://www.commedia.pt/ce
|