diff --git a/lcl/interfaces/win32/win32callback.inc b/lcl/interfaces/win32/win32callback.inc index 869a79627d..3ace505dbe 100644 --- a/lcl/interfaces/win32/win32callback.inc +++ b/lcl/interfaces/win32/win32callback.inc @@ -209,6 +209,18 @@ begin Result := Result or (Assigned(AWinControl) and ([csParentBackground, csOpaque] * AWinControl.ControlStyle = [csParentBackground])); end; +procedure DisposeComboEditWindowInfo(ComboBox: TCustomComboBox); +var + Buddy: HWND; + Info: TComboboxInfo; +begin + Info.cbSize := SizeOf(Info); + Win32Extra.GetComboBoxInfo(Combobox.Handle, @Info); + Buddy := Info.hwndItem; + if (Buddy <> Info.hwndCombo) and (Buddy <> 0) then + DisposeWindowInfo(Buddy); +end; + {------------------------------------------------------------------------------ Function: WindowProc Params: Window - The window that receives a message @@ -605,21 +617,6 @@ var end; end; - procedure DisposeComboEditWindowInfo(ComboBox: TCustomComboBox); - var - Buddy: HWND; - Info: TComboboxInfo; - begin - Info.cbSize := SizeOf(Info); - Win32Extra.GetComboBoxInfo(Combobox.Handle, @Info); - if Info.hwndItem <> Info.hwndCombo then - Buddy := Info.hwndItem - else - Buddy := 0; - if Buddy <> 0 then - DisposeWindowInfo(Buddy); - end; - procedure HandleScrollMessage(LMsg: integer); var ScrollInfo: TScrollInfo; @@ -1037,7 +1034,8 @@ begin WindowInfo^.IMEComposed:=True; // filter messages we want to pass on to LCL - if (Msg <> WM_KILLFOCUS) and (Msg <> WM_SETFOCUS) and (Msg <> WM_NCDESTROY) + if (Msg <> WM_KILLFOCUS) and (Msg <> WM_SETFOCUS) + {$ifndef RedirectDestroyMessages}and (Msg <> WM_NCDESTROY){$endif} and not ((Msg >= WM_CUT) and (Msg <= WM_CLEAR)) and ((Msg < WM_KEYFIRST) or (Msg > WM_KEYLAST)) and ((Msg < WM_MOUSEFIRST) or (Msg > WM_MOUSELAST)) then @@ -1373,6 +1371,7 @@ begin begin LMessage.Msg := LM_CUT; end; + {$ifndef RedirectDestroyMessages} WM_DESTROY: begin if CurrentWindow=Window then @@ -1383,6 +1382,7 @@ begin Windows.DestroyWindow(WindowInfo^.Overlay); LMessage.Msg := LM_DESTROY; end; + {$endif} WM_DESTROYCLIPBOARD: begin if assigned(OnClipBoardRequest) then begin @@ -2449,6 +2449,7 @@ begin if MouseDownFocusStatus = mfFocusSense then MouseDownFocusStatus := mfNone; end; + {$ifndef RedirectDestroyMessages} WM_NCDESTROY: begin // free our own data associated with window @@ -2456,6 +2457,7 @@ begin WindowInfo := nil; EnumProps(Window, @PropEnumProc); end; + {$endif} end; end; @@ -2648,6 +2650,57 @@ begin end; end; +{$ifdef RedirectDestroyMessages} +{------------------------------------------------------------------------------ + Function: DestroyWindowProc + Params: Window - The window that receives a message + Msg - The message received + WParam - Word parameter + LParam - Long-integer parameter + Returns: 0 if Msg is handled; non-zero long-integer result otherwise + + Handles messages after handle is destroyed + ------------------------------------------------------------------------------} + +function DestroyWindowProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam; + LParam: Windows.LParam): LResult; stdcall; +var + LMessage: TLMessage; + WindowInfo: PWin32WindowInfo; + lWinControl: TWinControl; +begin + CallDefaultWindowProc(Window, Msg, WParam, LParam); + case Msg of + WM_DESTROY: + begin + WindowInfo := GetWin32WindowInfo(Window); + if WindowInfo^.isChildEdit then + lWinControl := WindowInfo^.AWinControl + else + lWinControl := WindowInfo^.WinControl; + if CurrentWindow = Window then + CurrentWindow := 0; + if lWinControl is TCustomComboBox then + DisposeComboEditWindowInfo(TCustomComboBox(lWinControl)); + if WindowInfo^.Overlay<>HWND(nil) then + Windows.DestroyWindow(WindowInfo^.Overlay); + if lWinControl <> nil then + begin + FillChar(LMessage, SizeOf(LMessage), 0); + LMessage.Msg := LM_DESTROY; + DeliverMessage(lWinControl, LMessage); + end; + end; + WM_NCDESTROY: + begin + // free our own data associated with window + DisposeWindowInfo(Window); + EnumProps(Window, @PropEnumProc); + end; + end; +end; +{$endif} + {------------------------------------------------------------------------------ Procedure: TimerCallBackProc Params: window_hnd - handle of window for timer message, not set in this implementation diff --git a/lcl/interfaces/win32/win32defines.inc b/lcl/interfaces/win32/win32defines.inc index 3b7d486fe0..738f52b2c6 100644 --- a/lcl/interfaces/win32/win32defines.inc +++ b/lcl/interfaces/win32/win32defines.inc @@ -41,4 +41,5 @@ {$ENDIF} {$ENDIF} -{$DEFINE UseVistaDialogs} \ No newline at end of file +{$DEFINE UseVistaDialogs} +{.$DEFINE RedirectDestroyMessages} diff --git a/lcl/interfaces/win32/win32int.pp b/lcl/interfaces/win32/win32int.pp index a1cd6601b3..219d76300d 100644 --- a/lcl/interfaces/win32/win32int.pp +++ b/lcl/interfaces/win32/win32int.pp @@ -237,6 +237,10 @@ function WindowProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam; LParam: Windows.LParam): LResult; stdcall; function CallDefaultWindowProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam; LParam: Windows.LParam): LResult; +{$ifdef RedirectDestroyMessages} +function DestroyWindowProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam; + LParam: Windows.LParam): LResult; stdcall; +{$endif} implementation diff --git a/lcl/interfaces/win32/win32object.inc b/lcl/interfaces/win32/win32object.inc index 9bc2964229..9ede445a60 100644 --- a/lcl/interfaces/win32/win32object.inc +++ b/lcl/interfaces/win32/win32object.inc @@ -82,7 +82,12 @@ begin DeleteObject(FDotsPatternBitmap); if FAppHandle <> 0 then + begin + {$ifdef RedirectDestroyMessages} + SetWindowLong(FAppHandle, GWL_WNDPROC, PtrInt(@DestroyWindowProc)); + {$endif} DestroyWindow(FAppHandle); + end; if UnicodeEnabledOS then begin diff --git a/lcl/interfaces/win32/win32wscontrols.pp b/lcl/interfaces/win32/win32wscontrols.pp index 9a79f6680d..9b451defde 100644 --- a/lcl/interfaces/win32/win32wscontrols.pp +++ b/lcl/interfaces/win32/win32wscontrols.pp @@ -574,6 +574,9 @@ var Handle: HWND; begin Handle := AWinControl.Handle; + {$ifdef RedirectDestroyMessages} + SetWindowLong(Handle, GWL_WNDPROC, PtrInt(@DestroyWindowProc)); + {$endif} DestroyWindow(Handle); end;