View Issue Details

IDProjectCategoryView StatusLast Update
0031738LazarusWidgetsetpublic2020-04-01 18:44
ReporterAnton Kavalenka Assigned ToJuha Manninen  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Platformi386OSLinux 
Product Version1.9 (SVN) 
Summary0031738: customdrawn: Patch to implement EnumDisplayMonitors and GetMonitorInfo for CD_X11 and CD_win32
DescriptionPatch provided to at least prevent crash on access to non-existent TMonitor instance.
TagsNo tags attached.
Fixed in Revisionr62841
LazTarget-
WidgetsetCustomDrawn
Attached Files

Relationships

related to 0036574 closedJuha Manninen Patches [patch] CustomDrawn: Fixed crash on startup 

Activities

Anton Kavalenka

2017-04-30 19:09

reporter  

customdrawn.diff (5,896 bytes)   
Index: customdrawnobject_x11.inc
===================================================================
--- customdrawnobject_x11.inc	(revision 54782)
+++ customdrawnobject_x11.inc	(working copy)
@@ -674,6 +674,7 @@
   end
   else begin
     lTimer := XTimerListHead;
+    if not Assigned(lTimer) then exit;
     lTimeoutInterval:= trunc((lTimer.Expires-now)*KMsToDateTime);
     if lTimeoutInterval < 0 then lTimeoutInterval:= 0; // we missed a timer: a quick look to
     // pending messages then go process the timer
Index: customdrawnwinapi_win.inc
===================================================================
--- customdrawnwinapi_win.inc	(revision 54782)
+++ customdrawnwinapi_win.inc	(working copy)
@@ -1245,11 +1245,12 @@
 begin
   Result := Integer(Windows.EndPaint(Handle, @PS));
 end;
+*)
 
-function TWin32WidgetSet.EnumDisplayMonitors(hdc: HDC; lprcClip: PRect; lpfnEnum: MonitorEnumProc; dwData: LPARAM): LongBool;
+function TCDWidgetSet.EnumDisplayMonitors(hdc: HDC; lprcClip: PRect; lpfnEnum: MonitorEnumProc; dwData: LPARAM): LongBool;
 begin
   Result := MultiMon.EnumDisplayMonitors(hdc, lprcClip, lpfnEnum, dwData);
-end;*)
+end;
 
 type
   TProcRedirRec = record
@@ -1918,7 +1919,7 @@
   Result := Windows.GetMapMode(DC);
 end;
 
-function TWin32WidgetSet.GetMonitorInfo(hMonitor: HMONITOR; lpmi: LCLType.PMonitorInfo): Boolean;
+function TCDWidgetSet.GetMonitorInfo(hMonitor: HMONITOR; lpmi: LCLType.PMonitorInfo): Boolean;
 {$IFDEF WindowsUnicodeSupport}
 var
   LocalInfo: TMonitorInfoExW;
Index: customdrawnwinapi_x11.inc
===================================================================
--- customdrawnwinapi_x11.inc	(revision 54782)
+++ customdrawnwinapi_x11.inc	(working copy)
@@ -1665,23 +1665,32 @@
   ACritSec:=System.PRTLCriticalSection(CritSection);
   System.EnterCriticalsection(ACritSec^);
 end;
+*)
 
