Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.11.2009, 12:51   #1
TaYgA
Форумчанин
 
Аватар для TaYgA
 
Регистрация: 24.09.2009
Сообщений: 264
По умолчанию MyCalendar в Delphi

Здравствуйте дорогие эксперты... Делаю календарь, что то типо на любой год

Возникает ошибка в компаненте MyCalendar, как исправить я не знаю (MyCalendar - это переделанный компанент Calendar) Стандартным компанентом пользоваться не могу т.к. нельзя выделять другим цветом опредённые даты... Ошибка связана с выбором года в SpinEdit... Выкладываю свой проект, чтоб было наглядней. Надеюсь на вашу помощь
Вложения
Тип файла: zip Календарь.zip (254.1 Кб, 20 просмотров)
TaYgA вне форума Ответить с цитированием
Старый 02.11.2009, 13:40   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Вся проблема в том что ты в OnShow создаешь календари последовательно.
Вот строчка:
Код:
SpinEdit1.Value:=Cal1.Year;
Которая возбуждает событие OnChange
В котором ты обращаешся к этим календарям, в часности ко второму календарю
Код:
 Cal2.Year:=SpinEdit1.Value; Cal2.Month:=2;
который еще не создан.

У тя три выхода
1. Проверять на вшивость:
Код:
if Cal2<>nil then
  Cal2.Year:=SpinEdit1.Value; Cal2.Month:=2;
2. Отключать обработчик:
Код:
SpinEdit1.OnChange:=nil;
SpinEdit1.Value:=Cal1.Year;
SpinEdit1.OnChange:=OnChange;

И так для остальных
3.Все календари собрать в TObjectList или в динмассив и в цикле по нему проходя работать с только созданными экземплярами - это наилучший вариант.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 02.11.2009, 14:57   #3
TaYgA
Форумчанин
 
Аватар для TaYgA
 
Регистрация: 24.09.2009
Сообщений: 264
По умолчанию

Stilet, спасибо... Буду разбираться

Вынужден вернуться к этой теме... Предыдущую ошибку исправил, теперь при загрузки проекта всё работает правельно, но когда изменяешь год в SpinEdit в Январе не правельно указываются числа... Не могу понять из-за чего... Так же не могу понять как определённому числу присвоить другой цвет... Делал так:
Код:
Cal2.AlterColor:=clRed;
Cal2.AlterCells:=[29]; \\Отмечает 23 февраля красным цвет
При изменении года цвет остаётся в той же ячейки, а число переходит в другую ячейу..... Как это исправить?!?!

Неужели никто не знает как это делать?!?! Как можно присвоить определённой ячеки цвет и чтоб с изменение года закрашенная ячейка не оставалась на месте?!?! Хотябы поделитесь своими мыслями, а то я всю голову уже себе изломал

Последний раз редактировалось Stilet; 05.11.2009 в 16:32.
TaYgA вне форума Ответить с цитированием
Старый 05.11.2009, 16:33   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Как можно присвоить определённой ячеки цвет
Для этого нужно изучать кишки этого компонента.
Залезь в генофонд и посмотри как там и что.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 05.11.2009, 17:14   #5
TaYgA
Форумчанин
 
Аватар для TaYgA
 
Регистрация: 24.09.2009
Сообщений: 264
По умолчанию

Пробывал, мне это не сильно помогло Может быть вы подскажите...
Код:
constructor TMyCalendar.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  { defaults }
  FUseCurrentDate := True;
  FixedCols := 0;
  FixedRows := 1;
  ColCount := 7;
  RowCount := 7;
  ScrollBars := ssNone;
  Options := Options - [goRangeSelect] + [goDrawFocusSelected];
  FDate := Date;
  UpdateCalendar;
end;

procedure TMyCalendar.Change;
begin
  if Assigned(FOnChange) then FOnChange(Self);
end;

procedure TMyCalendar.Click;
var
  TheCellText: string;
begin
  inherited Click;
  TheCellText := CellText[Col, Row];
  if TheCellText <> '' then Day := StrToInt(TheCellText);
end;

function TMyCalendar.IsLeapYear(AYear: Integer): Boolean;
begin
  Result := (AYear mod 4 = 0) and ((AYear mod 100 <> 0) or (AYear mod 400 = 0));
end;

function TMyCalendar.DaysPerMonth(AYear, AMonth: Integer): Integer;
const
  DaysInMonth: array[1..12] of Integer = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
begin
  Result := DaysInMonth[AMonth];
  if (AMonth = 2) and IsLeapYear(AYear) then Inc(Result); { leap-year Feb is special }
end;

function TMyCalendar.DaysThisMonth: Integer;
begin
  Result := DaysPerMonth(Year, Month);
end;

procedure TMyCalendar.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
var
  TheText: string;
  AltCell: byte;
begin
  TheText := CellText[ACol, ARow];
  AltCell:=ARow*ColCount+ACol;
  with ARect, Canvas do
    begin
    if AltCell in FAlterCells then Font.Color:=FAlterColor;
    if AltCell in FBoldCells then Font.Style:=[fsBold];
    TextRect(ARect, Left + (Right - Left - TextWidth(TheText)) div 2,
      Top + (Bottom - Top - TextHeight(TheText)) div 2, TheText);
    end;
end;

function TMyCalendar.GetCellText(ACol, ARow: Integer): string;
var
  DayNum: Integer;
begin
  if ARow = 0 then  { day names at tops of columns }
    Result := ShortDayNames[(StartOfWeek + ACol) mod 7 + 1]
  else
  begin
    DayNum := FMonthOffset + ACol + (ARow - 1) * 7;
    if (DayNum < 1) or (DayNum > DaysThisMonth) then Result := ''
    else Result := IntToStr(DayNum);
  end;
end;

