Q&A

  • Calendar의 날짜에...
안녕하세요. Calendar의 특정날짜에 제가 원하는 그래픽을 표시해 넣고 싶은데 어떻게 하면 되나요? 예를 들면 토요일이나 일요일을 붉은색으로 표시해 넣는다던지, 혹은 기념일에 해당하는 날짜에 원하는 특별한 기호같은 것을 삽입해 넣고 싶은데요, 혹시 방법이 있다면 알려 주시겠어요?



1  COMMENTS
  • Profile
    김영대 1999.05.31 20:17
    북해 께서 말씀하시기를...

    > 안녕하세요. Calendar의 특정날짜에 제가 원하는 그래픽을 표시해 넣고 싶은데 어떻게 하면 되나요? 예를 들면 토요일이나 일요일을 붉은색으로 표시해 넣는다던지, 혹은 기념일에 해당하는 날짜에 원하는 특별한 기호같은 것을 삽입해 넣고 싶은데요, 혹시 방법이 있다면 알려 주시겠어요?

    >



    안녕하세요 김영대입니다

    아래 예제는 제가 전에 만들었던 스케쥴관리의 일부를 발췌한건대

    폼위에는 크기가 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.



    • 최재형
    • 1999.06.01 08:04
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 전철호
      1999.06.02 02:39
      조민경 께서 말씀하시기를... > > 최재형 께서 말씀하시기를... > > 안녕하세요. > > 혼자서 고민하다...
    • 박형진
    • 1999.06.01 06:34
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 글쎄요.
      1999.06.01 19:34
      박형진 께서 말씀하시기를... > 프로그램과 일치하지 않는 해상도에서 실행시켰을때 해상도를 프로그램에 ...
    • 구창민
      1999.06.01 06:26
      이승윤 께서 말씀하시기를... > Button1 := TButton.Create(Self); > Button1.Caption := 'Button1'; > ...
    • 이승윤
      1999.06.01 22:20
      질문에 답해 주셔서 정말로 감사합니다. 덕분에 막히 속히 훤하게 뚤린것 같습니다. 질문했던 문제가 해...
    • 이상석
    • 1999.06.01 04:22
    • 3 COMMENTS
    • /
    • 0 LIKES
    • redhead
      1999.06.01 04:56
      if DMtwt.QueryZumin.FieldByName('Juminno').asstring = Jumin.Text Then begin ...
    • 이상석
      1999.06.01 08:40
      redhead 께서 말씀하시기를... > if DMtwt.QueryZumin.FieldByName('Juminno').asstring = Jumin...
    • redhead
      1999.06.01 18:40
      이상석 께서 말씀하시기를... > redhead 께서 말씀하시기를... > > if DMtwt.QueryZumin.FieldBy...
    • Heaven
    • 1999.06.01 04:05
    • 2 COMMENTS
    • /
    • 0 LIKES
    • redhead
      1999.06.01 05:04
      Heaven 께서 말씀하시기를... > 안녕하세요... > > 이렇게 자주 질문을 드리는군요. > 제가 FieldEdit...
    • Heaven
      1999.06.01 20:58
      고맙습니다. redhead님... 답변 잘 보았습니다. 해주신대로 Post를 하니 변경이 됩니다. 그런데, 에디...
    • 김성관
    • 1999.05.31 23:29
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 이정욱
      1999.06.01 02:32
      각각의 유닛에서 서로 참조하려고 해서 그런것입니다. 소스의 맨위 Uses 절을 보셔서 두개의 유닛이 서로 ...
    • 배수영
    • 1999.05.31 23:09
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 안치봉
      1999.06.01 00:34
      배수영 께서 말씀하시기를... > 아래는 제가 작성한 32bit dll file(omin32.dll)의 함수를 선언부분입니다...
    • Heaven
    • 1999.05.31 21:14
    • 2 COMMENTS
    • /
    • 0 LIKES
    • rambo
      1999.06.01 01:19
      Heaven 께서 말씀하시기를... > 안녕하세요... > 항상 도움을 받는군요.. > > 다름이 아니라..Date형...
    • Heaven
      1999.06.01 04:07
      안녕하세요. 답변해 주셔서 고맙습니다.. 문제를 해결했네요.. 그럼..
    • july
    • 1999.05.31 19:44
    • 0 COMMENTS
    • /
    • 0 LIKES
    • 이현신
    • 1999.05.31 19:20
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 글쎄요.
      1999.06.01 01:30
      이현신 께서 말씀하시기를... > 어떤 시스템의 고유의 시리얼이나 스트링을 구할수는 없나요?.. > 하드의...
    • 김영대
      1999.05.31 21:05
      이현신 께서 말씀하시기를... > 어떤 시스템의 고유의 시리얼이나 스트링을 구할수는 없나요?.. > 하드의...
    • 1999.05.31 20:41
      정성호 께서 말씀하시기를... > 안녕하세요.. 꾸벅 ^^ > > 하나 여쭤볼게 있어서 이리 글을 올립니다....
    • 1999.05.31 20:43
      정성호 께서 말씀하시기를... > 안녕하세요...^^ 꾸벅... > > 여러가지로 부족한 점이 많아서 이리 글...
    • 북해
    • 1999.05.31 18:09
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 김영대
      1999.05.31 20:17
      북해 께서 말씀하시기를... > 안녕하세요. Calendar의 특정날짜에 제가 원하는 그래픽을 표시해 넣고 싶은...
    • 하명훈
    • 1999.05.31 15:10
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 1999.05.31 20:48
      하명훈 께서 말씀하시기를... > delphi3.0으로 db를 엑세스하는 프린트폼을 Quick Report로 만들었습니다...
    • 한 재
    • 1999.05.31 14:49
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 김태균
      1999.05.31 18:02
      내용을 보니 체인지 이벤트가 일어날 때 combo의 내용에 들어 있는 파일의 이름을 불러서 메모에 내용을...
    • 1999.05.31 17:56
      한 재 께서 말씀하시기를... > 가르쳐주신 것을 바탕으로 맹글어봤는데 컴파일이 안되는군요. > 문제...