[Delphi] Onhint scheiden per form

Pagina: 1
Acties:

  • Dala
  • Registratie: November 2000
  • Laatst online: 19-08 10:22
ik heb dus voor dit topic een voorbeeld programma gemaakt..

simpel: 2 forms op elk form een status bar met 1 panel en 1 knopje(incl. hint).

source:
form1
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
46
47
48
49
50
51
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    Button1: TButton;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
    procedure ToonHint(Sender: Tobject); 
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure Tform1.ToonHint(Sender: Tobject);
begin
 StatusBar1.Panels[0].Text := GetLongHint(Application.Hint);
end;



procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnHint := toonhint;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
form2.showmodal;
end;


end.


Form2:
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
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm2 = class(TForm)
    StatusBar1: TStatusBar;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure ToonHint(Sender: Tobject);
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation


{$R *.dfm}

procedure Tform2.ToonHint(Sender: Tobject);
begin
 StatusBar1.Panels[0].Text := GetLongHint(Application.Hint);

end; 
procedure TForm2.FormCreate(Sender: TObject);
begin
Application.OnHint := toonhint;
end;

end.


Nu is dus het probleem dat alle hint in het 2e form word weergegeven, en als ik een timer zet dat na 1 seconden op form1 de onhint zet, word daar alle hints weer gegeven.

Eigenlijk natuurlijk wel logisch, want je vangt alle hints op van de gehele application. en gezien dat forms zelf geen onhint hebben, zie ik even niet in hoe ik het zou kunnen oplossen. Het zou natuurlijk kunnen zijn dat ik iets over het hoofd zie, maar dat lijkt me gek. In iedergeval, als iemand een oplossing zou weten.. zou het natuurlijk erg fijn zijn :)

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 00:12

Tomatoman

Fulltime prutser

Leg eerst even uit wat je precies wilt. Wanneer wil je welke hint op welk form zien? Wat is je main form? En is het andere form modal of modeless?

Een goede grap mag vrienden kosten.


  • Dala
  • Registratie: November 2000
  • Laatst online: 19-08 10:22
tomatoman schreef op 01 September 2003 @ 19:20:
Leg eerst even uit wat je precies wilt. Wanneer wil je welke hint op welk form zien? Wat is je main form? En is het andere form modal of modeless?
elke button heeft een hint, en als je erover heen gaat zou je in de status balk de hint moeten zien.

form1 is het basis form... en form2 later toegevoegd...

het is dus gewoon met delphi in 1 minuut gemaakt. geen instellingen aan het form verandert, gewoon 2 losse forms. waarbij form1 een showmodal van form2 aanroept bij click op de button.

edit:

de source van het voorbeeld project is aanwezig.
http://members.home.nl/davy.landman/GoT/hint%20test.rar

[ Voor 10% gewijzigd door Dala op 01-09-2003 19:45 ]


Verwijderd

3 Mogelijkheden:
- Het OnHint event niet redirecten in de FormCreate, maar in de FormActivate.
- Bij modal forms (zoals in jouw voorbeeld) bij de FormCreate een pointer naar het oude event bewaren en die bij de FormDestroy weer terugzetten.
- Een centrale OnHint event handler schrijven die 't event dispatcht naar het actieve form (de veiligste manier, IMHO).

  • Dala
  • Registratie: November 2000
  • Laatst online: 19-08 10:22
Verwijderd schreef op 01 September 2003 @ 19:52:
3 Mogelijkheden:
- Het OnHint event niet redirecten in de FormCreate, maar in de FormActivate.
- Bij modal forms (zoals in jouw voorbeeld) bij de FormCreate een pointer naar het oude event bewaren en die bij de FormDestroy weer terugzetten.
- Een centrale OnHint event handler schrijven die 't event dispatcht naar het actieve form (de veiligste manier, IMHO).
ik heb optie 1 gebruikt :) .. is het simpelste :Y)

Verwijderd

