Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/VCL/Multi-Monitor Support    [ Add a report in this area ]  
Report #:  64619   Status: Closed
Hints sometimes crash program when Multiple Monitors are used
Project:  Delphi Build #:  11.0.2902.10471
Version:    11.0 Submitted By:   Paul Klink
Report Type:  Minor failure / Design problem Date Reported:  7/19/2008 1:34:11 AM
Severity:    Infrequently encountered problem Last Updated: 3/20/2012 2:24:39 AM
Platform:    All platforms Internal Tracking #:   262556
Resolution: Cannot Reproduce (Resolution Comments) Resolved in Build: : 12.0.3112.14858
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: None
Description
When a program runs within a multiple monitor desktop environment, then the its hints can cause the program to generate a nil pointer exception.  This seems to occur when the program is running in the secondary monitor and the secondary monitor is to the left of the primary monitor.

This occurs because the Screen.MonitorFromPoint (in Controls.pas) sometimes returns nil - which causes the exception.  Not sure of the exact circumstances which causes this.

See Workaround for modification to Controls.pas to fix the above problem.
Steps to Reproduce:
1) Create a simple VCL Forms application which contains a control (say button) which displays a hint.
2) Run the program on a computer with multiple monitors and where the secondary monitor is to the left of the primary monitor.
3) Move the mouse over the control to bring up the hint.

The program may bring up a nil pointer exception when the hint appears.   If not, leave the program idle for 1 minute and try again.  If still does not raise an exception, try moving program around on screen and then try again.
Workarounds
Modify unit Controls.pas as below:

In method THintWindow.ActivateHint, add 3 lines as shown below:

    Monitor := Screen.MonitorFromPoint(Point(Rect.Left, Rect.Top));
    if Assigned(Monitor) then // add this line
    begin  // add this line
      if Width > Monitor.Width then
        Width := Monitor.Width;
      if Height > Monitor.Height then
        Height := Monitor.Height;
      if Rect.Top + Height > Monitor.Top + Monitor.Height then
        Rect.Top := (Monitor.Top + Monitor.Height) - Height;
      if Rect.Left + Width > Monitor.Left + Monitor.Width then
        Rect.Left := (Monitor.Left + Monitor.Width) - Width;
      if Rect.Left < Monitor.Left then Rect.Left := Monitor.Left;
      if Rect.Bottom < Monitor.Top then Rect.Bottom := Monitor.Top;
    end;  // add this line
Attachment
None
Comments

None

Server Response from: ETNACODE01