delphi 是否可以检测窗口是否部分隐藏?

tpxzln5u  于 2022-11-23  发布在  其他
关注(0)|答案(2)|浏览(228)

是否有可能检测到我的应用程序以外的程序的窗口是1)完全可见、2)部分隐藏还是3)完全隐藏?我希望能够告诉我的应用程序,如果窗口(基于检索到的句柄)是不可见的。我不关心窗口是否有焦点、z顺序是什么,或者其他任何事情,我只想知道窗口显示了多少。如果我需要其他东西来得到这个,我很好,但是这可能吗?谢谢。

isr3a4wc

isr3a4wc1#

Raymond Chen几年前写了一本an article about this
其要点是,你可以使用GetClipBox来告诉你一个窗口的设备上下文有什么样的裁剪区域。空区域意味着窗口被完全遮挡,而复杂区域意味着它被部分遮挡。如果它是一个简单的(矩形)区域,那么可见性取决于可见的矩形是否与窗口的边界重合。
一个DC一次只能被一个线程使用。因此,你不应该为一个不属于你的应用程序获取一个窗口的DC。否则,你可能会遇到这样的情况:当你还在使用它来检查剪辑区域时,另一个应用程序--不知道你在做什么--试图使用它的DC。使用它来判断你自己的窗口应该是非常安全的。我也是。

8yoxcaq7

8yoxcaq72#

下面是我用来确定表单是否对用户实际可见(即使只是部分可见)的解决方案。

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;

相关问题