Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

A DBGrid with a clickable button

2,972 views
Skip to first unread message

Stark

unread,
Feb 12, 2012, 10:54:10 AM2/12/12
to

I found a number of examples on the web on how to add a CheckBox in a DBGrid
column, but I need a Button. Inspired by those examples, I tried by myself
with little success. In my test project I get a button in a boolen field (it
could be any field), but the button remains pushed when clicked, and only
the click on a button in another row will reset it raised. I cant find a
remedy ? This is the OnDrawColumnCell I wrote:

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
with Sender as TDBGrid do
begin
if Column.Field.DataType = ftBoolean then
begin
Canvas.FillRect(Rect);
DrawFrameControl(Canvas.Handle, Rect, DFC_BUTTON, DFCS_BUTTONPUSH);
end;
end;
end;

Jamie

unread,
Feb 12, 2012, 12:07:32 PM2/12/12
to
I see a potential problem here, this above code does not say when at
what point does the event get called? After reviewing the events that
are available to you (TDBGrid), it is my best guess that this event
above only gets called after the mouse is released and not when it is
pushed down.

How ever, a simple test can determine this, if you press and hold the
mouse key down and see your little button drawn, then you are in luck :)

You can stash the RECT value away and process the WM_KEYUP message in
the form that contains this DBgrid.. When you process this message,
check to see if the stashed RECT is valid? IN other words, its not set
to a 0 value, if so then process the graphics code needed to undo the
button box and then clear the RECT value. You could also test for the
currently active control while there to save time.

You cold also simply assign a Button over that area and then process
the DB code yourself in the button event. Set your own image on the
button. They're a few ways :)


Jamie


Stark

unread,
Feb 12, 2012, 6:09:32 PM2/12/12
to

"Jamie" <jamie_ka1lpa_not_v...@charter.net> ha scritto nel
messaggio news:LgSZq.19832$E07....@newsfe10.iad...
I am not sure I understand your comments. I'll try to explain what I did: In
a form I have a DBGrid and a Table as Datasource. I want one of the columns
to display a button, rather then its content. So I set DefaultDrawing to
true and paint the button with DrawFrameControl. The DBGrid1
OnDrawColumnCell event is called initially when the DBGrid associated table
is opened and whenever any cell is entered or the grid scrolled. The button
shows correctly. But clicking on it, the button is repainted pushed and does
not raise if clicked again. If I click on the button in another row, this
will show pushed and the previous will raise. If you have an idea on how to
correct this behaviour, can you show an example ? Thanks

Jamie

unread,
Feb 12, 2012, 9:01:49 PM2/12/12
to
I only assumed you wanted the button to raise as you lifted your
mouse button? Now it seems you want a toggle action?

If the DataType boolean isn't changing state then how would you
expect it to redraw anything but the same thing, over and over again?

If infact the DataType value is changing when you click there, then
you need another DrawFrameCOntrol in a raise state when the DataType is
false. I see that you are only drawing one state there and most likely
the form isn't getting a Invalidate to repaint that area otherwise.

Put a Beep in the event code to see if your clicks are even reaching
it all the time.. It is possible the canvas thinks you don't need to
update there and there for, it does not always get called.

Jamie


Hans-Peter Diettrich

unread,
Feb 13, 2012, 3:50:00 AM2/13/12
to
Stark schrieb:

> I am not sure I understand your comments. I'll try to explain what I
> did: In a form I have a DBGrid and a Table as Datasource. I want one of
> the columns to display a button, rather then its content. So I set
> DefaultDrawing to true and paint the button with DrawFrameControl.

This IMO is the wrong approach. Such drawings tend to disappear almost
immediately. Try to find the properties that make the control behave as
you want.

> The
> DBGrid1 OnDrawColumnCell event is called initially when the DBGrid
> associated table is opened and whenever any cell is entered or the grid
> scrolled. The button shows correctly. But clicking on it, the button is
> repainted pushed and does not raise if clicked again.

AFAIR there exists some propery AllowAllUp (or the like). When such
buttons are grouped, they can behave like radio buttons (exactly one
down), or as independent up/down buttons. That's different behaviour
from ordinary push buttons (OK, Cancel...).

DoDi

Stark

unread,
Feb 13, 2012, 8:48:40 AM2/13/12
to
>
> I only assumed you wanted the button to raise as you lifted your mouse
> button? Now it seems you want a toggle action?
>
> If the DataType boolean isn't changing state then how would you
> expect it to redraw anything but the same thing, over and over again?
>
> If infact the DataType value is changing when you click there, then you
> need another DrawFrameCOntrol in a raise state when the DataType is
> false. I see that you are only drawing one state there and most likely
> the form isn't getting a Invalidate to repaint that area otherwise.
>
> Put a Beep in the event code to see if your clicks are even reaching it
> all the time.. It is possible the canvas thinks you don't need to
> update there and there for, it does not always get called.
>
> Jamie
>
Sorry for my english, but I don't want a toggle action. I just want a
clickable button, that is a button that when clicked just blinks and stays
as it is. What happens is that when I click the button becomes pushed and
stays pushed. If I click a button in another row, this will become pushed,
and the previous is raised. It is not what I want. In fact I wanted to give
the user a way to choose one of the rows of the DBGrid and push its button
to act on that row. I may find another way, for example a single external
button; the user can highlight a row and then push this single button.
I just wanted what I thought was a more intuitive interface for the user..

GS

unread,
Feb 13, 2012, 10:40:33 AM2/13/12
to
Stark was thinking very hard :
Just a thought...

Intuitively, most users would expect a menu/toolbar/button to act on a
selection of the grid, whether it be a single cell or a range. What
they would not expect is to find a button in the grid as might be done
with a spreadsheet, for example, using Form or ActiveX controls.

I use Farpoint's Spread.ocx in place of any control where I want a grid
or multi-columns. I know there's a similar control available for Delphi
but I don't know if it hosts buttons as does the Spread.ocx!
Regardless, I don't like putting buttons on a spreadsheet because they
don't stay put after hiding rows/cols without tonnes of positioning
code. Might seem trivial for a few buttons but not how I want to work
with dozens of them! It's easier to make cells 'look/behave' like
buttons and use a 'SelectionChange' event to fire their respective
procedures.

--
Garry

Free usenet access at http://www.eternal-september.org
ClassicVB Users Regroup! comp.lang.basic.visual.misc


Jamie

unread,
Feb 13, 2012, 5:48:41 PM2/13/12
to
Right, and your code isn't going to allow for that.

THe boolean value you are testing remains the same between the click
down and click up. You need to test for the mouse state when you're
there to properly indicate if you should be drawing the button down or up.

Basically, you need to check the mouse state. I suppose you could also
test for the boolean value to not draw the button at all, that is your
choice.


Jamie


Stark

unread,
Feb 14, 2012, 6:11:04 AM2/14/12
to
>> I just wanted what I thought was a more intuitive interface for the
>> user..
>
> Right, and your code isn't going to allow for that.
>
I think this comment will put an end to the discussion. At the end, I was
rather after a technical problem and forgot the main question which is the
ease of use for the user. I guess my wasn't a good idea and I will abandon
it. Thanks all of you for your help

0 new messages