Recent

Author Topic: 2 questions regarding String Grids  (Read 1507 times)

Badger

  • Full Member
  • ***
  • Posts: 153
2 questions regarding String Grids
« on: June 12, 2024, 08:52:00 am »
I have two questions marginally related.
I have a String Grid on a panel in a scroll box. This is initial the configuration of the attached program.
If you run the program you can scroll up and down with the mouse wheel with the cursor over the scroll box.  You can also scroll with the cursor over the panel.  Normally, if you scroll up and down over the StringGrid it only scrolls the cells.  I have added an OnMouseWheel event to override this.  Unfortunately, the scrollbox keeps on scrolling past its limits. Can anyone give me a fix for this or suggest an alternative way of doing it.
My second question, assuming I can get the scroll box responding properly, is that I I am using the dataUtils unit to create a number of components and do common tasks. (Click the button to activate this) To do complete this I need to add the OnMouseWheel event at run time.  I thought I knew how to do this but it refuses to compile. (Reverse all the commented out code in "DataUtils").

Code: Pascal  [Select][+][-]
  1. unit MainUnit;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, DataUtils,
  9.   Grids, Buttons, StdCtrls, Types;
  10.  
  11. type
  12.  
  13.   { TMainForm }
  14.  
  15.   TMainForm = class(TForm)
  16.     Button1: TButton;
  17.     Panel1: TPanel;
  18.     ScrollBox1: TScrollBox;
  19.     StringGrid1: TStringGrid;
  20.     procedure Button1Click(Sender: TObject);
  21.     procedure StringGrid1MouseWheel(Sender: TObject; Shift: TShiftState;
  22.       WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  23.   private
  24.  
  25.   public
  26.  
  27.   end;
  28.  
  29. var
  30.   MainForm: TMainForm;
  31.   StGrids:Array of TStringGrid;
  32.   Panels:Array of TPanel;
  33.   Scrolls:Array of TScrollbox;
  34.   PageNum:Integer;
  35.  
  36. implementation
  37.  
  38. {$R *.lfm}
  39.  
  40. { TMainForm }
  41.  
  42.  
  43.  
  44.  
  45. procedure TMainForm.StringGrid1MouseWheel(Sender: TObject; Shift: TShiftState;
  46.   WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  47. begin
  48.  
  49.   Scrollbox1.ScrollBy(0,Wheeldelta div 10);
  50. end;
  51.  
  52.  
  53. procedure TMainForm.Button1Click(Sender: TObject);
  54. begin
  55.   PutScrollboxOnForm(MainForm,PageNum);
  56.  
  57.   PlacePanelInScrollBox(Scrolls[PageNum],PageNum);
  58.  
  59.   PutGridOnPanel(Panels[PageNum],PageNum);
  60.  
  61. end;
  62.  
  63. end.  

Code: Pascal  [Select][+][-]
  1. object MainForm: TMainForm
  2.   Left = 346
  3.   Height = 496
  4.   Top = 119
  5.   Width = 714
  6.   Caption = 'MainForm'
  7.   ClientHeight = 496
  8.   ClientWidth = 714
  9.   LCLVersion = '2.2.4.0'
  10.   object ScrollBox1: TScrollBox
  11.     Left = 72
  12.     Height = 296
  13.     Top = 80
  14.     Width = 408
  15.     HorzScrollBar.Page = 376
  16.     VertScrollBar.Page = 292
  17.     ClientHeight = 292
  18.     ClientWidth = 387
  19.     TabOrder = 0
  20.     object Panel1: TPanel
  21.       Left = 11
  22.       Height = 304
  23.       Top = 16
  24.       Width = 365
  25.       Caption = 'Panel1'
  26.       ClientHeight = 304
  27.       ClientWidth = 365
  28.       TabOrder = 0
  29.       object StringGrid1: TStringGrid
  30.         Left = 24
  31.         Height = 272
  32.         Top = 16
  33.         Width = 312
  34.         TabOrder = 0
  35.         OnMouseWheel = StringGrid1MouseWheel
  36.       end
  37.     end
  38.   end
  39.   object Button1: TButton
  40.     Left = 160
  41.     Height = 25
  42.     Top = 424
  43.     Width = 184
  44.     Caption = 'Click to add programatically'
  45.     OnClick = Button1Click
  46.     TabOrder = 1
  47.   end
  48. end

Code: Pascal  [Select][+][-]
  1. unit datautils;
  2.  
  3. {$mode ObjFPC}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils,Forms, Controls, Printers,
  9.   ExtCtrls,
  10.    graphics, Grids;
  11.  
  12.  
  13.   Procedure PutScrollboxOnForm(TheForm:TForm;PN:Integer);
  14.   Procedure PlacePanelInScrollBox(SB:TScrollBox;PN:Integer);
  15.   Procedure PutGridOnPanel(Pan:TPanel;PN:Integer);
  16. //  Procedure GridScrolling(Sender: TObject; Shift: TShiftState;
  17. //    WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  18.  
  19.  
  20. implementation
  21.  
  22. Uses
  23.   MainUnit;
  24.  
  25. procedure PutScrollboxOnForm(TheForm: TForm;PN:Integer);
  26. begin
  27.   SetLength(Scrolls,PN+1);
  28.             Scrolls[PN]:=TScrollBox.Create(TheForm);
  29.             with Scrolls[PN] do
  30.             begin
  31.               Parent:=TheForm;
  32.               width:=500;
  33.               Height:=400;
  34.               Left:=8;
  35.               Top:=8;
  36.               visible:=True;
  37.               refresh;
  38.             end;
  39. end;
  40.  
  41. procedure PlacePanelInScrollBox(SB:TScrollBox;PN:Integer);
  42. begin
  43.   SetLength(Panels,PN+1);
  44.   Panels[PN]:=TPanel.Create(MainUnit.Scrolls[PN]);
  45.   with Panels[PN] do
  46.   begin
  47.     Parent:=SB;
  48.     width:=300;
  49.     Height:=500;
  50.     Left:=8;
  51.     Top:=8;
  52.     color:=clwhite;
  53.     visible:=True;
  54.     refresh;
  55.   end;
  56. end;
  57.  
  58. procedure PutGridOnPanel(Pan: TPanel; PN: Integer);
  59. begin
  60.   SetLength(StGrids,PN+1);
  61.   StGrids[PN]:=TStringGrid.Create(MainUnit.Panels[PN]);
  62.   with StGrids[PN] do
  63.   begin
  64.     Parent:=Pan;
  65.     width:=250;
  66.     Height:=400;
  67.     Left:=8;
  68.     Top:=8;
  69.     color:=clwhite;
  70.     visible:=True;
  71.     //OnMouseWheel:=@GridScrolling;
  72.     refresh;
  73.   end;
  74. end;
  75. (*
  76. procedure GridScrolling(Sender: TObject; Shift: TShiftState;
  77.   WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  78. begin
  79.   Sender as TStringgrid.Parent.Parent.ScrollBy(WheelDelta);
  80. end;
  81.     *)
  82. end.
  83.            
Badger
(A bad tempered, grumpy animal that sleeps most of the winter!)

If at first you don't succeed - you're running about average!

I'm using Windows 10 Lazarus v2.2.4  FPC 3.2.2   Win 32/64

cdbc

  • Hero Member
  • *****
  • Posts: 1645
    • http://www.cdbc.dk
Re: 2 questions regarding String Grids
« Reply #1 on: June 12, 2024, 09:29:19 am »
Hi
This:
Code: Pascal  [Select][+][-]
  1. (*
  2. procedure GridScrolling(Sender: TObject; Shift: TShiftState;
  3.   WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  4. begin
  5.   Sender as TStringgrid.Parent.Parent.ScrollBy(WheelDelta);
  6. end;
  7.     *)
Can't be a simple procedure, it *has* to be a method on an object/class
- - - Stick it in a class or an object and Bob's your uncle - - -
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

cdbc

  • Hero Member
  • *****
  • Posts: 1645
    • http://www.cdbc.dk
Re: 2 questions regarding String Grids
« Reply #2 on: June 12, 2024, 09:52:10 am »
Hi ...again
Or you can play dirty like this:
Code: Pascal  [Select][+][-]
  1. unit datautils;
  2.  
  3. {$mode ObjFPC}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils,Forms, Controls, Printers,
  9.   ExtCtrls,
  10.    graphics, Grids;
  11. { Hack start }
  12. type
  13.   { declare an object to host our method, yes it's a hack :o) }
  14.   THack = object
  15.     procedure GridScrolling(Sender: TObject;
  16.                             Shift: TShiftState;
  17.                             WheelDelta: Integer;
  18.                             MousePos: TPoint;
  19.                             var Handled: Boolean);
  20.   end; { THack }
  21. { end of hack }
  22.  
  23.   Procedure PutScrollboxOnForm(TheForm:TForm;PN:Integer);
  24.   Procedure PlacePanelInScrollBox(SB:TScrollBox;PN:Integer);
  25.   Procedure PutGridOnPanel(Pan:TPanel;PN:Integer);
  26.  
  27.  
  28. implementation
  29.  
  30. Uses
  31.   MainUnit;
  32.  
  33. var { declare a variable of our object/hack }
  34.   Hack: THack;
  35.  
  36. procedure PutScrollboxOnForm(TheForm: TForm;PN:Integer);
  37. begin
  38.   SetLength(Scrolls,PN+1);
  39.             Scrolls[PN]:=TScrollBox.Create(TheForm);
  40.             with Scrolls[PN] do
  41.             begin
  42.               Parent:=TheForm;
  43.               width:=500;
  44.               Height:=400;
  45.               Left:=8;
  46.               Top:=8;
  47.               visible:=True;
  48.               refresh;
  49.             end;
  50. end;
  51.  
  52. procedure PlacePanelInScrollBox(SB:TScrollBox;PN:Integer);
  53. begin
  54.   SetLength(Panels,PN+1);
  55.   Panels[PN]:=TPanel.Create(MainUnit.Scrolls[PN]);
  56.   with Panels[PN] do
  57.   begin
  58.     Parent:=SB;
  59.     width:=300;
  60.     Height:=500;
  61.     Left:=8;
  62.     Top:=8;
  63.     color:=clwhite;
  64.     visible:=True;
  65.     refresh;
  66.   end;
  67. end;
  68.  
  69. procedure PutGridOnPanel(Pan: TPanel; PN: Integer);
  70. begin
  71.   SetLength(StGrids,PN+1);
  72.   StGrids[PN]:=TStringGrid.Create(MainUnit.Panels[PN]);
  73.   with StGrids[PN] do
  74.   begin
  75.     Parent:=Pan;
  76.     width:=250;
  77.     Height:=400;
  78.     Left:=8;
  79.     Top:=8;
  80.     color:=clwhite;
  81.     visible:=True;
  82.     { here we utilize our hack/object to host the event-handler }
  83.     OnMouseWheel:=@Hack.GridScrolling;
  84.     refresh;
  85.   end;
  86. end;
  87.  
  88. { Hack start }
  89. { THack is a nifty way of converting a function or a procedure into a method :o) }
  90. procedure THack.GridScrolling(Sender: TObject;
  91.                               Shift: TShiftState;
  92.                               WheelDelta: Integer;
  93.                               MousePos: TPoint;
  94.                               var Handled: Boolean);
  95. begin
  96.   Sender as TStringgrid.Parent.Parent.ScrollBy(WheelDelta);
  97. end;
  98. { end of hack }
  99. end.
  100.  
It's your unit, with a few modifications of mine, it should work now...
Just look for the word 'Hack' and you'll find my mods...  :D
It's a bit /Old School/, but hey... that's fun too  8-) ...and easy.
HTH
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

TRon

  • Hero Member
  • *****
  • Posts: 3621
Re: 2 questions regarding String Grids
« Reply #3 on: June 12, 2024, 10:11:08 am »
Just look for the word 'Hack' and you'll find my mods...  :D
I always name the object 'events' or 'eventhandlers' ... no idea it was considered a hack  :)

Quote
It's a bit /Old School/, but hey... that's fun too  8-) ...and easy.
Exactly why I use that all the time: quick and easy.

You can always figure out a more proper solution/location (for the event handlers) when things are working (or just leave it as is).
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

jamie

  • Hero Member
  • *****
  • Posts: 6733
Re: 2 questions regarding String Grids
« Reply #4 on: June 12, 2024, 11:42:09 pm »
if I am following this correctly, shouldn't a simple

Code: Pascal  [Select][+][-]
  1. Handled := True;
  2.  

In the MouseWhile Event for the stringgrid be enough to not send it to the scrollbox ?
The only true wisdom is knowing you know nothing

Badger

  • Full Member
  • ***
  • Posts: 153
Re: 2 questions regarding String Grids
« Reply #5 on: June 13, 2024, 06:50:14 am »
I'll give your suggestions a try tonight.

Quote
It's a bit /Old School/, but hey... that's fun too  8-) ...and easy.
You don't know the meaning of old school!! I cut my teeth on a PDP11, a Commodore 64 and an Amstrad! :D
Badger
(A bad tempered, grumpy animal that sleeps most of the winter!)

