Recent

Author Topic: Turn OnClick event on and off in code?(Solved)  (Read 1135 times)

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Turn OnClick event on and off in code?(Solved)
« on: June 13, 2022, 04:59:14 am »
I have a deck of cards named I1..I52.  (TImage)
CardArray[1].Image:=I1..CardArray[52]:=I52
I need to turn the clicked event on while the hands of Bridge are played out and turned off after the last trick.

I suppose I could write;

Code: Pascal  [Select][+][-]
  1. procedure Tform1.Onclick(S: Integer);
  2.  begin
  3.   Case S: begin
  4.                 code to turn the event on
  5.               end;
  6.   end;

Brute force would work but there must be a better way.
« Last Edit: June 13, 2022, 07:00:22 pm by JLWest »
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

speter

  • Sr. Member
  • ****
  • Posts: 349
Re: Turn OnClick event on and off in code?
« Reply #1 on: June 13, 2022, 06:02:06 am »
Do you have a variable representing the state-of-the-game (I usually have a variable called "finished" or "game_over").
If you have something like that you could test it's value at the start of the procedure and exit (if the game is over)...

cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

Handoko

  • Hero Member
  • *****
  • Posts: 5158
  • My goal: build my own game engine using Lazarus
Re: Turn OnClick event on and off in code?
« Reply #2 on: June 13, 2022, 08:08:11 am »
Disabling/Enabling an object's event can be done by:
- Setting the event to nil and point it back to the event (see the first code)
- Using a variable as mentioned by @speter (see the second code)


Solution 1

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     btnEnable1: TButton;
  16.     btnDisable: TButton;
  17.     btnEnable2: TButton;
  18.     btnDisable2: TButton;
  19.     Label1: TLabel;
  20.     Panel1: TPanel;
  21.     Panel2: TPanel;
  22.     procedure btnDisable2Click(Sender: TObject);
  23.     procedure btnDisableClick(Sender: TObject);
  24.     procedure btnEnable1Click(Sender: TObject);
  25.     procedure btnEnable2Click(Sender: TObject);
  26.     procedure Panel1Click(Sender: TObject);
  27.     procedure Panel2Click(Sender: TObject);
  28.   end;
  29.  
  30. var
  31.   Form1: TForm1;
  32.  
  33. implementation
  34.  
  35. {$R *.lfm}
  36.  
  37. { TForm1 }
  38.  
  39. procedure TForm1.Panel1Click(Sender: TObject);
  40. begin
  41.   Panel1.Color := Random($FFFFFF);
  42. end;
  43.  
  44. procedure TForm1.Panel2Click(Sender: TObject);
  45. begin
  46.   Panel2.Caption := Random($FFFFFF).ToString;
  47. end;
  48.  
  49. procedure TForm1.btnEnable1Click(Sender: TObject);
  50. begin
  51.   Panel1.OnClick := @Panel1Click;
  52. end;
  53.  
  54. procedure TForm1.btnEnable2Click(Sender: TObject);
  55. begin
  56.   Panel2.OnClick := @Panel2Click;
  57. end;
  58.  
  59. procedure TForm1.btnDisableClick(Sender: TObject);
  60. begin
  61.   Panel1.OnClick := nil;
  62. end;
  63.  
  64. procedure TForm1.btnDisable2Click(Sender: TObject);
  65. begin
  66.   Panel2.OnClick := nil;
  67. end;
  68.  
  69. end.

