Jump to content
Luiz Felipe Heemann

When I perform the OnDblClick event (Form1) to open Form2, it fires the OnCellClick event of Form2, without having clicked on the form2 grid

Recommended Posts

Event form 1:

procedure TForm1.Panel1DblClick(Sender: TObject);
begin
  TForm2.Create(Self).ShowModal;
end;

Event form 2:

procedure TForm2.DBGrid1CellClick(Column: TColumn);
begin
  ShowMessage('Test');
end;

What should I do to avoid fom2's onCellClick event?

Share this post


Link to post
Guest

I would try to post a message (if this is Windows).

Share this post


Link to post

The problem is how to open Form2 without firing the OnCellClick() present in the DBGrid in Form2. The use of PostMessage() message haddling like suggest does the same problem above.

Edited by Luiz Felipe Heemann

Share this post


Link to post

@Luiz Felipe Heemann As @Dany Marmur said, create a custom message and handler:

 

const 
  CM_OPEN_FORM2 = WM_APP + 1337;
 
TForm1 = class(TForm)
.
private
    procedure CM_OPEN_FORM2_HANDLER(var Message: TMessage); message CM_OPEN_FORM2;
..

procedure TForm1.CM_OPEN_FORM2_HANDLER(var Message: TMessage);
begin
 TForm2.Create(Self).ShowModal;
end;

procedure TForm1.Panel1DblClick(Sender: TObject);
begin
 Postmessage(Self.Handle, CM_OPEN_FORM2, 0,0);
end;

 

Edited by Attila Kovacs

Share this post


Link to post
Guest

@Attila Kovacs That does not help.

 

The DoubleClick event is fired when the mouse button is down.

Then the new form with the TDbGrid is shown (and under the mouse pointer).

When you release the mouse button the MouseUp event is fired and that will cause the MouseClick event of the TDBGrid gets fired.

 

So we must "eat" that MouseUp event somehow ... like

 

type
  TMainForm = class(TForm)
    procedure Form_DblClick(Sender: TObject);
    procedure Form_MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  private
    FDoubleClickFlag: Boolean;
    procedure ExecuteDialog();
  public
  end;

procedure TMainForm.ExecuteDialog;
var
  dlg: TDialogForm;
begin
  dlg := TDialogForm.Create(nil);
  try
    dlg.ShowModal();
  finally
    dlg.Free;
  end;
end;

procedure TMainForm.Form_DblClick(Sender: TObject);
begin
  FDoubleClickFlag := True;
end;

procedure TMainForm.Form_MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if FDoubleClickFlag then
  begin
    FDoubleClickFlag := False;
    ExecuteDialog();
  end;
end;

 

Share this post


Link to post
Guest

Sertac mentioned on SO that this a VCL design error ...

 

It is the default behavior from the OS and it is documented

Quote

Only windows that have the CS_DBLCLKS style can receive WM_LBUTTONDBLCLK messages, which the system generates whenever the user presses, releases, and again presses the left mouse button within the system's double-click time limit. Double-clicking the left mouse button actually generates a sequence of four messages: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK, and WM_LBUTTONUP.

MSDN Docs: WM_LBUTTONDBLCLK

 

VCL fires the DoubleClick event when it receives the WM_LBUTTONDBLCLK message.

 

And try to open a file from explorer with a double click. Press the mouse button down/up/down (hold it) ... guess what will happen ...

Edited by Guest

Share this post


Link to post

@Schokohase I see. Yes its windows. I don't know why does it fire MouseUp after DblClick... Your version could be also strange if someone does not releases the button after the second click.

 

I'd still go with something like this, if there are no other side effects:

(Well, actually a modal window overtakes the message loop, so no effect beyond modal forms.)

var
  WasDblClick: boolean;

procedure TForm1.MyOnMessage(var Msg: TMsg; var Handled: boolean);
begin
  case Msg.Message of
    WM_LBUTTONDBLCLK:
      WasDblClick := True;
    WM_LBUTTONUP:
      if WasDblClick then
      begin
        // v0.2
        Msg.Message := WM_CANCELMODE;
        WasDblClick := False;
        
      { 
        // v0.1 
        PostMessage(Msg.hwnd, WM_CANCELMODE, 0, 0);
        WasDblClick := False;
        Handled := True;
      } 
      
      end;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := MyOnMessage;
end;

 

Edited by Attila Kovacs

Share this post


Link to post
37 minutes ago, Schokohase said:

Sertac mentioned on SO that this a VCL design error ...

 

No, it is not, it is the default behavior from the OS and it is documented

MSDN Docs: WM_LBUTTONDBLCLK

 

VCL fires the DoubleClick event when it receives the WM_LBUTTONDBLCLK message. That is not the fault of the VCL.

 

And try to open a file from explorer with a double click. Press the mouse button down/up/down (hold it) ... guess what will happen ...

The design error is converting left button up into click. That's what Sertac said. Read his comment carefully. A click is button down, capture, button up. 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×