Mocht je niet al je forms al aanmaken voor Application.Run (m.i. een erg slechte gewoonte, maar wel akelig ingeburgerd bij Delphi programmeurs), zet dan ook even voor de zekerheid een "Application.OnHint := nil" in de FormDestroy (of destructor) van je forms.
Daarmee voorkom je dat een OnHint event tussen de wal en het schip terechtkomt en staat te verwijzen naar een TNotifyEvent dat net is opgeruimd...

(vandaar dat mijn voorkeur uitgaat naar een centrale event handler :))

edit:
En een check op (csDestroying in ComponentState) in ToonHint kan dan ook geen kwaad: het kan gebeuren dat 't form nog wel bestaat, maar dat de statusbar al gefreed is. De kans is klein, maar dat zijn zo van die freak access violations die vrijwel nooit voorkomen maar waar je dagen naar kunt zoeken.

[ Voor 26% gewijzigd door Verwijderd op 01-09-2003 21:02 ]


Verwijderd

Verwijderd schreef op 01 September 2003 @ 20:54:
Mocht je niet al je forms al aanmaken voor Application.Run (m.i. een erg slechte gewoonte, maar wel akelig ingeburgerd bij Delphi programmeurs)
Ik ben het er niet mee eens dat dat een slechte gewoonte is. Wat is het voordeel van alle forms bij het opstarten van de applicatie al in de lucht te schieten? Volgens mij is dit vragen om bugs, omdat elke keer als je de form opent dezelfde instantie van de form weer word "hergebruikt". Ook word het als je die globale form pointer variabelen gebruikt erg vaag als je een form meerdere keren in beeld wil hebben. Of begrijp ik er nou niets van?

Verwijderd

't Staat er wat ongelukkig denk ik, maar ik vind juist het wel aanmaken van al die forms een slechte gewoonte. Oftewel, we zijn 't eens. :)

  • Dala
  • Registratie: November 2000
  • Laatst online: 19-08 10:22
dus het zo mooier zijn om bij elke aanroep van een form (showmodal) ... hem nieuw te createn?

zou me dat niet ook geheugen besparen? want normaal laad hij inderdaad alle forms op.

Verwijderd

Jep en jep. :)
Dus niet:
Delphi:
1
Form2.ShowModal;

maar
Delphi:
1
2
3
4
5
with TForm2.Create(Self) do try
  ShowModal;
finally
  Release;
end;


En uit al je code (behalve je mainform, datamodules en evt. forms die er altijd moeten zijn) regels als
Delphi:
1
2
var
  Form2: TForm2;

weghalen. Die globale variabelen die Delphi standaard aanmaakt (vraag me niet waarom :?) zorgen alleen maar voor nauwelijks te debuggen problemen (Form2 wordt aangesproken i.p.v. de net aangemaakte nieuwe TForm2...).

En een betere naam dan TForm2 is natuurlijk ook altijd prettig. :)

  • Dala
  • Registratie: November 2000
  • Laatst online: 19-08 10:22
Verwijderd schreef op 03 September 2003 @ 13:35:
Jep en jep. :)
Dus niet:
Delphi:
1
Form2.ShowModal;

maar
Delphi:
1
2
3
4
5
with TForm2.Create(Self) do try
  ShowModal;
finally
  Release;
end;


En uit al je code (behalve je mainform, datamodules en evt. forms die er altijd moeten zijn) regels als
Delphi:
1
2
var
  Form2: TForm2;

weghalen. Die globale variabelen die Delphi standaard aanmaakt (vraag me niet waarom :?) zorgen alleen maar voor nauwelijks te debuggen problemen (Form2 wordt aangesproken i.p.v. de net aangemaakte nieuwe TForm2...).

En een betere naam dan TForm2 is natuurlijk ook altijd prettig. :)
het weghalen van
Delphi:
1
2
var
  Form2: TForm2;

is een nieuw gegeven voor me.. maar het oproepen van forms zo heb ik al vaker gedaan ja :)
maar inderdaad een goed idee om het zo te doen voor alle oproepen (op sommig na... maar dat ligt aan het programma :))
Pagina: 1