Что такое дескриптор окна

Что такое дескриптор окна

Одним из важнейших понятий в Windows-программировании является понятие объектного дескриптора (handle). В Windows все объекты — кисти, перья, растры, указатели мыши, контексты устройств, окна, экземпляры программ— идентифицируются 32-разрядным (в Winl6 — 16-разрядным) целым числом, которое называется дескриптором (иногда манипулятором). С каждым дескриптором связывается идентификатор типа, начинающийся с буквы "Н" (в языке Си — с "h" нижнего регистра. В отличие от Pascal, регистр в Си имеет значение). Например, hwnd— это дескриптор окна. Дескрипторы ссылаются на объекты, находящиеся под управлением системы Windows. Работающая операционная система отслеживает все дескрипторы которые служат связующими звеньями между загруженными объектами вызвавшими их приложениями.

Когда мы создаем некоторый объект в Windows, ему присваивается уникальный 32-разрядный дескриптор, который в последующем передается каждой функции, при работе с этим объектом. Это главное различие между функциями Widows API и стандартными методами класса Object Pascal. Вторые связаны с тем экземпляром класса, через который они вызываются, и поэтому не требуют явного указания на объект. Первым необходимо такое указание (что и делается с помощью дескриптора), т. к. они сами по себе никак не связаны ни с одним объектом.

В Delphi для хранения дескриптора объектов определен тип THandle:

type THandle : LongInt;

Кроме типа THandle в Delphi поддерживаются также имена типов, пришедшие из С++, а именно: hwnd, hmenu, hkey и другие имена, начинающиеся с префикса. Н (Handle).

При использовании функций Windows API к объектам Object Pascal следует понимать, что данные функции "не знают" о внутренних механизмах работы Delphi.

Поясним на примере: если скрыть окно не с помощью метода Delphi Hide, а с помощью функции WinAPI showWindow(Handle, sw_Hide), то в Delphi не возникнет событие onHide, потому что оно генерируется упомянутыми внутренними механизмами. Следует об этом помнить.

Но случается такое только когда функциями Windows API дублируется то, что можно сделать с помощью Delphi. Для вызова функций Windows API для объекта, созданного с помощью Delphi, используйте свойство объекта Handle, — в нем хранится дескриптор.

Читайте также

Сообщения операционной системы Windows очень напоминают событийные сообщения Delphi.

Каждое сообщение Windows имеет свой уникальный номер (идентификатор).