Pay attention on the @ symbol in the code above (see line #51 & #56).


Solution 2

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     btnEnable1: TButton;
  16.     btnDisable: TButton;
  17.     btnEnable2: TButton;
  18.     btnDisable2: TButton;
  19.     Label1: TLabel;
  20.     Panel1: TPanel;
  21.     Panel2: TPanel;
  22.     procedure btnDisable2Click(Sender: TObject);
  23.     procedure btnDisableClick(Sender: TObject);
  24.     procedure btnEnable1Click(Sender: TObject);
  25.     procedure btnEnable2Click(Sender: TObject);
  26.     procedure FormCreate(Sender: TObject);
  27.     procedure Panel1Click(Sender: TObject);
  28.     procedure Panel2Click(Sender: TObject);
  29.   private
  30.     ClickEnabled: array[1..2] of Boolean;
  31.   end;
  32.  
  33. var
  34.   Form1: TForm1;
  35.  
  36. implementation
  37.  
  38. {$R *.lfm}
  39.  
  40. { TForm1 }
  41.  
  42. procedure TForm1.Panel1Click(Sender: TObject);
  43. begin
  44.   if ClickEnabled[1] then
  45.     Panel1.Color := Random($FFFFFF);
  46. end;
  47.  
  48. procedure TForm1.Panel2Click(Sender: TObject);
  49. begin
  50.   if ClickEnabled[2] then
  51.     Panel2.Caption := Random($FFFFFF).ToString;
  52. end;
  53.  
  54. procedure TForm1.FormCreate(Sender: TObject);
  55. begin
  56.   // Enable OnClick on all panels
  57.   ClickEnabled[1] := True;
  58.   ClickEnabled[2] := True;
  59. end;
  60.  
  61. procedure TForm1.btnEnable1Click(Sender: TObject);
  62. begin
  63.   ClickEnabled[1] := True;
  64. end;
  65.  
  66. procedure TForm1.btnEnable2Click(Sender: TObject);
  67. begin
  68.   ClickEnabled[2] := True;
  69. end;
  70.  
  71. procedure TForm1.btnDisableClick(Sender: TObject);
  72. begin
  73.   ClickEnabled[1] := False;
  74. end;
  75.  
  76. procedure TForm1.btnDisable2Click(Sender: TObject);
  77. begin
  78.   ClickEnabled[2] := False;
  79. end;
  80.  
  81. end.

The code above uses an array to remember which item is turn on or off, see line #30. Usually programmers count from 0 for arrays but to make it easier to understand, I used 1 in the code above.
« Last Edit: June 13, 2022, 08:35:46 am by Handoko »

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Re: Turn OnClick event on and off in code?
« Reply #3 on: June 13, 2022, 04:18:56 pm »
Hi
Hi Handoko

The following code get an error that it's not a member. @CardArray.Image.Click; I tried @CardArray.Image.Click; and @CardArray.ImageClick;

Code: Pascal  [Select][+][-]
  1. procedure TForm1.CardEventOn;
  2.  Var
  3.   i : Integer;
  4.   Image : TImage;
  5.  begin
  6.   for i := 1 to 52 do begin
  7.      CardArray[i].Image.OnClick:=@CardArray[i].Image.Click;   // Error
  8.   end;
  9.  end;  
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

Handoko

  • Hero Member
  • *****
  • Posts: 5158
  • My goal: build my own game engine using Lazarus
Re: Turn OnClick event on and off in code?
« Reply #4 on: June 13, 2022, 06:02:50 pm »
Try this demo:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, ExtCtrls, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     btnDisable1: TButton;
  16.     btnDisable2: TButton;
  17.     btnDisable3: TButton;
  18.     ImageList1: TImageList;
  19.     Label1: TLabel;
  20.     procedure CardOnClickEvent(Sender: TObject);
  21.     procedure FormCreate(Sender: TObject);
  22.     procedure btnDisable1Click(Sender: TObject);
  23.     procedure btnDisable2Click(Sender: TObject);
  24.     procedure btnDisable3Click(Sender: TObject);
  25.   private
  26.     Cards: array[1..3] of TImage;
  27.   end;
  28.  
  29. var
  30.   Form1: TForm1;
  31.  
  32. implementation
  33.  
  34. {$R *.lfm}
  35.  
  36. { TForm1 }
  37.  
  38. procedure TForm1.CardOnClickEvent(Sender: TObject);
  39. var
  40.   Current: TImage;
  41. begin
  42.   if not(Sender is TImage) then Exit; // Prevent posible error
  43.   Current := Sender as TImage;
  44.   Current.Picture.Clear;
  45.   Application.ProcessMessages;
  46.   Sleep(100);
  47.   ImageList1.GetBitmap(Random(3), Current.Picture.Bitmap);
  48. end;
  49.  
  50. procedure TForm1.FormCreate(Sender: TObject); // Generate and show the cards
  51. var
  52.   i: Integer;
  53. begin
  54.   for i := 1 to 3 do
  55.   begin
  56.     // Generate the card
  57.     Cards[i] := TImage.Create(Self);
  58.     Cards[i].Width   := 86;
  59.     Cards[i].Height  := 125;
  60.     // Get a random image from ImageList1
  61.     ImageList1.GetBitmap(Random(3), Cards[i].Picture.Bitmap);
  62.     // Show the card
  63.     Cards[i].Parent  := Self;
  64.     Cards[i].Top     := 40;
  65.     Cards[i].Left    := i * 130 - 60;
  66.     // Link the CardOnClicEvent to the card, see line #38
  67.     Cards[i].OnClick := @CardOnClickEvent;
  68.   end;
  69. end;
  70.  
  71. procedure TForm1.btnDisable1Click(Sender: TObject);
  72. begin
  73.   case (Cards[1].OnClick <> nil) of
  74.     True:   begin
  75.               btnDisable1.Caption := 'Click to' + #10 + 'Enable';
  76.               Cards[1].OnClick    := nil;               // Disable OnClick
  77.             end;
  78.     False:  begin
  79.               btnDisable1.Caption := 'Click to' + #10 + 'Disable';
  80.               Cards[1].OnClick    := @CardOnClickEvent; // Encable OnClick
  81.             end;
  82.   end;
  83. end;
  84.  
  85. procedure TForm1.btnDisable2Click(Sender: TObject);
  86. begin
  87.   case (Cards[2].OnClick <> nil) of
  88.     True:   begin
  89.               btnDisable2.Caption := 'Click to' + #10 + 'Enable';
  90.               Cards[2].OnClick    := nil;               // Disable OnClick
  91.             end;
  92.     False:  begin
  93.               btnDisable2.Caption := 'Click to' + #10 + 'Disable';
  94.               Cards[2].OnClick    := @CardOnClickEvent; // Encable OnClick
  95.             end;
  96.   end;
  97. end;
  98.  
  99. procedure TForm1.btnDisable3Click(Sender: TObject);
  100. begin
  101.   case (Cards[3].OnClick <> nil) of
  102.     True:   begin
  103.               btnDisable3.Caption := 'Click to' + #10 + 'Enable';
  104.               Cards[3].OnClick    := nil;               // Disable OnClick
  105.             end;
  106.     False:  begin
  107.               btnDisable3.Caption := 'Click to' + #10 + 'Disable';
  108.               Cards[3].OnClick    := @CardOnClickEvent; // Encable OnClick
  109.             end;
  110.   end;
  111. end;
  112.  
  113. end.

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Re: Turn OnClick event on and off in code?
« Reply #5 on: June 13, 2022, 06:59:59 pm »
@Handoko

Yea, I see how you did this.

Thanks
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

 

TinyPortal © 2005-2018