Recent

Author Topic: Autoclose PopupNotifier  (Read 2121 times)

runs

  • New Member
  • *
  • Posts: 26
Autoclose PopupNotifier
« on: February 17, 2018, 01:58:42 pm »
I made this to autoclose a PopupNotifier

1) Create a descendant class:

Code: Pascal  [Select][+][-]
  1. type
  2.   TAutoclosePopupNotifier= class(TPopupNotifier)
  3.   private
  4.     Timer: TTimer;
  5.     procedure OnTimer;
  6.   public
  7.     constructor Create;
  8.     destructor Destroy; override;
  9.   end;

2) Go with this class:

Code: Pascal  [Select][+][-]
  1. {TAutoclosePopupNotifier}
  2. constructor TAutoclosePopupNotifier.Create;
  3. begin
  4.   inherited;
  5.   Timer:= TTimer.Create(nil);
  6.   Timer.Interval := 3000;
  7.   Timer.OnTimer:= OnTimer;
  8.   Timer.Enabled:= True;
  9. end;
  10.  
  11. destructor TAutoclosePopupNotifier.Destroy;
  12. begin
  13.   Timer.Free;
  14.   inherited;
  15. end;
  16.  
  17. procedure TAutoclosePopupNotifier.OnTimer;
  18. begin
  19.   self.Hide;
  20. end;  

But error message!!!:

formmain.pas(790,26) Error: Incompatible type for arg no. 1: Got "untyped", expected "<procedure variable type of procedure(TObject) of object;Register>"

on the Timer.OnTimer:= OnTimer;  line

I you could help me...  :D
« Last Edit: February 17, 2018, 02:24:49 pm by runs »
Projects: LibreStaff

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Autoclose PopupNotifier
« Reply #1 on: February 17, 2018, 02:33:17 pm »
Code: Pascal  [Select][+][-]
  1. type
  2.   TAutoclosePopupNotifier= class(TPopupNotifier)
  3.   private
  4.     Timer: TTimer;
  5.     procedure OnTimer;
  6.   public
  7.     constructor Create;
  8.     destructor Destroy; override;
  9.   end;

I think the line #5 above should be:

Code: Pascal  [Select][+][-]
  1.     procedure OnTimer(Sender: TObject);
   

jamie

  • Hero Member
  • *****
  • Posts: 6091
Re: Autoclose PopupNotifier
« Reply #2 on: February 17, 2018, 03:12:44 pm »
I noticed you didn't override the CONSTRUCTOR  CREATE  in your class?
The only true wisdom is knowing you know nothing

runs

  • New Member
  • *
  • Posts: 26
Re: Autoclose PopupNotifier
« Reply #3 on: February 17, 2018, 03:43:18 pm »
I try:

procedure OnTimer(Sender: TObject);

Timer.OnTimer:= OnTimer;

and get the same error.

and if:

constructor Create; override;

it arises the following error:

formmain.pas(22,17) Error: There is no method in an ancestor class to be overridden: "constructor Create;"
« Last Edit: February 17, 2018, 03:46:59 pm by runs »
Projects: LibreStaff

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: Autoclose PopupNotifier
« Reply #4 on: February 17, 2018, 03:50:06 pm »
If you are not in {$mode delphi} then

Code: Pascal  [Select][+][-]
  1.   Timer.OnTimer:= @OnTimer;
  2.  

That (with the change of the signature of OnTimer as noted above) does then compile for me.
I did not test if it works as you expect though, only that it compiles.

Bart
« Last Edit: February 17, 2018, 03:59:18 pm by Bart »

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Autoclose PopupNotifier
« Reply #5 on: February 17, 2018, 03:57:21 pm »
formmain.pas(22,17) Error: There is no method in an ancestor class to be overridden: "constructor Create;"

The original create constructor carries a parameter. Your declaration should look the same in case you wish to override.
Code: Pascal  [Select][+][-]
  1. constructor Create(AOwner: TComponent); override;
  2.  
Unless your code relies on calling your new create method (without Owner parameter) of course.

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: Autoclose PopupNotifier
« Reply #6 on: February 17, 2018, 04:02:55 pm »
This the is the "final" result and it compiles for me.

Code: Pascal  [Select][+][-]
  1. ....
  2.  
  3. type
  4.   TAutoclosePopupNotifier= class(TPopupNotifier)
  5.   private
  6.     Timer: TTimer;
  7.     procedure OnTimer(Sender: TObject);
  8.   public
  9.     constructor Create(AOwner: TComponent); override;
  10.     destructor Destroy; override;
  11.   end;
  12.  
  13. implementation
  14.  
  15. {TAutoclosePopupNotifier}
  16. constructor TAutoclosePopupNotifier.Create(AOwner: TComponent);
  17. begin
  18.   inherited Create(AOwner);
  19.   Timer:= TTimer.Create(nil);
  20.   Timer.Interval := 3000;
  21.   Timer.OnTimer:= @OnTimer;
  22.   Timer.Enabled:= True;
  23. end;
  24.  
  25. destructor TAutoclosePopupNotifier.Destroy;
  26. begin
  27.   Timer.Free;
  28.   inherited;
  29. end;
  30.  
  31. procedure TAutoclosePopupNotifier.OnTimer(Sender: TObject);
  32. begin
  33.   self.Hide;
  34. end;
  35.  

Bart

runs

  • New Member
  • *
  • Posts: 26
Re: Autoclose PopupNotifier
« Reply #7 on: February 17, 2018, 04:40:01 pm »
Yes, it works cool.

Thanks you all!!!  :D
Projects: LibreStaff

runs

  • New Member
  • *
  • Posts: 26
Re: Autoclose PopupNotifier
« Reply #8 on: February 17, 2018, 05:15:58 pm »
The complete worrking code in my software.


Code: Pascal  [Select][+][-]
  1. unit AutoclosePopupNotifier;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, resource, versiontypes, versionresource, Controls, Forms,
  9.   PopupNotifier, ExtCtrls;
  10.  
  11. type
  12.   TAutoclosePopupNotifier= class(TPopupNotifier)
  13.   private
  14.     Timer: TTimer;
  15.     procedure OnTimer(Sender: TObject);
  16.   public
  17.     constructor Create(AOwner: TComponent);override;
  18.     destructor Destroy; override;
  19. end;
  20.  
  21. var
  22.   PopNotifierObj: TAutoclosePopupNotifier;
  23.  
  24.  
  25. implementation
  26.  
  27. {TAutoclosePopupNotifier}
  28. constructor TAutoclosePopupNotifier.Create(AOwner: TComponent);
  29. begin
  30.   inherited Create(AOwner);
  31.   Timer:= TTimer.Create(nil);
  32.   Timer.Interval:= 3000;
  33.   Timer.OnTimer:= @OnTimer;
  34.   Timer.Enabled:= True;
  35. end;
  36.  
  37. destructor TAutoclosePopupNotifier.Destroy;
  38. begin
  39.   Timer.Free;
  40.   inherited;
  41. end;
  42.  
  43. procedure TAutoclosePopupNotifier.OnTimer(Sender: TObject);
  44. begin
  45.   self.Hide;
  46.   PopNotifierObj.Free;
  47. end;
  48.  
  49. procedure PopNotifier(AOwner:TComponent; Title: string; Text: string; Point: TPoint);
  50. begin
  51.   PopNotifierObj:= TAutoclosePopupNotifier.Create(AOwner);
  52.   PopNotifierObj.Title:= Title;
  53.   PopNotifierObj.Text:= Text;
  54.   PopNotifierObj.ShowAtPos(Point.x, Point.y);
  55. end;
  56.  
  57. end.      
       

And I call from other forms:

Code: Pascal  [Select][+][-]
  1. AutoclosePopupNotifier.PopNotifier(FrmMain, 'Title here', 'Caption here', FrmMain.ScreenToClient(Mouse.CursorPos));



Projects: LibreStaff

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: Autoclose PopupNotifier
« Reply #9 on: February 17, 2018, 05:58:34 pm »
The complete worrking code in my software.
1. You forgot to put the procedure PopNotifier to the interface section.
2. Use
Code: Pascal  [Select][+][-]
  1. Timer:= TTimer.Create(Self); // not TTimer.Create(nil);
and TPopupNotifier component will free the timer itself. Therefore, exclude the destructor completely.
3. Bad use of the global variable PopNotifierObj. If the PopNotifier procedure is called before the timer triggered, there will be a double release of the used object when the second timer is triggered. Change in OnTimer code to
Code: Pascal  [Select][+][-]
  1. //...
  2.   Sender.Free; // not PopNotifierObj.Free;
and move "var PopNotifierObj: TAutoclosePopupNotifier;" into the procedure PopNotifier.


 

TinyPortal © 2005-2018