(ниже представлена обработка сообщения wm_move.

При обработке сообщений часто приходится сталкиваться с ситуациями, когда один 32-разрядный…

Большая часть функций API уже импортирована в среду Delphi и описана в ее модулях

Подпишись на нашу группу в контакте и будь в курсе обновлений:

Не понятно, как определить дескриптор окна, которое находится под текущим окном. Текущее окно определяю так:
GetCursorPos(pt)
h := WindowFromPoint(pt)
В моём случае текущее окно — это форма моего приложения, а окно, дескриптор которого надо определить — это окно, находящееся на рабочем столе

Читайте также:  I3 2100 видеокарта совместимость


Anatoly Podgoretsky © ( 2008-09-10 13:27 ) [1]

> dmitry_12_08_73 (10.09.2008 13:24:00) [0]

Под текущим окном может находиться множество окон, а не одно.


clickmaker © ( 2008-09-10 13:35 ) [2]

GetNextWindow, пока не наткнулись на искомое


dmitry_12_08_73 © ( 2008-09-10 13:39 ) [3]

Нужен дескриптор окна, которое видимо для текущей позиции указателя мыши


Германн © ( 2008-09-10 13:42 ) [4]

Судя по http://delphimaster.net/view/2-1220964901/
опять что-то делается перанально.


oldman © ( 2008-09-10 13:43 ) [5]


> dmitry_12_08_73 © (10.09.08 13:39) [3]
> Нужен дескриптор окна, которое видимо

А система откуда это знает?
Если под твоих окном находится два взаимноперекрывающихся окна, откуда системе знать, какое было активным последнее?


dmitry_12_08_73 © ( 2008-09-10 13:56 ) [6]

Для текущего курсора мыши видно только одно окно или его часть — вот для этого окна и надо определить дескриптор. Форму своего приложения я не считаю — мне надо определить дескриптор окна под этой формой.


Юрий Зотов © ( 2008-09-10 14:04 ) [7]


dmitry_12_08_73 © ( 2008-09-10 14:13 ) [8]

В моём случае WindowFromPoint возвращает дескриптор моей формы, а мне надо дескриптор окна, находящегося под ней


Anatoly Podgoretsky © ( 2008-09-10 14:17 ) [9]

> dmitry_12_08_73 (10.09.2008 13:56:06) [6]


Anatoly Podgoretsky © ( 2008-09-10 14:20 ) [10]

> dmitry_12_08_73 (10.09.2008 14:13:08) [8]

А ты снача убери свое окно с этой точки.


dmitry_12_08_73 © ( 2008-09-10 14:23 ) [11]

Ещё раз. У меня курсор мыши находится над моей формой, а надо получить handle окна, которое находится под ней, как будто моей формы нет. WindowFromPoint возвращает handle моей формы — это мне не подходит.


Юрий Зотов © ( 2008-09-10 14:26 ) [12]

GetWindow c GW_HWNDNEXT?


Юрий Зотов © ( 2008-09-10 14:29 ) [13]

Видимо, действительно нужен цикл. Идем от формы по Z-порядку, для каждого окна получаем его Rect и проверям PtInRect.


dmitry_12_08_73 © ( 2008-09-10 14:54 ) [14]

Спасибо, Юрий, буду пробовать


Юрий Зотов © ( 2008-09-10 15:00 ) [15]

Цикл нужен потому, что под формой могут находиться несколько неперекрывающихся окон и то из них, которое "под курсором" не обязательно идет сразу за формой в Z-порядке.


dmitry_12_08_73 © ( 2008-09-10 15:52 ) [16]

Извиняюсь, но не получается организовать цикл, может подскажите как?


Amoeba © ( 2008-09-10 15:57 ) [17]


Юрий Зотов © ( 2008-09-10 16:28 ) [18]

Код написан "навскидку", возможны ошибки.

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;

Читайте также:  Телекомпания вид жди меня


dmitry_12_08_73 © ( 2008-09-10 16:50 ) [19]

Вы знаете, я тоже писал подобное по вашему совету, но в результате получаем handle текущего на данный момент под курсором окна, которое не обязательно видимо. А мне надо handle только видимого в данной точке окна.


© ( 2008-09-10 17:00 ) [20]

Попробуй так:
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;


© ( 2008-09-10 17:01 ) [21]

> SetForegroundWindow(H);

Думаю догадался, что это просто для проверки 🙂


dmitry_12_08_73 © ( 2008-09-10 18:09 ) [22]

Функция IsWindowVisible позволяет определить видимо или нет окно в целом, а мне надо определить видимость окна ИМЕННО в заданной точке рабочего стола


Юрий Зотов © ( 2008-09-10 18:28 ) [23]

Люди, кто-нибудь что-нибудь понимает?


dmitry_12_08_73 © ( 2008-09-10 18:36 ) [24]

Можно я поясню из-за чего весь сыр-бор.
Я копирую образ экрана на форму в своём приложении, а затем мне надо выделять своими рамками окна, которые находятся на рабочем столе. Так как форма переднего плана — это моя форма, я не могу определить handle окон, которые находятся под моей формой. handle мне надо для дальнейшего выделения текущего под курсором окна рамкой.


© ( 2008-09-10 19:45 ) [25]

> [24] dmitry_12_08_73 © (10.09.08 18:36)

А чем не устраивают ответы выше?
Если честно, то я присоединяюсь к [23], даже после пояснения всего сыра-бора.


© ( 2008-09-10 20:26 ) [26]

Оно:
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;

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.
? На коленке писано. 🙂


© ( 2008-09-10 20:30 ) [27]

Желательно, перед запуском "проги" из [26], несколько калькуляторов запустить, для пущего эффекта)


