Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.04.18;
Скачать: [xml.tar.bz2];

Вниз

Перекрыто ли окно   Найти похожие ветки 

 
krush   (2004-03-29 12:48) [0]

Уважаемые Мастера, как можно узнать перекрыто ли мое окно другими?


 
Юрий Зотов ©   (2004-03-29 13:46) [1]

EnumWindows
В callback"е - GetWindowRect + IntersectRec + WindowFromPoint


 
Pikachu ©   (2004-03-29 19:59) [2]

Юрий если теб не затруднит по подробней раскажи об этом...


 
pasha_golub ©   (2004-03-29 20:11) [3]


function EnumTopWindowsProc (WindowHandle : HWND; Data : Pointer) : BOOL; stdcall;
begin
{Вот тут колдуем с Юрий Зотов ©   (29.03.04 13:46) [1], а именно с GetWindowRect + IntersectRec + WindowFromPoint}
 Result := true;
end;

вызываем вот так

EnumWindows(@EnumTopWindowsProc,0);


 
Юрий Зотов ©   (2004-03-29 21:17) [4]

Наверняка есть ошибки, но набросок примерно такой

type
 PWnd = ^HWND;

function GetTopParent(Wnd: HWND): HWND;
begin
 repeat
   Result := GetParent(Wnd);
   if Result <> 0 then Wnd := Result
 until Result = 0;
 Result := Wnd
end;

function EnumWindowProc(Wnd: HWND; TargetWnd: PWnd): BOOL; stdcall;
// To stop enumeration, it must return FALSE.
var
 Rct, TargetRct, OverRct: TRect;
 P: TPoint;
begin
 GetWindowRect(Wnd, Rct);
 GetWindowRect(TargetWnd^, TargetRct);
 Result := not IntersectRect(OverRct, Rct, TargetRct);
 if not Result then
 begin
   P.X := (OverRct.Left + OverRct.Right) div 2;
   P.Y := (OverRct.Top + OverRct.Bottom) div 2;
   Wnd := GetTopParent(WindowFromPoint(P));
   Result := Wnd <> TargetWnd^;
   if not Result then TargetWnd^ := Wnd
 end
end;

function IsWindowOverlapped(Wnd: HWND): boolean;
var
 OldWnd: HWND;
begin
 OldWnd := Wnd;
 EnumWindows(@EnumWindowProc, LParam(@OldWnd));
 Result := OldWnd <> Wnd
end;


 
Pikachu ©   (2004-03-29 21:45) [5]

Юра вопрос был как можно узнать перекрыто ли мое окно другими?
в твоём коде 3 функции  не могу понять как это всё работает если мож прокоминтируй..


 
Игорь Шевченко ©   (2004-03-29 21:49) [6]

Может, пригодится:
Я определял, какой процент окна (TfMain) виден на экране (в том числе окно может быть заслонено другими окнами или не полностью помещаться на экране)

unit main;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 ExtCtrls;

type
 TfMain = class(TForm)
   Timer1: TTimer;
   procedure Timer1Timer(Sender: TObject);
 private
   procedure DisplayVisiblePortion();
   function CalcVisiblePortion() : Integer;
 end;

var
 fMain: TfMain;

implementation

{$R *.DFM}

function RectSquare (const Rect: TRect) : Integer;
begin
 with Rect do
   Result := (Right - Left) * (Bottom - Top);
 if Result < 0 then
   Result := - Result;
end;

type
 TRectArray = array[0..16384] of TRect;
 PRectArray = ^TRectArray;

function RgnSquare (Rgn: HRGN): Integer;
var
 DataSize: DWORD;
 RgnData: PRGNDATA;
 Rectangles: PRectArray;
 I: Integer;
begin
 Result := 0;
 DataSize := GetRegionData(Rgn, 0, nil);
 if DataSize > 0 then begin
   GetMem(RgnData, DataSize);
   try
     GetRegionData(Rgn, DataSize, RgnData);
     Rectangles := PRectArray(@RgnData.Buffer);
     for I:=0 to Pred(RgnData^.rdh.nCount) do
       Inc(Result, RectSquare(Rectangles^[I]));
   finally
     FreeMem(RgnData, DataSize);
   end;
 end;
end;

function CalcSquarePortion (SquareWhole, SquarePart: Integer): Integer;
begin
 if SquarePart >= SquareWhole then
   Result := 100
 else
   Result := Trunc((SquarePart / SquareWhole) * 100);
end;

function TfMain.CalcVisiblePortion: Integer;
var
 SiblingRect: TRect;
 Workarea: TRect;
 WinRect: TRect;
 Tmp: TRect;
 VisiblePortion: TRect;
 Sibling: HWND;
 WindowSquare: Integer;
 WindowRgn, Rgn, TmpRgn: HRGN;