-function TQtWidgetSet.EnumDisplayMonitors(hdc: HDC; lprcClip: PRect;
+function TCDWidgetSet.EnumDisplayMonitors(hdc: HDC; lprcClip: PRect;
   lpfnEnum: MonitorEnumProc; dwData: LPARAM): LongBool;
 var
-  i: integer;
-  Desktop: QDesktopWidgetH;
+  cnt,i:integer;
+  pscr:PScreen;
+  r:TRect;
 begin
-  Desktop := QApplication_desktop();
-  Result := True;
-  for i := 0 to QDesktopWidget_numScreens(Desktop) - 1 do
+  Result:=false;
+  if not Assigned(lpfnEnum) then exit;
+  cnt:=XScreenCount(fDisplay);
+  for i:=0 to cnt-1 do
   begin
-    Result := Result and lpfnEnum(i + 1, 0, nil, dwData);
-    if not Result then break;
+  	pscr:=XScreenOfDIsplay(fDisplay,i);
+    if not Assigned(pscr) then exit;
+    r.Top:=0;
+    r.Left:=0;
+    r.Right:=pscr^.width;
+    r.Bottom:=pscr^.height;
+    lpfnEnum(hMonitor(pscr),0,@r,dwData);
   end;
+	Result:=(cnt>0);
 end;
 
-
+(*
 function CharsetToQtCharSet(const ALCLCharset: Byte): QFontDatabaseWritingSystem;
 begin
   Result := QFontDatabaseAny;
@@ -2911,25 +2920,22 @@
   else
     Result := 0;
 end;
+*)
 
-function TQtWidgetSet.GetMonitorInfo(Monitor: HMONITOR; lpmi: PMonitorInfo): Boolean;
+function TCDWidgetSet.GetMonitorInfo(Monitor: HMONITOR; lpmi: PMonitorInfo): Boolean;
 var
-  Desktop: QDesktopWidgetH;
+  pscr:PScreen absolute Monitor;
 begin
-  Result := (lpmi <> nil) and (lpmi^.cbSize >= SizeOf(TMonitorInfo)) or (Monitor = 0);
-  if not Result then Exit;
-  Desktop := QApplication_desktop();
-  Dec(Monitor);
-  Result := (Monitor >= 0) and (Monitor < PtrUInt(QDesktopWidget_numScreens(Desktop)));
-  if not Result then Exit;
-  QDesktopWidget_screenGeometry(Desktop, @lpmi^.rcMonitor, Monitor);
-  QDesktopWidget_availableGeometry(Desktop, @lpmi^.rcWork, Monitor);
-  if PtrUInt(QDesktopWidget_primaryScreen(Desktop)) = Monitor then
-    lpmi^.dwFlags := MONITORINFOF_PRIMARY
-  else
-    lpmi^.dwFlags := 0;
+  Result := false;
+  if (lpmi = nil) or (lpmi^.cbSize < SizeOf(TMonitorInfo)) or (Monitor = 0) then exit;
+
+  lpmi^.rcMonitor:=REct(0,0,pscr^.width,pscr^.height);
+  lpmi^.rcWork:=lpmi^.rcMonitor;
+  lpmi^.dwFlags := MONITORINFOF_PRIMARY;
+  Result:=true;
 end;
 
+(*
 {------------------------------------------------------------------------------
   Method:  TQtWidgetSet.GetDeviceSize
   Params:  none
Index: customdrawnwinapih.inc
===================================================================
--- customdrawnwinapih.inc	(revision 54782)
+++ customdrawnwinapih.inc	(working copy)
@@ -83,7 +83,7 @@
 function EnableWindow(hWnd: HWND; bEnable: Boolean): Boolean; override;
 function EndPaint(Handle: hwnd; var PS: TPaintStruct): Integer; override;*)
 procedure EnterCriticalSection(var CritSection: TCriticalSection); override;
-//function EnumDisplayMonitors(hdc: HDC; lprcClip: PRect; lpfnEnum: MonitorEnumProc; dwData: LPARAM): LongBool; override;
+function EnumDisplayMonitors(hdc: HDC; lprcClip: PRect; lpfnEnum: MonitorEnumProc; dwData: LPARAM): LongBool; override;
 function EnumFontFamiliesEx(DC: HDC; lpLogFont: PLogFont; Callback: FontEnumExProc; Lparam: LParam; Flags: dword): longint; override;
 //function ExcludeClipRect(dc: hdc; Left, Top, Right, Bottom : Integer) : Integer; override;
 function ExtCreatePen(dwPenStyle, dwWidth: DWord; const lplb: TLogBrush; dwStyleCount: DWord; lpStyle: PDWord): HPEN; override;
@@ -118,9 +118,9 @@
 function GetFocus: HWND; override;
 (*function GetForegroundWindow: HWND; override;*)
 function GetKeyState(nVirtKey: Integer): Smallint; override;
-(*function GetMapMode(DC: HDC): Integer; override;
+(*function GetMapMode(DC: HDC): Integer; override;*)
 function GetMonitorInfo(Monitor: HMONITOR; lpmi: PMonitorInfo): Boolean; override;
-function GetObject(GDIObj: HGDIOBJ; BufSize: Integer; Buf: Pointer): Integer; override;*)
+(*function GetObject(GDIObj: HGDIOBJ; BufSize: Integer; Buf: Pointer): Integer; override;*)
 function GetParent(Handle : HWND): HWND; override;
 function GetProp(Handle : hwnd; Str : PChar): Pointer; override;
 function GetRgnBox(RGN : HRGN; lpRect : PRect) : Longint; override;
customdrawn.diff (5,896 bytes)   

Juha Manninen

2017-10-09 18:28

developer   ~0103295

Felipe, can you please look at the patch.

Anton Kavalenka

2020-01-31 08:13

reporter   ~0120814

Is not this a clone of 0036574 ?

Anton Kavalenka

2020-02-02 08:34

reporter   ~0120845

New patch
customdrawn.patch (5,372 bytes)   
Index: lcl/interfaces/customdrawn/customdrawnobject_x11.inc
===================================================================
--- lcl/interfaces/customdrawn/customdrawnobject_x11.inc	(revision 62605)
+++ lcl/interfaces/customdrawn/customdrawnobject_x11.inc	(working copy)
@@ -674,6 +674,7 @@
   end
   else begin
     lTimer := XTimerListHead;
+    if not Assigned(lTimer) then exit;
     lTimeoutInterval:= trunc((lTimer.Expires-now)*KMsToDateTime);
     if lTimeoutInterval < 0 then lTimeoutInterval:= 0; // we missed a timer: a quick look to
     // pending messages then go process the timer
Index: lcl/interfaces/customdrawn/customdrawnwinapi_win.inc
===================================================================
--- lcl/interfaces/customdrawn/customdrawnwinapi_win.inc	(revision 62605)
+++ lcl/interfaces/customdrawn/customdrawnwinapi_win.inc	(working copy)
@@ -1243,11 +1243,12 @@
 begin
   Result := Integer(Windows.EndPaint(Handle, @PS));
 end;
+*)
 
-function TWin32WidgetSet.EnumDisplayMonitors(hdc: HDC; lprcClip: PRect; lpfnEnum: MonitorEnumProc; dwData: LPARAM): LongBool;
+function TCDWidgetSet.EnumDisplayMonitors(hdc: HDC; lprcClip: PRect; lpfnEnum: MonitorEnumProc; dwData: LPARAM): LongBool;
 begin
   Result := MultiMon.EnumDisplayMonitors(hdc, lprcClip, lpfnEnum, dwData);
-end;*)
+end;
 
 type
   TProcRedirRec = record
