Can I detect if a window is partly hidden?

给你一囗甜甜゛ 提交于 2019-12-07 11:33:53

问题


Is it possible to detect if a window for a program outside mine is 1) completely visible, 2) partly hidden, or 3) completely hidden? I want to be able to tell my application not to do anything if a window (based on a retrieved handle) isn't visible. I don't care if the window has focus or not,what the z order is, or anything else, I'm just interested in how much of the window shows. If I need something else to get this, I'm fine, but is it possible? Thanks.


回答1:


Raymond Chen wrote an article about this a few years ago.

The gist of it is that you can use GetClipBox to tell you what kind of clipping region a window's device context has. A null region means the window is totally obscured, and a complex region means it's partially obscured. If it's a simple (rectangular) region, then visibility depends on whether the visible rectangle coincides with the bounds of the window.

A DC can only be used by one thread at a time. Therefore, you should not acquire the DC of a window for an application that isn't yours. Otherwise, you may encounter a situation where the other application — unaware of what you're doing — attempts to use its DC while you're still using it to inspect the clipping region. It should be perfectly safe to use it to make judgments about your own windows, though.




回答2:


Here's the solution I used to determine if a form is actually visible (even only partially) to the user. You can easily adapt to your exact use case.

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;


来源:https://stackoverflow.com/questions/3154214/can-i-detect-if-a-window-is-partly-hidden

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!