Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How can one control button action? 3

Status
Not open for further replies.

terrytype

Programmer
Jun 1, 2011
97
ZA
I use Delphi 6 and have an application in which one should either tab forwards or backwards from a particular input field in a grid. If one depresses the Down-button or Up-Button from that field the application freezes up - for good reasons which I need not go into here. Ability to use the Up/Down-buttons anywhere else is fine [required in fact.] Is there a method whereby during RunTime I can prevent the Up/Down-buttons having any effect from a particular field? Thanks in advance.

Old Man Delphi
 
again, be more specific:

what grid do you use?

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Sorry about that!
I should have mentioned to begin with that I am using a Paradox table.
I have a TDBGrid which has its DataSource [DataSet] hooked to TQuery which is updated by a TUpdateSQL. But the SQL code in the TQuery and the the TUpdateSQL are determinded during Runtime. In addition I have a TDBNavigator with relies upon the same DataSource [DataSet]. Anything else I can tell you? Thanks for your interest. :)

Old Man Delphi
 
So if I understand you correctly, you want to disable up/down keyevents for a particular column in the TDBGrid?

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
It would appear that I need something like the following code to resolve this thread but
I need a greater mind than mine to imagine what that might be.

The Windows Virtual-Key Code for DOWN ARROW key being VK_DOWN 0x28
and for UP ARROW key being VK_UP 0x26.

Anybody?

Code:
procedure TfrmCB.grdCBEnter(Sender: TObject);
begin
  if grdCB.SelectedIndex = 5 then  //  Selected field in the grid
   // ...what? I don't want the Down Arrow or UP Arrow to respond whilst this field is selected.
end;

Old Man Delphi
 
Look at the OnKeyDown or OnKeyUp events for TDBGrid. Assign null (#0) to the "Key" field in the event handler.

It is not possible for anyone to acknowledge truth when their salary depends on them not doing it.
 
Thanks Glenn999.
Unfortunately that doesn't work because grdCBKeyDown is effective each time depress a key - anywhere on the grid - including making entries [even one character] anywhere on the grid.

What I need is for DOWN ARROW [on the keyboard] to be disabled ONLY when I enter ONE PARTICULAR field in the grid.

It would seem that one needs to rely upon if grdCB.SelectedIndex = 5 in order to immobilise the UP/DOWN arrows with code from within Delphi6.

Is that even possible?

By the way I get exceptions as below from your kind suggestion

Code:
procedure TfrmCB.grdCBKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  Key := #0;     // Exception "Incompatible types: Word and Char"
  Key := 'nul';  // Exception "Incomptatible types: Word and String"
  Key := nul;    // Exception "Undeclared identifier 'nul"'

Old Man Delphi
 
It's a pity that you are using Delphi 6 as there is a very simple way to implement this in Delphi 2007 onwards by using class helpers.

I'm describing how to do it in case it prompts someone else for a solution which is applicable to Delphi 6.

The basic problem is that you need access to the protected property Col which is declared in TCustomGrid. Col tells you the column of the currently selected cell.

If you knew the column then the OnKeyDown handler could implement something like:
Code:
begin
  if grid.Col = RestrictedColumn then
    if key in [ VK_UP, VK_DOWN ] then
      key := 0;
end;
In Delphi 2007 onwards you can declare a helper class as follows:
Code:
type
  TDBGridHelper = class helper for TCustomGrid
    function ClickedCol: integer;
  end;
and a suitable function
Code:
function TDBGridHelper.ClickedCol: integer;
begin
  result := Col;
end;
Your OnKeyDown handler can then implement the required functionality as follows:
Code:
begin
  if grid.ClickedCol = RestrictedColumn then
    if key in [ VK_UP, VK_DOWN ] then
      key := 0;
end;
Hope that contributes to a solution.

Andrew
 
Not tested, but this should be what you need...

Code:
procedure TForm1.DBGrid1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  case DBGrid1.SelectedField.Index of
    0: begin

    end;
    1: begin

    end;
    2: begin
      //Assume this is the column you don't want to trigger
      if Key in [VK_Up, VK_Down] then
        Key:= 0;
    end;
  end;
end;

JD Solutions
 
JD Solutions. I have no way of knowing where you are but I am in Cape Town [South Africa]and it is Friday 22H30 here and I heard the warning from this site come through of your addition to this thread. I simply had to try it! :) I am ever grateful to you because it solved my problem after I modified your code to be as below - leaving this thread now concluded. Thanks once again! :)

