Q&A
HOME
Tips & Tech
Q&A
Discuss
Download
자유게시판
홍보 / 광고
구인 / 구직
LOGIN
회원가입
일정관리 프로그램을 만들려고 합니다.
안녕하세요..
다름이 아니라 일정관리 프로그램을 아주 간단히 만들려고 합니다.
폼은 달력이 절반을 찾이 하는데 일반적인 컴포넌트는 날짜 부분에 클릭을하면
입력이 되지 않네요. 이 기능을 가진 컴퍼넌트가 없는지..
있으면 알려주시면 감사 하겠습니다.
저도 소스를 감사하는 마음으로 공개를 하겠습니다.
1
COMMENTS
김영대
•
1999.10.22 22:33
정용석 wrote:
> 안녕하세요..
> 다름이 아니라 일정관리 프로그램을 아주 간단히 만들려고 합니다.
> 폼은 달력이 절반을 찾이 하는데 일반적인 컴포넌트는 날짜 부분에 클릭을하면
> 입력이 되지 않네요. 이 기능을 가진 컴퍼넌트가 없는지..
> 있으면 알려주시면 감사 하겠습니다.
> 저도 소스를 감사하는 마음으로 공개를 하겠습니다.
아래 예제는 제가 전에 만들었던 스케쥴관리의 일부를 발췌한건대
폼위에는 크기가 700*500 정도의 비어있는 TImage 하고
년월을 입력받는 TMaskEdit 와 TButton 하나를 올려놓은 다음
아래 소스를 추가하세요
아래 소스는 TImage에 직접 그래픽으로 달력을 그리므로 그림같은것은
직접 Canvas 에 그리시면 됩니다
그리고 일정의 내용을 입력하는 부분은 없습니다
소스의 맨 뒷부분을 보시면 쉽게 구현하실 수 있을 겁니다
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Mask, ComCtrls, Printers;
type
TMainForm = class(TForm)
Button1: TButton;
ME_yyyymm: TMaskEdit;
Image_Schedule: TImage;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure DrawBackGround(yyyymm: String);
procedure DrawProgressBar(yyyymm, StartDate, EndDate: String; iColor: TColor);
procedure DrawEvent(yyyymm, EventDate, Event: String; iColor: TColor);
end;
const
DayOfWeekNames: array[0..6] of String =('일','월','화','수','목','금','토');
NameHeight = 22;
var
MainForm: TMainForm;
OccupationEvent: array[0..31] of Integer;
OccupationBar: array[0..31] of Integer;
MasterCanvas: TCanvas;
implementation
{$R *.DFM}
procedure TMainForm.FormCreate(Sender: TObject);
begin
Image_Schedule.Picture.Bitmap := TBitmap.Create; {bitmap 생성}
MasterCanvas := Image_Schedule.Picture.Bitmap.Canvas;
ME_yyyymm.EditMask := '####.##;0;_';
ME_yyyymm.Text := '199905';
end;
{===============================================================================
주어진 년월의 마지막 일자를 구한다
===============================================================================}
function Get_LastDay(yyyy,mm: Integer): Integer;
var
MyDate: TDateTime;
Convert_OK: Boolean;
dd: Integer;
begin
Convert_OK := True;
dd := 28;
while Convert_OK do
begin
try
MyDate := EncodeDate(yyyy, mm, dd);
except
on EConvertError do
Convert_OK := False;
end;
if Convert_OK then
Inc(dd)
else
Dec(dd);
end;
Get_LastDay := dd;
end;
{===============================================================================
주어진 달의 주수를 구한다(마지막 주의 의미)
===============================================================================}
function Get_weeks(yyyy,mm: Integer): Integer;
var
MyDate: TDateTime;
i, weeks: Integer;
Convert_OK: Boolean;
begin
weeks := 0;
for i := 1 to 31 do
begin
try
Convert_OK := True;
MyDate := EncodeDate(yyyy, mm, i);
except
on EConvertError do
Convert_OK := False;
end;
if Convert_OK then
if (DayOfWeek(MyDate) = 7) or (Get_LastDay(yyyy,mm) = i) then {토요일이나 달의 마지막이면 1주}
Inc(weeks);
end;
Get_weeks := weeks;
end;
{===============================================================================
주어진 달의 주에 해당하는 날짜from, to, 주의 첫번째 날의 요일번호를 구한다
===============================================================================}
procedure Get_weekfrto(yyyy,mm,week:Integer; var weekfrom:Integer; var weekto:Integer; var dayweek:Integer);
var
MyDate: TDateTime;
i, j, weeks: Integer;
Convert_OK: Boolean;
begin
weekfrom := 0;
weekto := 0;
dayweek := 0;
weeks := 0;
for i := 1 to 31 do
begin
try
Convert_OK := True;
MyDate := EncodeDate(yyyy, mm, i);
except
on EConvertError do
Convert_OK := False;
end;
if Convert_OK then
begin
if (DayOfWeek(MyDate) = 7) or (Get_LastDay(yyyy,mm) = i) then {토요일이나 달의 마지막이면 1주}
Inc(weeks);
if weeks = week then
begin
weekto := i; {주의 마지막 일자}
for j := i downto 1 do
begin
MyDate := EncodeDate(yyyy, mm, j);
if (DayOfWeek(MyDate) = 1) or (j = 1) then {일요일이나 그달의 1일이면 주의 시작 일자}
begin
weekfrom := j; {주의 시작 일자}
dayweek := DayOfWeek(MyDate); {주의 첫번째 날의 요일번호}
Break;
end;
end;
System.Exit;
end;
end;
end;
end;
function indc_date(yyyymmdd: String; disc: Integer): String;
var
yyyy,mm,dd: Integer;
MyDate: TDateTime;
Convert_OK: Boolean;
begin
yyyy := StrToIntDef(Copy(yyyymmdd,1,4),-1);
mm := StrToIntDef(Copy(yyyymmdd,5,2),-1);
dd := StrToIntDef(Copy(yyyymmdd,7,2),-1);
if (yyyy <= 0) or (mm <= 0) or (dd <= 0) then
begin
indc_date := '';
System.exit;
end;
if disc = 0 then
begin
try
Convert_OK := True;
MyDate := EncodeDate(yyyy, mm, dd);
except
on EConvertError do
Convert_OK := False;
end;
if Convert_OK then
begin
indc_date := FormatDateTime('yyyymmdd', MyDate);
end
else
begin
indc_date := '';
end;
end
else
begin
Convert_OK := True;
try
MyDate := EncodeDate(yyyy, mm, dd);
except
on EConvertError do
Convert_OK := False;
end;
if Convert_OK then
begin
indc_date := FormatDateTime('yyyymmdd', MyDate+disc);
end
else
begin
indc_date := '';
end;
end;
end;
{===============================================================================
주어진 년,월,일이 들어가는 주를 구한다
===============================================================================}
function Get_thisweek(yyyy,mm,dd: Integer): Integer;
var
MyDate: TDateTime;
i, weeks: Integer;
Convert_OK: Boolean;
begin
weeks := 0;
for i := 1 to 31 do
begin
try
Convert_OK := True;
MyDate := EncodeDate(yyyy, mm, i);
except
on EConvertError do
Convert_OK := False;
end;
if Convert_OK then
if (DayOfWeek(MyDate) = 7) or (Get_LastDay(yyyy,mm) = i) then {토요일이나 달의 마지막이면 1주}
begin
Inc(weeks);
if dd <= i then // 해당 주를 찾았다
Break;
end;
end;
Get_thisweek := weeks;
end;
function DayOfWeekNum(yyyymmdd: String): Integer;
var
yyyy,mm,dd: Integer;
MyDate: TDateTime;
begin
yyyy := StrToIntDef(Copy(yyyymmdd,1,4),-1);
mm := StrToIntDef(Copy(yyyymmdd,5,2),-1);
dd := StrToIntDef(Copy(yyyymmdd,7,2),-1);
Result := -1;
try
MyDate := EncodeDate(yyyy, mm, dd);
Result := DayOfWeek(MyDate);
except
on EConvertError do
Result := -1;
end;
end;
procedure TMainForm.DrawBackGround(yyyymm: String);
var
max_day, max_week: Integer;
day_width, day_height: Integer;
weekfrom, weekto, dayweek: Integer;
i, j, k, yyyy, mm: Integer;
temp: String;
begin
yyyy := StrToIntDef(Copy(yyyymm,1,4),0);
mm := StrToIntDef(Copy(yyyymm,5,2),0);
if (yyyy = 0) or (mm = 0) then
System.Exit;
for i := Low(OccupationEvent) to High(OccupationEvent) do
OccupationEvent[i] := 0;
for i := Low(OccupationBar) to High(OccupationBar) do
OccupationBar[i] := 0;
// 달의 마지막일자
max_day := Get_LastDay(yyyy, mm);
// 달의 주수
max_week := Get_weeks(yyyy, mm);
day_width := Image_Schedule.Width div 7; // 가로 7칸의 각 폭
day_height := (Image_Schedule.Height-NameHeight) div 6; // 세로 6칸의 각 높이
MasterCanvas.Font := Self.Font;
// 이전의 화면을 지운다
Image_Schedule.Picture.Bitmap.Width := Image_Schedule.Width;
Image_Schedule.Picture.Bitmap.Height := Image_Schedule.Height;
MasterCanvas.Brush.Color := clBtnFace;
MasterCanvas.FillRect(Rect(0, 0, Image_Schedule.Width, Image_Schedule.Height));
// 각 일자명을 그린다
MasterCanvas.Brush.Color := clYellow;
for i := 0 to 6 do
begin
MasterCanvas.Rectangle(day_width*i, 0,
day_width*(i+1), NameHeight);
if i = 0 then // 일요일
MasterCanvas.Font.Color := clRed
else if i = 6 then // 토요일
MasterCanvas.Font.Color := clBlue
else // 평일
MasterCanvas.Font.Color := clBlack;
MasterCanvas.TextOut(day_width*i+5, 5, DayOfWeekNames[i]);
end;
// 스케줄의 각 일자의 직사각형을 그린다
MasterCanvas.Brush.Color := clWhite;
for i := 0 to (max_week-1) do
begin
for j := 0 to 6 do
MasterCanvas.Rectangle(day_width*j, day_height*i+NameHeight,
day_width*(j+1), day_height*(i+1)+NameHeight);
end;
// 스케줄의 각 일자를 출력
k := 0;
for i := 0 to (max_week-1) do // 달의 주수만큼
begin
// 주어진 달의 주에 해당하는 날짜from, to, 주의 첫번째 날의 요일번호
Get_weekfrto(yyyy,mm,i+1, weekfrom, weekto, dayweek);
for j := 0 to 6 do
begin
if ((j+1) >= dayweek) and
((k+1) <= max_day) then
begin
Inc(k);
if j = 0 then // 일요일
MasterCanvas.Font.Color := clRed
else if j = 6 then // 토요일
MasterCanvas.Font.Color := clBlue
else // 평일
MasterCanvas.Font.Color := clBlack;
MasterCanvas.Brush.Color := clWhite;
MasterCanvas.TextOut(day_width*j+5, day_height*i+5+NameHeight, inttostr(k));
end;
end;
end;
end;
procedure TMainForm.DrawProgressBar(yyyymm, StartDate, EndDate: String; iColor: TColor);
var
day_width, day_height: Integer;
daynum, dayweek: Integer;
yyyy, mm: Integer;
CurDate: String;
iPos: Integer;
begin
yyyy := StrToIntDef(Copy(yyyymm,1,4),0);
mm := StrToIntDef(Copy(yyyymm,5,2),0);
if (yyyy = 0) or (mm = 0) then
System.Exit;
iPos := 1;
CurDate := StartDate; // 시작일자
while CurDate <= EndDate do
begin
if Copy(CurDate,1,6) = yyyymm then // 기준월의 날짜만 그린다
begin
// 요일에 출력되는 막대 카운트
OccupationBar[StrToIntDef(Copy(CurDate,7,2),0)] :=
OccupationBar[StrToIntDef(Copy(CurDate,7,2),0)] + 1;
if iPos < OccupationBar[StrToIntDef(Copy(CurDate,7,2),0)] then // 해당기간의 최대 카운트
iPos := OccupationBar[StrToIntDef(Copy(CurDate,7,2),0)];
end;
CurDate := indc_date(CurDate, 1); // 날짜증가
end;
day_width := Image_Schedule.Width div 7; // 가로 7칸의 각 폭
day_height := (Image_Schedule.Height-NameHeight) div 6; // 세로 6칸의 각 높이
CurDate := StartDate; // 시작일자
while CurDate <= EndDate do
begin
if Copy(CurDate,1,6) = yyyymm then // 기준월의 날짜만 그린다
begin
daynum := Get_thisweek(StrToInt(Copy(CurDate,1,4)), // 해당 년월일의 주번호
StrToInt(Copy(CurDate,5,2)),
StrToInt(Copy(CurDate,7,2)));
dayweek := DayOfWeekNum(CurDate); // 요일번호
// 막대기
MasterCanvas.Brush.Color := iColor;
MasterCanvas.FillRect(Rect(day_width*(dayweek-1)+ 4,
day_height*(daynum-1)+ day_height-(iPos*5)-2+NameHeight,
day_width*(dayweek-1)+ day_width-4,
day_height*(daynum-1)+ day_height-(iPos*5)+1+NameHeight));
if CurDate = StartDate then // 시작점 그리기
MasterCanvas.FillRect(Rect(day_width*(dayweek-1)+ 4,
day_height*(daynum-1)+ day_height-(iPos*5)-2+NameHeight-1,
day_width*(dayweek-1)+ 6,
day_height*(daynum-1)+ day_height-(iPos*5)-2+NameHeight+1));
if CurDate = EndDate then // 종료점 그리기
MasterCanvas.FillRect(Rect(day_width*(dayweek-1)+ day_width-6,
day_height*(daynum-1)+ day_height-(iPos*5)+1+NameHeight-1,
day_width*(dayweek-1)+ day_width-4,
day_height*(daynum-1)+ day_height-(iPos*5)+1+NameHeight+1));
end;
CurDate := indc_date(CurDate, 1); // 날짜증가
end;
end;
procedure TMainForm.DrawEvent(yyyymm, EventDate, Event: String; iColor: TColor);
var
day_width, day_height: Integer;
daynum, dayweek: Integer;
iPos: Integer;
begin
if Copy(EventDate,1,6) <> yyyymm then // 기준월의 날짜에 속하지 않으면...
System.Exit;
// 요일에 출력되는 이벤트 카운트
OccupationEvent[StrToIntDef(Copy(EventDate,7,2),0)] :=
OccupationEvent[StrToIntDef(Copy(EventDate,7,2),0)] + 1;
iPos := OccupationEvent[StrToIntDef(Copy(EventDate,7,2),0)];
day_width := Image_Schedule.Width div 7; // 가로 7칸의 각 폭
day_height := (Image_Schedule.Height-NameHeight) div 6; // 세로 6칸의 각 높이
daynum := Get_thisweek(StrToInt(Copy(EventDate,1,4)), // 해당 년월일의 주번호
StrToInt(Copy(EventDate,5,2)),
StrToInt(Copy(EventDate,7,2)));
dayweek := DayOfWeekNum(EventDate); // 요일번호
MasterCanvas.Font.Color := iColor;
MasterCanvas.Brush.Color := clWhite;
MasterCanvas.TextOut(day_width*(dayweek-1)+ (day_width div 2) - (MasterCanvas.TextWidth(Event) div 2),
day_height*(daynum-1)+ (iPos*13) +3+ NameHeight, Event);
end;
procedure TMainForm.Button1Click(Sender: TObject);
begin
// 기준년월의 달력을 그린다
DrawBackGround(ME_yyyymm.Text);
// 기준년월의 각 스케쥴과 이벤트를 그린다
DrawProgressBar(ME_yyyymm.Text, '19990506', '19990510', clRed);
DrawEvent(ME_yyyymm.Text, '19990507', '검토', clGreen);
DrawEvent(ME_yyyymm.Text, '19990503', '술먹는날', clGreen);
DrawEvent(ME_yyyymm.Text, '19990513', '술먹는날', clGreen);
DrawEvent(ME_yyyymm.Text, '19990523', '술먹는날', clGreen);
DrawProgressBar(ME_yyyymm.Text, '19990501', '19990505', clRed);
DrawEvent(ME_yyyymm.Text, '19990502', '생일이브', clRed);
DrawEvent(ME_yyyymm.Text, '19990503', '생일', clRed);
DrawProgressBar(ME_yyyymm.Text, '19990520', '19990530', clBlue);
DrawEvent(ME_yyyymm.Text, '19990522', '검수일', clBlue);
DrawEvent(ME_yyyymm.Text, '19990529', '토요근무', clBlue);
DrawProgressBar(ME_yyyymm.Text, '19990503', '19990506', clBlack);
DrawEvent(ME_yyyymm.Text, '19990503', '시연회', clBlack);
DrawProgressBar(ME_yyyymm.Text, '19990726', '19990726', clBlue);
DrawEvent(ME_yyyymm.Text, '19990726', '생일', clBlue);
end;
end.
0
0
삭제
수정
댓글
(NOTICE) You must be
logged in
to comment on this post.
한근수
•
1999.10.22 22:49
1
COMMENTS
/
0
LIKES
[급]테이블 필드명을 에디트 박스에 옮기기.
오승섭
•
1999.10.22 23:28
안녕하세요 .... 먼저 4개의 Edit Component의 이름을 Edit1, Edit2, Edit3, Edit4라고 하고요. Table...
최종오
•
1999.10.22 21:35
1
COMMENTS
/
0
LIKES
Real에서 String으로 형변환을 하고 싶습니다.
이정욱
•
1999.10.22 22:23
FloatToStr 이란 함수가 있습니다. 최종오 wrote: > Real에서 String 으로 형 변환을 하고 싶습니다. ...
문영철
1999.10.22 19:56
0
COMMENTS
/
0
LIKES
환율,주가정보를 accept 받는 방법
김경율
•
1999.10.22 19:53
1
COMMENTS
/
0
LIKES
한글 입력 키값을 알려면???
권경부
•
1999.10.22 20:08
김경율 wrote: > 제가 이번에 간단한 타자 연습기를 만들려고 하는 데 > 한글자판 에서 ㄱ,ㄴ,ㄷ 이런식...
이용호
•
1999.10.22 19:43
1
COMMENTS
/
0
LIKES
file 이동에 관해서...
김영대
•
1999.10.22 22:19
이용호 wrote: > 제가 server->client->server 이런 식으로 file을 이동시키려고 합니다. > 화일 이동하...
박성훈
1999.10.22 18:32
0
COMMENTS
/
0
LIKES
TCollection객체사용중에러가 나는데요
전용규
•
1999.10.22 18:28
1
COMMENTS
/
0
LIKES
Midas client 배포
김영대
•
1999.10.22 22:18
> 3 Tier로 작성된 client application을 배포하고자 할때 Application Server > 에서 사용하는 통신 prot...
조창범
•
1999.10.22 18:10
1
COMMENTS
/
0
LIKES
데이타베이스의 선택?
이정욱
•
1999.10.22 22:25
상용DB엔진인 아폴로를 사용해 보세요. 아폴로는 C/S버전도 따로 있습니다. 아폴로 C/S버전의 특징은 추...
정용석
•
•
1999.10.22 09:22
1
COMMENTS
/
2
LIKES
일정관리 프로그램을 만들려고 합니다.
안녕하세요.. 다름이 아니라 일정관리 프로그램을 아주 간단히 만들려고 합니다. 폼은 달력이 절반을 찾이 하는데 일반적인 컴포넌트는 날짜 부분에 클릭을하면 입력이 되지 않네요. 이 기능을 가진 컴퍼넌트가 없는지.. 있으면 알려주시...
김영대
•
1999.10.22 22:33
정용석 wrote: > 안녕하세요.. > 다름이 아니라 일정관리 프로그램을 아주 간단히 만들려고 합니다. > ...
안재현
•
1999.10.22 05:22
2
COMMENTS
/
0
LIKES
MS-SQL 7.0에서 decimal field 문제
최수영
•
1999.10.22 17:50
안재현 wrote: > 안녕하십니까? > 델파이를 이용하여 업무 프로그램을 개발 중입니다. > 숫자가 들어가...
안재현
•
1999.10.22 18:54
최수영 wrote: > 이상하네요! 저흰 사이베이스 11.0.2.2 For NT를 사용합니다! float라는 것은 > 정확...
홍세비
1999.10.22 04:41
0
COMMENTS
/
0
LIKES
TAPI함수를 사용하려면....
최영국
1999.10.22 04:11
0
COMMENTS
/
0
LIKES
dll내의 폼에서 호출폼의 TDatabase 공유하기
김종석
•
1999.10.22 03:49
2
COMMENTS
/
0
LIKES
랜 으로 연결된 컴의 파일을 읽어오고 싶어요...살려주세요
문영철
•
1999.10.22 19:08
다음 예제를 보면 이해가 되실겁니다. readme.txt를 특정화일이름으로 바꾸시면 화일종류에 맞게 오픈이됩...
최영국
•
1999.10.22 04:27
참 저도 한참 초보인데 이런 질문에 답을 한다고 덤벼들다니 정말 부끄럽습니다. 그런데 질문하신 내용만...
이화
•
1999.10.22 03:19
2
COMMENTS
/
0
LIKES
db에서 이미지 저장하는 방법 알려주세요...
이재식
•
1999.10.23 02:51
이화 wrote: > db는 파라독스 이구요.. > > 소스를 어떻게 해야 할지 몰라서.. > > 예) > begin >...
김영대
•
1999.10.22 22:37
이화 wrote: > db는 파라독스 이구요.. > > 소스를 어떻게 해야 할지 몰라서.. > > 예) > begin >...
모영찬
•
1999.10.22 02:47
1
COMMENTS
/
0
LIKES
프린트(PRINT)시 폰트 지정을 어케하나요?
김영대
•
1999.10.22 22:41
모영찬 wrote: > 안녕하십니까... > > 제가 프린터로 삼보 스타일러스에 출력하려고 합니다. > 그리고...
조복기
•
1999.10.22 02:08
1
COMMENTS
/
0
LIKES
윈도우 시작키를 제어하는 방법 있나요?..Plz..
김영대
•
1999.10.22 23:02
조복기 wrote: > > 안녕하세요.. > 프로그램특성상 윈도우즈에서 사용하는 키들을 후킹으로 막고있는데...
하윤철
1999.10.22 02:31
0
COMMENTS
/
0
LIKES
델파이로 엑셀 다루기를 OLE 말고 COM으로...
조창범
•
1999.10.21 23:13
1
COMMENTS
/
0
LIKES
시간이 변하지 않네요...
권경부
•
1999.10.22 02:33
조창범 wrote: > 제가 STATUSBAR 콤포넌트에 시계를 볼수 있게끔 Time을 써주었는데.. > 처음 실행시켰을...
박경환
1999.10.21 22:51
0
COMMENTS
/
0
LIKES
Ics에서 한글사용법좀 ...
델초보
•
1999.10.21 21:13
1
COMMENTS
/
0
LIKES
[재질문]messagedlg....
권경부
•
1999.10.22 02:47
델초보 wrote: > 폼이 있고...상위에 작은 폼이 있어요... > 그 상위폼에서 messagedlg를 부르고 yes나 n...
정용석
1999/10/22 09:22
Views
355
Likes
2
Comments
1
Reports
0
Tag List
수정
삭제
목록으로
한델 로그인 하기
로그인 상태 유지
아직 회원이 아니세요? 가입하세요!
암호를 잊어버리셨나요?
> 안녕하세요..
> 다름이 아니라 일정관리 프로그램을 아주 간단히 만들려고 합니다.
> 폼은 달력이 절반을 찾이 하는데 일반적인 컴포넌트는 날짜 부분에 클릭을하면
> 입력이 되지 않네요. 이 기능을 가진 컴퍼넌트가 없는지..
> 있으면 알려주시면 감사 하겠습니다.
> 저도 소스를 감사하는 마음으로 공개를 하겠습니다.
아래 예제는 제가 전에 만들었던 스케쥴관리의 일부를 발췌한건대
폼위에는 크기가 700*500 정도의 비어있는 TImage 하고
년월을 입력받는 TMaskEdit 와 TButton 하나를 올려놓은 다음
아래 소스를 추가하세요
아래 소스는 TImage에 직접 그래픽으로 달력을 그리므로 그림같은것은
직접 Canvas 에 그리시면 됩니다
그리고 일정의 내용을 입력하는 부분은 없습니다
소스의 맨 뒷부분을 보시면 쉽게 구현하실 수 있을 겁니다
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Mask, ComCtrls, Printers;
type
TMainForm = class(TForm)
Button1: TButton;
ME_yyyymm: TMaskEdit;
Image_Schedule: TImage;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure DrawBackGround(yyyymm: String);
procedure DrawProgressBar(yyyymm, StartDate, EndDate: String; iColor: TColor);
procedure DrawEvent(yyyymm, EventDate, Event: String; iColor: TColor);
end;
const
DayOfWeekNames: array[0..6] of String =('일','월','화','수','목','금','토');
NameHeight = 22;
var
MainForm: TMainForm;
OccupationEvent: array[0..31] of Integer;
OccupationBar: array[0..31] of Integer;
MasterCanvas: TCanvas;
implementation
{$R *.DFM}
procedure TMainForm.FormCreate(Sender: TObject);
begin
Image_Schedule.Picture.Bitmap := TBitmap.Create; {bitmap 생성}
MasterCanvas := Image_Schedule.Picture.Bitmap.Canvas;
ME_yyyymm.EditMask := '####.##;0;_';
ME_yyyymm.Text := '199905';
end;
{===============================================================================
주어진 년월의 마지막 일자를 구한다
===============================================================================}
function Get_LastDay(yyyy,mm: Integer): Integer;
var
MyDate: TDateTime;
Convert_OK: Boolean;
dd: Integer;
begin
Convert_OK := True;
dd := 28;
while Convert_OK do
begin
try
MyDate := EncodeDate(yyyy, mm, dd);
except
on EConvertError do
Convert_OK := False;
end;
if Convert_OK then
Inc(dd)
else
Dec(dd);
end;
Get_LastDay := dd;
end;
{===============================================================================
주어진 달의 주수를 구한다(마지막 주의 의미)
===============================================================================}
function Get_weeks(yyyy,mm: Integer): Integer;
var
MyDate: TDateTime;
i, weeks: Integer;
Convert_OK: Boolean;
begin
weeks := 0;
for i := 1 to 31 do
begin
try
Convert_OK := True;
MyDate := EncodeDate(yyyy, mm, i);
except
on EConvertError do
Convert_OK := False;
end;
if Convert_OK then
if (DayOfWeek(MyDate) = 7) or (Get_LastDay(yyyy,mm) = i) then {토요일이나 달의 마지막이면 1주}
Inc(weeks);
end;
Get_weeks := weeks;
end;
{===============================================================================
주어진 달의 주에 해당하는 날짜from, to, 주의 첫번째 날의 요일번호를 구한다
===============================================================================}
procedure Get_weekfrto(yyyy,mm,week:Integer; var weekfrom:Integer; var weekto:Integer; var dayweek:Integer);
var
MyDate: TDateTime;
i, j, weeks: Integer;
Convert_OK: Boolean;
begin
weekfrom := 0;
weekto := 0;
dayweek := 0;
weeks := 0;
for i := 1 to 31 do
begin
try
Convert_OK := True;
MyDate := EncodeDate(yyyy, mm, i);
except
on EConvertError do
Convert_OK := False;
end;
if Convert_OK then
begin
if (DayOfWeek(MyDate) = 7) or (Get_LastDay(yyyy,mm) = i) then {토요일이나 달의 마지막이면 1주}
Inc(weeks);
if weeks = week then
begin
weekto := i; {주의 마지막 일자}
for j := i downto 1 do
begin
MyDate := EncodeDate(yyyy, mm, j);
if (DayOfWeek(MyDate) = 1) or (j = 1) then {일요일이나 그달의 1일이면 주의 시작 일자}
begin
weekfrom := j; {주의 시작 일자}
dayweek := DayOfWeek(MyDate); {주의 첫번째 날의 요일번호}
Break;
end;
end;
System.Exit;
end;
end;
end;
end;
function indc_date(yyyymmdd: String; disc: Integer): String;
var
yyyy,mm,dd: Integer;
MyDate: TDateTime;
Convert_OK: Boolean;
begin
yyyy := StrToIntDef(Copy(yyyymmdd,1,4),-1);
mm := StrToIntDef(Copy(yyyymmdd,5,2),-1);
dd := StrToIntDef(Copy(yyyymmdd,7,2),-1);
if (yyyy <= 0) or (mm <= 0) or (dd <= 0) then
begin
indc_date := '';
System.exit;
end;
if disc = 0 then
begin
try
Convert_OK := True;
MyDate := EncodeDate(yyyy, mm, dd);
except
on EConvertError do
Convert_OK := False;
end;
if Convert_OK then
begin
indc_date := FormatDateTime('yyyymmdd', MyDate);
end
else
begin
indc_date := '';
end;
end
else
begin
Convert_OK := True;
try
MyDate := EncodeDate(yyyy, mm, dd);
except
on EConvertError do
Convert_OK := False;
end;
if Convert_OK then
begin
indc_date := FormatDateTime('yyyymmdd', MyDate+disc);
end
else
begin
indc_date := '';
end;
end;
end;
{===============================================================================
주어진 년,월,일이 들어가는 주를 구한다
===============================================================================}
function Get_thisweek(yyyy,mm,dd: Integer): Integer;
var
MyDate: TDateTime;
i, weeks: Integer;
Convert_OK: Boolean;
begin
weeks := 0;
for i := 1 to 31 do
begin
try
Convert_OK := True;
MyDate := EncodeDate(yyyy, mm, i);
except
on EConvertError do
Convert_OK := False;
end;
if Convert_OK then
if (DayOfWeek(MyDate) = 7) or (Get_LastDay(yyyy,mm) = i) then {토요일이나 달의 마지막이면 1주}
begin
Inc(weeks);
if dd <= i then // 해당 주를 찾았다
Break;
end;
end;
Get_thisweek := weeks;
end;
function DayOfWeekNum(yyyymmdd: String): Integer;
var
yyyy,mm,dd: Integer;
MyDate: TDateTime;
begin
yyyy := StrToIntDef(Copy(yyyymmdd,1,4),-1);
mm := StrToIntDef(Copy(yyyymmdd,5,2),-1);
dd := StrToIntDef(Copy(yyyymmdd,7,2),-1);
Result := -1;
try
MyDate := EncodeDate(yyyy, mm, dd);
Result := DayOfWeek(MyDate);
except
on EConvertError do
Result := -1;
end;
end;
procedure TMainForm.DrawBackGround(yyyymm: String);
var
max_day, max_week: Integer;
day_width, day_height: Integer;
weekfrom, weekto, dayweek: Integer;
i, j, k, yyyy, mm: Integer;
temp: String;
begin
yyyy := StrToIntDef(Copy(yyyymm,1,4),0);
mm := StrToIntDef(Copy(yyyymm,5,2),0);
if (yyyy = 0) or (mm = 0) then
System.Exit;
for i := Low(OccupationEvent) to High(OccupationEvent) do
OccupationEvent[i] := 0;
for i := Low(OccupationBar) to High(OccupationBar) do
OccupationBar[i] := 0;
// 달의 마지막일자
max_day := Get_LastDay(yyyy, mm);
// 달의 주수
max_week := Get_weeks(yyyy, mm);
day_width := Image_Schedule.Width div 7; // 가로 7칸의 각 폭
day_height := (Image_Schedule.Height-NameHeight) div 6; // 세로 6칸의 각 높이
MasterCanvas.Font := Self.Font;
// 이전의 화면을 지운다
Image_Schedule.Picture.Bitmap.Width := Image_Schedule.Width;
Image_Schedule.Picture.Bitmap.Height := Image_Schedule.Height;
MasterCanvas.Brush.Color := clBtnFace;
MasterCanvas.FillRect(Rect(0, 0, Image_Schedule.Width, Image_Schedule.Height));
// 각 일자명을 그린다
MasterCanvas.Brush.Color := clYellow;
for i := 0 to 6 do
begin
MasterCanvas.Rectangle(day_width*i, 0,
day_width*(i+1), NameHeight);
if i = 0 then // 일요일
MasterCanvas.Font.Color := clRed
else if i = 6 then // 토요일
MasterCanvas.Font.Color := clBlue
else // 평일
MasterCanvas.Font.Color := clBlack;
MasterCanvas.TextOut(day_width*i+5, 5, DayOfWeekNames[i]);
end;
// 스케줄의 각 일자의 직사각형을 그린다
MasterCanvas.Brush.Color := clWhite;
for i := 0 to (max_week-1) do
begin
for j := 0 to 6 do
MasterCanvas.Rectangle(day_width*j, day_height*i+NameHeight,
day_width*(j+1), day_height*(i+1)+NameHeight);
end;
// 스케줄의 각 일자를 출력
k := 0;
for i := 0 to (max_week-1) do // 달의 주수만큼
begin
// 주어진 달의 주에 해당하는 날짜from, to, 주의 첫번째 날의 요일번호
Get_weekfrto(yyyy,mm,i+1, weekfrom, weekto, dayweek);
for j := 0 to 6 do
begin
if ((j+1) >= dayweek) and
((k+1) <= max_day) then
begin
Inc(k);
if j = 0 then // 일요일
MasterCanvas.Font.Color := clRed
else if j = 6 then // 토요일
MasterCanvas.Font.Color := clBlue
else // 평일
MasterCanvas.Font.Color := clBlack;
MasterCanvas.Brush.Color := clWhite;
MasterCanvas.TextOut(day_width*j+5, day_height*i+5+NameHeight, inttostr(k));
end;
end;
end;
end;
procedure TMainForm.DrawProgressBar(yyyymm, StartDate, EndDate: String; iColor: TColor);
var
day_width, day_height: Integer;
daynum, dayweek: Integer;
yyyy, mm: Integer;
CurDate: String;
iPos: Integer;
begin
yyyy := StrToIntDef(Copy(yyyymm,1,4),0);
mm := StrToIntDef(Copy(yyyymm,5,2),0);
if (yyyy = 0) or (mm = 0) then
System.Exit;
iPos := 1;
CurDate := StartDate; // 시작일자
while CurDate <= EndDate do
begin
if Copy(CurDate,1,6) = yyyymm then // 기준월의 날짜만 그린다
begin
// 요일에 출력되는 막대 카운트
OccupationBar[StrToIntDef(Copy(CurDate,7,2),0)] :=
OccupationBar[StrToIntDef(Copy(CurDate,7,2),0)] + 1;
if iPos < OccupationBar[StrToIntDef(Copy(CurDate,7,2),0)] then // 해당기간의 최대 카운트
iPos := OccupationBar[StrToIntDef(Copy(CurDate,7,2),0)];
end;
CurDate := indc_date(CurDate, 1); // 날짜증가
end;
day_width := Image_Schedule.Width div 7; // 가로 7칸의 각 폭
day_height := (Image_Schedule.Height-NameHeight) div 6; // 세로 6칸의 각 높이
CurDate := StartDate; // 시작일자
while CurDate <= EndDate do
begin
if Copy(CurDate,1,6) = yyyymm then // 기준월의 날짜만 그린다
begin
daynum := Get_thisweek(StrToInt(Copy(CurDate,1,4)), // 해당 년월일의 주번호
StrToInt(Copy(CurDate,5,2)),
StrToInt(Copy(CurDate,7,2)));
dayweek := DayOfWeekNum(CurDate); // 요일번호
// 막대기
MasterCanvas.Brush.Color := iColor;
MasterCanvas.FillRect(Rect(day_width*(dayweek-1)+ 4,
day_height*(daynum-1)+ day_height-(iPos*5)-2+NameHeight,
day_width*(dayweek-1)+ day_width-4,
day_height*(daynum-1)+ day_height-(iPos*5)+1+NameHeight));
if CurDate = StartDate then // 시작점 그리기
MasterCanvas.FillRect(Rect(day_width*(dayweek-1)+ 4,
day_height*(daynum-1)+ day_height-(iPos*5)-2+NameHeight-1,
day_width*(dayweek-1)+ 6,
day_height*(daynum-1)+ day_height-(iPos*5)-2+NameHeight+1));
if CurDate = EndDate then // 종료점 그리기
MasterCanvas.FillRect(Rect(day_width*(dayweek-1)+ day_width-6,
day_height*(daynum-1)+ day_height-(iPos*5)+1+NameHeight-1,
day_width*(dayweek-1)+ day_width-4,
day_height*(daynum-1)+ day_height-(iPos*5)+1+NameHeight+1));
end;
CurDate := indc_date(CurDate, 1); // 날짜증가
end;
end;
procedure TMainForm.DrawEvent(yyyymm, EventDate, Event: String; iColor: TColor);
var
day_width, day_height: Integer;
daynum, dayweek: Integer;
iPos: Integer;
begin
if Copy(EventDate,1,6) <> yyyymm then // 기준월의 날짜에 속하지 않으면...
System.Exit;
// 요일에 출력되는 이벤트 카운트
OccupationEvent[StrToIntDef(Copy(EventDate,7,2),0)] :=
OccupationEvent[StrToIntDef(Copy(EventDate,7,2),0)] + 1;
iPos := OccupationEvent[StrToIntDef(Copy(EventDate,7,2),0)];
day_width := Image_Schedule.Width div 7; // 가로 7칸의 각 폭
day_height := (Image_Schedule.Height-NameHeight) div 6; // 세로 6칸의 각 높이
daynum := Get_thisweek(StrToInt(Copy(EventDate,1,4)), // 해당 년월일의 주번호
StrToInt(Copy(EventDate,5,2)),
StrToInt(Copy(EventDate,7,2)));
dayweek := DayOfWeekNum(EventDate); // 요일번호
MasterCanvas.Font.Color := iColor;
MasterCanvas.Brush.Color := clWhite;
MasterCanvas.TextOut(day_width*(dayweek-1)+ (day_width div 2) - (MasterCanvas.TextWidth(Event) div 2),
day_height*(daynum-1)+ (iPos*13) +3+ NameHeight, Event);
end;
procedure TMainForm.Button1Click(Sender: TObject);
begin
// 기준년월의 달력을 그린다
DrawBackGround(ME_yyyymm.Text);
// 기준년월의 각 스케쥴과 이벤트를 그린다
DrawProgressBar(ME_yyyymm.Text, '19990506', '19990510', clRed);
DrawEvent(ME_yyyymm.Text, '19990507', '검토', clGreen);
DrawEvent(ME_yyyymm.Text, '19990503', '술먹는날', clGreen);
DrawEvent(ME_yyyymm.Text, '19990513', '술먹는날', clGreen);
DrawEvent(ME_yyyymm.Text, '19990523', '술먹는날', clGreen);
DrawProgressBar(ME_yyyymm.Text, '19990501', '19990505', clRed);
DrawEvent(ME_yyyymm.Text, '19990502', '생일이브', clRed);
DrawEvent(ME_yyyymm.Text, '19990503', '생일', clRed);
DrawProgressBar(ME_yyyymm.Text, '19990520', '19990530', clBlue);
DrawEvent(ME_yyyymm.Text, '19990522', '검수일', clBlue);
DrawEvent(ME_yyyymm.Text, '19990529', '토요근무', clBlue);
DrawProgressBar(ME_yyyymm.Text, '19990503', '19990506', clBlack);
DrawEvent(ME_yyyymm.Text, '19990503', '시연회', clBlack);
DrawProgressBar(ME_yyyymm.Text, '19990726', '19990726', clBlue);
DrawEvent(ME_yyyymm.Text, '19990726', '생일', clBlue);
end;
end.