![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Клик сквозь окно [D6, WinXP]
Мыш © (2004-02-04 08:19:00)Понадобилось сделать так, чтобы клик мышью пришелся по тем же координатам, но в окне, которое находится под программой. Это не всегда будет окно, на единицу меньшее в z- последовательности, т.к. сквозь прогу может просвечивать сразу несколько окошек. Я так понимаю, нужно передать сообщение клика, но кому? как определить это окошко?
NAlexey (2004-02-19 11:30:00) [1]Мой пример действует не на все окна, по всей видимости они обрабатывают WM_CLOSE по своему, но возможно доказывает правильность подхода:
procedure TForm1.FormClick(Sender: TObject);
var
lHandle: THandle;
begin
lHandle := Self.Handle;
while (lHandle <> 0) and
(DWORD(GetWindowLong(lHandle, GWL_HINSTANCE)) = hInstance)
do
lHandle := GetNextWindow(lHandle, GW_HWNDNEXT);
if GetParent(lHandle) <> 0 then
repeat
lHandle := GetParent(lHandle);
until GetParent(lHandle) = 0;
if lHandle <> 0 then
SendMessage(lHandle, WM_CLOSE , 0, 0);
end;
GrayFace (2004-02-19 06:30:00) [2]Rouse_ © (17.02.04 12:18) [13]
Это не исходники хинтов, а исходники чьей-то проги.
В исходниках хинтов разобраться сложнее, чем написать самому.
Rouse_ (2004-02-17 12:18:00) [3]> [9] Walker © (15.02.04 02:12)
procedure TForm1.Button1Click(Sender: TObject);
var
H: THintWindow;
begin
H := THintWindow.Create(self);
H.ActivateHint(Rect(10, 10, 200, 200), 'qwe');
end;
Хоть общелкайся ;)
GrayFace (2004-02-17 06:41:00) [4]Мыш, надо передавать те сообения, которые к тебе приходят, т.е. когда приходит WM_RBUTTONDOWN, шлешь sendmessage(hh,WM_RBUTTONDOWN,lparam,wparam), а sendmessage(hh,WM_RBUTTONUp,0,0) только когда придет соответствующее сообщение.
hh определяй, как я написал в [7]
Мыш (2004-02-16 12:49:00) [5]:) Еще предлагали при клике вырезать регион, а потом заново заполнять :) Даже если бы я был извращенцем, проблемы такие методы не решали бы, - как, например выделять текст сквозь окно?
2 Walker: спасибо за совет, очень интересно было посмотреть как сделаны хинты, однако я ничего там кроме
procedure THintWindow.WMNCHitTest(var Message: TWMNCHitTest);
begin
Message.Result := HTTRANSPARENT;
end;
интересного не нашел. А это только делает все окно недоступным, однако клики сквозь него не проходят. Может я не там искал, но я по поиску посмотрел все исходники дельфи на предмет слва hint и больше ничего не обнаружил.
DVM (2004-02-15 14:59:00) [6]Могу предложитьтакой вариант: при щелчке окно прячется на мгновение, затем вызывается функция WindowFromPoint() и сообщение о клике передается этому окну, свое окно возвращаем на место. Правда уверен, что есть более оптимальный вариант.
Walker (2004-02-15 02:12:00) [7]Чего вы дурю страдаете... посмотрите исходники Hint-ов, я сяс точно не помню, но при создании всплывающего окна ему задаётся свойство - не принимать клики мышки... если вдруг окажется, что курсор мыши окажется над всплывающем окне и пользователь щелкнет мышкой, то сообщение о клике автоматически переадресуется тому объекту, которое находится под Hint-ом...
Мыш (2004-02-13 19:01:00) [8]Нифига не получается... Посылаю два сообщения полученному окну, а оно вместо попап-менюшки молчаливо говорит мне о том, откуда у меня руки растут.
hh:=GetNextWindow(handle,GW_HWNdnext);
sendmessage(hh,WM_RBUTTONDOWN,0,0);
sendmessage(hh,WM_RBUTTONUp,0,0);
GrayFace (2004-02-04 16:39:00) [9]GetWindow и GetWindowNext перебирают все окна подряд. Если вызвать на form1.handle, то возвратит Application.handle. В этот пример надо только вставить проверку на положение мыша.
var w:hwnd;
begin
w:=GetNextWindow(handle,GW_HWNdNext);
while (w<>0) and (w<>GetDesktopWindow) do
begin
if (w=Application.handle) or IsIconic(w) or not
IsWindowVisible(w) then w:=GetNextWindow(w,GW_HWNdNext)
else break;
end;
ShowWindow(w,sw_hide);
end;
Suntechnic (2004-02-04 16:02:00) [10]>Мыш ©
Да мало ли почему WM_CLOSE не отрабатывает. Может там специальная обработка для него имеется. Ты лучше смотри возвращает лиGetNextWindow(handle,GW_HWNdNext);тот дескриптор, что тебе нужен.
Мыш (2004-02-04 15:42:00) [11]а я же еще не до конца рассказал :) у меня GetWindow не работает :(
Делаю так:
var
hh:hwnd;
hh:=GetNextWindow(handle,GW_HWNdNext);
SendMessage(hh,WM_CLOSE ,0,0);
Пока взял wm_close, чтобы проверить, (на собственном окне form.handle оно срабатывает), но эффекта - ноль
Suntechnic (2004-02-04 14:49:00) [12]Да, кстати для проверки находится ли точка в пределах окна можешь использовать
PtInRect.
Suntechnic (2004-02-04 14:46:00) [13]>Мыш ©
...но в окне, которое находится под программой. Это не всегда будет окно, на единицу меньшее в z- последовательности...
Я что-то не совсем понял эту фразу, но в любом случае, если тебе надо найти предыдущее окно в z- последовательности, то вызываешьGetWindowс параметромGW_HWNDNEXT. Дальше проверяешь, а находится ли данная точка в пределах найденного окна и если нет берёшь следующее.... В самом худшем случае в desktop упрёшься :)
Мыш (2004-02-04 13:12:00) [14]Здесь изврат и не требуется. Висит инфо-окно, мешается, полупрозрачное. Нужно кликать сквозь него. Есть программа Самурайз, там это реализовано.
Алхимик (2004-02-04 12:07:00) [15]А что за задача то?
Может всё без изврата можно организовать?