@@ -1921,7 +1922,7 @@
   Result := Windows.GetMapMode(DC);
 end;
 
-function TWin32WidgetSet.GetMonitorInfo(hMonitor: HMONITOR; lpmi: LCLType.PMonitorInfo): Boolean;
+function TCDWidgetSet.GetMonitorInfo(hMonitor: HMONITOR; lpmi: LCLType.PMonitorInfo): Boolean;
 {$IFDEF WindowsUnicodeSupport}
 var
   LocalInfo: TMonitorInfoExW;
Index: lcl/interfaces/customdrawn/customdrawnwinapi_x11.inc
===================================================================
--- lcl/interfaces/customdrawn/customdrawnwinapi_x11.inc	(revision 62605)
+++ lcl/interfaces/customdrawn/customdrawnwinapi_x11.inc	(working copy)
@@ -1665,23 +1665,32 @@
   ACritSec:=System.PRTLCriticalSection(CritSection);
   System.EnterCriticalsection(ACritSec^);
 end;
+*)
 
-function TQtWidgetSet.EnumDisplayMonitors(hdc: HDC; lprcClip: PRect;
+function TCDWidgetSet.EnumDisplayMonitors(hdc: HDC; lprcClip: PRect;
   lpfnEnum: MonitorEnumProc; dwData: LPARAM): LongBool;
 var
-  i: integer;
-  Desktop: QDesktopWidgetH;
+  cnt,i:integer;
+  pscr:PScreen;
+  r:TRect;
 begin
-  Desktop := QApplication_desktop();
-  Result := True;
-  for i := 0 to QDesktopWidget_numScreens(Desktop) - 1 do
+  Result:=false;
+  if not Assigned(lpfnEnum) then exit;
+  cnt:=XScreenCount(fDisplay);
+  for i:=0 to cnt-1 do
   begin
-    Result := Result and lpfnEnum(i + 1, 0, nil, dwData);
-    if not Result then break;
+  	pscr:=XScreenOfDIsplay(fDisplay,i);
+    if not Assigned(pscr) then exit;
+    r.Top:=0;
+    r.Left:=0;
+    r.Right:=pscr^.width;
+    r.Bottom:=pscr^.height;
+    lpfnEnum(hMonitor(pscr),0,@r,dwData);
   end;
+	Result:=(cnt>0);
 end;
 
-
+(*
 function CharsetToQtCharSet(const ALCLCharset: Byte): QFontDatabaseWritingSystem;
 begin
   Result := QFontDatabaseAny;
@@ -2911,25 +2920,22 @@
   else
     Result := 0;
 end;
+*)
 
-function TQtWidgetSet.GetMonitorInfo(Monitor: HMONITOR; lpmi: PMonitorInfo): Boolean;
+function TCDWidgetSet.GetMonitorInfo(Monitor: HMONITOR; lpmi: PMonitorInfo): Boolean;
 var
-  Desktop: QDesktopWidgetH;
+  pscr:PScreen absolute Monitor;
 begin
-  Result := (lpmi <> nil) and (lpmi^.cbSize >= SizeOf(TMonitorInfo)) or (Monitor = 0);
-  if not Result then Exit;
-  Desktop := QApplication_desktop();
-  Dec(Monitor);
-  Result := (Monitor >= 0) and (Monitor < PtrUInt(QDesktopWidget_numScreens(Desktop)));
-  if not Result then Exit;
-  QDesktopWidget_screenGeometry(Desktop, @lpmi^.rcMonitor, Monitor);
-  QDesktopWidget_availableGeometry(Desktop, @lpmi^.rcWork, Monitor);
-  if PtrUInt(QDesktopWidget_primaryScreen(Desktop)) = Monitor then
-    lpmi^.dwFlags := MONITORINFOF_PRIMARY
-  else
-    lpmi^.dwFlags := 0;
+  Result := false;
+  if (lpmi = nil) or (lpmi^.cbSize < SizeOf(TMonitorInfo)) or (Monitor = 0) then exit;
+
+  lpmi^.rcMonitor:=REct(0,0,pscr^.width,pscr^.height);
+  lpmi^.rcWork:=lpmi^.rcMonitor;
+  lpmi^.dwFlags := MONITORINFOF_PRIMARY;
+  Result:=true;
 end;
 
+(*
 {------------------------------------------------------------------------------
   Method:  TQtWidgetSet.GetDeviceSize
   Params:  none
Index: lcl/interfaces/customdrawn/customdrawnwinapih.inc
===================================================================
--- lcl/interfaces/customdrawn/customdrawnwinapih.inc	(revision 62605)
+++ lcl/interfaces/customdrawn/customdrawnwinapih.inc	(working copy)
@@ -118,9 +118,9 @@
 function GetFocus: HWND; override;
 (*function GetForegroundWindow: HWND; override;*)
 function GetKeyState(nVirtKey: Integer): Smallint; override;
-//function GetMapMode(DC: HDC): Integer; override;
+(*function GetMapMode(DC: HDC): Integer; override;*)
 function GetMonitorInfo(Monitor: HMONITOR; lpmi: PMonitorInfo): Boolean; override;
-//function GetObject(GDIObj: HGDIOBJ; BufSize: Integer; Buf: Pointer): Integer; override;
+(*function GetObject(GDIObj: HGDIOBJ; BufSize: Integer; Buf: Pointer): Integer; override;*)
 function GetParent(Handle : HWND): HWND; override;
 function GetProp(Handle : hwnd; Str : PChar): Pointer; override;
 function GetRgnBox(RGN : HRGN; lpRect : PRect) : Longint; override;
customdrawn.patch (5,372 bytes)   

Juha Manninen

2020-04-01 12:45

developer   ~0121828

I applied this as Felipe is not active right now.
Thanks.

Issue History

Date Modified Username Field Change
2017-04-30 19:09 Anton Kavalenka New Issue
2017-04-30 19:09 Anton Kavalenka File Added: customdrawn.diff
2017-10-09 18:27 Juha Manninen Assigned To => Felipe Monteiro de Carvalho
2017-10-09 18:27 Juha Manninen Status new => assigned
2017-10-09 18:28 Juha Manninen Note Added: 0103295
2020-01-31 08:13 Anton Kavalenka Note Added: 0120814
2020-02-02 08:34 Anton Kavalenka File Added: customdrawn.patch
2020-02-02 08:34 Anton Kavalenka Note Added: 0120845
2020-04-01 06:26 Juha Manninen Relationship added related to 0036574
2020-04-01 06:30 Juha Manninen Assigned To Felipe Monteiro de Carvalho => Juha Manninen
2020-04-01 12:45 Juha Manninen Status assigned => resolved
2020-04-01 12:45 Juha Manninen Resolution open => fixed
2020-04-01 12:45 Juha Manninen Fixed in Revision => r62841
2020-04-01 12:45 Juha Manninen LazTarget => -
2020-04-01 12:45 Juha Manninen Widgetset CustomDrawn => CustomDrawn
2020-04-01 12:45 Juha Manninen Note Added: 0121828
2020-04-01 18:44 Anton Kavalenka Status resolved => closed