Kill a message

Hi,

I display a MessageDlg asking the user if he really wants to cancel any edits if he moves off the current unsaved node in a trees OnChanging event. Problem is, the MouseDown is processed after this event in the Trees OnMouseDown event. The result is a drag image. I need to cancel(kill) the mouse down message as it is not needed.

Regards,
Dion.
DionoAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
vorisekConnect With a Mentor Commented:
You can disable dragging by additional variable like this:

var CanDrag:boolean=true;

procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
 TreeHitTest: THitTests;
 PopupPT: TPoint;
begin
 { Allow the drag to start if not on the button. }
 TreeHitTest := TTreeView(Sender).GetHitTestInfoAt(X, Y);

 if (htOnItem in TreeHitTest) then
 begin
   if (Button <> mbRight)then
   begin
     { Only allow to drag from nodes on level 2, or 3 in the case of 'other parent'. }
     if (TTreeView(Sender).Selected.Level = 2) then
       if CanDrag then TTreeView(Sender).BeginDrag(false, 5);
       candrag:=true;
   end
 end;(* *)

end;

procedure TForm1.TreeView1Changing(Sender: TObject; Node: TTreeNode;
  var AllowChange: Boolean);
begin
if MessageDlg('Are you sure you want to CANCEL all Changes!!', mtWarning, [mbYes, mbNo], 0) =
mrYes then
    begin
           candrag:=false;
    end;
end;
0
 
kretzschmarCommented:
? cannot recognize your problem with this sample

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ImgList, ComCtrls;

type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    ImageList1: TImageList;
    CheckBox1: TCheckBox;
    procedure TreeView1Changing(Sender: TObject; Node: TTreeNode;
      var AllowChange: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.TreeView1Changing(Sender: TObject; Node: TTreeNode;
  var AllowChange: Boolean);
var box_result : Integer;
begin
  if checkbox1.checked then //to simulate a changed-Status
  begin
    box_result := messagedlg('Data changed!'+#10+'Save ?',mtConfirmation,mbYesNoCancel,0);
    case box_result of
      mrYes    : Begin
                   //Code for Saving
                   AllowChange := True;
                 end;
      mrNo     : Begin
                   //Code for Cancel Saving, if needed
                   AllowChange := True;
                 end;
      mrCancel : Begin
                   //Abort Node-change
                   AllowChange := False;
                 end;
    end;
  end;
end;

end.

Did i miss something?

meikl ;-)

0
 
MarcGCommented:
To kill an event just assign nil to it, in your example:
TreeView1.OnMouseDown := nil;
If you need it again: TreeView1.OnMouseDown := TreeView1MouseDown;//Or whatever your Procedure is called
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
kretzschmarCommented:
hmm,
i see know your problem, guessing you the the drgamode of your tree set to dmAutomatic,

i've enhanced my sample to avoid this

procedure TForm1.TreeView1Changing(Sender: TObject; Node: TTreeNode;
  var AllowChange: Boolean);
var box_result : Integer;
begin
  if checkbox1.checked then //to simulate a changed-Status
  begin
    box_result := messagedlg('Data changed!'+#10+'Save ?',mtConfirmation,mbYesNoCancel,0);
    If TreeView1.Dragging then   //Discard any Uneeded Drag here
      TreeView1.EndDrag(False);
    case box_result of
      mrYes    : Begin
                   //Code for Saving
                   AllowChange := True;
                 end;
      mrNo     : Begin
                   //Code for Cancel Saving, if needed
                   AllowChange := True;
                 end;
      mrCancel : Begin
                   //Abort Node-change
                   AllowChange := False;
                 end;
    end;
  end;
end;

hope this helps

meikl ;-)
0
 
DionoAuthor Commented:
Meikl, the OnChanging event is fired first(ie not dragging yet!), then the OnMouseDown is fired; I don't want it to fire. By the way, I have already tried you last solution.

Thanks,
Dion.

0
 
kretzschmarCommented:
hmm,

just set the dragmode back to dmManual,
and use the mousemove-event to initiate dragging like

procedure TForm1.TreeView1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  If ssleft in shift then
    TreeView1.BeginDrag(False); //or TreeView1.BeginDrag(False,10)
end;

meikl ;-)
0
 
DionoAuthor Commented:
If I dont display a MessageDlg box, everything behaves normally. Displaying the MessageDlg seems to cause the mouse to be in 'MouseDown' mode. After clicking the MessageDlg box, if I move the mouse(without holding any button down), it changes to a drag image. I must click elsewhere to cancel the drag.

Cheers,
Dion.
0
 
vorisekCommented:
Try call
 PostMessage (ActiveControl.Handle,wm_LButtonUp,0,0);
before you call the message box.
0
 
DionoAuthor Commented:
Hi,

Here is a snippet of the code - excuse all the commenting.


procedure TPupilForm.tvFamilyMembersChanging(Sender: TObject;
  Node: TTreeNode; var AllowChange: Boolean);
var
  MouseDownMSG: TagMSG;
begin
  AllowChange := true;

  if dmPupil.tblFTPerson.State in dsEditModes then
  begin
    if PupilForm.miSaveOnExit.Checked then
    begin
      if CheckFamilyTreeInput then
        bbtPupilInfoSaveClick(Sender)
      else
      begin
        MessageDlg('Please ensure all Data is entered...', mtWarning, [mbOK], 0);
        AllowChange := false;
      end;
    end

    else
    begin
//      Perform(WM_LBUTTONUP, 0, 0);
  //    PostMessage(tvFamilyMembers.Handle,wm_LButtonUp,0,0);
      if MessageDlg('Are you sure you want to CANCEL all Changes!!', mtWarning, [mbYes, mbNo], 0) = mrYes then
      begin
        DoRelativeInfoCancels;
//        Perform(WM_LBUTTONUP, 0, 0);
      end;
//      else
      begin
        AllowChange := false;
      //  KillMessage(tvFamilyMembers.Handle, WM_LBUTTONDOWN);
      end;
    end;
  end

  else if pcFamilyDetails.ActivePage = tsCorrespond then
  begin
  end

  else if pcFamilyDetails.ActivePage = tsAccountPayee then
  begin
  end;

end;
0
 
vorisekCommented:
Does not raise your problem anything else ?
If I put to OnChanging only the message no problem occurs.

procedure TForm1.TreeView1Changing(Sender: TObject; Node: TTreeNode;
  var AllowChange: Boolean);
begin
if MessageDlg('Are you sure you want to CANCEL all Changes!!', mtWarning, [mbYes, mbNo], 0) =
mrYes then
     begin  
       sysutils.beep;
     end;
end;

Try to simplify your code as much as possible.
0
 
DionoAuthor Commented:
Vorisek, try the same bit of code , but add an OnMouseDown event that looks like this:-

procedure TPupilForm.tvFamilyMembersMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  TreeHitTest: THitTests;
  PopupPT: TPoint;
begin
  { Allow the drag to start if not on the button. }
  TreeHitTest := TTreeView(Sender).GetHitTestInfoAt(X, Y);

  if (htOnItem in TreeHitTest) then
  begin
    if (Button <> mbRight) then
    begin
      { Only allow to drag from nodes on level 2, or 3 in the case of 'other parent'. }
      if (TTreeView(Sender).Selected.Level = 2) then
        TTreeView(Sender).BeginDrag(false, 5);
    end

The only I have managed to get the app to ignore the mouse down is by doing what MarcG suggested. Is there not a more elegant solution?

Cheers,
Dion.
 
0
 
DionoAuthor Commented:
Thanks guys!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.