Solved

non-rectangular controls on a form - how to detect mouse events

Posted on 2002-06-06
8
314 Views
Last Modified: 2010-04-04
I am building an application for viewing entities and relationships, and something that I expected to be trivial has instead been a very interesting problem.

Practically, the application GUI consists of a master form that contains other forms (representing entities) and a custom control that draws a line connecting two forms (representing associations).

The Delphi TControl methods that detect a mouse event are built on the assumption that all controls are rectangular.  On a screen showing a master entity and 50 owned entities with their relationships, I have 50 lines at varous angles extending from the master entity to the owned entities.

The math to detect whether a mouse click is on the line or not is trivial.  What I haven't figured out is how to get the mouse click event past the topmost control in a stack of overlapping rectangles - ie the control asks "Are you inside of me?  No -- let the next guy handle it" without creating an entirely new heirarchy from the TControl level down.

I can clone Borland's code and make the necessary changes (call it TFancyControl in the FancyControls unit if you like), but that seems like a kludge.

I am sure that this has been solved a hundred times, but my strength is in the business process rahter than in the GUI end of things.

Any assistance will be appreciated.

Thanks in advance.
0
Comment
Question by:swift99
  • 4
  • 3
8 Comments
 
LVL 4

Expert Comment

by:nestorua
ID: 7061261
HI,
I think it may be done the following way:
obtain the coords of mouse pointer, convert them into coords
of the corresponding (maybe you must travel over all the controls you want to check) control and determine if the point
belong to this control.
Sincerely,
Nestorua.
0
 
LVL 27

Accepted Solution

by:
kretzschmar earned 100 total points
ID: 7061278
get the devexpress forumlibrary (for free) at
www.devexpress.com

just register yourself in the forum there
you may get then a welcome-mail with a download link

in this library is a dfxConnector-component,
(connects two controls with a line)

gussing thats it what you need

meikl ;-)

0
 
LVL 6

Author Comment

by:swift99
ID: 7061296
I have traced in the debugger and already determined that none of the available mouse events are fired on the parent form.  They are intercepted by the contained controls first.

This is intended for use in an enterprise environment, so I cannot guarantee that the associative representation control will always be on a form that I have defined.  The logic has to be self contained to the extent that the control will always behave correctly, at least within a Delphi VCL environment.

Hmmm ... Is there maybe a way to kick the mouse event back to the winProc?

The key to the whole thing is this method from the VCL, which (sadly) is private and is not virtual.

function TWinControl.ControlAtPos(const Pos: TPoint; AllowDisabled: Boolean): TControl;
var
  I: Integer;
  P: TPoint;
begin
  if FControls <> nil then
    for I := FControls.Count - 1 downto 0 do
    begin
      Result := FControls[I];
      with Result do
      begin
        P := Point(Pos.X - Left, Pos.Y - Top);
        if PtInRect(ClientRect, P) and    // *** This is the line that causes my problem ***
          ((csDesigning in ComponentState) and (Visible or
          not (csNoDesignVisible in ControlStyle)) or
          (Visible and (Enabled or AllowDisabled) and
          (Perform(CM_HITTEST, 0, Longint(PointToSmallPoint(P))) <> 0))) then
          Exit;
      end;
    end;
  Result := nil;
end;

function TWinControl.IsControlMouseMsg(var Message: TWMMouse): Boolean;
var
  Control: TControl;
  P: TPoint;
begin
  if GetCapture = Handle then
  begin
    Control := nil;
    if (CaptureControl <> nil) and (CaptureControl.Parent = Self) then
      Control := CaptureControl;
  end else
    Control := ControlAtPos(SmallPointToPoint(Message.Pos), False);
  Result := False;
  if Control <> nil then
  begin
    P.X := Message.XPos - Control.Left;
    P.Y := Message.YPos - Control.Top;
    Control.Perform(Message.Msg, Message.Keys, Longint(PointToSmallPoint(P)));
    Result := True;  // *** This line means that once a control is recognized there is ***
                             //       no chance of passing the event back to the WndProc for
                             //       someone else to handle.
  end;
end;
0
 
LVL 6

Author Comment

by:swift99
ID: 7061298
meikl: Thanks!  I'll check it out.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 6

Author Comment

by:swift99
ID: 7061306
meikl: Now I feel foolish - we have developers express tools here as a part of our standard setup.  :o(

It's 2:00 in the morning, that's my excuse.   :o)

lolrof
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 7061313
you should go into your bed and sleep a while,
if i'm awake so long time, then i'm near dead in head ;-)
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 7061319
oops,
thanks for the grade,
hope you get it work

meikl ;-)
0
 
LVL 6

Author Comment

by:swift99
ID: 7061365
I'd love to get to bed, but I have to wait for this !@#$%^&*() report to print.  It takes 3 hours on a maxed out IBM 9000, and it's three days late.  I'm on call for the first time in this group, and we didn't even know our group owned this program when it blew up.  Since I'm not an MVS COBOL person by inclination, it's been interesting trying to debug and run the program.

The good news is that while it's running I have time to focus on other things.  The bad news is that while it's running I have to stick around so I can check it's output before I go to bed.   :o)

Isn't on-call duty fun?  <insert heavy does of sarcasm>
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Delphi TcxGrid group footer summary 3 203
Downloading email attachments 2 67
Convert GUI app into console app for Win32 Env 5 78
can't find the executable in Simulator 1 77
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
Concerto provides fully managed cloud services and the expertise to provide an easy and reliable route to the cloud. Our best-in-class solutions help you address the toughest IT challenges, find new efficiencies and deliver the best application expe…

932 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now