Форум: "Основная";
Текущий архив: 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.04 c