Jump to content

[Ajuda] MonthCalendar


CanonTG
 Share

Recommended Posts

O TMonthCalendar é um wrapper para um controlo do próprio Windows: http://msdn.microsoft.com/en-us/library/windows/desktop/bb760917(v=vs.85).aspx

O teu nível de controlo sobre ele é mínimo.

Nomeadamente, o tamanho é definido pelo próprio Windows, e a característica de mostrar o antes e depois do mês actual, creio que também.

Precisas de um componente de calendário não descendente do TMonthCalendar para poderes alterar isso!

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Link to comment
Share on other sites

Eu precisei de algo parecido, para um software que suporta touchscreen, e o TMonthCalendar era pequeno demais para usar com os dedos.

Resultado: Criei eu um.

Uma Form, com os botões do tamanho que quis, e todas as características que eu precisava, para igualar ao restante ambiente do programa.

Claro que para usar só o calendário é um overkill, mas podes fazer algo parecido, para as tuas necessidades.

Em alternativa, pesquisar por um componente semelhante, mas com possibilidade de alterar o tamanho.

O Negrito é a mesma coisa... Um componente que não se baseio no do Windows permitirá certamente esse tipo de controle.

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Link to comment
Share on other sites

Isto foi assim visto rápido... mas dá como eu tinha dito... pode é estar com demasiado lixo.

Basicamente o texto do TCalendar é desenhado no evento DrawCell, por isso tens de fazer um override a esse método e colocar a Bold as celulas que quiseres

Uma solução é

TMyCalendar=class(TCalendar)
 procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override;
end;

procedure TMyCalendar.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
var
  TheText: string;
begin
  TheText := self.CellText[ACol, ARow];
  Canvas.Font.Style:=[fsbold]; // esta linha poe o texto da celula a bold
  with ARect, Canvas do
  TextRect(ARect, Left + (Right - Left - TextWidth(TheText)) div 2,
	Top + (Bottom - Top - TextHeight(TheText)) div 2, TheText);
end;

Só tens de criar o teu calendario a partir deste tipo e mudar o código do DrawCell para o que queres.

Isto quase de certeza que pode ser simplificado usando um class interceptor para o TCalendar mas assim de repente nao consegui, se calhar o nunopicado pode dar uma dica sobre isto 😛

Edited by Kline777
Link to comment
Share on other sites

Neste caso, penso que nada como um Class Interceptor... 🙂

Kline, pegando no teu código, e com algumas alterações, ficaria:

Na secção Interface, antes da declaração da form, mete-se o interceptor.

No caso, vamos interceptar o constructor Create e o método DrawCell:

type
 TCalendar = Class(Vcl.Samples.Calendar.TCalendar)  // Dependendo da versão do Delphi, pode não ser necessário meter o namespace completo)
 public
   procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override;
   constructor Create(AOwner: TComponent); override;
 End;
 TForm1 = class(TForm)
   calendar1: TCalendar;    // Esta linha tem de ser posterior ao interceptor, caso contrario não funciona.
 private
   { Private declarations }
 public
   { Public declarations }
 end;

De seguida, a implementação dos novos métodos.

Aqui a ordem é indiferente, logo que esteja na secção Implementation da unit.

constructor TCalendar.Create(AOwner: TComponent);
begin
    DefaultDrawing := false;
    inherited;
end;

procedure TCalendar.DrawCell(ACol: Integer; ARow: Integer; ARect: TRect; AState: TGridDrawState);
begin
    Canvas.Font.Style := [fsbold];          // esta linha poe o texto da celula a bold
    inherited;
end;

Claro que no DrawCell podes personalizar, meter Bold só onde te interessa por exemplo, e não em todas as células.

Mas a moral da história é que com o Interceptor, podes dar nova vida ao TCalendar.

Edited by nunopicado

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Link to comment
Share on other sites

Por exemplo, se alterares o DrawCell de cima, por este, só mete a bold o dia actual:

procedure TCalendar.DrawCell(ACol: Integer; ARow: Integer; ARect: TRect; AState: TGridDrawState);
begin
    if CellText[ACol,ARow] = FormatDateTime('d',date)
       then Canvas.Font.Style:=[fsbold];
    inherited;
end;
  • Vote 1

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Link to comment
Share on other sites

Eu vi logo que davas aí um toque de classe ^^

Melhor que isto só componentes externos, mas sinceramente é uma brutal oportunidade para 'fuçar' no código dos componentes e aprender uma coisas novas.

Tive recentemente o mesmo problema mas foi com um calendar para FireMonkey (Android) e a solução foi parecida...

Link to comment
Share on other sites

lol Tá boa...

A ideia do interceptor é só para que não seja preciso registar o novo componente, ou criá-lo em runtime.

Até pode ser preciso mais do que um TCalendar e já nem é preciso fazer mais nada, o interceptor apanha tudo o que estiver declarado depois dele.

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Link to comment
Share on other sites

Pois, primeiro não pus também, e deu barraca. 🙂

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Link to comment
Share on other sites

Eu estou no delphi 2009 e não tem a propriedade TCalendar.DrawCell :/

Não é que não tenha, tu é que não a vês... 🙂

O TCalendar é descendente da TCustomGrid, que tem o DrawCell. Logo, o TCalendar também o tem.

No entanto, quem construiu o TCalendar achou por bem que quem o usasse não tivesse direito a ele, e como tal, escondeu-a.

O Class Interceptor que te mostrei em cima serve para isso mesmo: Ir buscar métodos e propriedades escondidas e/ou adicionar novos(as).

Ou seja, se meteres o Class Interceptor tal como meti no exemplo em cima, antes da chamada ao TCalendar (apenas com a noção que no D2009 não deverá ser necessário meter todo o namespace do TCalendar como eu meti), o DrawCell não só vai ficar visível, como será alterado pelo que eu meti.

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.