Могу ли я определить, частично ли скрыто окно? - PullRequest
4 голосов
/ 01 июля 2010

Можно ли определить, является ли окно для программы вне моей программы 1) полностью видимым, 2) частично скрытым или 3) полностью скрытым?Я хочу, чтобы приложение могло ничего не делать, если окно (на основе извлеченного дескриптора) не видно.Мне все равно, имеет ли окно фокус или нет, каков порядок z или что-то еще, мне просто интересно, сколько окна показывает.Если мне нужно что-то еще, чтобы получить это, я в порядке, но возможно ли это?Спасибо.

Ответы [ 2 ]

6 голосов
/ 01 июля 2010

Рэймонд Чен написал статью об этом несколько лет назад.

Суть в том, что вы можете использовать GetClipBox, чтобы сказать вам, какого родаобласти отсечения контекст устройства окна.Нулевая область означает, что окно полностью скрыто, а сложная область означает, что оно частично закрыто.Если это простая (прямоугольная) область, то видимость зависит от того, совпадает ли видимый прямоугольник с границами окна.

Одновременно DC может использовать только один поток.Следовательно, вам не следует приобретать DC окна для приложения, которое не принадлежит вам.В противном случае вы можете столкнуться с ситуацией, когда другое приложение - не подозревая о том, что вы делаете, - пытается использовать свой DC, в то время как вы все еще используете его для проверки области отсечения.Это должно быть совершенно безопасно, чтобы использовать его для вынесения суждений о ваших окнах.

4 голосов
/ 01 июля 2010

Вот решение, которое я использовал, чтобы определить, действительно ли форма видима (хотя бы частично) пользователю. Вы можете легко адаптироваться к вашему конкретному случаю использования.

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...