function TMyCalendar.SelectCell(ACol, ARow: Longint): Boolean;
begin
  if ((not FUpdating) and FReadOnly) or (CellText[ACol, ARow] = '') then
    Result := False
  else Result := inherited SelectCell(ACol, ARow);
end;

procedure TMyCalendar.SetCalendarDate(Value: TDateTime);
begin
  FDate := Value;
  UpdateCalendar;
  Change;
end;

function TMyCalendar.StoreCalendarDate: Boolean;
begin
  Result := not FUseCurrentDate;
end;

function TMyCalendar.GetDateElement(Index: Integer): Integer;
var
  AYear, AMonth, ADay: Word;
begin
  DecodeDate(FDate, AYear, AMonth, ADay);
  case Index of
    1: Result := AYear;
    2: Result := AMonth;
    3: Result := ADay;
    else Result := -1;
  end;
end;

procedure TMyCalendar.SetDateElement(Index: Integer; Value: Integer);
var
  AYear, AMonth, ADay: Word;
begin
  if Value > 0 then
  begin
    DecodeDate(FDate, AYear, AMonth, ADay);
    case Index of
      1: if AYear <> Value then AYear := Value else Exit;
      2: if (Value <= 12) and (Value <> AMonth) then AMonth := Value else Exit;
      3: if (Value <= DaysThisMonth) and (Value <> ADay) then ADay := Value else Exit;
      else Exit;
    end;
    FDate := EncodeDate(AYear, AMonth, ADay);
    FUseCurrentDate := False;
    UpdateCalendar;
    Change;
  end;
end;

procedure TMyCalendar.SetStartOfWeek(Value: TDayOfWeek);
begin
  if Value <> FStartOfWeek then
  begin
    FStartOfWeek := Value;
    UpdateCalendar;
  end;
end;

Последний раз редактировалось TaYgA; 05.11.2009 в 17:16.
TaYgA вне форума Ответить с цитированием
Старый 05.11.2009, 17:17   #6
TaYgA
Форумчанин
 
Аватар для TaYgA
 
Регистрация: 24.09.2009
Сообщений: 264
По умолчанию

Код:
procedure TMyCalendar.SetUseCurrentDate(Value: Boolean);
begin
  if Value <> FUseCurrentDate then
  begin
    FUseCurrentDate := Value;
    if Value then
    begin
      FDate := Date; { use the current date, then }
      UpdateCalendar;
    end;
  end;
end;

{ Given a value of 1 or -1, moves to Next or Prev month accordingly }
procedure TMyCalendar.ChangeMonth(Delta: Integer);
var
  AYear, AMonth, ADay: Word;
  NewDate: TDateTime;
  CurDay: Integer;
begin
  DecodeDate(FDate, AYear, AMonth, ADay);
  CurDay := ADay;
  if Delta > 0 then ADay := DaysPerMonth(AYear, AMonth)
  else ADay := 1;
  NewDate := EncodeDate(AYear, AMonth, ADay);
  NewDate := NewDate + Delta;
  DecodeDate(NewDate, AYear, AMonth, ADay);
  if DaysPerMonth(AYear, AMonth) > CurDay then ADay := CurDay
  else ADay := DaysPerMonth(AYear, AMonth);
  CalendarDate := EncodeDate(AYear, AMonth, ADay);
end;

procedure TMyCalendar.PrevMonth;
begin
  ChangeMonth(-1);
end;

procedure TMyCalendar.NextMonth;
begin
  ChangeMonth(1);
end;

procedure TMyCalendar.NextYear;
begin
  if IsLeapYear(Year) and (Month = 2) and (Day = 29) then Day := 28;
  Year := Year + 1;
end;

procedure TMyCalendar.PrevYear;
begin
  if IsLeapYear(Year) and (Month = 2) and (Day = 29) then Day := 28;
  Year := Year - 1;
end;

procedure TMyCalendar.UpdateCalendar;
var
  AYear, AMonth, ADay: Word;
  FirstDate: TDateTime;
begin
  FUpdating := True;
  try
    DecodeDate(FDate, AYear, AMonth, ADay);
    FirstDate := EncodeDate(AYear, AMonth, 1);
    FMonthOffset := 2 - ((DayOfWeek(FirstDate) - StartOfWeek + 7) mod 7); { day of week for 1st of month }
    if FMonthOffset = 2 then FMonthOffset := -5;
    MoveColRow((ADay - FMonthOffset) mod 7, (ADay - FMonthOffset) div 7 + 1,
      False, False);
    Invalidate;
  finally
    FUpdating := False;
  end;
end;

procedure TMyCalendar.WMSize(var Message: TWMSize);
var
  GridLines: Integer;
begin
  GridLines := 6 * GridLineWidth;
  DefaultColWidth := (Message.Width - GridLines) div 7;
  DefaultRowHeight := (Message.Height - GridLines) div 7;
end;
Сам компонент я уже выкладывал вместе с проектом.... Если этого не достаточно то можно посмотреть там....
TaYgA вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
На Delphi 7 сделать игру кто хочет стать миллионером в delphi 7 666dart666 Помощь студентам 11 04.11.2010 17:57
Программа-тест в Delphi) скиньте))а то програмку здавать преподу надо,и самой хочется понять Delphi Верчик Помощь студентам 9 02.03.2009 17:46
Delphi. Как нарисовать в Delphi два движущиеся шара с определенной скоростью? redred Общие вопросы Delphi 10 11.12.2007 10:43
Как открыть БД, написанную в Delphi если нf другой машине Delphi нет? dagarik БД в Delphi 7 22.10.2007 17:54
не StringGrid1.Cells[1,1]:='Delphi'; а вот так SG1.C[1,1]:='Delphi' Nemesisking Компоненты Delphi 7 08.09.2007 03:27