disable all application windows, when the AppHandle is disabled (fixes bug #788)

git-svn-id: trunk@7158 -
This commit is contained in:
vincents 2005-05-06 20:07:29 +00:00
parent 46e25c6f67
commit a9cdded52a
3 changed files with 86 additions and 58 deletions

View File

@ -788,6 +788,11 @@ Begin
Begin
If WParam <> 0 Then
LMessage.Msg := LM_SETEDITABLE;
If Window=TWin32WidgetSet(InterfaceObject).FAppHandle then
if WParam=0 then
DisableApplicationWindows(Window)
else
EnableApplicationWindows(Window);
If (lWinControl is TCustomSpinEdit) then
EnableSpinEditBuddy(Window, WParam<>0);
@ -1582,6 +1587,9 @@ end;
{
$Log$
Revision 1.207 2005/05/06 20:07:29 vincents
disable all application windows, when the AppHandle is disabled (fixes bug 788)
Revision 1.206 2005/05/05 12:57:43 micha
improve click-focus-click implies doubleclick heuristic to check for focus change within handling of mouseclick

View File

@ -87,6 +87,16 @@ function GetFileVersion(FileName: string): dword;
function AllocWindowInfo(Window: HWND): PWindowInfo;
function DisposeWindowInfo(Window: HWND): boolean;
function GetWindowInfo(Window: HWND): PWindowInfo;
function DisableWindowsProc(Window: HWND; Data: LParam): LongBool; stdcall;
procedure DisableApplicationWindows(Window: HWND);
procedure EnableApplicationWindows(Window: HWND);
type
PDisableWindowsInfo = ^TDisableWindowsInfo;
TDisableWindowsInfo = record
NewModalWindow: HWND;
DisabledWindowList: TList;
end;
var
DefaultWindowInfo: TWindowInfo;
@ -880,7 +890,7 @@ begin
Result := WS_CLIPCHILDREN or WS_CLIPSIBLINGS;
case Style of
bsSizeable, bsSizeToolWin:
Result := Result or (WS_POPUP or WS_THICKFRAME or WS_CAPTION);
Result := Result or (WS_OVERLAPPED or WS_THICKFRAME or WS_CAPTION);
bsSingle, bsToolWindow:
Result := Result or (WS_OVERLAPPED or WS_BORDER or WS_CAPTION);
bsDialog:
@ -951,6 +961,70 @@ begin
Result := @DefaultWindowInfo;
end;
{-----------------------------------------------------------------------------
Function: DisableWindowsProc
Params: Window - handle of toplevel windows to be disabled
Data - handle of current window form
Returns: Whether the enumeration should continue
Used in LM_SHOWMODAL to disable the windows of application thread
except the current form.
-----------------------------------------------------------------------------}
function DisableWindowsProc(Window: HWND; Data: LParam): LongBool; stdcall;
var
Buffer: array[0..15] of Char;
begin
Result:=true;
// Don't disable the current window form
if Window = PDisableWindowsInfo(Data)^.NewModalWindow then exit;
// Don't disable any ComboBox listboxes
if (GetClassName(Window, @Buffer, sizeof(Buffer))<sizeof(Buffer))
and (StrIComp(Buffer, 'ComboLBox')=0) then exit;
if not IsWindowVisible(Window) or not IsWindowEnabled(Window) then exit;
PDisableWindowsInfo(Data)^.DisabledWindowList.Add(Pointer(Window));
EnableWindow(Window,False);
end;
var
InDisableApplicationWindows: boolean = false;
procedure DisableApplicationWindows(Window: HWND);
var
DisableWindowsInfo: PDisableWindowsInfo;
WindowInfo: PWindowInfo;
begin
// prevent recursive calling when the AppHandle window is disabled
If InDisableApplicationWindows then exit;
InDisableApplicationWindows:=true;
New(DisableWindowsInfo);
DisableWindowsInfo^.NewModalWindow := Window;
DisableWindowsInfo^.DisabledWindowList := TList.Create;
WindowInfo := GetWindowInfo(DisableWindowsInfo^.NewModalWindow);
WindowInfo^.DisabledWindowList := DisableWindowsInfo^.DisabledWindowList;
EnumThreadWindows(GetWindowThreadProcessId(DisableWindowsInfo^.NewModalWindow, nil),
@DisableWindowsProc, LPARAM(DisableWindowsInfo));
Dispose(DisableWindowsInfo);
InDisableApplicationWindows := false;
end;
procedure EnableApplicationWindows(Window: HWND);
var
WindowInfo: PWindowInfo;
I: integer;
begin
WindowInfo := GetWindowInfo(Window);
if WindowInfo^.DisabledWindowList <> nil then
begin
for I := 0 to WindowInfo^.DisabledWindowList.Count - 1 do
EnableWindow(HWND(WindowInfo^.DisabledWindowList.Items[I]), true);
FreeAndNil(WindowInfo^.DisabledWindowList);
end;
end;
{$IFDEF ASSERT_IS_ON}
{$UNDEF ASSERT_IS_ON}
{$C-}

View File

@ -133,41 +133,6 @@ type
implementation
type
PDisableWindowsInfo = ^TDisableWindowsInfo;
TDisableWindowsInfo = record
NewModalWindow: HWND;
DisabledWindowList: TList;
end;
{-----------------------------------------------------------------------------
Function: DisableWindowsProc
Params: Window - handle of toplevel windows to be disabled
Data - handle of current window form
Returns: Whether the enumeration should continue
Used in LM_SHOWMODAL to disable the windows of application thread
except the current form.
-----------------------------------------------------------------------------}
function DisableWindowsProc(Window: HWND; Data: LParam): LongBool; stdcall;
var
Buffer: array[0..15] of Char;
begin
Result:=true;
// Don't disable the current window form
if Window = PDisableWindowsInfo(Data)^.NewModalWindow then exit;
// Don't disable any ComboBox listboxes
if (GetClassName(Window, @Buffer, sizeof(Buffer))<sizeof(Buffer))
and (StrIComp(Buffer, 'ComboLBox')=0) then exit;
if not IsWindowVisible(Window) or not IsWindowEnabled(Window) then exit;
PDisableWindowsInfo(Data)^.DisabledWindowList.Add(Pointer(Window));
EnableWindow(Window,False);
end;
{ TWin32WSScrollBox }
function TWin32WSScrollBox.CreateHandle(const AWinControl: TWinControl;
@ -267,17 +232,8 @@ begin
end;
procedure TWin32WSCustomForm.CloseModal(const ACustomForm: TCustomForm);
var
WindowInfo: PWindowInfo;
I: integer;
begin
WindowInfo := GetWindowInfo(ACustomForm.Handle);
if WindowInfo^.DisabledWindowList <> nil then
begin
for I := 0 to WindowInfo^.DisabledWindowList.Count - 1 do
EnableWindow(HWND(WindowInfo^.DisabledWindowList.Items[I]), true);
FreeAndNil(WindowInfo^.DisabledWindowList);
end;
EnableApplicationWindows(ACustomForm.Handle);
end;
procedure TWin32WSCustomForm.SetBorderIcons(const AForm: TCustomForm;
@ -351,19 +307,9 @@ begin
end;
procedure TWin32WSCustomForm.ShowModal(const ACustomForm: TCustomForm);
var
DisableWindowsInfo: PDisableWindowsInfo;
WindowInfo: PWindowInfo;
begin
New(DisableWindowsInfo);
DisableWindowsInfo^.NewModalWindow := ACustomForm.Handle;
DisableWindowsInfo^.DisabledWindowList := TList.Create;
WindowInfo := GetWindowInfo(DisableWindowsInfo^.NewModalWindow);
WindowInfo^.DisabledWindowList := DisableWindowsInfo^.DisabledWindowList;
EnumThreadWindows(GetWindowThreadProcessId(DisableWindowsInfo^.NewModalWindow, nil),
@DisableWindowsProc, LPARAM(DisableWindowsInfo));
ShowWindow(DisableWindowsInfo^.NewModalWindow, SW_SHOW);
Dispose(DisableWindowsInfo);
DisableApplicationWindows(ACustomForm.Handle);
ShowWindow(ACustomForm.Handle, SW_SHOW);
end;
{ TWin32WSHintWindow }