begin
 if IsIconic(Handle) then begin
   Result := 0;
   Exit;
 end;
 Rgn := CreateRectRgn (0, 0, 0, 0);
 try
   SystemParametersInfo(SPI_GETWORKAREA, 0, @Workarea, 0);
   GetWindowRect(Handle, WinRect);
   WindowSquare := RectSquare(WinRect);
   IntersectRect(VisiblePortion, WinRect, WorkArea);
   Result := CalcSquarePortion(WindowSquare, RectSquare(VisiblePortion));
   if Result > 0 then begin
     WindowRgn := CreateRectRgnIndirect(VisiblePortion);
     try
       Sibling := GetWindow(Handle, GW_HWNDPREV);
       while (Sibling <> 0) and (Result > 0) do begin
         if IsWindowVisible(Sibling) and not IsIconic(Sibling) then
           if IsZoomed(Sibling) then begin
             Result := 0;
             Break;
           end else begin
             GetWindowRect(Sibling, SiblingRect);
             IntersectRect(Tmp, VisiblePortion, SiblingRect);
             if not IsRectEmpty(Tmp) then begin
               TmpRgn := CreateRectRgnIndirect(Tmp);
               try
                 if CombineRgn(Rgn, Rgn, TmpRgn, RGN_OR) = ERROR then
                   RaiseLastWin32Error;
               finally
                 DeleteObject(TmpRgn);
               end;
             end;
             TmpRgn := CreateRectRgn(0, 0, 0, 0);
             if CombineRgn(TmpRgn, WindowRgn, Rgn, RGN_DIFF) = ERROR then
               RaiseLastWin32Error;
             Result := CalcSquarePortion(WindowSquare, RgnSquare(TmpRgn));
             DeleteObject(TmpRgn);
           end;
         Sibling := GetWindow(Sibling, GW_HWNDPREV);
       end;
     finally
       DeleteObject(WindowRgn);
     end;
   end;
 finally
   DeleteObject(Rgn);
 end;
end;

procedure TfMain.DisplayVisiblePortion;
begin
 Caption := Format ("%d%% percents visible", [CalcVisiblePortion()]);
end;

procedure TfMain.Timer1Timer(Sender: TObject);
begin
 DisplayVisiblePortion;
end;

end.


 
Pikachu ©   (2004-03-30 01:06) [7]

Спосибо за ответы,хочется отмететь что примеры очень даже показательны,но мне это не помогло,хотя и дают информацию о том перекрыто ли окно полностью или частично.

Пожалуста подскажите какой флаг меняется в проге когда какой либо контрол на моей форме перекрывается другим окном????


 
Германн ©   (2004-03-30 03:47) [8]

А с чего ты взял, что в проге есть "некие флаги", и что они меняются, когда "какой либо контрол на моей форме перекрывается другим окном"?

Об этом знает только сама система, т.е. Windows. У нее и спрашивай, если сможешь.


 
Юрий Зотов ©   (2004-03-30 07:33) [9]

> Pikachu ©   (29.03.04 21:45) [5]
> если мож прокоминтируй..

Попробуем. Но повторяю - внимательно проверьте код, в нем скорее всего есть ошибки.

// Это - главная функция. На входе - хэндл проверяемого окна,
// на выходе - перекрыто оно другими (True), или нет (False).
function IsWindowOverlapped(Wnd: HWND): boolean;
var
 OldWnd: HWND;
begin
 // Запомним хэндл окна
 OldWnd := Wnd;
 // И пройдемся по всем окнам верхнего уровня в системе,
 // передав адрес OldWnd, как параметр callback-функции
 EnumWindows(@EnumWindowProc, LParam(@OldWnd));
 // Если OldWnd изменилось, то окно перекрыто
 Result := OldWnd <> Wnd
end;

type
PWnd = ^HWND;

// Это callback-функция для EnumWindows. Пока она не вернет
// False, перебор окон продолжается. Wnd - хэндл очередного окна, TargetWnd - адрес переменной OldWnd (см. выше)
function EnumWindowProc(Wnd: HWND; TargetWnd: PWnd): BOOL; stdcall;
var
 Rct, TargetRct, OverRct: TRect;
 P: TPoint;
begin
 // Берем прямоугольник окна Wnd и нашего окна
 GetWindowRect(Wnd, Rct);
 GetWindowRect(TargetWnd^, TargetRct);
 // Проверяем их пересечение
 Result := not IntersectRect(OverRct, Rct, TargetRct);
 // Если пересекаются, надо выяснить, какое окно сверху
 if not Result then
 begin
  // Берем центр области пересечения
  P.X := (OverRct.Left + OverRct.Right) div 2;
  P.Y := (OverRct.Top + OverRct.Bottom) div 2;
  // И получаем окно верхнего уровня в этой точке
  Wnd := GetTopParent(WindowFromPoint(P));
  // Если это не наше окно, то надо остановить перебор и в
  // переменную OldWnd записать хэндл перекрывающего окна
  Result := Wnd <> TargetWnd^; // Кажется, здесь ошибка, надо =
  if not Result then TargetWnd^ := Wnd
end
end;

// Это вспомогательная функция. Если Wnd - это хэндл дочернего
// окна, то дает его родительское окно верхнего уровня, иначе
// дает само это окно
function GetTopParent(Wnd: HWND): HWND;
begin
repeat
  Result := GetParent(Wnd);
  if Result <> 0 then Wnd := Result
until Result = 0;
Result := Wnd
end;


 
Pikachu ©   (2004-03-30 17:23) [10]

Спасиб за помощь  но развиваю темы для определение прекрыт ли контрол моеёй формы...


 
Pikachu ©   (2004-03-30 17:32) [11]

я потдерживаю ещё тему Оброботка сообщения WM_MouseMove так на мой взгляд в этом есть сходство...



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.04.18;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.031 c
1-1080810813
Denisoid
2004-04-01 13:13
2004.04.18
Вопрос по ShellTreeView!


1-1080426680
killer
2004-03-28 01:31
2004.04.18
каким образом можно импортировать функцию в DLL?


3-1079703410
Zilog
2004-03-19 16:36
2004.04.18
ComboBox с записями из БД


6-1076491996
Iks
2004-02-11 12:33
2004.04.18
Отправить письмо со вложенной ссылкой ???


3-1079596522
sheriff
2004-03-18 10:55
2004.04.18
ADOConnection &amp; Service Application





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский