1 Option Explicit
2
3
4 ''' // **********************************************************************************
5 ''' // Date Picker Class
6 ''' // **********************************************************************************
7
8 'DEVELOPED AND TESTED UNDER MICROSOFT ACCESS 97 VBA
9 ' There is a seperate A2K or higher version required because
10 ' A97 does not support AddressOf.
11 ' That is the only difference between the A97 and the A2K versions.
12 '
13 'Copyright: Stephen Lebans - Lebans Holdings 1999 Ltd.
14 ' Pedro Gil
15 ' Please feel free to use this code within your own
16 ' projects whether they are private or commercial applications
17 ' without obligation.
18 ' This code may not be resold by itself or as part of a collection.
19 '
20 'Name: clsMonthCal
21 '
22 'Version: 2.05
23 '
24 'Purpose:
25 ' To allow for the selection of a Date or Dates using the standard
26 ' Windows Month Calendar control without having to use the ActiveX control.
27 '
28 'Authors: Stephen Lebans
29 ' Pedro Gil
30
31 'Email: Stephen@lebans.com
32 ' pmpg98@hotmail.com
33 '
34 'Web Site: www.lebans.com
35 '
36 'Date: December 09, 2004
37 '
38 'Credits: Pedro Gil for doing the background
39 ' research necessary to code a working model.
40 ' Stephen Lebans for the API non ActiveX solution,
41 ' with autosizing, user selectable display.
42 ' Michael Kaplan for the idea to create the
43 ' Month Calendar directly from the Common Control DLL.
44 ' jwolzvb@yahoo.de for a VB example of implementing
45 ' a 1 month ActiveX MonthCalendar control.
46 '
47 'BUGS: Please report any bugs to Stephen@Lebans.com
48 '
49 'What's Missing:
50 ' Proper error handling.
51 '
52 'How it Works:
53 ' The Month Calendar is created directly with the
54 ' API's contained in the Common Controls DLL. In this manner we bypass
55 ' the DatePicker ActiveX control, which is simply a wrapper for these
56 ' calls anyway. This removes any problems from distribution and
57 ' especially version issues of using the ActiveX control.
58
59 ' DAYSTATE:
60 ' Have a look at the Initialize sub for this Class to see how to
61 ' set the DayStates for the months. You can also set the bits
62 ' in the array yourself if you are converting data that you
63 ' are storing in your own tables.
64 '
65 ' This is the ?th release. We have exposed most of the properties of the
66 ' Month Calendar. Simply add your own for any we have left out.
67
68 ''' // **********************************************************************************
69 ''' // Ver.: 3.0.0
70 ''' // (c) 2009; digital-ecom GmbH
71 ''' // Adapted to MS Excel incl. Excel 2000
72
73 ''' // Extension:
74 ''' // Allow setting a restricted date range a user can use, i.e. no dates smaller 01.04.2007 and/or no dates greater 01.04.2010.
75 ''' // digital-ecom GmbH, 22.05.2009
76
77 ''' // Bug Fixing:
78 ''' // When closing the dialog, especially on cancel:
79 ''' // First activate Excel Window, then close Calendar Ctrl - this assures we do not jump to other applications when simply closing
80 ''' // the calendar Ctrl and it does prevent screen flickering.
81 ''' // digital-ecom GmbH, 08.05.2009
82
83 ''' // Made the control capable to be used with modeless user forms.
84 ''' // digital-ecom GmbH, May 2009
85
86 ''' // Made code readable ... <sigh />
87 ''' // Added usage of just one constant for Classname and Title
88
89 ''' // Note: All original comments were used where possible. Our comments are introduced by ''' // always.
90 ''' // **********************************************************************************
91
92 Private Type RECT
93 Left As Long
94 Top As Long
95 Right As Long
96 Bottom As Long
97 End Type
98
99 Private Type POINTAPI
100 X As Long
101 y As Long
102 End Type
103
104
105 'Window Style Bits
106 Private Const WS_OVERLAPPED = &H0&
107 Private Const WS_POPUP = &H80000000
108 Private Const WS_CHILD = &H40000000
109 Private Const WS_MINIMIZE = &H20000000
110 Private Const WS_VISIBLE = &H10000000
111 Private Const WS_DISABLED = &H8000000
112 Private Const WS_CLIPSIBLINGS = &H4000000
113 Private Const WS_CLIPCHILDREN = &H2000000
114 Private Const WS_MAXIMIZE = &H1000000
115 Private Const WS_CAPTION = &HC00000
116 Private Const WS_BORDER = &H800000
117 Private Const WS_DLGFRAME = &H400000
118 Private Const WS_VSCROLL = &H200000
119 Private Const WS_HSCROLL = &H100000
120 Private Const WS_SYSMENU = &H80000
121 Private Const WS_THICKFRAME = &H40000
122
123 ' SetWindowPos Flags
124 Private Const SWP_NOSIZE = &H1
125
126
127 'Windows Style Bits Specific to DTP
128 Private Const DTS_UPDOWN As Long = &H1 '0x0001 // use UPDOWN instead of MONTHCAL
129 Private Const DTS_SHOWNONE As Long = &H2 '0x0002 // allow a NONE selection
130 Private Const DTS_SHORTDATEFORMAT As Long = &H0 '0x0000 // use the short date format (app must forward WM_WININICHANGE messages)
131 Private Const DTS_LONGDATEFORMAT As Long = &H4 '0x0004 // use the long date format (app must forward WM_WININICHANGE messages)
132 Private Const DTS_TIMEFORMAT As Long = &H9 '0x0009 // use the time format (app must forward WM_WININICHANGE messages)
133 Private Const DTS_APPCANPARSE As Long = &H10 '0x0010 // allow user entered strings (app MUST respond to DTN_USERSTRING)
134 Private Const DTS_RIGHTALIGN As Long = &H20 '0x0020 // right-align popup instead of left-align it
135
136 ' Used to change Font for Month Calendar common control
137 Private Const WM_SETFONT = &H30
138
139 '// bit-packed array of "bold" info for a month
140 '// if a bit is on, that day is drawn bold
141 Private Type MONTHDAYSTATE
142 lpMONTHDAYSTATE As Long
143 End Type
144
145 Private Type SYSTEMTIME
146 wYear As Integer
147 wMonth As Integer
148 wDayOfWeek As Integer
149 wDay As Integer
150 wHour As Integer
151 wMinute As Integer
152 wSecond As Integer
153 wMilliseconds As Integer
154 End Type
155
156 Private Type NMHDR
157 hwndFrom As Long
158 idfrom As Long
159 code As Long 'Integer
160 End Type
161
162 Private Type NMDAYSTATE
163 nmhd As NMHDR ' // this must be first, so we don't break WM_NOTIFY
164 stStart As SYSTEMTIME
165 cDayState As Long
166 prgDayState(11) As MONTHDAYSTATE ' For ease of use always specify 12 months of data - points to cDayState MONTHDAYSTATEs
167 End Type
168
169 Private Declare Function apiCreateWindowEx Lib "user32.dll" Alias "CreateWindowExA" _
170 (ByVal dwExStyle As Long, _
171 ByVal lpClassName As String, _
172 ByVal lpWindowName As String, _
173 ByVal dwStyle As Long, _
174 ByVal X As Long, _
175 ByVal y As Long, _
176 ByVal nWidth As Long, _
177 ByVal nHeight As Long, _
178 ByVal hWndParent As Long, _
179 ByVal hMenu As Long, _
180 ByVal hInstance As Long, _
181 lpParam As Any) As Long
182
183 Private Declare Function apiDestroyWindow Lib "user32" Alias "DestroyWindow" _
184 (ByVal hwnd As Long) As Long
185
186 Private Declare Function apiCreateFont Lib "gdi32" Alias "CreateFontA" _
187 (ByVal h As Long, ByVal w As Long, ByVal E As Long, ByVal O As Long, _
188 ByVal w As Long, ByVal i As Long, ByVal u As Long, ByVal s As Long, _
189 ByVal c As Long, ByVal OP As Long, ByVal CP As Long, ByVal Q As Long, _
190 ByVal PAF As Long, ByVal f As String) As Long
191
192 Private Declare Function apiMulDiv Lib "kernel32" Alias "MulDiv" _
193 (ByVal nNumber As Long, _
194 ByVal nNumerator As Long, ByVal nDenominator As Long) As Long
195
196 'To register the class
197 Private Type INITCOMMONCONTROLSEXSTRUCT
198 dwsize As Long
199 dwICC As Long
200 End Type
201
202 Private Declare Function apiInitCommonControlsEx Lib "Comctl32" Alias "InitCommonControlsEx" _
203 (lpInitCtrls As INITCOMMONCONTROLSEXSTRUCT) As Long
204
205 Private Const ICC_DATE_CLASSES = &H100
206
207 'Get Instance of Access by KEN GETZ
208 'required for CreateWindowEx hInstance
209 'Put this in the declarations area of a standard module.
210 Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
211 (ByVal hwnd As Long, _
212 ByVal nIndex As Long) As Long
213
214
215 Private Const GWL_HINSTANCE = (-6)
216
217 'To check the space needed by the control
218 Private Const LOGPIXELSX = 88
219 Private Const LOGPIXELSY = 90
220 Private Const TWIPSPERINCH = 1440
221
222 Private Declare Function GetClientRect Lib "user32" _
223 (ByVal hwnd As Long, lpRect As RECT) As Long
224
225 Private Declare Function GetWindowRect Lib "user32" _
226 (ByVal hwnd As Long, lpRect As RECT) As Long
227
228 Private Declare Function AdjustWindowRect Lib "user32" _
229 (lpRectl As RECT, ByVal dwStyle As Long, ByVal bMenu As Long) As Long
230
231 Private Declare Function AdjustWindowRectEx Lib "user32" _
232 (lpRect As RECT, ByVal dsStyle As Long, ByVal bMenu As Long, ByVal dwEsStyle As Long) As Long
233
234 Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
235
236 Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
237
238 Private Declare Function apiSendMessage Lib "user32" Alias "SendMessageA" _
239 (ByVal hwnd As Long, _
240 ByVal wMsg As Long, _
241 ByVal wParam As Long, _
242 lParam As Any) As Long
243
244 Private Declare Function apiSetWindowPos Lib "user32" Alias "SetWindowPos" _
245 (ByVal hwnd As Long, _
246 ByVal hWndInsertAfter As Long, _
247 ByVal X As Long, _
248 ByVal y As Long, _
249 ByVal cx As Long, _
250 ByVal cy As Long, _
251 ByVal wFlags As Long) As Long
252
253 Private Declare Function apiCreateIC Lib "gdi32" Alias "CreateICA" _
254 (ByVal lpDriverName As String, _
255 ByVal lpDeviceName As String, _
256 ByVal lpOutput As String, _
257 lpInitData As Any) As Long
258
259 Private Declare Function apiGetDeviceCaps Lib "gdi32" Alias "GetDeviceCaps" _
260 (ByVal hdc As Long, _
261 ByVal nIndex As Long) As Long
262
263 Private Declare Function apiDeleteDC Lib "gdi32" Alias "DeleteDC" _
264 (ByVal hdc As Long) As Long
265
266
267
268
269 Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
270 (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
271
272 Private Declare Function GetDesktopWindow Lib "user32" () As Long
273
274 Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
275 (ByVal lpClassName As String, _
276 ByVal lpWindowName As String) As Long
277
278 Private Declare Function Beep Lib "kernel32" _
279 (ByVal dwFreq As Long, ByVal dwDuration As Long) As Long
280
281
282
283 ' Color Types
284 Private Const CTLCOLOR_MSGBOX = 0
285 Private Const CTLCOLOR_EDIT = 1
286 Private Const CTLCOLOR_LISTBOX = 2
287 Private Const CTLCOLOR_BTN = 3
288 Private Const CTLCOLOR_DLG = 4
289 Private Const CTLCOLOR_SCROLLBAR = 5
290 Private Const CTLCOLOR_STATIC = 6
291 Private Const CTLCOLOR_MAX = 8 ' three bits max
292
293 Private Const COLOR_SCROLLBAR = 0
294 Private Const COLOR_BACKGROUND = 1
295 Private Const COLOR_ACTIVECAPTION = 2
296 Private Const COLOR_INACTIVECAPTION = 3
297 Private Const COLOR_MENU = 4
298 Private Const COLOR_WINDOW = 5
299 Private Const COLOR_WINDOWFRAME = 6
300 Private Const COLOR_MENUTEXT = 7
301 Private Const COLOR_WINDOWTEXT = 8
302 Private Const COLOR_CAPTIONTEXT = 9
303 Private Const COLOR_ACTIVEBORDER = 10
304 Private Const COLOR_INACTIVEBORDER = 11
305 Private Const COLOR_APPWORKSPACE = 12
306 Private Const COLOR_HIGHLIGHT = 13
307 Private Const COLOR_HIGHLIGHTTEXT = 14
308 Private Const COLOR_BTNFACE = 15
309 Private Const COLOR_BTNSHADOW = 16
310 Private Const COLOR_GRAYTEXT = 17
311 Private Const COLOR_BTNTEXT = 18
312 Private Const COLOR_INACTIVECAPTIONTEXT = 19
313 Private Const COLOR_BTNHIGHLIGHT = 20
314
315 Private Declare Function GetSysColor Lib "user32" (ByVal nIndex As Long) As Long
316
317 'SysMonthCal32 messages
318 Private Const MCM_FIRST = &H1000&
319 Private Const MCM_GETCURSEL = &H1001& '(MCM_FIRST + 1)
320 Private Const MCM_SETCURSEL = (MCM_FIRST + 2)
321 Private Const MCM_GETMINREQRECT = (MCM_FIRST + 9)
322 Private Const MCM_SETMAXSELCOUNT = (MCM_FIRST + 4)
323
324 Private Const MCM_GETRANGE = (MCM_FIRST + 17)
325 Private Const MCM_SETRANGE = (MCM_FIRST + 18)
326
327 'Public Const DTM_SETRANGE = &H1004&
328 Private Const GDTR_MIN = 1
329 Private Const GDTR_MAX = 2
330
331 Private Const MCM_GETSELRANGE = (MCM_FIRST + 5)
332 Private Const MCM_GETMONTHRANGE = (MCM_FIRST + 7)
333
334
335 Private Const MCM_SETCOLOR = (MCM_FIRST + 10)
336 Private Const MCM_GETCOLOR = (MCM_FIRST + 11)
337
338 Private Const MCM_SETTODAY = (MCM_FIRST + 12)
339 Private Const MCM_GETTODAY = (MCM_FIRST + 13)
340 Private Const MCM_SETFIRSTDAYOFWEEK = (MCM_FIRST + 15)
341 Private Const MCM_GETFIRSTDAYOFWEEK = (MCM_FIRST + 16)
342 Private Const MCM_SETDAYSTATE = (MCM_FIRST + 8)
343 Private Const MCM_SETSELRANGE = (MCM_FIRST + 6)
344
345
346 Private Const MCM_GETMAXTODAYWIDTH = (MCM_FIRST + 21)
347
348 'Color part's of the Calendar
349 Private Const MCSC_BACKGROUND = 0 '// the background color (between months)
350 Private Const MCSC_TEXT = 1 '// the dates
351 Private Const MCSC_TITLEBK = 2 '// background of the title
352 Private Const MCSC_TITLETEXT = 3
353 Private Const MCSC_MONTHBK = 4 '// background within the month cal
354 Private Const MCSC_TRAILINGTEXT = 5 '// the text color of header & trailing days
355
356 Private Const MCS_DAYSTATE = &H1
357 Private Const MCS_MULTISELECT = &H2
358 Private Const MCS_WEEKNUMBERS = &H4
359 Private Const MCS_NOTODAYCIRCLE = &H8
360 Private Const MCS_NOTODAY = &H10
361 Private Const GMR_VISIBLE = 0 '// visible portion of display
362 Private Const GMR_DAYSTATE = 1 ' // above plus the grayed out parts of partially displayed months
363
364 ' Window field offsets for GetWindowLong() and GetWindowWord()
365 Private Const GWL_WNDPROC = (-4)
366 'Private Const GWL_HINSTANCE = (-6)
367 Private Const GWL_HWNDPARENT = (-8)
368 Private Const GWL_STYLE = (-16)
369 Private Const GWL_EXSTYLE = (-20)
370 Private Const GWL_USERDATA = (-21)
371 Private Const GWL_ID = (-12)
372
373 Private Const POINTSPERINCH As Long = 72
374
375 Private Const cerrPropertyNotFound As Integer = 3270
376
377 ' Generally use Hex values but
378 ' Decimal is clearer for educational purposes.
379 Const Bit10 = 128
380 Const Bit9 = 128
381 Const Bit8 = 128
382 Const Bit7 = 64
383 Const Bit6 = 32
384 Const Bit5 = 16
385 Const Bit4 = 8
386 Const Bit3 = 4
387 Const Bit2 = 2
388 Const Bit1 = 1
389
390 ' Not used anymore
391 Private Const NotAColor = &HEF000000
392
393 ' Leftover DAO props so that Reference to DAO is no longer required.
394 Private Const dbLongDAO = 4
395 Private Const dbTextDAO = 10
396
397
398 ' Module Level Variables
399
400 ' Junk vars
401 Private lngRet As Long
402 Private blRet As Boolean
403 Private varTemp As Variant
404
405 ' Current Y axis Resolution in Dots per Inch
406 Private lngYdpi As Long
407
408 ' General purpose RECT structure
409 Private udtRECT As RECT
410
411 ' There is a bug in Access when using the SetWindowPos API
412 ' on a Form from an external Class module.
413 ' Specifically if the Form contains a Header or a
414 ' Command Button they are resized along with the Form.
415 ' To get around this we need to store the original
416 ' height of the CommandButton.
417 Private originalCmdButHeight As Integer
418
419 ' hWnd for the Month Calendar control
420 Private m_hWndDTP As Long
421 ' hWnd for the Form used to display the Calendar
422 ' Private m_Form As Access.Form
423
424 'Properties used to create the Month Calendar
425 Private m_MonthColumns As Integer
426 Private m_MonthRows As Integer
427 Private m_SelectedDate As Date
428
429 ' To init SetSelectedDateRange
430 Private m_StartDate As Date
431 Private m_EndDate As Date
432
433 Private m_FontName As String
434 Private m_FontSize As Integer
435 Private m_ShowWeekNumbers As Long
436
437 ' Allow the user to select a Range of Dates
438 Private m_MultiSelect As Long
439
440 ' Max number of days in a user selectable range
441 Private m_MaxSelectRangeofDays As Integer
442
443 Private m_SetRangeOfDays As Long
444
445
446 ' Offset from the Top of our Form where we draw the
447 ' Month Calendar. Allows any controls we have placed at the
448 ' top of the Form to be visible.
449 Private m_CalendarYOffset As Integer
450
451 ' Month Calendar Color props
452 Private m_BackColor As Long
453 Private m_ForeColor As Long
454 Private m_MonthBackColor As Long
455 Private m_TitleBackColor As Long
456 Private m_TitleForeColor As Long
457 Private m_TrailingForeColor As Long
458 ' Original values of above color props
459 ' that exist at time of Calendar creation.
460 ' These color values are as per the Users Window setting
461 Private m_BackColorOrig As Long
462 Private m_ForeColorOrig As Long
463 Private m_MonthBackColorOrig As Long
464 Private m_TitleBackColorOrig As Long
465 Private m_TitleForeColorOrig As Long
466 Private m_TrailingForeColorOrig As Long
467
468 Private m_NoToday As Long
469 Private m_NoTodayCircle As Long
470
471 ' Store current Cursor location for this session
472 Private m_cursorX As Long
473 Private m_cursorY As Long
474 Private m_PositionAtCursor As Boolean
475 ' Cursor coords when Calendar is first loaded
476 Private m_cursorXinitpos As Long
477 Private m_cursorYinitpos As Long
478 ' Positioning of Calendar Window
479 Private m_WindowLocation As Long
480
481 ' Requried to calculate Calendar Height
482 Dim m_TodayHeight As Long
483
484 ' Temp vars to hold the size of our Calendar
485 Private lngTempRight As Long
486 Private lngTempBottom As Long
487 Private hFontPrevious As Long
488
489 Public m_Hwnd As Long
490 Private m_hWndForm As Long
491
492 ' Click once to close the Calendar?
493 Private m_oneClick As Boolean
494
495 ' Max 12 Months displayed at once
496 ' plus one month before and after = 14 months
497 ' Allow for years 1000 to 3000
498 Private BoldDayStates(1000 To 3000, 1 To 14) As MONTHDAYSTATE
499
500 ''' // Create unique naming of Class and unique labeling of Controls Title by using (one!) constant accross this module.
501 ''' // The same constants are used within the modDateTimePicker module.
502 Const CLASSNAME = "MonthCalendar"
503 Const TITLE = "Date Picker:"
504
505 ' Create the Month Calendar
506 Public Sub CreateDTPControl()
507 Dim appHWnd As Long
508
509 ' Only create MonthCalendar if there is a host window
510 If m_Hwnd = 0 Then Exit Sub
511
512 ''' // Get handle to Excel application window
513 If Val(Application.Version) < 10 Then
514 appHWnd = FindWindow("XLMAIN", vbNullString) ''' // < Excel 2000
515 Else
516 appHWnd = Application.hwnd
517 End If
518
519 ' Temp vars
520 Dim udtICC As INITCOMMONCONTROLSEXSTRUCT
521 Dim lngStyle As Long
522 Dim hInstance As Long
523
524 'Temp handle to Information context
525 Dim lngIC As Long
526
527 ''' // If there is an existant DTP destroy it
528 If m_hWndDTP <> 0 Then
529 Call apiDestroyWindow(m_hWndDTP)
530 End If
531
532 ' Courtesy of Ken Getz
533 hInstance = GetWindowLong(appHWnd, GWL_HINSTANCE)
534 udtICC.dwsize = Len(udtICC)
535 udtICC.dwICC = ICC_DATE_CLASSES
536 Call apiInitCommonControlsEx(udtICC)
537
538 ' The Calendar MultiSelect property determines whether the
539 ' user can select a range of dates ' WS_BORDER Or WS_OVERLAPPED
540 lngStyle = WS_BORDER Or WS_CHILD Or m_MultiSelect _
541 Or m_ShowWeekNumbers Or m_NoToday Or m_NoTodayCircle Or m_NoToday Or WS_VISIBLE Or MCS_DAYSTATE ' DayState not ready yet! Or MCS_DAYSTATE
542
543
544 ' Create our Month Calendar
545 m_hWndDTP = apiCreateWindowEx(0&, _
546 "SysMonthCal32", _
547 "DateTimePicker", _
548 lngStyle, _
549 0, _
550 0, _
551 250, _
552 250, _
553 m_Hwnd, _
554 0&, _
555 hInstance, _
556 ByVal 0&)
557
558 ' Modified to allow for different screen resolutions
559 ' and printer output. Needed to Calculate Font size
560 lngIC = apiCreateIC("DISPLAY", vbNullString, vbNullString, vbNullString)
561 If lngIC <> 0 Then
562 lngYdpi = apiGetDeviceCaps(lngIC, LOGPIXELSY)
563 apiDeleteDC (lngIC)
564 Else
565 lngYdpi = 120 'Default average value
566 End If
567
568
569 ' Grab all of the Color props before we mangle them!
570 m_BackColorOrig = BackColor
571 m_ForeColorOrig = ForeColor
572 m_MonthBackColorOrig = MonthBackColor
573 m_TitleBackColorOrig = TitleBackColor
574 m_TitleForeColorOrig = TitleForeColor
575 m_TrailingForeColorOrig = TrailingForeColor
576
577 ' Call our Sub to redraw the Form holding our Calendar
578 ' and position the Calendar appropriately.
579 ReDraw
580 End Sub
581
582
583 Public Sub ReDraw()
584 Dim appHWnd As Long
585 ' Redraw and Position the Parent Form and the Calendar
586
587 ' Only create MonthCalendar if there is a host window
588 If m_Hwnd = 0 Then Exit Sub
589
590 If Val(Application.Version) < 10 Then
591 appHWnd = FindWindow("XLMAIN", vbNullString)
592 Else
593 appHWnd = Application.hwnd
594 End If
595
596 Dim lngXtraPixels As Long
597 ' Make sure the Calendar has time to be initially rendered.
598 DoEvents
599
600 ' Re-render using our props for FontName and FontSize
601 Me.ChangeFont
602
603 ' ****************************
604 ' NOT READY YET!!!!
605 ' TEST FOR DAYSTATE
606 'Me.DayState = 1
607
608 ' Set max range of days user can select
609 Call apiSendMessage(m_hWndDTP, MCM_SETMAXSELCOUNT, m_MaxSelectRangeofDays, ByVal 0&)
610
611 ' If EndDate is Set and MultiSelect then call SetSelectedDateRange
612 If m_EndDate <> 0 And m_EndDate <> 0 And m_MultiSelect = MCS_MULTISELECT Then
613 SetSelectedDateRange m_StartDate, m_EndDate
614 Else
615
616 Dim udtST As SYSTEMTIME
617 With udtST
618 .wYear = year(m_StartDate)
619 .wMonth = month(m_StartDate)
620 .wDay = day(m_StartDate)
621 End With
622 Call apiSendMessage(m_hWndDTP, MCM_SETCURSEL, ByVal 0&, udtST)
623 End If
624
625 ' Get the size required to display 1 complete month of the calendar.
626 Call apiSendMessage(m_hWndDTP, MCM_GETMINREQRECT, ByVal 0&, udtRECT)
627
628 ' Check is TODAY is showing at bottom of Calendar
629 If m_NoToday = 0 Then
630 lngXtraPixels = apiSendMessage(m_hWndDTP, MCM_GETMAXTODAYWIDTH, ByVal 0&, ByVal 0&)
631 Else
632 lngXtraPixels = udtRECT.Right ' = lngXtraPixels
633 End If
634
635 ' Set color props
636 If m_BackColor <> NotAColor Then
637 Call apiSendMessage(m_hWndDTP, MCM_SETCOLOR, MCSC_BACKGROUND, ByVal m_BackColor)
638 End If
639
640 If m_ForeColor <> NotAColor Then
641 Call apiSendMessage(m_hWndDTP, MCM_SETCOLOR, MCSC_TEXT, ByVal m_ForeColor)
642 End If
643
644 If m_MonthBackColor <> NotAColor Then
645 Call apiSendMessage(m_hWndDTP, MCM_SETCOLOR, MCSC_MONTHBK, ByVal m_MonthBackColor)
646 End If
647
648 If m_TitleForeColor <> NotAColor Then
649 Call apiSendMessage(m_hWndDTP, MCM_SETCOLOR, MCSC_TITLETEXT, ByVal m_TitleForeColor)
650 End If
651
652 If m_TitleBackColor <> NotAColor Then
653 Call apiSendMessage(m_hWndDTP, MCM_SETCOLOR, MCSC_TITLEBK, ByVal m_TitleBackColor)
654 End If
655
656 If m_TrailingForeColor <> NotAColor Then
657 Call apiSendMessage(m_hWndDTP, MCM_SETCOLOR, MCSC_TRAILINGTEXT, ByVal m_TrailingForeColor)
658 End If
659
660 ' This is the function to tell us what size the window would be
661 ' to hold the entire Client Rectangle area. In other words it adds
662 ' on the height for the Title Bar, Bottom Border etc.
663 Dim rc1 As RECT
664 Dim rc2 As RECT
665 Dim rc3 As RECT
666 Dim BarBordersY As Integer
667 Dim BarBordersX As Integer
668
669 ' Get rectangle for our Form
670 ' Debug.Print "GetWindowRect- Me.hWnd:" & m_Form.hWnd
671 lngRet = GetWindowRect(m_hWndDTP, rc1)
672 lngRet = GetClientRect(m_hWndDTP, rc2)
673 ' Calculate Borders and Title Bar area.
674 BarBordersY = ((rc1.Bottom - rc1.Top) - (rc2.Bottom - rc2.Top)) + 10
675 BarBordersX = ((rc1.Right - rc1.Left) - (rc2.Right - rc2.Left)) + 10
676
677 With udtRECT
678 ' Handle possible extra Today string Width
679 udtRECT.Right = lngXtraPixels
680
681 ' An OS bug/feature requires us to round up
682 If m_NoToday <> 0 Then
683 lngTempRight = (.Right * m_MonthColumns) + (m_MonthColumns - 1) * 6 'BarBordersX 'm_MonthColumns * 2 '5
684 lngTempBottom = (.Bottom * m_MonthRows) + (m_MonthRows * (m_TodayHeight * 1.5)) ' (m_TodayHeight * 4) '(m_MonthRows - 1) * 24 '12 'BarBordersY 'm_MonthRows * m_TodayHeight ')) ' + 10 ''m_MonthRows * 15
685 ' ADD CODE TO HELP WITH NUMBER OF ROWS.
686 ' If only 1 run then only need *2 or *3
687 Else
688 lngTempRight = (.Right * m_MonthColumns) + (m_MonthColumns - 1) * 6 'BarBordersX '+ m_MonthColumns * 2 '5
689 lngTempBottom = (.Bottom * m_MonthRows) ' + (m_MonthRows - 1) * 1 '12 'BarBordersY '+ m_MonthRows * 10
690 End If
691 End With
692
693 ' Resize the Month Calendar to display the user selected
694 ' number of months. The CalendarYOffset is used to allow
695 ' any controls we have placed at the Top of our Form
696 ' to be visible.
697 ' ***DEBUG - BUG FIX ******
698 ' Try to fix visual display bug
699 ' when only 1 month is selected.
700 ' The left most column dissappears when
701 ' when selecting a range of dates
702 ' Add 4 pixels to the COntrol's Width
703
704 If m_MonthRows = 1 And m_MonthColumns = 1 Then
705 Call apiSetWindowPos(m_hWndDTP, 0&, 0&, _
706 0&, lngTempRight + 4, lngTempBottom, 0&)
707 Else
708 Call apiSetWindowPos(m_hWndDTP, 0&, 0&, _
709 0&, lngTempRight, lngTempBottom, 0&)
710 End If
711
712 ' Get rectangle for our Form
713 ' Debug.Print "GetWindowRect- Me.hWnd:" & m_Form.hWnd
714 ' lngRet = GetWindowRect(m_Hwnd, rc1)
715 ' lngRet = GetClientRect(m_Hwnd, rc2)
716 ' Get rectangle for our Calendar
717 lngRet = GetWindowRect(m_hWndDTP, rc3)
718
719 lngRet = GetWindowLong(m_Hwnd, GWL_STYLE)
720 lngRet = AdjustWindowRect(rc3, lngRet, -1)
721
722 ' Resize our Form to display the entire Calendar
723 ' Position Window at current cursor location.
724 ' We will use the Cursor location when the Window was first
725 ' created, not the current location. User could be
726 ' selecting a Menu when this Redraw Sub is called.
727 ' We also need to allow the user to manually move
728 ' and place this window and respect those
729 ' coordinates for this session.
730 ' So if the current XY WIndow Coords are not the same
731 ' as the stored Mouse Coords then let the current
732 ' Calendars Parent Window coords stand.
733 ' We do this directly in the Windows Procedure
734 ' by resetting the CursorX and CursorY props
735 ' on the Window Move message.
736
737 If m_PositionAtCursor Then
738 ' Position Window at Cursor Location when
739 ' Calendar was created.
740
741 ' Also add an option to position cursor itself in middle of calendar window
742 ' May 05 - update m_cursorXinitpos and m_cursorYinitpos to reflect current cursor location when this calendar is opened
743 ' This is done in the modCalendar module when the parent window for the Calendar is created.
744
745 'June 7, 2003 fixing position at cursor logic
746 ' PositionAtCursor = True
747
748 ' First check to ensure entire calendar window will fit.
749 ' If not MAKE IT!
750 ' COMING IN NEXT RELEASE!
751 With udtRECT
752 Call apiSetWindowPos(m_Hwnd, 0&, m_cursorX, m_cursorY, rc3.Right - rc3.Left, _
753 rc3.Bottom - rc3.Top, 0&)
754 End With
755
756 Else
757 ' Position Window according to users Menu selections
758 ' a) 0 -Pop at cursor location when user activates Calendar
759 ' b) 1 -Where they manually move/leave it at
760 ' c) 2 -Centered in Access App Window
761 ' d) 3 -Centered on entire screen
762 ' d) 4 -Top Left Corner
763 ' Debug.Print "m_WindowLocation:" & m_WindowLocation
764
765 Select Case m_WindowLocation
766 Case 1
767 With udtRECT
768 Call apiSetWindowPos(m_Hwnd, 0&, m_cursorX, m_cursorY, rc3.Right - rc3.Left, _
769 rc3.Bottom - rc3.Top, 0&)
770 End With
771 Case 2
772 ' Centered within main Access App Window
773 ' Get rectangle for our Calendar
774 lngRet = GetWindowRect(appHWnd, rc2)
775 With udtRECT
776 Call apiSetWindowPos(m_Hwnd, 0&, ((rc2.Right - rc2.Left) - (rc3.Right - rc3.Left)) / 2, _
777 ((rc2.Bottom - rc2.Top) - (rc3.Bottom - rc3.Top)) / 2, rc3.Right - rc3.Left, _
778 rc3.Bottom - rc3.Top, 0&)
779 End With
780 Case 3
781 ' Centered within Screen
782 ' Get rectangle for our Calendar
783 Dim hWndDeskTop As Long
784 hWndDeskTop = GetDesktopWindow()
785 lngRet = GetWindowRect(hWndDeskTop, rc2)
786 With udtRECT
787 Call apiSetWindowPos(m_Hwnd, 0&, ((rc2.Right - rc2.Left) - (rc3.Right - rc3.Left)) / 2, _
788 ((rc2.Bottom - rc2.Top) - (rc3.Bottom - rc3.Top)) / 2, rc3.Right - rc3.Left, _
789 rc3.Bottom - rc3.Top, 0&)
790 End With
791 Case 4
792 ' Upper Left Hand Corner of Screen
793 ' Get rectangle for our Calendar
794 lngRet = GetWindowRect(hWndDeskTop, rc2)
795 With udtRECT
796 Call apiSetWindowPos(m_Hwnd, 0&, 2, _
797 2, rc3.Right - rc3.Left, _
798 rc3.Bottom - rc3.Top, 0&)
799 End With
800 Case Else
801 With udtRECT
802 Call apiSetWindowPos(m_Hwnd, 0&, m_cursorX, m_cursorY, rc3.Right - rc3.Left, _
803 rc3.Bottom - rc3.Top, 0&)
804 End With
805 End Select
806 End If
807 End Sub
808
809 Public Sub ResetCalendarColors()
810 ' Reset all of the color props to their original setting
811 ' as per the users system settings for the GUI.
812 BackColor = m_BackColorOrig
813 ForeColor = m_ForeColorOrig
814 MonthBackColor = m_MonthBackColorOrig
815 TitleBackColor = m_TitleBackColorOrig
816 TitleForeColor = m_TitleForeColorOrig
817 TrailingForeColor = m_TrailingForeColorOrig
818 End Sub
819
820
821 ''' // Ver.: 3.0.0; 22.05.2009; (c) digital-ecom GmbH
822 ''' // Allow specifying a restriced date range
823 Public Function SetDateRange(TimeArray As Variant)
824 Dim sSystemTime(1) As SYSTEMTIME
825
826 sSystemTime(0).wDay = TimeArray(0, 0)
827 sSystemTime(0).wMonth = TimeArray(1, 0)
828 sSystemTime(0).wYear = TimeArray(2, 0)
829
830 sSystemTime(1).wDay = TimeArray(0, 1)
831 sSystemTime(1).wMonth = TimeArray(1, 1)
832 sSystemTime(1).wYear = TimeArray(2, 1)
833
834 Call apiSendMessage(m_hWndDTP, MCM_SETRANGE, GDTR_MIN + GDTR_MAX, ByVal sSystemTime(0))
835 End Function
836
837
838 Public Property Let MultiSelect(ms As Boolean)
839 ' Allow user to select a Range of dates instead of just one.
840 If ms Then
841 m_MultiSelect = MCS_MULTISELECT
842 Else
843 m_MultiSelect = 0
844 End If
845 ' Update custom property
846 SetProperty "MultiSelect", dbLongDAO, m_MultiSelect
847 End Property
848
849 Public Property Get MultiSelect() As Boolean
850 If m_MultiSelect = MCS_MULTISELECT Then
851 MultiSelect = True
852 Else
853 MultiSelect = False
854 End If
855 End Property
856
857 Public Property Let MaxSelectRangeofDays(maxdays As Integer)
858 ' Maximum days user can select in a range of dates.
859 If maxdays > 365 Or maxdays < 0 Then
860 m_MaxSelectRangeofDays = 7
861 Else
862 m_MaxSelectRangeofDays = maxdays
863 End If
864 CreateDTPControl
865 End Property
866
867 Public Property Get MaxSelectRangeofDays() As Integer
868 MaxSelectRangeofDays = m_MaxSelectRangeofDays
869 End Property
870
871 Public Property Let CalendarYOffset(YOffset As Integer)
872 ' Offset from the Top of our Form where we will
873 ' draw our Calendat. This will leave us room at the
874 ' the top of our Form for our controls.
875 ' Some boundary checking. We'll arbitrarily use 3 inches for now.
876 ' This prop is expressed in TWIPS!
877 If YOffset > 3 * TWIPSPERINCH Or YOffset < 0 Then
878 m_CalendarYOffset = 0
879 Else
880 m_CalendarYOffset = YOffset
881 End If
882 'CreateDTPControl
883 End Property
884
885 Public Property Get CalendarYOffset() As Integer
886 CalendarYOffset = m_CalendarYOffset
887 End Property
888
889 Public Property Let MonthRows(ByVal newMonthRows As Byte)
890 ' The Month Calendar allows for a maximum of 12 months
891 ' to be displayed at once.
892 If newMonthRows > 12 Or newMonthRows < 0 Then
893 newMonthRows = 1
894 End If
895 If newMonthRows * m_MonthColumns > 12 Then
896 m_MonthRows = 12 / m_MonthColumns
897 Else
898 m_MonthRows = newMonthRows
899 End If
900
901 ' Update custom property
902 Call SetProperty("MonthRows", dbLongDAO, m_MonthRows)
903 End Property
904
905 Public Property Get MonthRows() As Byte
906 MonthRows = m_MonthRows
907 End Property
908
909 Public Property Let MonthColumns(ByVal newMonthColumns As Byte)
910 ' The Month Calendar allows for a maximum of 12 months
911 ' to be displayed at once.
912 If newMonthColumns > 12 Or newMonthColumns < 0 Then
913 newMonthColumns = 1
914 End If
915
916 If newMonthColumns * m_MonthRows > 12 Then
917 m_MonthColumns = 12 / m_MonthRows
918 Else
919 m_MonthColumns = newMonthColumns
920 End If
921 ' Update custom property
922 Call SetProperty("MonthColumns", dbLongDAO, m_MonthColumns)
923 End Property
924
925 Public Property Get MonthColumns() As Byte
926 MonthColumns = m_MonthColumns
927 End Property
928
929 Public Property Let WindowLocation(loc As Long)
930 ' Allow user to select position of Calendar Window
931 'Debug.Print "Prop Let:" & loc
932 If loc < 0 Or loc > 4 Then
933 m_WindowLocation = 0
934 Else
935 m_WindowLocation = loc
936 End If
937
938 ' Update custom property
939 SetProperty "WindowLocation", dbLongDAO, m_WindowLocation
940 'Debug.Print "Saved Prop :" & m_WindowLocation
941 End Property
942
943 Public Property Get WindowLocation() As Long
944 WindowLocation = m_WindowLocation
945 End Property
946
947
948 Public Property Let PositionAtCursor(bl As Boolean)
949 ' Does user want to popup Calendar at Current Cursor location
950 ' When they invoke the Calendar?
951 Dim pt As POINTAPI
952 m_PositionAtCursor = bl
953 If bl Then
954 ' lngRet = GetCursorPos(pt)
955 m_cursorX = m_cursorXinitpos
956 m_cursorY = m_cursorYinitpos
957 End If
958 End Property
959
960
961 Public Property Get PositionAtCursor() As Boolean
962 PositionAtCursor = m_PositionAtCursor
963 End Property
964
965
966 Public Property Let CursorXinit(X As Long)
967 ' Store Cursor position
968 m_cursorXinitpos = X
969 If Me.PositionAtCursor = True Then
970 m_cursorX = X
971 End If
972 ' Update custom property
973 'Call SetProperty("CursorX", dbLongDAO, m_cursorX)
974 End Property
975
976 Public Property Let CursorYinit(y As Long)
977 ' Store Cursor position
978 m_cursorYinitpos = y
979 If Me.PositionAtCursor = True Then
980 m_cursorY = y
981 End If
982 ' Redraw the control
983 CreateDTPControl
984 ' Update custom property
985 'Call SetProperty("CursorY", dbLongDAO, m_cursorY)
986 End Property
987
988 Public Property Let CursorX(X As Long)
989 ' X pos.
990 m_cursorX = X
991 ' Update custom property
992 Call SetProperty("CursorX", dbLongDAO, m_cursorX)
993 End Property
994
995 Public Property Let CursorY(y As Long)
996 ' Y pos.
997 m_cursorY = y
998 ' Update custom property
999 Call SetProperty("CursorY", dbLongDAO, m_cursorY)
1000 End Property
1001
1002
1003 Public Property Get CursorX() As Long
1004 ' X pos.
1005 CursorX = m_cursorX
1006 End Property
1007
1008 Public Property Get CursorY() As Long
1009 ' Y Pos.
1010 CursorY = m_cursorY
1011 End Property
1012
1013
1014 Public Property Let FontSize(FS As Integer)
1015 ' Font Size to render the Calendar with.
1016 If FS = 0 Or FS < 0 Then FS = 8
1017 If FS > 24 Then FS = 8
1018 m_FontSize = FS
1019 ' Update custom property
1020 SetProperty "FontSize", dbLongDAO, m_FontSize
1021 End Property
1022
1023 Public Property Get FontSize() As Integer
1024 FontSize = m_FontSize
1025 End Property
1026
1027 Public Property Let FontName(fn As String)
1028 ' Font Name to render the Calendar with.
1029 m_FontName = fn
1030 ' Update custom property
1031 Call SetProperty("FontName", dbTextDAO, m_FontName)
1032 End Property
1033
1034 Public Property Get FontName() As String
1035 FontName = m_FontName
1036 End Property
1037
1038 Public Property Let ShowWeekNumbers(bl As Boolean)
1039 ' Show Week Numbers
1040 If bl Then
1041 m_ShowWeekNumbers = MCS_WEEKNUMBERS
1042 Else
1043 m_ShowWeekNumbers = 0
1044 End If
1045 ' Update custom property
1046 Call SetProperty("MCS_WEEKNUMBERS", dbLongDAO, m_ShowWeekNumbers)
1047
1048 ' Redraw the control
1049 CreateDTPControl
1050 End Property
1051
1052 Public Property Get ShowWeekNumbers() As Boolean
1053 If m_ShowWeekNumbers = MCS_WEEKNUMBERS Then
1054 ShowWeekNumbers = True
1055 Else
1056 ShowWeekNumbers = False
1057 End If
1058 End Property
1059
1060 Public Property Get NoTodayCircle() As Boolean
1061 If m_NoTodayCircle = 0 Then
1062 NoTodayCircle = False
1063 Else
1064 NoTodayCircle = True
1065 End If
1066 End Property
1067
1068 Public Property Let NoTodayCircle(bl As Boolean)
1069 ' Show Circle around Today's Date
1070 If bl Then
1071 m_NoTodayCircle = MCS_NOTODAYCIRCLE
1072 Else
1073 m_NoTodayCircle = 0
1074 End If
1075
1076 ' Update custom property
1077 Call SetProperty("NoTodayCircle", dbLongDAO, m_NoTodayCircle)
1078
1079 ' Redraw the control
1080 CreateDTPControl
1081 End Property
1082
1083 Public Property Get NoToday() As Boolean
1084 If m_NoToday = 0 Then
1085 NoToday = False
1086 Else
1087 NoToday = True
1088 End If
1089 End Property
1090
1091 Public Property Let NoToday(bl As Boolean)
1092 ' Show Today's date at bottom of Calendar
1093 If bl Then
1094 m_NoToday = MCS_NOTODAY
1095 Else
1096 m_NoToday = 0
1097 End If
1098 ' Update custom property
1099 Call SetProperty("NoToday", dbLongDAO, m_NoToday)
1100
1101 ' Redraw the control
1102 CreateDTPControl
1103 End Property
1104
1105
1106 Public Property Let hwnd(h As Long)
1107 ' Host Window
1108 m_Hwnd = h
1109
1110 ' ReCreate the control
1111 CreateDTPControl
1112 End Property
1113
1114 Public Property Get hwnd() As Long
1115 ' MonthCalendar Parent Window
1116 hwnd = m_Hwnd
1117 End Property
1118
1119 Public Property Let hWndForm(h As Long)
1120 ' Calling Form's Window Handle
1121 m_hWndForm = h
1122 End Property
1123
1124 Public Property Get hWndForm() As Long
1125 ' Calling Form's Window Handle
1126 hWndForm = m_hWndForm
1127 End Property
1128
1129
1130 Public Property Get hWndCal() As Long
1131 ' MonthCalendar Window
1132 hWndCal = m_hWndDTP
1133 End Property
1134
1135 Public Property Let OneClick(bl As Boolean)
1136 ' Click Once to Close our Calendar.
1137 m_oneClick = bl
1138 ' Update custom property
1139 Call SetProperty("OneClick", dbLongDAO, m_oneClick)
1140 End Property
1141
1142 Public Property Get OneClick() As Boolean
1143 OneClick = m_oneClick
1144 End Property
1145
1146 Public Property Let SelectedDate(ByVal newSelectedDate As Date)
1147 ' Date pre-selected in the Calendar.
1148 ' Default is Today's date.
1149 Dim udtST As SYSTEMTIME
1150 m_SelectedDate = newSelectedDate
1151 With udtST
1152 .wYear = year(newSelectedDate)
1153 .wMonth = month(newSelectedDate)
1154 .wDay = day(newSelectedDate)
1155 End With
1156
1157 m_StartDate = newSelectedDate
1158 If m_MultiSelect <> MCS_MULTISELECT Then
1159 Call apiSendMessage(m_hWndDTP, MCM_SETCURSEL, ByVal 0&, udtST)
1160 Else
1161 m_StartDate = newSelectedDate
1162 m_EndDate = m_StartDate
1163 Call SetSelectedDateRange(m_StartDate, m_EndDate)
1164 ' Sets the
1165 End If
1166 End Property
1167
1168
1169 Public Sub SetSelectedDateRange(ByVal StartDate As Date, ByVal EndDate As Date)
1170 ' Sets the Range of Dates visible in the Calendar
1171 Dim udtST(1) As SYSTEMTIME
1172
1173 If m_MultiSelect <> MCS_MULTISELECT Then Exit Sub
1174
1175 ' Fill in the start and ending SYSTEMTIME structures
1176 With udtST(0)
1177 .wDay = day(StartDate)
1178 .wMonth = month(StartDate)
1179 .wYear = year(StartDate)
1180 End With
1181
1182 With udtST(1)
1183 .wDay = day(EndDate)
1184 .wMonth = month(EndDate)
1185 .wYear = year(EndDate)
1186 End With
1187 lngRet = apiSendMessage(m_hWndDTP, MCM_SETSELRANGE, ByVal 0&, udtST(0))
1188 With udtST(0)
1189 m_SelectedDate = DateSerial(.wYear, .wMonth, .wDay)
1190 End With
1191 'With udtST(1)
1192 ' m_endSelectedDate = DateSerial(.wYear, .wMonth, .wDay)
1193 'End With
1194 End Sub
1195
1196
1197 Public Property Get StartSelectedDate() As Date
1198 ' Either the current single date selected by the user
1199 ' or the First date in a user selected range of dates.
1200 Dim udtST As SYSTEMTIME
1201
1202 If m_MultiSelect = MCS_MULTISELECT Then
1203 StartSelectedDate = GetSelectedDates(True)
1204 Else
1205 Call apiSendMessage(m_hWndDTP, MCM_GETCURSEL, ByVal 0&, udtST)
1206 With udtST
1207 m_SelectedDate = DateSerial(.wYear, .wMonth, .wDay)
1208 End With
1209 StartSelectedDate = m_SelectedDate
1210 End If
1211 End Property
1212
1213 Public Property Get EndSelectedDate() As Date
1214 ' The End date in a user selected range of dates.
1215 Dim udtST As SYSTEMTIME
1216
1217 If m_MultiSelect = MCS_MULTISELECT Then
1218 EndSelectedDate = GetSelectedDates(False)
1219 Else
1220 Call apiSendMessage(m_hWndDTP, MCM_GETCURSEL, ByVal 0&, udtST)
1221 With udtST
1222 m_SelectedDate = DateSerial(.wYear, .wMonth, .wDay)
1223 End With
1224 EndSelectedDate = m_SelectedDate
1225 End If
1226 End Property
1227
1228 Private Function GetSelectedDates(StartEnd As Boolean) As Date
1229 ' Return Start or END date of user selected Range
1230 ' If StartEnd = TRUE then return Start Date
1231 ' If StartEnd = FALSE then return END Date
1232 Dim arrayTime(0 To 1) As SYSTEMTIME
1233 Dim DateStart As Date
1234 Dim DateEnd As Date
1235
1236 ' Get the currently selected range
1237 lngRet = apiSendMessage(m_hWndDTP, MCM_GETSELRANGE&, ByVal 0&, arrayTime(0))
1238
1239 ' Convert to our Date format
1240 With arrayTime(0)
1241 DateStart = DateSerial(.wYear, .wMonth, .wDay)
1242 End With
1243 With arrayTime(1)
1244 DateEnd = DateSerial(.wYear, .wMonth, .wDay)
1245 End With
1246
1247 ' Return specified Start or End date
1248 If StartEnd Then
1249 GetSelectedDates = DateStart
1250 Else
1251 GetSelectedDates = DateEnd
1252 End If
1253 End Function
1254
1255 Public Sub SetViewableMonths(numMonths As Integer)
1256 ' How many months are viewable in the Calendar.
1257 ' Options are 1,2,3,4,6,9,12
1258
1259 Select Case numMonths
1260 Case 1
1261 MonthColumns = 1
1262 MonthRows = 1
1263
1264 Case 2
1265 MonthColumns = 2
1266 MonthRows = 1
1267
1268 Case 3
1269 MonthColumns = 3
1270 MonthRows = 1
1271
1272 Case 4
1273 MonthColumns = 2
1274 MonthRows = 2
1275
1276 Case 6
1277 MonthColumns = 3
1278 MonthRows = 2
1279
1280 Case 8
1281 MonthColumns = 4
1282 MonthRows = 2
1283
1284 Case 9
1285 MonthColumns = 3
1286 MonthRows = 3
1287
1288 Case 12
1289 MonthColumns = 4
1290 MonthRows = 3
1291
1292 Case Else
1293 MonthColumns = 1
1294 MonthRows = 1
1295
1296 End Select
1297
1298 ' Create the new Month Calender
1299 If m_hWndDTP = 0 Then
1300 CreateDTPControl
1301 Else
1302 ReDraw
1303 End If
1304 End Sub
1305
1306 Public Sub SelectFont()
1307 Dim f As FormFontInfo
1308
1309 ' Set some Defaults for the Font Dialog
1310 With f
1311 .Color = 0
1312 .Height = m_FontSize '12
1313 .Weight = 400
1314 .Italic = False
1315 .UnderLine = False
1316 .name = m_FontName '"Arial"
1317 End With
1318
1319 ' Call the Font Dialog
1320 blRet = DialogFont(f, m_hWndDTP)
1321 If blRet Then
1322 ' Copy users selections over to
1323 ' our class vars
1324 With f
1325 FontName = .name
1326 FontSize = .Height
1327 End With
1328 ' store selection to Custom Property
1329 ReDraw
1330 End If
1331 End Sub
1332
1333
1334 Public Sub ChangeFont()
1335
1336 ' ******************
1337 ' DEBUG
1338 ' ******************
1339
1340 'Exit Sub
1341
1342
1343 ' User selectable Font size for the Calendar.
1344 ' From limited testing it seems the Calendar
1345 ' deletes the Font we pass to it. Needs further
1346 ' testing though!
1347
1348 ' Font Height in Device Pixels
1349 Dim fheight As Integer
1350
1351 ' Declared at module level so that I can DeleteObject
1352 ' on all fonts I create
1353 'Dim hFontPrevious As Long
1354
1355 ' Newly created Font
1356 Dim hFont As Long
1357
1358 ' Calculate/Convert requested Font Height
1359 ' into Font's Device Coordinate space
1360 fheight = apiMulDiv(m_FontSize, lngYdpi, 72)
1361
1362 ' We use a negative value to signify
1363 ' to the CreateFont function that we want a Glyph
1364 ' outline of this size not a bounding box.
1365
1366 hFont = apiCreateFont(-fheight, 0, _
1367 0, 0, 400, _
1368 0, 0, _
1369 0, 0, 0, _
1370 0, 0, 0, m_FontName) '"Verdana")
1371
1372 lngRet = apiSendMessage(m_hWndDTP, WM_SETFONT, hFont, ByVal -1)
1373
1374 If hFontPrevious <> 0 Then
1375 DeleteObject hFontPrevious
1376 End If
1377
1378 ' Store current Font into Previous var
1379 hFontPrevious = hFont
1380
1381 DoEvents
1382
1383 ' Let's compute the height of 1 line of Text with this Font
1384 ' This figure willbe added to the desired window height
1385 ' of the Calendar when the NoToday flag is TRUE
1386 ' Store the results in the module level var m_TodayHeight
1387 Dim sngTemp As Single
1388 sngTemp = CSng(m_FontSize) / CSng(POINTSPERINCH)
1389 sngTemp = sngTemp * CSng(lngYdpi)
1390 m_TodayHeight = CLng(sngTemp)
1391 'ReDraw
1392 End Sub
1393
1394 Public Sub ChooseColors(index As Long)
1395 ' Index is the color index
1396 Dim lngNewColor As Long
1397 ' Call the Color Dialog Window
1398
1399 lngNewColor = aDialogColor(m_hWndDTP) ' Apr 02/2004 Dialog was behind CalendarApplication.hWndAccessApp)
1400 ' User did not pick a color
1401 If lngNewColor = -1 Then Exit Sub
1402
1403 ' Save users selection into the corresponding property
1404 Select Case index
1405 Case MCSC_BACKGROUND
1406 BackColor = lngNewColor
1407
1408 Case MCSC_MONTHBK
1409 MonthBackColor = lngNewColor
1410
1411 Case MCSC_TEXT
1412 ForeColor = lngNewColor
1413
1414 Case MCSC_TITLEBK
1415 TitleBackColor = lngNewColor
1416
1417 Case MCSC_TITLETEXT
1418 TitleForeColor = lngNewColor
1419
1420 Case MCSC_TRAILINGTEXT
1421 TrailingForeColor = lngNewColor
1422
1423 Case Else
1424 End Select
1425
1426 End Sub
1427
1428 Public Property Let BackColor(ByVal newColor As Long)
1429 m_BackColor = newColor
1430 'If the control is allready created set the Back Color
1431 'Debug.Print Hex(newColor)
1432 If m_hWndDTP <> 0 Then
1433 Call apiSendMessage(m_hWndDTP, MCM_SETCOLOR, MCSC_BACKGROUND, ByVal newColor)
1434 End If
1435 ' Update custom property
1436 Call SetProperty("BackColor", dbLongDAO, m_BackColor)
1437 End Property
1438
1439 Public Property Get BackColor() As Long
1440 lngRet = apiSendMessage(m_hWndDTP, MCM_GETCOLOR, MCSC_BACKGROUND, 0&)
1441 BackColor = lngRet
1442 End Property
1443
1444 Public Property Let ForeColor(ByVal newColor As Long)
1445 m_ForeColor = newColor
1446 'If the control is allready created set the Fore Color
1447 If m_hWndDTP <> 0 Then
1448 Call apiSendMessage(m_hWndDTP, MCM_SETCOLOR, MCSC_TEXT, ByVal newColor)
1449 End If
1450 ' Update custom property
1451 Call SetProperty("ForeColor", dbLongDAO, m_ForeColor)
1452 End Property
1453
1454 Public Property Get ForeColor() As Long
1455 lngRet = apiSendMessage(m_hWndDTP, MCM_GETCOLOR, MCSC_TEXT, 0&)
1456 ForeColor = lngRet
1457 End Property
1458
1459 Public Property Let MonthBackColor(ByVal newColor As Long)
1460 m_MonthBackColor = newColor
1461 'If the control is allready created set the Month Back Color
1462 If m_hWndDTP <> 0 Then
1463 Call apiSendMessage(m_hWndDTP, MCM_SETCOLOR, MCSC_MONTHBK, ByVal newColor)
1464 End If
1465 ' Update custom property
1466 Call SetProperty("MonthBackColor", dbLongDAO, m_MonthBackColor)
1467 End Property
1468
1469 Public Property Get MonthBackColor() As Long
1470 lngRet = apiSendMessage(m_hWndDTP, MCM_GETCOLOR, MCSC_MONTHBK, 0&)
1471 MonthBackColor = lngRet
1472 End Property
1473
1474 Public Property Let TitleBackColor(ByVal newColor As Long)
1475 m_TitleBackColor = newColor
1476 'If the control is allready created set the Title Back Color
1477 If m_hWndDTP <> 0 Then
1478 Call apiSendMessage(m_hWndDTP, MCM_SETCOLOR, MCSC_TITLEBK, ByVal newColor)
1479 End If
1480 ' Update custom property
1481 Call SetProperty("TitleBackColor", dbLongDAO, m_TitleBackColor)
1482 End Property
1483
1484 Public Property Get TitleBackColor() As Long
1485 lngRet = apiSendMessage(m_hWndDTP, MCM_GETCOLOR, MCSC_TITLEBK, 0&)
1486 TitleBackColor = lngRet
1487 End Property
1488
1489 Public Property Let TitleForeColor(ByVal newColor As Long)
1490 m_TitleForeColor = newColor
1491 'If the control is allready created set the Title Fore Color
1492 If m_hWndDTP <> 0 Then
1493 Call apiSendMessage(m_hWndDTP, MCM_SETCOLOR, MCSC_TITLETEXT, ByVal newColor)
1494 End If
1495
1496 ' Update custom property
1497 Call SetProperty("TitleForeColor", dbLongDAO, m_TitleForeColor)
1498 End Property
1499 Public Property Get TitleForeColor() As Long
1500 lngRet = apiSendMessage(m_hWndDTP, MCM_GETCOLOR, MCSC_TITLETEXT, 0&)
1501 TitleForeColor = lngRet
1502 End Property
1503
1504 Public Property Let TrailingForeColor(ByVal newColor As Long)
1505 m_TrailingForeColor = newColor
1506 'If the control is allready created set the Title Fore Color
1507 If m_hWndDTP <> 0 Then
1508 Call apiSendMessage(m_hWndDTP, MCM_SETCOLOR, MCSC_TRAILINGTEXT, ByVal newColor)
1509 End If
1510 ' Update custom property
1511 Call SetProperty("TrailingForeColor", dbLongDAO, m_TrailingForeColor)
1512 End Property
1513
1514 Public Property Get TrailingForeColor() As Long
1515 lngRet = apiSendMessage(m_hWndDTP, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0&)
1516 TrailingForeColor = lngRet
1517 End Property
1518
1519
1520
1521 Public Property Let DAYSTATE(ByVal month As Long)
1522 ' *****************************
1523 ' Use the SetBoldDayState function instead
1524
1525 ' *****************************
1526
1527 ' If MonthCal does not exist then exit.
1528 '
1529 'If m_hWndDTP = 0 Then Exit Property
1530 '
1531 ''(DWORD)SNDMSG(hmc, MCM_GETMONTHRANGE, (WPARAM)(gmr), (LPARAM)(rgst))
1532 'Dim arrayTime(0 To 1) As SYSTEMTIME
1533 'Dim arrayDayStates() As MONTHDAYSTATE
1534 '
1535 'Dim DateStart As Date
1536 'Dim DateEnd As Date
1537 'Dim VisibleMonths As Long
1538 'Dim StartMonth As Long
1539 'Dim EndMonth As Long
1540 'Dim ctr As Long
1541 '' Get the currently selected range
1542 'VisibleMonths = apiSendMessage(m_hWndDTP, MCM_GETMONTHRANGE, ByVal GMR_DAYSTATE, arrayTime(0))
1543 ' If VisibleMonths = 0 Then Exit Property
1544 'ReDim arrayDayStates(VisibleMonths - 1)
1545 '' What is First visible month
1546 'StartMonth = arrayTime(0).wMonth
1547 '
1548 'For ctr = 0 To VisibleMonths - 1
1549 ' arrayDayStates(ctr).lpMONTHDAYSTATE = BoldDayStates(StartMonth).lpMONTHDAYSTATE
1550 ' StartMonth = StartMonth + 1
1551 ' ' Rollover after 12 months
1552 ' If StartMonth = 13 Then StartMonth = 1
1553 'Next ctr
1554 '
1555 'lngRet = apiSendMessage(m_hWndDTP, MCM_SETDAYSTATE, UBound(arrayDayStates) + 1, arrayDayStates(0))
1556 '
1557 '
1558 End Property
1559 Public Function GetDAYSTATE(ByVal year As Long, ByVal month As Long) As Long
1560 GetDAYSTATE = BoldDayStates(year, month).lpMONTHDAYSTATE
1561 End Function
1562
1563
1564
1565
1566 ' Turn on Bolding for specified days of the month
1567 ' Use named arguments when calling this function to
1568 ' cut down on your typing.
1569 ' ie. SetBoldDayState numYear 2004, numMonth:=1, day = 19
1570 Public Function SetBoldDayState(numYear As Long, numMonth As Long, day As Long, Optional ResetMonth As Boolean = False) '_
1571 '
1572 'Optional One As Boolean, Optional Two As Boolean, _
1573 'Optional Three As Boolean, Optional Four As Boolean, _
1574 'Optional Five As Boolean, Optional Six As Boolean, _
1575 'Optional Seven As Boolean, Optional Eight As Boolean, _
1576 'Optional Nine As Boolean, Optional Ten As Boolean, _
1577 'Optional Eleven As Boolean, Optional Twelve As Boolean, _
1578 'Optional Thirteen As Boolean, Optional Fourteen As Boolean, _
1579 'Optional Fifthteen As Boolean, Optional Sixteen As Boolean, _
1580 'Optional Seventeen As Boolean, Optional Eighteen As Boolean, _
1581 'Optional NineTeen As Boolean, Optional Twenty As Boolean, _
1582 'Optional TwentyOne As Boolean, Optional TwentyTwo As Boolean, _
1583 'Optional TwentyThree As Boolean, Optional TwentyFour As Boolean, _
1584 'Optional TwentyFive As Boolean, Optional TwentySix As Boolean, _
1585 'Optional TwentySeven As Boolean, Optional TwentyEight As Boolean, _
1586 'Optional TwentyNine As Boolean, Optional Thirty As Boolean, _
1587 'Optional ThirtyOne As Boolean, Optional ThirtyTwo As Boolean)
1588 '
1589
1590 '
1591 ' Init the month we are working with.
1592 ' Only clear this var if ResetMonth = TrUE
1593 If ResetMonth Then
1594 BoldDayStates(numYear, numMonth).lpMONTHDAYSTATE = 0
1595 End If
1596
1597 If day > 0 And day < 31 Then day = day - 1
1598 'BoldDayStates(numMonth) = BoldDays
1599 BoldDayStates(numYear, numMonth).lpMONTHDAYSTATE = BoldDayStates(numYear, numMonth).lpMONTHDAYSTATE Or 2 ^ day
1600 '
1601 'If One Then BoldDayStates(numMonth).lpMONTHDAYSTATE = 1 'BoldDayStates(numMonth).lpMONTHDAYSTATE Or 1
1602 'If Two Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 1
1603 'If Three Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 2
1604 'If Four Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 3
1605 'If Five Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 4
1606 'If Six Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 5
1607 'If Seven Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 6
1608 'If Eight Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 7
1609 'If Nine Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 8
1610 'If Ten Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 9
1611 'If Eleven Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 10
1612 'If Twelve Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 11
1613 'If Thirteen Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 12
1614 'If Fourteen Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 13
1615 'If Fifthteen Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 14
1616 'If Sixteen Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 15
1617 'If Seventeen Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 16
1618 'If Eighteen Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 17
1619 'If NineTeen Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 18
1620 '
1621 'If Twenty Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 19
1622 'If TwentyOne Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 20
1623 'If TwentyTwo Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 21
1624 'If TwentyThree Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 22
1625 'If TwentyFour Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 23
1626 'If TwentyFive Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 24
1627 'If TwentySix Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 25
1628 'If TwentySeven Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 26
1629 'If TwentyEight Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 27
1630 'If TwentyNine Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 28
1631 '
1632 'If Thirty Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 29
1633 'If ThirtyOne Then BoldDayStates(numMonth).lpMONTHDAYSTATE = BoldDayStates(numMonth).lpMONTHDAYSTATE Or 2 ^ 30
1634 '
1635 End Function
1636
1637
1638 Private Sub Class_Initialize()
1639 ' Number of pixels to leave at the Top of the form before we
1640 ' begin to draw our Calendar. This leaves room for any
1641 ' controls we have at the top of the form.
1642 Me.CalendarYOffset = 20
1643
1644 ' Default Number of Columns and Rows
1645 ' 6 month display
1646 'Me.MonthColumns = 3
1647 'Me.MonthRows = 2
1648 ' Check and see if Custom Prop exists
1649 blRet = GetProperty("MonthColumns", varTemp)
1650 If blRet Then
1651 m_MonthColumns = varTemp
1652 Else
1653 m_MonthColumns = 3
1654 End If
1655
1656 blRet = GetProperty("MonthRows", varTemp)
1657 If blRet Then
1658 m_MonthRows = varTemp
1659 Else
1660 m_MonthRows = 2
1661 End If
1662
1663
1664 ' Default Font stuff
1665 ' Check and see if Custom Prop exists
1666 blRet = GetProperty("FontName", varTemp)
1667 If blRet Then
1668 Me.FontName = varTemp
1669 Else
1670 Me.FontName = "Arial"
1671 End If
1672
1673 blRet = GetProperty("FontSize", varTemp)
1674 If blRet Then
1675 Me.FontSize = varTemp
1676 Else
1677 Me.FontSize = 8
1678 End If
1679
1680 hFontPrevious = 0
1681
1682 blRet = GetProperty("MCS_MULTISELECT", varTemp)
1683 If blRet Then
1684 MultiSelect = varTemp
1685 Else
1686 ' MultiSelect to start
1687 MultiSelect = MCS_MULTISELECT '0 to Turn Off
1688 End If
1689
1690 blRet = GetProperty("MCS_WEEKNUMBERS", varTemp)
1691 If blRet Then
1692 ShowWeekNumbers = varTemp
1693 Else
1694 ' MultiSelect to start
1695 ShowWeekNumbers = MCS_WEEKNUMBERS '0 to Turn Off
1696 End If
1697
1698 blRet = GetProperty("NoToday", varTemp)
1699 If blRet Then
1700 m_NoToday = varTemp
1701 Else
1702 ' Show Today is turned off
1703 m_NoToday = MCS_NOTODAY '0 to Turn Off
1704 End If
1705
1706 blRet = GetProperty("NoTodayCircle", varTemp)
1707 If blRet Then
1708 m_NoTodayCircle = varTemp
1709 Else
1710 ' Show Today is turned off
1711 m_NoToday = MCS_NOTODAYCIRCLE '0 to Turn Off
1712 End If
1713
1714
1715 blRet = GetProperty("WindowLocation", varTemp)
1716 If blRet Then
1717 m_WindowLocation = varTemp
1718 Else
1719 ' Window Location
1720 m_WindowLocation = 0
1721 End If
1722
1723 ' June 7, 2003
1724 ' Fixing PositionAtCursor logic
1725 If varTemp = 0 Then
1726 ' Init
1727 Me.PositionAtCursor = True
1728 Else
1729 Me.PositionAtCursor = False
1730 End If
1731
1732 ' Only load if PositionAtCursor is False
1733 If Not Me.PositionAtCursor Then
1734 blRet = GetProperty("Cursorx", varTemp)
1735 If blRet Then
1736 m_cursorX = varTemp
1737 Else
1738 ' Leave Alone!
1739 m_cursorX = 0
1740 End If
1741 End If
1742
1743 'Only load if PositionAtCursor is False
1744 If Not Me.PositionAtCursor Then
1745 blRet = GetProperty("CursorY", varTemp)
1746 If blRet Then
1747 m_cursorY = varTemp
1748 Else
1749 ' Get current Cursor Position!
1750 'Dim pt As POINTAPI
1751 'lngRet = GetCursorPos(pt)
1752 ' m_cursorXinit = pt.x
1753 ' m_cursorYinit = pt.y
1754 ' m_cursorX = pt.x
1755 'm_cursorY = pt.y
1756 m_cursorY = 0
1757 End If
1758 End If
1759
1760 ' Check our Color props.
1761 ' Set var to NotAColor constant if prop doesn't exist
1762 blRet = GetProperty("BackColor", varTemp)
1763 If blRet Then
1764 m_BackColor = varTemp
1765 Else
1766 ' Set var to nonexistent color
1767 m_BackColor = NotAColor
1768 End If
1769
1770 blRet = GetProperty("MonthBackColor", varTemp)
1771 If blRet Then
1772 m_MonthBackColor = varTemp
1773 Else
1774 ' Set var to nonexistent color
1775 m_MonthBackColor = NotAColor
1776 End If
1777
1778
1779 blRet = GetProperty("ForeColor", varTemp)
1780 If blRet Then
1781 m_ForeColor = varTemp
1782 Else
1783 ' Set var to nonexistent color
1784 m_ForeColor = NotAColor
1785 End If
1786
1787 blRet = GetProperty("TitleBackColor", varTemp)
1788 If blRet Then
1789 m_TitleBackColor = varTemp
1790 Else
1791 ' Set var to nonexistent color
1792 m_TitleBackColor = NotAColor
1793 End If
1794
1795 blRet = GetProperty("TitleForeColor", varTemp)
1796 If blRet Then
1797 m_TitleForeColor = varTemp
1798 Else
1799 ' Set var to nonexistent color
1800 m_TitleForeColor = NotAColor
1801 End If
1802
1803 blRet = GetProperty("TrailingForeColor", varTemp)
1804 If blRet Then
1805 m_TrailingForeColor = varTemp
1806 Else
1807 ' Set var to nonexistent color
1808 m_TrailingForeColor = NotAColor
1809 End If
1810
1811 blRet = GetProperty("OneClick", varTemp)
1812 If blRet Then
1813 m_oneClick = varTemp
1814 Else
1815 ' Set var to nonexistent color
1816 m_oneClick = True
1817 End If
1818
1819 ' Max number of days user can select in a continuous range
1820 m_MaxSelectRangeofDays = 31
1821 ' To select a Range of Dates add code like below
1822 'm_EndDate = #2/27/00#
1823 'm_StartDate = #2/21/00#
1824
1825 ' Set DayState
1826 ' For this example we will set one day per month
1827 ' corresponding to the Month number
1828 Erase BoldDayStates
1829 ' Here is an example of how to Set the BoldDayState prop for Jan 19,2004.
1830 ' ie. SetBoldDayState numYear 2004, numMonth:=1, day = 19
1831
1832 End Sub
1833
1834 Public Sub Class_Terminate()
1835 ' Cleanup after ourselves.
1836 On Error Resume Next
1837
1838 'Debug.Print "start ClsMonthCalendat Terminated:" & Now
1839 ' March 05 Debug
1840 ' Not getting a clean exit when user Closes
1841 ' Calling Form with Calendar still Open
1842 If m_hWndDTP <> 0 Then
1843 lngRet = apiDestroyWindow(m_hWndDTP)
1844 'Debug.Print "Destroyed m_hWndDTP:" & lngRet
1845 End If
1846
1847 ' Wait until Window is definately gone!
1848 lngRet = apiDestroyWindow(Me.m_Hwnd)
1849 'Debug.Print "Destroyed Me.m_Hwnd:" & lngRet
1850 DoEvents
1851
1852 Dim hWndTemp As Long
1853
1854 ' If this window already exists then exit!
1855 hWndTemp = 1
1856 Do While hWndTemp <> 0
1857 hWndTemp = FindWindow(CLASSNAME, TITLE)
1858 'Debug.Print "MonthCal Hwnd -hWndTemp:" & hWndTemp
1859 Loop
1860
1861 ' See if we have a new Font handle hanging around.
1862 If hFontPrevious <> 0 Then
1863 'Debug.Print "deleting FOnt"
1864 DeleteObject hFontPrevious
1865 End If
1866
1867 'Debug.Print "End ClsMonthCalendar Terminated:" & Now
1868 End Sub
1869
1870 ' *** CODE END ***
1871
1872
1873 Private Function GetProperty(ByVal strPropName As String, ByRef strPropValue As Variant) As Boolean
1874 ' Changed strPropValue as String to as Variant
1875
1876 Const cProcedureName As String = "GetProperty"
1877 On Error GoTo Err_Handler
1878
1879 Dim sDefault As String
1880
1881 Select Case strPropName
1882
1883 Case "BackColor"
1884 sDefault = vbWhite
1885
1886 Case "FontName"
1887 sDefault = "Arial"
1888
1889 Case "FontSize"
1890 sDefault = 8
1891
1892 Case "ForeColor"
1893 sDefault = GetSysColor(COLOR_WINDOWTEXT)
1894
1895 Case "MonthBackColor"
1896 sDefault = vbWhite
1897
1898 Case "MonthColumns"
1899 sDefault = 1
1900
1901 Case MultiSelect
1902 sDefault = "0" 'false
1903
1904 Case "NoToday"
1905 sDefault = MCS_NOTODAY
1906
1907 Case "NoTodayCircle"
1908 sDefault = MCS_NOTODAYCIRCLE
1909
1910 Case "OneClick"
1911 sDefault = "1" ' true
1912
1913 Case "MCS_WEEKNUMBERS"
1914 sDefault = MCS_WEEKNUMBERS
1915
1916 Case "MonthRows"
1917 sDefault = 1
1918
1919 Case "TitleBackColor"
1920 sDefault = GetSysColor(COLOR_ACTIVECAPTION)
1921
1922 Case "TitleForeColor"
1923 sDefault = vbWhite 'GetSysColor() 'vbTitleBarText
1924
1925 Case "TrailingForeColor"
1926 sDefault = GetSysColor(COLOR_GRAYTEXT) ' apiSendMessage(m_hWndDTP, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0&)
1927
1928 Case "WindowLocation"
1929 ' Position Window according to users Menu selections
1930 ' a) 0 -Pop at cursor location when user activates Calendar
1931 ' b) 1 -Where they manually move/leave it at
1932 ' c) 2 -Centered in Access App Window
1933 ' d) 3 -Centered on entire screen
1934 ' d) 4 -Top Left Corner
1935 sDefault = 0
1936
1937
1938
1939 Case Else
1940 ' not possible...I hope!
1941 sDefault = ""
1942 GetProperty = False
1943 Exit Function
1944
1945 End Select
1946
1947 strPropValue = GetSetting("MonthCalendarSL", "CalendarProperties", strPropName, sDefault)
1948 GetProperty = True
1949
1950 Exit_Sub:
1951 On Error GoTo 0
1952 Exit Function
1953 Err_Handler:
1954 Resume Exit_Sub
1955 End Function
1956
1957
1958 Sub SetProperty(ByVal strPropName As String, ByVal varPropType As Variant, _
1959 ByVal varPropValue As Variant)
1960 Const cProcedureName As String = "SetProperty"
1961 On Error GoTo Err_Handler
1962
1963 SaveSetting "MonthCalendarSL", "CalendarProperties", strPropName, varPropValue
1964
1965 Exit_Sub:
1966 On Error GoTo 0
1967 Exit Sub
1968 Err_Handler:
1969 Resume Exit_Sub
1970 End Sub
1971
1972
1973
1974 'Private Function GetProperty(ByVal strPropName As String, ByRef strPropValue As Variant) As Boolean
1975 '' Changed strPropValue as String to as Variant
1976 '
1977 'Const cProcedureName As String = "GetProperty"
1978 'On Error GoTo Err_Handler
1979 'Dim db As DAO.Database
1980 '
1981 ' Set db = CurrentDb
1982 ' strPropValue = db.Properties(strPropName)
1983 ' GetProperty = True
1984 '
1985 'Exit_Sub:
1986 ' On Error GoTo 0
1987 ' Set db = Nothing
1988 ' Exit Function
1989 'Err_Handler:
1990 ' GetProperty = False
1991 ' Select Case Err
1992 ' Case cerrPropertyNotFound
1993 ' Case Else
1994 ' ' Call LogError(Err.Number, Err.Description, cModuleName & cProcedureName)
1995 ' End Select
1996 ' Resume Exit_Sub
1997 'End Function
1998
1999
2000
2001
2002
2003 'Sub SetProperty(ByVal strPropName As String, ByVal varPropType As Variant, _
2004 ' ByVal varPropValue As Variant)
2005 'Const cProcedureName As String = "SetProperty"
2006 'On Error GoTo Err_Handler
2007 'Dim db As DAO.Database
2008 'Dim prp As DAO.Property
2009 '
2010 ' Set db = DBEngine(0)(0)
2011 ' db.Properties(strPropName).Value = varPropValue
2012 '
2013 'Exit_Sub:
2014 ' On Error GoTo 0
2015 ' Set prp = Nothing
2016 ' Set db = Nothing
2017 ' Exit Sub
2018 'Err_Handler:
2019 ' Select Case Err
2020 ' Case cerrPropertyNotFound
2021 ' Set prp = db.CreateProperty(strPropName, varPropType, varPropValue)
2022 ' db.Properties.Append prp
2023 ' Case Else
2024 ' 'Call LogError(Err.Number, Err.Description, cModuleName & cProcedureName)
2025 ' End Select
2026 ' Resume Exit_Sub
2027 '
2028 'End Sub
2029
2030
2031
2032
2033 'typedef DWORD MONTHDAYSTATE, FAR * LPMONTHDAYSTATE;
2034 '// BOOL MonthCal_SetDayState(HWND hmc, int cbds, DAYSTATE *rgds)
2035 '// cbds is the count of DAYSTATE items in rgds and it must be equal
2036 '// to the value returned from MonthCal_GetMonthRange(hmc, GMR_DAYSTATE, NULL)
2037 '// This sets the DAYSTATE bits for each month (grayed and non-grayed
2038 '// days) displayed in the calendar. The first bit in a month's DAYSTATE
2039 '// corresponts to bolding day 1, the second bit affects day 2, etc.
2040 '#define MCM_SETDAYSTATE (MCM_FIRST + 8)
2041 '#define MonthCal_SetDayState(hmc, cbds, rgds)
2042 'SNDMSG(hmc, MCM_SETDAYSTATE, (WPARAM)(cbds), (LPARAM)(rgds))
2043
2044
2045
2046 '
2047 ' lngStyle = GetWindowLong(m_hWndDTP, GWL_STYLE)
2048 ' 'We can Set/Reset these styles with recreating the Control:
2049 ' lngStyle = lngStyle And Not (MCS_WEEKNUMBERS Or MCS_NOTODAY Or MCS_NOTODAYCIRCLE)
2050 ' If m_WeekNumbers Then lngStyle = lngStyle Or MCS_WEEKNUMBERS
2051 ' If Not m_ShowToday Then lngStyle = lngStyle Or MCS_NOTODAY
2052 ' If Not m_TodayCircle Then lngStyle = lngStyle Or MCS_NOTODAYCIRCLE
2053 ' SetWindowLong m_hWndDTP, GWL_STYLE, lngStyle
2054 '
2055
2056
2057 ' ************************
2058 ' DEBUG GPF
2059 ' ************************
2060 'Public Property Get xx() As Long
2061 'xx = 1
2062 'End Property
2063
2064
2065 Public Function IsCalendar() As Boolean
2066 Dim hWndTemp As Long
2067
2068 ' If this window already exists then exit!
2069 hWndTemp = 0
2070 hWndTemp = FindWindow(CLASSNAME, TITLE)
2071 If hWndTemp <> 0 Then
2072 IsCalendar = True
2073 Call Beep(12000, 1000)
2074 Else
2075 IsCalendar = False
2076 End If
2077 End Function