代码之家  ›  专栏  ›  技术社区  ›  Tom A RRUZ

我能探测到一扇窗户是否部分被隐藏了吗?

  •  4
  • Tom A RRUZ  · 技术社区  · 14 年前

    是否有可能检测到矿井外程序的窗口是1)完全可见、2)部分隐藏还是3)完全隐藏?如果窗口(基于检索到的句柄)不可见,我希望能够告诉我的应用程序不要做任何事情。我不在乎窗口是否有焦点,Z顺序是什么,或者其他什么,我只是对窗口显示的内容感兴趣。如果我需要别的东西来买这个,我很好,但有可能吗?谢谢。

    2 回复  |  直到 14 年前
        1
  •  6
  •   Rob Kennedy    14 年前

    陈瑞蒙写道 an article about this 几年前。

    要点是你可以用 GetClipBox 告诉您窗口的设备上下文具有哪种剪切区域。空区域表示窗口完全被遮挡,复杂区域表示窗口部分被遮挡。如果是一个简单的(矩形)区域,那么可见性取决于可见矩形是否与窗口边界重合。

    一个DC一次只能由一个线程使用。因此,不应为非您的应用程序获取窗口的DC。否则,您可能会遇到另一个应用程序“不知道您在做什么”试图在您仍在使用它检查剪切区域时使用它的DC的情况。用它来判断 你自己 不过是窗户。

        2
  •  4
  •   Francesca    14 年前

    下面是我用来确定表单是否对用户实际可见(甚至只是部分可见)的解决方案。您可以很容易地适应您的确切用例。

    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;