Code:
  if Key in [VK_Up, VK_Down] then
  case grdCB.SelectedField.Index of
  7: begin
      //Assume this is the column you don't want to trigger
       Key:= 0;
     end;
  end;


Old Man Delphi
 
My apologies. Upon further testing neither code works. :-(
From Break point placed at case grdCB.SelectedField.Index is indeed 7.
But Key remains unaffected.
Code:
   if Key in [VK_Up, VK_Down] then  
  case grdCB.SelectedField.Index of
  0: begin
     end;
  1: begin
     end;

  //Etc. Etc

  7: begin
       Key:= 0;// F8 does not even take one here. 
     end;




Old Man Delphi
 
try to set keypreview to true on the form and put the code in the onkeydown event of the form...

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Your requirements have changed! This is the first time you've mentioned F8.

Add F8 to the list of keys you want to trap. Based on JD's code I suggest something like:
Code:
procedure TForm1.DBGrid1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
const
  DoNotTriggerCodes = [ VK_Up, VK_Down, VK_F8 ];
begin
case grdCB.SelectedField.Index of
    0: begin
    end;
    1: begin
    end;
    7: begin
      //Assume this is the column you don't want to trigger
      if Key in DoNotTriggerCodes then
        Key:= 0;
    end;
  end;
end;

Andrew
 
Ho! Ho! Andrew!:) It seems you have forgotten that F8 is used during DESIGN TIME - whilst de-bugging. I don't need it during RUN TIME. My use of F8 was merely to see exactly what was happening in the procudure; more particularly whether the value of Key WAS in fact being changed to '0'. On that score I would mention that I tried logic, within the procedure, which succesfully forces Key to '0'.

But this leaves the application in an unending loop as determined during DESIGN TIME through the use of the Break Point at if Key in [VK_Up, VK_Down] then . The Break Point revealing that, despite my logic, Key repeatedy resumes its original value ['52924'].

Meanwhle whosrdaddy thanks for your suggestion and am investigating.



Old Man Delphi
 
Thanks whosrdaddy but your suggestion doesn't have any effect.



Old Man Delphi
 
I never knew that F8 was used during Design Time? How does that work? I've only used F8 whilst debugging at run time.

Are you confusing SelectedField.Index with the column number of your DBGrid?

When debugging, place a breakpoint on your case statement and check that 7 (in your case (sic)) which is the eighth field in the Fields property of your dataset is the one you actually want.

Andrew
 
Andrew My apologies! You are quite right! I intended to convey [somewhat badly] that I do not use F8 in the normal running of the Application which is what you appeared to think.

As it happens I have moved the procedure to another form which somehow causes the following to work - solving part of my problem. In that grdCBKeyDown does what I want. But grdCBKeyUp causes the application to hang. Despite the code being identical except for VK_UP being swapped for VK_DOWN.

Code:
procedure TfrmCB.grdCBKey[b]Down[/b](Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key in [b][VK_Down][/b] then
  case grdCB.SelectedField.Index of
  7: begin
       Key:= 0;
     end;
 end;
end;

procedure TfrmCB.grdCBKey[b]Up[/b](Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key in [b][VK_UP][/b] then
  case grdCB.SelectedField.Index of
  7: begin
       Key:= 0;
     end;
  end;
end;



Old Man Delphi
 
Why are you trying to handle VK_UP in the OnKeyUp handler?

Surely this should be in the OnKeyDown handler? You want to inhibit the key BEFORE it's action takes place.

Andrew
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top