If at first you don't succeed - you're running about average!

I'm using Windows 10 Lazarus v2.2.4  FPC 3.2.2   Win 32/64

cdbc

  • Hero Member
  • *****
  • Posts: 1645
    • http://www.cdbc.dk
Re: 2 questions regarding String Grids
« Reply #6 on: June 13, 2024, 07:12:45 am »
Hi
Quote
Commodore 64
Yup, me too, with tape loading...  :D
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Badger

  • Full Member
  • ***
  • Posts: 153
Re: 2 questions regarding String Grids
« Reply #7 on: June 13, 2024, 07:50:21 am »
PDP was toggle switches!
Badger
(A bad tempered, grumpy animal that sleeps most of the winter!)

If at first you don't succeed - you're running about average!

I'm using Windows 10 Lazarus v2.2.4  FPC 3.2.2   Win 32/64

Badger

  • Full Member
  • ***
  • Posts: 153
Re: 2 questions regarding String Grids
« Reply #8 on: June 13, 2024, 09:01:56 am »
Still got a couple of problems.

Firstly, the  scrollbox in the first part of the program is still scrolling past the ends of the scrollbox 'canvas'.

Secondly, I had to modify the THack.GridScrolling procedure as follows
Code: Pascal  [Select][+][-]
  1. procedure THack.GridScrolling(Sender: TObject;
  2.                               Shift: TShiftState;
  3.                               WheelDelta: Integer;
  4.                               MousePos: TPoint;
  5.                               var Handled: Boolean);
  6. var
  7.   APanel:TPanel;
  8.   AScroll:TScrollbox;
  9. begin
  10.   APanel:=TPanel.Create(Sender as TStringgrid) ;
  11.  
  12.   AScroll:=TScrollbox.Create(APAnel);
  13.  
  14.   AScroll.ScrollBy(0,WheelDelta);
  15. end;  

However, when I run the program I get the error message - TWinControl.ScrollBy_WS: Handle not allocated at the line AScroll.ScrollBy(0,WheelDelta); 
Badger
(A bad tempered, grumpy animal that sleeps most of the winter!)

If at first you don't succeed - you're running about average!

I'm using Windows 10 Lazarus v2.2.4  FPC 3.2.2   Win 32/64

cdbc

  • Hero Member
  • *****
  • Posts: 1645
    • http://www.cdbc.dk
Re: 2 questions regarding String Grids
« Reply #9 on: June 13, 2024, 09:23:20 am »
Hi
Hmmm...
In that handler procedure:
Code: Pascal  [Select][+][-]
  1. procedure THack.GridScrolling(Sender: TObject;
  2.                               Shift: TShiftState;
  3.                               WheelDelta: Integer;
  4.                               MousePos: TPoint;
  5.                               var Handled: Boolean);
  6. var
  7.   APanel:TPanel;
  8.   AScroll:TScrollbox;
  9. begin
  10.   APanel:=TPanel.Create(Sender as TStringgrid) ;
  11.   // try to set parent for APanel, maybe that will jolt the 'HandleNeeded'
  12.   APanel.Parent:= (Sender as TStringgrid){.Parent?!?};
  13.   AScroll:=TScrollbox.Create(APAnel);
  14.   // dunno 'bout 'parent' business here?!? Trial 'n error...
  15.   AScroll.ScrollBy(0,WheelDelta);
  16. end;
note: I've got this funny feeling, that something else is wrong...  %)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

 

TinyPortal © 2005-2018