 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Martin Nijhoff Guest
|
Posted: Thu Mar 30, 2006 2:03 pm Post subject: Keyboard behaviour of TStringGrid |
|
|
Hi,
I use a component derived from TStringGrid, to display data in tabular form.
The grid consists of value cells (displaying integers, floats and strings)
and label cells, which describe the contents of the value cells. Each row in
the grid can contain more than one set of label + value cells, for example:
First name: Martin Last name: Nijhoff Age: 33
where 'First name:', 'Last name:' and 'Age:' are label cells and 'Martin',
'Nijhoff' and '33' are value cells.
The user should only be able to select a value cell in the grid. For this
purpose, I use an OnSelectCell handler, which sets CanSelect=false for label
cells. This works fine when the user selects cells using the mouse. However,
if the keyboard is used, the label cells 'block' the value cells next to it,
because the unselectable cells are not skipped-over.
I had a look at the VCL source and found that the keyboard behaviour is
implemented in TCustomGrid. The 'navigational' keypresses are handled by
KeyDown(), which calls FocusCell() to select the cell. FocusCell() calls
MoveCurrent to change the current selection, which in turn calls
SelectCell() to trigger the OnSelectCell event. If SelectCell() returns
false, indicating the cell can't be selected, then MoveCurrent() does
nothing.
To change the keyboard behaviour of my string grid component, I would have
to override MoveCurrent() and include some logic to skip over unselectable
cells if SelectCell() returns false. Unfortunately, MoveCurrent() is a
private method, so I can't override it.
Is there any way to change the keyboard behaviour, without having to write a
string grid component from scratch?
Any help would be greatly appreciated.
Martin |
|
| Back to top |
|
 |
JD Guest
|
Posted: Fri Mar 31, 2006 8:03 am Post subject: Re: Keyboard behaviour of TStringGrid |
|
|
"Martin Nijhoff" <dont (AT) mail (DOT) me> wrote:
| Quote: |
[...]
First name: Martin Last name: Nijhoff Age: 33
where 'First name:', 'Last name:' and 'Age:' are label cells
and 'Martin', 'Nijhoff' and '33' are value cells.
[...] Is there any way to change the keyboard behaviour,
|
Override it's KeyDown method so you can determine if the next
cell would be a label cell. From there you can decide if you
want to swallow the key and manually set the Col property or
do nothing and allow the grid to process the key (you could
also optionally increment the Row property so that the user
doesn't have to change fingers on the arrow keys). For example
assumes the above record is the entire row layout):
protected:
DYNAMIC void __fastcall KeyDown(Word &Key, TShiftState Shift);
//-------------------------------------------------------------
void __fastcall TMyGrid::KeyDown(Word &Key, TShiftState Shift)
{
if( Key == VK_LEFT )
{
if( Col == 1 )
{
if( Row > FixedRows ) --Row;
Col = 5;
}
else Col -= 2;
Key = 0;
}
else if( Key == VK_RIGHT )
{
if( Col == 5 )
{
if( Row < (RowCount - 1) ) ++Row;
Col = 1;
}
else Col += 2;
Key = 0;
}
TStringGrid::KeyDown(Key, Shift);
}
//-------------------------------------------------------------
~ JD |
|
| Back to top |
|
 |
Martin Nijhoff Guest
|
Posted: Fri Mar 31, 2006 9:03 am Post subject: Re: Keyboard behaviour of TStringGrid |
|
|
Thanks for your reply, JD.
| Quote: | assumes the above record is the entire row layout):
|
Unfortunately, this is not the case. A row can also consist of a single
label cell or a single value cell. If a value cell contains a string value
that consists of two or more lines of text, than the value cell uses an
entire row and the label cell is located in the row above it. For example:
First name: Martin Last name: Nijhoff Age: 33
Street: Blablablablablabla Number: 123
Remarks:
Blabla blablabla blablablabla blabla blablabla blablablabla blabla
blablablabla blabla blabla blablabla bla blablabla blabla blabla
blabla blabla blablabla blablablabla blabla blablabla blablablabla.
The grid can also contain a number of 'informative' cells, which are not
linked to any value cells at all.
There is no way of knowing what the layout of the grid is, except what the
application reports back in the OnSelectCell event. The grid component is
used for a number of tables, all with varying layouts. The solution you
proposed would mean that I would have to write custom grid components for
each table.
Any other suggestions?
Martin |
|
| Back to top |
|
 |
JD Guest
|
Posted: Fri Mar 31, 2006 1:03 pm Post subject: Re: Keyboard behaviour of TStringGrid |
|
|
"Martin Nijhoff" <dont (AT) mail (DOT) me> wrote:
| Quote: | Thanks for your reply, JD.
assumes the above record is the entire row layout):
Unfortunately, this is not the case. [...]
|
You can intercept WM_KEYDOWN and and add your own event so
that each instance can have it's own method of handling the
key press. For example:
typedef int __fastcall (__closure *TOnGridKeyDown)(TObject* Sender, int Key );
//-------------------------------------------------------------
class TMyGrid : public TStringGrid
{
__published:
protected:
virtual void __fastcall WndProc( TMessage &Message );
private:
typedef TStringGrid inherited;
TOnGridKeyDown FOnGridKeyDown;
public:
__fastcall TMyGrid( TComponent* Owner );
__property TOnGridKeyDown OnGridKeyDown = { read = FOnGridKeyDown, write = FOnGridKeyDown };
};
//-------------------------------------------------------------
#endif
//-------------------------------------------------------------
void __fastcall TMyGrid::WndProc( TMessage &Message )
{
if( FOnGridKeyDown ) Message.WParam = FOnGridKeyDown( this, Message.WParam );
inherited::WndProc( Message );
}
//-------------------------------------------------------------
~ JD |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|