개요
TDateTimePicker 또는 TMonthCalendar 컴포넌트를 사용하여 특정 날짜를 강조하거나 마킹하는 기능은 사용자에게 중요한 일정을 시각적으로 표시하는 데 유용합니다. 본 기사에서는 기본 컴포넌트인 TMonthCalendar를 이용하여 원하는 날짜를 마킹(볼드체)하는 방법에 대해 자세히 알아보겠습니다.
TMonthCalendar의 "OnGetMonthInfo" 이벤트 활용
이 이벤트는 TMonthCalendar 컴포넌트에 새로운 월이 표시될 때 호출되며, 화면에 노출되는 일자에 대한 특정 속성을 초기화할 때 사용됩니다. 이를 통해 특정 날짜를 굵게 표시할 수 있습니다.
기본적인 날짜 마킹 방법
예를 들어, 표시된 달력의 1일과 8일을 굵게 표시하려면 다음과 같은 코드를 사용할 수 있습니다:
BoldDays([1, 8], MonthBoldInfo);
또는
unsigned bolddays[2] = {1, 2};
BoldDays(bolddays, MonthBoldInfo);
매월 다른 사용자 지정일자 마킹
위와 같이 처리하면 모든 월에 동일한 날짜가 굵게 표시됩니다. 하지만 일정 관리와 같이 매월 다른 특정 날을 마킹해야 하는 경우에는 약간의 추가 처리가 필요합니다.
OnGetMonthInfo 이벤트 처리
OnGetMonthInfo 이벤트는 달력의 월이 바뀔 때마다 발생합니다. 이 이벤트는 첫 번째는 이전 달, 두 번째는 이번 달, 세 번째는 다음 달에 대해 각각 호출됩니다. 따라서 현재 월만 선택하여 마킹 날짜 리스트를 얻고 표시해야 합니다. 이때 월만 넘어오므로 연도를 유추해야 합니다.
TMonthCalendar의 "BoldDays" 함수 사용
BoldDays 함수는 지정된 날짜들을 1~31 비트로 매핑하여 DWORD 값으로 MonthBoldInfo에 반환합니다.
MonthCalendar1.BoldDays([3, 21, 28], MonthBoldInfo); // Day 3, 21, 28
테스트 프로그램 구현
TEST 프로그램 결과
다음은 특정한 날짜를 굵게 표시하는 테스트 프로그램의 결과입니다.
TEST 프로그램 소스
unit uTestMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, CommCtrl;
type
TForm1 = class(TForm)
calendar: TMonthCalendar;
procedure calendarGetMonthInfo(Sender: TObject; Month: Cardinal;
var MonthBoldInfo: Cardinal);
private
function SetExistDateToCalenar(ADate: TDateTime): DWORD;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type
TArrBold = array of DWORD;
const
testBoldDates : array[1..12] of array[0..6] of DWORD =
((1,3,4,6,7,8,9), (1,2,3,4,5,9,10), (4,6,8,15,19,20,21),
(11,22,23,24,25,29,30), (11,12,13,14,15,19,20), (5,10,15,20,25,26,27),
(2,4,6,8,10,12,14), (12,14,16,18,20,22,24), (1,3,5,7,5,9,10),
(4,8,12,16,20,24,28), (1,2,4,8,16,21,22), (1,3,5,16,20,24,28));
var
_LastMonth : integer;
_LastYear : integer;
_LastTickCount : Integer;
_CallCountOfMonthInfo : Integer;
function CheckTickCount:Boolean;
var
C:Cardinal;
begin
C:=GetTickCount;
Result: = _LastTickCount+100 < C;
_LastTickCount := C;
end;
function TForm1.SetExistDateToCalenar(ADate: TDateTime) : DWORD;
var
DayStates: array[0..2] of DWORD;
mon : DWORD;
arrDate : array of DWORD;
yy, mm, dd : Word;
begin
result := 0;
DecodeDate(ADate, yy, mm, dd);
if Length(testBoldDates[mm])>0 then
begin
calendar.BoldDays(testBoldDates[mm], mon);
DayStates[1] := mon;
result := mon;
end
else
begin
DayStates[1] := 0;
result := 0;
end;
DayStates[0] := 0;
DayStates[2] := 0;
SendMessage(calendar.Handle, MCM_SETDAYSTATE, 3, longint(@DayStates));
end;
procedure TForm1.calendarGetMonthInfo(Sender: TObject; Month: Cardinal;
var MonthBoldInfo: Cardinal);
var
dd : TDateTime;
tmp : string;
Year, Mon, Day, YearMonth: Word;
begin
if CheckTickCount Or ((Month<>_LastMonth+1) And Not ((_LastMonth=12) And (Month=1))) then
begin
DecodeDate((Sender As TMonthCalendar).Date, Year, Mon, Day);
if Month>Mon then Dec(Year);
end
else
begin
if _LastMonth=12
then Year:=_LastYear+1
else Year:=_LastYear;
end;
_LastMonth:=Month;
_LastYear:=Year;
Inc(_CallCountOfMonthInfo);
if _CallCountOfMonthInfo=2 then
begin
tmp := Format('%4d-%2d-01', [Year, Month]);
tmp := StringReplace(tmp, ' ', '0', []);
MonthBoldInfo := SetExistDateToCalenar(StrToDate(tmp));
end
else
MonthBoldInfo := 0;
if _CallCountOfMonthInfo = 3 then
_CallCountOfMonthInfo := 0;
end;
end.
버튼 클릭 시 특정 날짜 마킹 예제
procedure TForm1.btnTestClick(Sender: TObject);
var
monInfo : Cardinal;
DayStates: array[0..2] of DWORD;
begin
calendar.BoldDays([1,2,3,4,5,6,7,8,9], monInfo);
DayStates[0] := 0;
DayStates[1] := monInfo;
DayStates[2] := 0;
SendMessage(calendar.Handle, MCM_SETDAYSTATE, 3, longint(@DayStates));
end;
결론
TMonthCalendar 컴포넌트를 사용하여 특정 날짜를 마킹하는 방법은 사용자에게 중요한 일정을 강조하는 데 매우 유용합니다. OnGetMonthInfo 이벤트와 BoldDays 함수를 적절히 활용하면 각 월마다 다른 날짜를 효과적으로 표시할 수 있습니다. 이와 같은 기능을 구현하면 일정 관리와 같은 어플리케이션에서 큰 도움이 될 것입니다.
'delphi' 카테고리의 다른 글
TRichEdit 컴포넌트에서 전체 선택 시 자동 스크롤 구현 방법 (0) | 2024.08.13 |
---|---|
TRichEdit에서 기본 컨텍스트 팝업 메뉴(Context Popup Menu) 활성화 방법 (0) | 2024.08.08 |
웹 페이지 요청 시 응답 헤더 처리 문제 해결 방법 (0) | 2024.08.07 |
TWebBrowser에서 자바스크립트 실행 방법 (0) | 2024.08.07 |
JSON(JavaScript Object Notation) 이해하기(Delphi에서의 활용 방법) (0) | 2024.08.07 |