![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Определение дескриптора окна под текущим окном [D7, WinXP]
dmitry_12_08_73 © (2008-09-10 13:24:00)Не понятно, как определить дескриптор окна, которое находится под текущим окном. Текущее окно определяю так:
GetCursorPos(pt)
h := WindowFromPoint(pt)
В моём случае текущее окно - это форма моего приложения, а окно, дескриптор которого надо определить - это окно, находящееся на рабочем столе
Юрий Зотов (2008-09-11 13:56:00) [1]> dmitry_12_08_73 © (11.09.08 11:00) [28]
Такие окна называются дочерними и GetNextWindow их действительно не ищет. И не должна, потому что об этом прямо сказано в документации (которую, кстати, неплохо было бы все же посмотреть).
Для поиска дочерних окон можно использовать GetWindow, GetChildWindow, FindWindowEx, EnumChildWindows.
dmitry_12_08_73 (2008-09-11 11:00:00) [2]Спасибо, я разобрался, помогло.
Но функция GetNextWindow ищет не все окна. Например не находит элементы внутри окна такие как кнопки, т.е. которые тоже имеют свой handle.
{RASkov} (2008-09-10 20:30:00) [3]Желательно, перед запуском "проги" из [26], несколько калькуляторов запустить, для пущего эффекта)
{RASkov} (2008-09-10 20:26:00) [4]Оно:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure FormClick(Sender: TObject);
private
{ Private declarations }
public
B: TBitMap;
OldHnwd: HWND;
{ Public declarations }
end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var DC: HDC;
begin
BorderStyle:=bsNone;
WindowState:=wsMaximized;
DoubleBuffered:=True;
B:=TBitMap.Create;
B.Width:=Screen.Width;
B.Height:=Screen.Height;
DC:=GetDC(0);
BitBlt(B.Canvas.Handle, 0, 0, B.Width, B.Height, DC, 0, 0, SRCCOPY);
ReleaseDC(0, DC);
Canvas.Brush.Style:=bsClear;
OldHnwd:=0;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var H: HWND; R: TRect; P: TPoint;
begin
H:=Application.Handle;
GetCursorPos(P);
repeat
H:=GetNextWindow(H, GW_HWNDNEXT);
if not IsWindowVisible(H) then Continue;
GetWindowRect(H, R);
until (H=0) or (PtInRect(R, P));
if OldHnwd=H then Exit else OldHnwd:=H;
with Canvas do begin
Draw(0, 0, B);
Pen.Width:=3;
Pen.Color:=clRed;
Rectangle(R);
end;
end;
procedure TForm1.FormClick(Sender: TObject);
begin
SetForegroundWindow(OldHnwd);
Close;
end;
end.
? На коленке писано... :)
{RASkov} (2008-09-10 19:45:00) [5]> [24] dmitry_12_08_73 © (10.09.08 18:36)
А чем не устраивают ответы выше?
Если честно, то я присоединяюсь к [23], даже после пояснения всего сыра-бора....
dmitry_12_08_73 (2008-09-10 18:36:00) [6]Можно я поясню из-за чего весь сыр-бор.
Я копирую образ экрана на форму в своём приложении, а затем мне надо выделять своими рамками окна, которые находятся на рабочем столе. Так как форма переднего плана - это моя форма, я не могу определить handle окон, которые находятся под моей формой. handle мне надо для дальнейшего выделения текущего под курсором окна рамкой.
Юрий Зотов (2008-09-10 18:28:00) [7]Люди, кто-нибудь что-нибудь понимает?
dmitry_12_08_73 (2008-09-10 18:09:00) [8]Функция IsWindowVisible позволяет определить видимо или нет окно в целом, а мне надо определить видимость окна ИМЕННО в заданной точке рабочего стола
{RASkov} (2008-09-10 17:01:00) [9]> SetForegroundWindow(H);
Думаю догадался, что это просто для проверки :)
{RASkov} (2008-09-10 17:00:00) [10]Попробуй так:
procedure TForm1.FormClick(Sender: TObject);
var H: HWND; R: TRect; P: TPoint;
begin
H:=Application.Handle;
GetCursorPos(P);
repeat
H:=GetNextWindow(H, GW_HWNDNEXT);
if not IsWindowVisible(H) then Continue;
GetWindowRect(H, R);
until (H=0) or (PtInRect(R, P));
SetForegroundWindow(H);
end;
dmitry_12_08_73 (2008-09-10 16:50:00) [11]Вы знаете, я тоже писал подобное по вашему совету, но в результате получаем handle текущего на данный момент под курсором окна, которое не обязательно видимо. А мне надо handle только видимого в данной точке окна.
Юрий Зотов (2008-09-10 16:28:00) [12]Код написан "навскидку", возможны ошибки.
function TForm1.GetUnderlayingWindow: HWND;
var
P: TPoint;
R: TRect;
begin
GetCursorPos(P);
Result := GetNextWindow(Handle, GW_HWNDNEXT);
while Result <> 0 do
begin
GetWindowRect(Result, R);
if PtInRect(P, R) then
Exit;
Result := GetNextWindow(Result, GW_HWNDNEXT);
end;
end;
Amoeba (2008-09-10 15:57:00) [13]Читать это:
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=432
dmitry_12_08_73 (2008-09-10 15:52:00) [14]Извиняюсь, но не получается организовать цикл, может подскажите как?
Юрий Зотов (2008-09-10 15:00:00) [15]Цикл нужен потому, что под формой могут находиться несколько неперекрывающихся окон и то из них, которое "под курсором" не обязательно идет сразу за формой в Z-порядке.
dmitry_12_08_73 (2008-09-10 14:54:00) [16]Спасибо, Юрий, буду пробовать
Юрий Зотов (2008-09-10 14:29:00) [17]Видимо, действительно нужен цикл. Идем от формы по Z-порядку, для каждого окна получаем его Rect и проверям PtInRect.
Юрий Зотов (2008-09-10 14:26:00) [18]GetWindow c GW_HWNDNEXT?
dmitry_12_08_73 (2008-09-10 14:23:00) [19]Ещё раз. У меня курсор мыши находится над моей формой, а надо получить handle окна, которое находится под ней, как будто моей формы нет. WindowFromPoint возвращает handle моей формы - это мне не подходит.
Anatoly Podgoretsky (2008-09-10 14:20:00) [20]> dmitry_12_08_73 (10.09.2008 14:13:08) [8]
А ты снача убери свое окно с этой точки.