{----------------------------------------------------------}
function IsMyFormCovered(const MyForm: TForm): Boolean;
var
MyRect: TRect;
MyRgn, TempRgn: HRGN;
RType: Integer;
hw: HWND;
begin
MyRect := MyForm.BoundsRect; // screen coordinates
MyRgn := CreateRectRgnIndirect(MyRect); // MyForm not overlapped region
hw := GetTopWindow(0); // currently examined topwindow
RType := SIMPLEREGION; // MyRgn type
// From topmost window downto MyForm, build the not overlapped portion of MyForm
while (hw<>0) and (hw <> MyForm.handle) and (RType <> NULLREGION) do
begin
// nothing to do if hidden window
if IsWindowVisible(hw) then
begin
GetWindowRect(hw, MyRect);
TempRgn := CreateRectRgnIndirect(MyRect);// currently examined window region
RType := CombineRgn(MyRgn, MyRgn, TempRgn, RGN_DIFF); // diff intersect
DeleteObject( TempRgn );
end; {if}
if RType <> NULLREGION then // there's a remaining portion
hw := GetNextWindow(hw, GW_HWNDNEXT);
end; {while}
DeleteObject(MyRgn);
Result := RType = NULLREGION;
end;
function IsMyFormVisible(const MyForm : TForm): Boolean;
begin
Result:= MyForm.visible and
isWindowVisible(MyForm.Handle) and
not IsMyFormCovered(MyForm);
end;
function IsMyFormCovered(const MyForm: TForm): Boolean;
var
RectForm, RectForeground: TRect;
hWndForeground: HWND;
begin
GetWindowRect(MyForm.Handle, RectForm);
hWndForeground := GetForegroundWindow;
if (hWndForeground <> MyForm.Handle) and (hWndForeground <> 0) then
begin
GetWindowRect(hWndForeground, RectForeground);
if (RectForm.Left < RectForeground.Right) and
(RectForm.Right > RectForeground.Left) and
(RectForm.Top < RectForeground.Bottom) and
(RectForm.Bottom > RectForeground.Top) then
Result := True
else
Result := False;
end else
Result := False;
end;
3条答案
按热度按时间cyvaqqii1#
几年前,我在一个表单上遇到了同样的问题:我正在寻找一种方法来确定一个表单是否对用户实际可见(即使只是部分可见)。
特别是当它应该是可见的,显示是真的,但窗口实际上完全在另一个后面。
下面是代码,它可以适用于WinControl...
hgtggwj02#
您可以将代码附加到OnPaint事件吗?这是非常经常调用,我认为只有当控件实际上要被绘制时才调用(例如,以您的意思可见)。
eqqqjvef3#
弗朗西丝卡的公认答案适用于大多数情况。但是,如果窗体移动到屏幕边界之外,则此方法无效。
以下是更好的答案: