Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Отпрака кликов под форму.


Автор: Messages 31.5.2006, 01:02
Вобщем проблемка. Нарисовала я себе красивые часики... прозрачные... по верх всех окон. Но хочецца, чтобы они не мешали нажимать на компоненты под ними. Как это сделать, подскажите, плиз? Вдруг это просто и я все пойму. smile 

Автор: Guedda 31.5.2006, 10:04
Над рабочей программой висит полупрозрачная форма с часиками. И нужно, чтобы часики эти были "полностью прозрачными", т.е. даже клики мышкой проходили сквозь неё.
У меня по этому поводу есть только одно предложение:
Сделать следующий обработчик:
Цитата

- обработать нажатие (клик)
- узнать координаты курсора (GetCursorPos - функция)
- узнать, что в этих координатах висит.
  

Автор: Messages 31.5.2006, 20:26
Плохо, очень плохо. Ибо если в точке висит несколько форм, несчитая часиков. Мы никогда не узнаем какая выше. smile
Или я об этом ничего не знаю? 

Автор: skyboy 31.5.2006, 22:00
Messages, по идее, как то можно работать с z-координатой окон...  

Автор: Mechanic 31.5.2006, 23:21
А если перехватить HitTest мессаги, и рассказывать в них Винде, что юзверь в окно не попал?  smile  

Автор: Sunvas 1.6.2006, 07:24
Цитата(skyboy @  31.5.2006,  22:00 Найти цитируемый пост)
Messages, по идее, как то можно работать с z-координатой окон...  

Z координаты в винде? Это что-то новое! 

Автор: Mechanic 1.6.2006, 09:33
Цитата(Sunvas @  1.6.2006,  07:24 Найти цитируемый пост)
Z координаты в винде? Это что-то новое!

Та да.. ZOrder не так давно придумали.. Позже, чем окна.. Минут на 15..  smile  

Автор: skyboy 1.6.2006, 09:50
Sunvas, гляди:
Цитата("Windows SDK")

Z ORDER
The Z order of a window indicates the window's position in a stack of overlapping windows. This window stack is oriented along an imaginary axis, the z-axis, extending outward from the screen. The window at the top of the Z order overlaps all other windows. The window at the bottom of the Z order is overlapped by all other windows. 

Честно говоря, времени на поиск+тестирование не было... Вот, что я нашёл:
Цитата

The GetNextWindow function retrieves the handle of the next or previous window in the Z order. The next window is below the specified window; the previous window is above. 

Формат функции
Цитата

HWND GetNextWindow(
    HWND hWnd,    // handle of current window
    UINT wCmd  // direction flag
   );

Вот только, придётся работать с размерами: вдруг следующее по z-order окно наодится не под твои, а далеко от него, а под твоим находится 5-е или 7-е по счёту....
Вот эта функция может пригодиться:
Цитата

The GetWindowRect function retrieves the dimensions of the bounding rectangle of the specified window. The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen. 
BOOL GetWindowRect(
    HWND hWnd,    // handle of window
    LPRECT lpRect  // address of structure for window coordinates
   );    

Сорри, что копи-пастю, а не направляю в справку, но тогда пришлось бы обьяснять, как добраться до Windows SDK  smile  

Автор: Yanis 1.6.2006, 09:57
В винде нет Z-координат. Есть упорядоченность окон по Z-координате, но это не значит, что существуют и координаты Z. 

Автор: Mechanic 1.6.2006, 10:08
А индекс в ZOrder'е - разве это не координата? Просто единица измерения по оси Z = одно окно vs пиксели по другим осям.  smile  

Автор: Yanis 1.6.2006, 10:13
Цитата(Mechanic @  1.6.2006,  11:08 Найти цитируемый пост)
А индекс в ZOrder'е - разве это не координата?

<индекс в Z-последовательности> != <координата> IMHO, но тут уже дело в трактовке. Каждый пологает как ему удобно smile  

Автор: skyboy 1.6.2006, 10:54
Yanis, ладно-ладно, пускай будет "Z-порядок". Но тогда для людей, впервые столкнувшимся с подобными вопросами будет не совсем понятно(по крайней мере мне этот термин не кажется "интуитивно понятным"), в то время, как понятие "глубины" или "кординаты z" ближе  к привычному человеку трёхмерному миру и потому легче воспринимается.

Добавлено @ 11:00 
Понял, в чём загвоздка. Два объекта по определению могут иметь одинаковую координату, а одно и то же место в z-order списке два разных окна занимать не могут! Сорри, был не прав.  

Автор: Yanis 1.6.2006, 11:02
Последовательность подразумевает, что окна идут друг за другом, перекрываются и т.д. smile
Я потому и сказал 
Цитата(Yanis @  1.6.2006,  11:13 Найти цитируемый пост)
Каждый пологает как ему удобно
 

Автор: skyboy 1.6.2006, 11:42
Messages, если полностью расписать алгоритм, то:
при помощи GetNextWindow перебираешь все окна, находящиеся ЗА твоим, пока не окончится список окон, или пока не найдёшь окно за своим, в пределах которого находятся координаты клика(размеры текущего обрабатываемого окна получаешь при помощи функции GetWindowRect; принадлежность точки клика прямоугольному региону можно определить при помощи функции PtInRegion); если обнаруживаешь, что окно подходит под параметры, ищешь для этого окна дочерние контролы/окна при помощи EnumChildWindows и для каждого из них(если я не путаю, то в этом месте ты уже будешь перебирать контролы) проверяешь принадлежность точки клика их региону(см. выше), как только найдёшь, необходимо рекурсивно повторить всё начиная с вызова EnumChildWindows, потому что на форме может лежать GroupBox, на нем - панель, на ней - панель и только уже потом - кнопка. Потому надо будет перебирать рекурсивно - чтоб ты не посылала клик панели, а добралась до кнопки. А потом уже, как найдёшь нужный объект, отсылаешь ему сообщение о клике при помощи SendMessage(сначала - сообщение WM_LBUTTONDOWN, а потом - WM_LBUTTONUP).
Я вообще почти не работал с Windows API, потому прошу критически относится к моим словам smile 

Автор: Rrader 1.6.2006, 12:17
Как вариант:
Код

procedure TForm1.FormCreate(Sender: TObject);
begin
  Color := clGreen;
  TransparentColor := True;
  TransparentColorValue := clGreen;
  AlphaBlend := True;
  AlphaBlendValue := 100;
  SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0,
    SWP_NOSIZE Or SWP_NOMOVE);
end;
 

Автор: Mechanic 2.6.2006, 01:22
Цитата(Rrader @  1.6.2006,  12:17 Найти цитируемый пост)
  AlphaBlendValue := 100;
  SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0,
    SWP_NOSIZE Or SWP_NOMOVE);

 smile 
И чё, это воркает? 

/me У него просто нет AlphaBlendValue (D5).  smile 

Бо уже покурил даже про XP Ghost Window:
Цитата(MSDN said)

Windows XP: If a top-level window stops responding to messages for more than several seconds, the system considers the window to be not responding and replaces it with a ghost window that has the same z-order, location, size, and visual attributes. This allows the user to move it, resize it, or even close the application. However, these are the only actions available because the application is actually not responding. When in the debugger mode, the system does not generate a ghost window.


 smile 

Цитата(Yanis @  1.6.2006,  10:13 Найти цитируемый пост)
<индекс в Z-последовательности> != <координата>

Другой бы спорил.. А мне пофик..  smile  Ну, ордер, так ордер. Все равно по ордеру, как и по коорде, можно сказать какое окно выше / ниже / дальше / ближе, а споры о терминологии оставим лингвистам и юристам.  smile  

Автор: Messages 9.6.2006, 12:05
Rrader, спасибо тебе за хорошую попытку. smile
 Для меня этот код не подходит. Ты просто делаешь дырку в форме вместо определенного цвета. А мне нужно, что бы не дырка. smile Что бы оно отображала стрелки, циферблат, напоминалки...  Это тоже вариант, но не мой.


To ALL, спасибо огромное за труды. Придется перебирать окна. smile Но если вдруг кто нить найдет способ по проще, Милости просим сообщить, предпологаеться много версий. smile

Возникает еще проблема. smile Что делать с меню? И если посылать клик окну в определенную координату, будет ли оно пересылать этот клик своей кнопке и т. д. в этой координате.

Ага, меню появляеться выше. Одной проблемой меньше. smileНо вот упростить процесс отправки не помешало бы. Буду эксперементировать. Если что сообщу. Но необещаю, что быстро: я счасс типа в больнице. smile 

Автор: Sunvas 12.6.2006, 00:54
Единственный выход, который я вижу, это использование оверлеев. 

Автор: Messages 12.6.2006, 06:18
Sunvas, а раскажи, что это? Ну, и с чем его едят?   smile 

Автор: Sunvas 12.6.2006, 11:08
Вот тут http://www.delphimaster.ru/articles/directx/ 

Автор: bems 16.6.2006, 23:38
Сам не пробовал но 
Цитата(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwui/html/layerwin.asp)

If the layered window has the WS_EX_TRANSPARENT extended window style, the shape of the layered window will be ignored and the mouse events will be passed to the other windows underneath the layered window.

 

Автор: Mailman 17.6.2006, 19:44
Если будет такая возможность, скинь плз вариант исходника данной функции - очень интересно. И полезно будет всем, думаю. 

Автор: bems 18.6.2006, 09:13
А функция старая - CreateWindowEx. 
Код

CreateWindowEx(WS_EX_TRANSPARENT or WS_LAYERED...
 

Автор: Messages 24.6.2006, 08:35
bems, спасибо. Но что-то я не могу понять где чего перегрузить, что бы этим свойством обладал мой класс:TForm. 

Автор: bems 24.6.2006, 10:18
например в OnCreate формы

SetWindowLong(handle,GWL_EXSTYLE,GetWindowLong(handle,GWL_EXSTYLE) or WS_EX_TRANSPARENT or WS_EX_LAYERED)

Добавлено @ 10:23 
Но только если у тебя AlphaBlend=true. Или ты используешь апишки для применения прозрачности. Иначе эффект будет несколько другой smile 

Автор: Messages 27.6.2006, 00:58
bems, все равно как добиваться прозрачности. Главное чтобы клики тоже прозрачные. smile Спс. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)