View Issue Details

IDProjectCategoryView StatusLast Update
0017549LazarusWidgetsetpublic2010-10-05 20:43
ReporterŽilvinas LedasAssigned ToFelipe Monteiro de Carvalho 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version0.9.29 (SVN)Product Build 
Target Version0.9.30Fixed in Version0.9.29 (SVN) 
Summary0017549: TrayIcon.GetPosition in Windows is wrong when task bar is not at the bottom (patch included)
DescriptionTrayIcon.GetPosition in Windows is wrong when task bar is not at the bottom, as the current code always returns:
Result.X := TaskbarRect.Right;
Result.Y := TaskbarRect.Top;

Attached patch fixes this problem and is multi-monitor aware.
Additional InformationFirst IF branch can be extended to:
---
  if (TaskbarRect.Top - TaskbarMonitor.Top = 0) and (TaskbarRect.Left - TaskbarMonitor.Left = 0) and (TaskbarRect.Right > TaskbarRect.Bottom) then
  begin
    { Taskbar is at the top of the monitor area }
    Result.X := TaskbarRect.Right;
    Result.Y := TaskbarRect.Bottom;
  end
  else if (TaskbarRect.Top - TaskbarMonitor.Top = 0) and (TaskbarRect.Left - TaskbarMonitor.Left = 0) and (TaskbarRect.Right <= TaskbarRect.Bottom) then
  begin
    { Taskbar is on the left side of the monitor area }
    Result.X := TaskbarRect.Right;
    Result.Y := TaskbarRect.Bottom;
  end
  else if (TaskbarRect.Left - TaskbarMonitor.Left = 0) then
  < ... >
---
but provided code in the patch is shortened.
TagsNo tags attached.
Fixed in Revision27584
LazTarget0.9.30
WidgetsetWin32/Win64
Attached Files
  • tray_icon_GetPosition_FIX.patch (1,435 bytes)
    Index: win32trayicon.inc
    ===================================================================
    --- win32trayicon.inc	(revision 27574)
    +++ win32trayicon.inc	(working copy)
    @@ -436,6 +436,7 @@
     var
       hWndTaskbar, hWndTray: HWND;
       TaskbarRect, TrayRect: TRect;
    +  TaskbarMonitor: TMonitor;
     begin
       Result := Point(0, 0);
     
    @@ -457,9 +458,28 @@
       Windows.GetWindowRect(hWndTray, @TrayRect);
       // OBS: Here TrayRect seams to have a wrong value, so we don't use it
     
    +  { We need this in order to "normalize" in later if statements. This is required to get right coordinates on multiple monitors }
    +  TaskbarMonitor := Screen.MonitorFromWindow(hWndTaskbar);
    +
       { Returns an aproximate position of the tray area }
    -  Result.X := TaskbarRect.Right;
    -  Result.Y := TaskbarRect.Top;
    +  if (TaskbarRect.Top - TaskbarMonitor.Top = 0) and (TaskbarRect.Left - TaskbarMonitor.Left = 0) then
    +  begin
    +    { Taskbar is at the top of the monitor area OR on the left side of the monitor area }
    +    Result.X := TaskbarRect.Right;
    +    Result.Y := TaskbarRect.Bottom;
    +  end
    +  else if (TaskbarRect.Left - TaskbarMonitor.Left = 0) then
    +  begin
    +    { Taskbar is at the bottom of the monitor area }
    +    Result.X := TaskbarRect.Right;
    +    Result.Y := TaskbarRect.Top;
    +  end
    +  else
    +  begin
    +    Result.X := TaskbarRect.Left;
    +    Result.Y := TaskbarRect.Bottom;
    +    { Taskbar is on the right side of the monitor area }
    +  end;
     end;
     
     
    

Activities

2010-10-05 14:27

 

tray_icon_GetPosition_FIX.patch (1,435 bytes)
Index: win32trayicon.inc
===================================================================
--- win32trayicon.inc	(revision 27574)
+++ win32trayicon.inc	(working copy)
@@ -436,6 +436,7 @@
 var
   hWndTaskbar, hWndTray: HWND;
   TaskbarRect, TrayRect: TRect;
+  TaskbarMonitor: TMonitor;
 begin
   Result := Point(0, 0);
 
@@ -457,9 +458,28 @@
   Windows.GetWindowRect(hWndTray, @TrayRect);
   // OBS: Here TrayRect seams to have a wrong value, so we don't use it
 
+  { We need this in order to "normalize" in later if statements. This is required to get right coordinates on multiple monitors }
+  TaskbarMonitor := Screen.MonitorFromWindow(hWndTaskbar);
+
   { Returns an aproximate position of the tray area }
-  Result.X := TaskbarRect.Right;
-  Result.Y := TaskbarRect.Top;
+  if (TaskbarRect.Top - TaskbarMonitor.Top = 0) and (TaskbarRect.Left - TaskbarMonitor.Left = 0) then
+  begin
+    { Taskbar is at the top of the monitor area OR on the left side of the monitor area }
+    Result.X := TaskbarRect.Right;
+    Result.Y := TaskbarRect.Bottom;
+  end
+  else if (TaskbarRect.Left - TaskbarMonitor.Left = 0) then
+  begin
+    { Taskbar is at the bottom of the monitor area }
+    Result.X := TaskbarRect.Right;
+    Result.Y := TaskbarRect.Top;
+  end
+  else
+  begin
+    Result.X := TaskbarRect.Left;
+    Result.Y := TaskbarRect.Bottom;
+    { Taskbar is on the right side of the monitor area }
+  end;
 end;
 
 

Felipe Monteiro de Carvalho

2010-10-05 17:36

developer   ~0041512

thanks, applied

Žilvinas Ledas

2010-10-05 20:43

reporter   ~0041520

Thanks ;)

Issue History

Date Modified Username Field Change
2010-10-05 14:27 Žilvinas Ledas New Issue
2010-10-05 14:27 Žilvinas Ledas File Added: tray_icon_GetPosition_FIX.patch
2010-10-05 14:27 Žilvinas Ledas Widgetset => Win32/Win64
2010-10-05 14:45 Vincent Snijders LazTarget => 0.9.30
2010-10-05 14:45 Vincent Snijders Assigned To => Felipe Monteiro de Carvalho
2010-10-05 14:45 Vincent Snijders Status new => assigned
2010-10-05 14:45 Vincent Snijders Target Version => 0.9.30
2010-10-05 17:36 Felipe Monteiro de Carvalho Fixed in Revision => 27584
2010-10-05 17:36 Felipe Monteiro de Carvalho Status assigned => resolved
2010-10-05 17:36 Felipe Monteiro de Carvalho Fixed in Version => 0.9.29 (SVN)
2010-10-05 17:36 Felipe Monteiro de Carvalho Resolution open => fixed
2010-10-05 17:36 Felipe Monteiro de Carvalho Note Added: 0041512
2010-10-05 20:43 Žilvinas Ledas Status resolved => closed
2010-10-05 20:43 Žilvinas Ledas Note Added: 0041520