dmitry_12_08_73 © ( 2008-09-11 11:00 ) [28]

Спасибо, я разобрался, помогло.
Но функция GetNextWindow ищет не все окна. Например не находит элементы внутри окна такие как кнопки, т.е. которые тоже имеют свой handle.


Юрий Зотов © ( 2008-09-11 13:56 ) [29]

> dmitry_12_08_73 © (11.09.08 11:00) [28]

Такие окна называются дочерними и GetNextWindow их действительно не ищет. И не должна, потому что об этом прямо сказано в документации (которую, кстати, неплохо было бы все же посмотреть).

Для поиска дочерних окон можно использовать GetWindow, GetChildWindow, FindWindowEx, EnumChildWindows.

Базовые классы элементов управления

Вслед за классом TComponent в иерархии базовых классов (см. рис. 2.1) располагается группа из трех классов, которые обеспечивают создание различных визуальных компонентов. Визуальные компоненты – это разнообразные стандартные для Windows и специальные (созданные разработчиками Inprise) элементы управления.

Понятно, что визуальные компоненты должны уметь отобразить себя на экране монитора и реагировать на целый ряд новых событий (реакция на мышь и клавиатуру, движение курсора и т. д.). Для этого в них встроен специальный механизм, обеспечивающий взаимодействие компонентов с графической подсистемой ОС (GUI).

Существует несколько типов элементов управления, которые существенно отличаются по своим возможностям и поведению. Каждому типу соответствует собственный класс иерархии.

Класс TWinControl обеспечивает использование в Delphi оконных элементов управления. Главное отличие оконного элемента управления от любых других – наличие дескриптора окна hwnd.

Дескриптор окна – это специальный идентификатор, который операционная система присваивает всем объектам, которые должны обладать свойствами окна. Если элемент управления имеет дескриптор окна, то он должен уметь выполнять следующие операции:

  • получать и передавать фокус управления во время выполнения приложения;
  • воспринимать управляющие воздействия от мыши и клавиатуры;
  • уметь размещать на себе другие элементы управления.

Оконными элементами управления являются не только формы, но и практически все стандартные элементы управления Windows: и списки, и редакторы имеют дескриптор окна.

Итак, все визуальные компоненты происходят от класса TWinControl. Однако нестандартные элементы управления имеют еще одного общего предка. Это класс TCustomContrl. Он существенно облегчает использование элементов управления, т. к. позволяет управлять отрисовкой компонента путем использования специального класса TCanvas – так называемой канвы (см. гл. 11) вместо обращения к системным функциям GUI.

Для обеспечения создания обычных (не оконных) элементов управления непосредственно от класса TControl порожден класс TGraphicControl. Его потомки не могут получать фокус, но используют для визуализации канву.

Ссылка на основную публикацию
Что такое адрес сервера на телефоне
Блог о модемах, роутерах и gpon ont терминалах. Частенько пользователи планшетов и смартфонов на Андроид сталкиваются с тем, что подключившись...
Что значит загрузочная флешка
Что такое загрузочная флешка / 8 способов создать загрузочную флешку Что такое загрузочная флешка / 8 способов создать загрузочную флешку...
Что значит заблокировать сообщение в телефоне
Текстовые сообщения очень удобны – ведь с их помощью вы можете получить информацию от другого абонента даже в тот момент,...
Что такое аккумулятор слайдер
Кроме достоинств, у литий-ионных аккумуляторов имеется немало минусов: Не выносят перезаряда. Подача тока на элемент питания должна быть прекращена, когда...
Adblock detector