Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi VCL: Property ausblenden bei Ableitung? (https://www.delphipraxis.net/105055-vcl-property-ausblenden-bei-ableitung.html)

blackdrake 14. Dez 2007 21:47


VCL: Property ausblenden bei Ableitung?
 
Hallo.

Ich bin dabei, eine einfache VCL zu entwickeln, die das Ereignis OnGetMonthInfo() von TMonthCalendar um den Parameter "Year" erweitert. Dazu muss ich auf das Ereignis OnGetMonthInfo abfangen, den Zusatzparameter berechnen und dann OnGetMonthInfoExt aufrufen. Es handelt sich hierbei um meine erste VCL, die ich entwickle. Ich möchte in dem Gebiet auch mal was dazulernen.

Das Problem ist nun: Der Benutzer erhält bei der Komponente 2 Events: OnGetMonthInfo und OnGetMonthInfoExt. OnGetMonthInfo wird jedoch beim Create() Ereignis belegt und soll vom Benutzer nicht mehr verändert werden! Bei der Ableitung TExtMonthCalendar soll also OnGetMonthInfo von TMonthCalendar verschwinden.

Delphi-Quellcode:
unit ExtMonthCalendar;

interface

uses
  SysUtils, Classes, Controls, ComCtrls, Messages, Windows, CommCtrl;

type
  TOnGetMonthInfoExtEvent = procedure(Sender: TObject; Month, Year: LongWord; var MonthBoldInfo: LongWord) of object;

  TExtMonthCalendar = class(TMonthCalendar)
  private
    FOnGetMonthInfoExt: TOnGetMonthInfoExtEvent;
    procedure MyGetMonthInfo(Sender: TObject; Month: LongWord; var MonthBoldInfo: LongWord);
  protected
  public
    constructor Create(AOwner: TComponent); override;
  published
    property OnGetMonthInfoExt: TOnGetMonthInfoExtEvent read FOnGetMonthInfoExt write FOnGetMonthInfoExt;
  end;

procedure Register;

implementation

constructor TExtMonthCalendar.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  OnGetMonthInfo := MyGetMonthInfo;
end;

procedure TExtMonthCalendar.MyGetMonthInfo(Sender: TObject; Month: LongWord; var MonthBoldInfo: LongWord);
var
  Year: integer;
begin
  if Assigned(FOnGetMonthInfoExt) then
  begin
    Year := 2007; // ToDo
    FOnGetMonthInfoExt(Sender, Month, Year, MonthBoldInfo);
  end;
end;

procedure Register;
begin
  RegisterComponents('Samples', [TExtMonthCalendar]);
end;

end.
Ich dachte mir nun, ich könnte meine neue Methode einfach auch OnGetMonthInfo anstelle von OnGetMonthInfoExt nennen. Dadurch kann der Benutzer auf das OnGetMonthInfo von TMonthCalendar nicht mehr zugreifen. Aber dann habe ich das Problem, dass ich bei der Create()-Methode das OnGetMonthInfo von TMonthCalendar nicht mehr setzen kann.

Ich hatte auch mal ausprobiert, über die Message CN_NOTIFY zu gehen, um das Ereignis auszulösen, aber dann müsste ich Quellcode von der ComCtrls.pas kopieren und das wäre dann keine wirkliche Ableitung mehr...

Gruß
blackdrake

Muetze1 14. Dez 2007 22:03

Re: VCL: Property ausblenden bei Ableitung?
 
Mir war langweilig...

Delphi-Quellcode:
unit ExtMonthCalendar;

interface

uses
  ComCtrls;

type
  TOnGetMonthInfoExtEvent = procedure(Sender: TObject; Month, Year: LongWord; var MonthBoldInfo: LongWord) of object;

  TExtMonthCalendar = class(TMonthCalendar)
  private
    FOnGetMonthInfoExt: TOnGetMonthInfoExtEvent;

    procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;
  published
    property OnGetMonthInfoExt: TOnGetMonthInfoExtEvent read FOnGetMonthInfoExt write FOnGetMonthInfoExt;
  end;

implementation

procedure TExtMonthCalendar.CNNotify(var Message: TWMNotify);
var
  ST: PSystemTime;
  I, MonthNo: Integer;
  CurState: PMonthDayState;
begin
  inherited;

  with Message, NMHdr^ do
  begin
    if code = MCN_GETDAYSTATE then
    begin
      with PNmDayState(NMHdr)^ do
      begin
        FillChar(prgDayState^, cDayState * SizeOf(TMonthDayState), 0);
        if Assigned(FOnGetMonthInfoExt) then
        begin
          CurState := prgDayState;
          for I := 0 to cDayState - 1 do
          begin
            MonthNo := stStart.wMonth + I;
            if MonthNo > 12 then MonthNo := MonthNo - 12;
            FOnGetMonthInfoExt(Self, MonthNo, stStart.wYear, CurState^);
            Inc(CurState);
          end;
        end;
      end;
    end;
  end;
end;

end.

blackdrake 14. Dez 2007 22:51

Re: VCL: Property ausblenden bei Ableitung?
 
Hallo.

Vielen Dank für die Vorlage. Ich hatte diese CN_NOTIFY-Variante zwar schon gehabt, jedoch bin ich nicht auf die Idee mit stStart.wMonth gekommen.

Folgendes funktioniert nun:

Delphi-Quellcode:
unit ExtMonthCalendar;

interface

uses
  Controls, ComCtrls, Messages, CommCtrl;

type
  TOnGetMonthInfoExtEvent = procedure(Sender: TObject; Month, Year: LongWord;
    var MonthBoldInfo: LongWord) of object;

  TExtMonthCalendar = class(TMonthCalendar)
  private
    FOnGetMonthInfo: TOnGetMonthInfoExtEvent;
    procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;
  published
    property OnGetMonthInfo: TOnGetMonthInfoExtEvent read FOnGetMonthInfo
                                                    write FOnGetMonthInfo;
  end;

implementation

procedure TExtMonthCalendar.CNNotify(var Message: TWMNotify);
var
  I, MonthNo: Integer;
  CurState: PMonthDayState;
  YearAdd: integer;
begin
  inherited;

  with Message, NMHdr^ do
  begin
    if code = MCN_GETDAYSTATE then
    begin
      with PNmDayState(NMHdr)^ do
      begin
        FillChar(prgDayState^, cDayState * SizeOf(TMonthDayState), 0);
        if Assigned(FOnGetMonthInfo) then
        begin
          CurState := prgDayState;
          for I := 0 to cDayState - 1 do
          begin
            MonthNo := stStart.wMonth + I;
            if MonthNo > 12 then
            begin
              MonthNo := MonthNo - 12;
              YearAdd := 1;
            end
            else
            begin
              YearAdd := 0;
            end;
            FOnGetMonthInfo(Self, MonthNo, stStart.wYear+YearAdd, CurState^);
            Inc(CurState);
          end;
        end;
      end;
    end;
  end;
end;

end.
(Korrigiert: YearAdd hinzugefügt, Ereignis "OnGetMonthInfo" von TMonthCalendar nun überschrieben und dadurch ersetzt)

Ein Problem hab ich jetzt aber mit der Komponente: Im falle von folgender Verwendung:

Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    my_cal: TExtMonthCalendar;
    procedure GetMonthInfo(Sender: TObject; Month, Year: Cardinal; var MonthBoldInfo: Cardinal);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.GetMonthInfo(Sender: TObject; Month, Year: Cardinal;
  var MonthBoldInfo: Cardinal);
var
  x: array of LongWord;
begin
  { zum Test }
  SetLength(x, 2);
  x[0] := month;
  x[1] := year-2000+10;

  (Sender as TMonthCalendar).BoldDays(x, MonthBoldInfo);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  my_cal := TExtMonthCalendar.Create(form1);
  my_cal.Parent := form1;
  my_cal.Left := 100;
  my_cal.top := 100;
  my_cal.Height := 500;
  my_cal.OnGetMonthInfo := GetMonthInfo;
end;
ist die fette hervorhebung der Datumsangaben erst nach einem Monats-Scrollen vorhanden. Ich habe mir die Unit ComCtrls.pas genau angeschaut und nach "OnGetMonthInfo" gesucht. Dort wird OnGetMonthInfo ebenfalls bei der CN_NOTIFY-Message aufgerufen, aber sonst nirgens. Mache ich die Markierung bei einer normalen TMonthCalendar-VCL, dann ist die Markierung von Anfang an da, so als würde OnGetMonthInfo im OnCreate-Ereignis aufgerufen werden.

Gruß
blackdrake


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:40 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz