Reputation: 21134
I have a stringgrid that shows a bunch of files and information about those files. More info is shown about the current selected item in a separate panel. So, I want to know when the selected row changes to update the panel. OnSelectCell is not good because it triggers BEFORE the selection is actually moved to the new location. This is what I mean:
function TStrGrd.SelectCell(ACol, ARow: Longint): Boolean; {override}
begin
Result:= inherited SelectCell(ACol, ARow);
Mesage('Cur row: '+ IntToStr(row));
Mesage('New row: '+ IntToStr(ARow));
{ My own event }
if Assigned(FCursorChanged)
then FCursorChanged(Self); <-------- user will see the old row
end;
If the last row is selected and I click the first row, I will get these messages:
Cur row: 999
New row: 0
It would work if I create my own event handler and pass to it the row where the selection IS GOING TO be moved. It should work 100% but I am not very happy with this because the user would have to write some extra code in that event handler.
I could intercept all user interactions (mouse/key down) and all selection changes I do programatically but this requires quite a lot of code. There should be a more elegant way.
Upvotes: 1
Views: 2060
Reputation: 16045
Not an answer. Just posting it to have multiline text.
I think you meant "to UPDATE the panel" rather than "to about" :-)
Still I cannot get what is wrong with a ROW parameter. You say "user would have to write some extra code in that event handler." but actually it is the opposite.
procedure ParamEvent(const grid: TStringGrid; const Row: integer);
begin
..do something with grid.Rows[Row] to update the panel
// ...and if I need, I also already know which Row was selected beforehand!
end;
procedure ParamLessEvent();
var grid: TStringGrid; Row: integer; // <<<<< EXTRA "coding" here
begin
grid := ..... some way to get the needed grid // <<<<< EXTRA coding here
Row := grid.Row; // <<<<< EXTRA coding here
...do something with grid.Rows[Row] to update the panel
// ...and if I would want to know which file just was DE-selected,
// I would have to code persisting of previous selected row
// number somewhere outside the grid
end;
now, really, why not use PostMessage ?
const WM_Grid_Event = WM_USER + 123; // I hope it is correct? I always mix wm_user and wm_app
type TMyGrid = class (TStringGrid)
....
private
procedure DelayedEvent(var MSG: TMessage); message WM_Grid_Event;
end;
function TMyGrid.SelectCell(ACol, ARow: Longint): Boolean; {override}
begin
Result:= inherited SelectCell(ACol, ARow);
Mesage('Cur row: '+ IntToStr(row));
Mesage('New row: '+ IntToStr(ARow));
PostMessage( Self.Handle, WM_Grid_Event, ARow, 0);
end;
procedure DelayedEvent(var MSG: TMessage);
begin
{ My own event }
if not Assigned(FCursorChanged) then exit;
if Self.Row = MSG.WParam (* changed already? *) then begin
FCursorChanged(Self);
end else begin
if MSG.LParam < 5 then // protection from infinite loop. OTOH I hope we would not EVER got here
PostMessage( Self.Handle, WM_Grid_Event, MSG.WParam, 1 + MSG.LParam);
end;
end;
Upvotes: 1