Getting the control under the cursor

I am implementing the Shift-F10 behaviour of bringing up the context menu for a control. I have written the code below to implement it:

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  Pos : TPoint;
  Control : TControl;

begin
  if (ssShift in Shift) and (Key = vk_F10) then // pop up the context menu
    try
      GetCursorPos(Pos);
      Control := FindVCLWindow(Pos);
      if Assigned(Control) then
        with Control do
          if Assigned(PopupMenu) then
            PopupMenu.Popup(Pos.X, Pos.Y);
    except
      // Don't worry about it
    end;
end;

However, FindVCLWindow always appears to return Nil. I can't see why this doesn't work, I think it should.

Anyone have any clues? I'm sure its something very obvious :-)

Cheers,

Raymond.
LVL 12
rwilson032697Asked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
aldynConnect With a Mentor Commented:
Nice puzzle :-)

1) If you set breakpoint before or exactly on FindVCLWindow then Control will be nil because window is switched to the source code window.
2) The code
        with Control do
          if Assigned(PopupMenu) then
checks the PopupMenu of the form, not of the control itself, because this property is declared as PROTECTED in TControl. Change it to
if Assigned(Tzzz(Control).PopupMenu) then
Tzzz(Control).PopupMenu.Popup(Pos.X, Pos.Y);
where Tzzz is any descendant of TControl wich publishes property PopupMenu
0
 
fulg0reCommented:
welp, i am not sure about the way to find contorl, yet it is for sure, not the one u use... FindVCL works on Twincontrol... so it WILL find, let's say TPanel... hmmm... maybe a loop on all children of the form, and check of coordinates will help?
0
 
rwilson032697Author Commented:
I initially started using ControlAtPos, but it only looks at the direct children, so a treeview embedded in a panel on a form wouldn't be picked up (at least thats what appeared to be happening, so I switched to FindVCLWindow...)

Cheers,

Raymond.
0
 
rwilson032697Author Commented:
aldyn:

1) Yes - you are right! I'll try it without the breaks!

Yup - FindVCLWindow works..

Here's the code that now works:

type
  THackedControl = class(TControl)
  end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);

var
  Pos : TPoint;
  TheControl : TControl;
  HackedControl : THackedControl;

begin
  if (ssShift in Shift) and (Key = vk_F10) then // pop up the context menu
    try
      GetCursorPos(Pos);
      TheControl := FindVCLWindow(Pos) as TControl;
      if Assigned(TheControl) then
        if Assigned(THackyControl(TheControl).PopupMenu) then
          begin
            THackyControl(TheControl).PopupMenu.Popup(Pos.X, Pos.Y);
            key := 0; // swallow the key
          end;
    except
      // Don't worry about it
    end;
end;

Thanks for the help out. Its getting too late for coding :-)

Cheers,

Raymond.
0
All Courses

From novice to tech pro — start learning today.