diff --git a/lcl/interfaces/win32/win32callback.inc b/lcl/interfaces/win32/win32callback.inc index c40834797b..1c4f8dfaa1 100644 --- a/lcl/interfaces/win32/win32callback.inc +++ b/lcl/interfaces/win32/win32callback.inc @@ -323,6 +323,8 @@ type { TWindowProcHelper } TWindowProcHelper = record + private + procedure SetlWinControl(AValue: TWinControl); private // WindowProc parameters Window: HWnd; // DWord / QWord @@ -332,7 +334,7 @@ type // Other variables LMessage: TLMessage; PLMsg: PLMessage; - lWinControl: TWinControl; + FlWinControl: TWinControl; WinProcess: Boolean; NotifyUserInput: Boolean; WindowInfo: PWin32WindowInfo; @@ -399,7 +401,16 @@ type procedure UpdateLMMovePos(X, Y: Smallint); procedure UpdateUIState(CharCode: Word); function DoWindowProc: LResult; // Called from the actual WindowProc. + property lWinControl: TWinControl read FlWinControl write SetlWinControl; end; + PWindowProcHelper = ^TWindowProcHelper; + + { TWindProcNotificationReceiver } + + TWindProcNotificationReceiver = class + procedure ReceiveDestroyNotify(Sender: TObject); + end; + // Implementation of TWindowProcHelper @@ -518,6 +529,18 @@ begin {$endif} end; +procedure TWindowProcHelper.SetlWinControl(AValue: TWinControl); +begin + if FlWinControl = AValue then Exit; + if FlWinControl <> nil then + FlWinControl.RemoveHandlerOnBeforeDestruction(@TWindProcNotificationReceiver(@Self).ReceiveDestroyNotify); + + FlWinControl := AValue; + + if FlWinControl <> nil then + FlWinControl.AddHandlerOnBeforeDestruction(@TWindProcNotificationReceiver(@Self).ReceiveDestroyNotify); +end; + procedure TWindowProcHelper.CalcClipRgn(PaintRegion: HRGN); var nSize: DWORD; @@ -1955,6 +1978,14 @@ begin end; end; +{ TWindProcNotificationReceiver } + +procedure TWindProcNotificationReceiver.ReceiveDestroyNotify(Sender: TObject); +begin + assert(PWindowProcHelper(Self)^.FlWinControl = Sender, 'TWindProcNotificationReceiver.ReceiveDestroyNotify: PWindowProcHelper(Self)^.FlWinControl = Sender'); + PWindowProcHelper(Self)^.lWinControl := nil; +end; + // This is called from the actual WindowProc. function TWindowProcHelper.DoWindowProc: LResult; @@ -1975,6 +2006,7 @@ const WM_DPICHANGED = $02E0; {$ENDIF} begin + try FillChar(LMessage, SizeOf(LMessage), 0); PLMsg := @LMessage; WinProcess := True; @@ -1987,6 +2019,7 @@ begin end else begin lWinControl := WindowInfo^.WinControl; end; + if (IgnoreNextCharWindow <> 0) and ((Msg = WM_CHAR) or (Msg = WM_SYSCHAR)) then begin if IgnoreNextCharWindow = Window then @@ -2702,6 +2735,10 @@ begin else if PLMsg = @LMNotify then Result := LMNotify.Result else if PLMsg = @LMMouseEvent then Result := LMMouseEvent.Result else Result := PLMsg^.Result; + + finally + lWinControl := nil; + end; end; {------------------------------------------------------------------------------ @@ -2732,6 +2769,7 @@ begin Helper.LParam := LParam; Helper.NMHdr := PNMHdr(LParam); Result := Helper.DoWindowProc; + Helper.lWinControl := nil; end; {$ifdef MSG_DEBUG}