[Delphi] Object Inspector geeft verkeerde class type aan

Pagina: 1
Acties:

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 08-05 18:37

Tomatoman

Fulltime prutser

Topicstarter
Ik heb in Delphi een TDialogManager component geschreven, die een DBLoginDlgOptions property heeft. Deze is van het type TCustomDBLoginDlgOptions; zie het linkerplaatje hieronder. Zodra een extra package wordt geregistreerd, wordt de DBLoginDlgOptions property automatisch vervangen door een data-aware versie van het type TDBLoginDlgOptions. In het rechterplaatje is dit package geregistreerd, waardoor je eigenlijk achter DBLoginDlgOptions de tekst (TDBLoginDlgOptions) zou moeten zien staan. Dat is niet het geval, er staat nog steeds (TCustomDBLoginDlgOptions).

niet data-aware (weergave klopt) data-aware (weergave is fout)
Afbeeldingslocatie: http://img115.exs.cx/img115/2594/custom1vf.gif Afbeeldingslocatie: http://img115.exs.cx/img115/7653/dbcustom5ht.gif


Om te kijken of ik geen programmeerfout heb gemaakt, heb ik aan TDBLoginDlgOptions even een property DBClassName toegevoegd, die de werkelijke class name weergeeft. Zoals je ziet is dat netjes TDBLoginDlgOptions. Hieruit valt te concluderen dat de Object Inspector naast DBLoginDlgOptions de verkeerde class type weergeeft. Mijn doel zal duidelijk zijn: ik wil dat hier de juiste class type wordt weergegeven (dus soms TCustomDBLoginDlgOptions en soms TDBLoginDlgOptions).

Om te kijken waar het misgaat heb ik de default design-time editor voor class properties, TClassProperty, vervangen door een descendant, TMyClassProperty. Dit is de code:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
unit DlgReg;

interface

uses
  Classes, DesignIntf, DesignEditors, Dlg, DlgConsts;

procedure Register;

implementation

type
  TMyClassProperty = class(TClassProperty)
  public
    function GetValue: string; override;
  end;

function TMyClassProperty.GetValue: string;
begin
  Result := inherited GetValue;
  // ShowMessage(Result);

  { inherited GetValue voert welgeteld 1 regel code uit, namelijk:
    FmtStr(Result, '(%s)', [GetPropType^.Name]); }
end;

procedure Register;
begin
  RegisterComponents('Dialogs', [TDialogManager]);
  RegisterPropertyEditor(TypeInfo(TCustomDBLoginDlgOptions), TDialogManager,
    '', TMyClassProperty); 
end;

end.
Het enige doel van deze property editor is dat ik via ShowMessage kan achterhalen wat GetValue retourneert. Dit blijkt altijd de string 'TCustomDBLoginDlgOptions' te zijn, zelfs als het werkelijke type TDBLoginDlgOptions is. Ik heb nog even geprobeerd hier een aparte property editor voor te registreren, maar dat maakte geen verschil. Conclusie: GetPropType^.Name retourneert soms de verkeerde class name.

Hoe krijg ik het voor elkaar dat de Object Inspector de juiste class name aangeeft? Het lijkt me dat ik daarvoor eenvoudigweg moet zorgen dat de property editor de juiste class name achterhaalt in de GetValue functie, maar hoe?

Een goede grap mag vrienden kosten.


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 08-05 18:37

Tomatoman

Fulltime prutser

Topicstarter
Ik wilde al bijna mijn bed instappen toen ik een ingeving kreeg. Onderstaande code zorgt ervoor dat de class type netjes wordt weergegeven. Het is niet meer dan een slordigheidje in Delphi, maar eigenlijk had mijn prachtige code natuurlijk in TClassProperty moeten zitten. :)
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
unit DlgReg;

interface

uses
  Classes, DesignIntf, DesignEditors, Dlg, DlgConsts;

procedure Register;

implementation

type
  TMyClassProperty = class(TClassProperty)
  protected
    function GetClassReferenceAt(Index: Integer): TPersistent; dynamic;
  public
    function GetValue: string; override;
  end;

function TMyClassProperty.GetClassReferenceAt(Index: Integer): TPersistent;
begin
  Result := TPersistent(GetOrdValueAt(Index));
end;

function TMyClassProperty.GetValue: string;
var
  i: Integer;
begin
  Result := GetClassReferenceAt(0).ClassName;
  for i := 1 to PropCount - 1 do
    if GetClassReferenceAt(i).ClassName <> Result then
    begin
      Result := '';
      Break;
    end;
end;

procedure Register;
begin
  RegisterComponents('Dialogs', [TDialogManager]);
  RegisterPropertyEditor(TypeInfo(TCustomDBLoginDlgOptions), TDialogManager,
    '', TMyClassProperty); 
end;

end.

[ Voor 12% gewijzigd door Tomatoman op 22-03-2005 05:01 . Reden: Nog wat verbeterd ]

Een goede grap mag vrienden kosten.


  • tombo_inc
  • Registratie: December 2004
  • Laatst online: 10-03 13:21

tombo_inc

uhuh

netjes script, ziet er leuk uit. maar ik neem aan dat je probleem nu opgelost is?

Microsoft Windows: A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 08-05 18:37

Tomatoman

Fulltime prutser

Topicstarter
* Tomatoman is weer een happy user :)

Een goede grap mag vrienden kosten.