Click сквозь окно

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
t116
Бывалый
Бывалый
 
Сообщения: 209
Зарегистрирован: 12.01.2007 (Пт) 12:11

Click сквозь окно

Сообщение t116 » 23.04.2007 (Пн) 19:08

Вот такая ситуация:

Имеется некое полупрозрачное окно программы, на котором расположени, скажем, только labels с информацией. Как сделать так, что бы, во-первых, окно никогда не получало фокус и было всегда на заднем плане (на рабочем столе) и, во-вторых, чтобы оно пропускало манипуляции мышкой сквозь себя? Тоесть, я жму на окне правой кнопкой мышки и появляется меню рабочего стола или жму левой кнопкой мышки и попадаю на значек, находящийся за формой.

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 23.04.2007 (Пн) 20:10

Пожалуй это невозможно. Если под мышкой есть окно, то оно будет получать фокус и клики. Можно попробовать отрисовывать изображение окна на бекграунде, как это делает AVS из винампа.
Лучший способ понять что-то самому — объяснить это другому.

keks-n
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2509
Зарегистрирован: 19.09.2005 (Пн) 17:17
Откуда: г. Москва

Сообщение keks-n » 23.04.2007 (Пн) 20:37

t116
Сабкласс всех мышиных событий. Отлов всех окнон под твоим(через FindWindow, GetWindow). Далее находшь то, на которое должен попасть клик. После чего ищешь контролы того окна и передаёшь мышиное событие нужному контролу.
Изображение

t116
Бывалый
Бывалый
 
Сообщения: 209
Зарегистрирован: 12.01.2007 (Пт) 12:11

Сообщение t116 » 23.04.2007 (Пн) 21:03

Antonariy

Интересно, а как это сделать?

keks-n
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2509
Зарегистрирован: 19.09.2005 (Пн) 17:17
Откуда: г. Москва

Сообщение keks-n » 23.04.2007 (Пн) 21:28

dim desk as long, hdc as long
Findwindow "Progman"
GetDC(desk)

Вот на нём и рисуй.
Изображение

t116
Бывалый
Бывалый
 
Сообщения: 209
Зарегистрирован: 12.01.2007 (Пт) 12:11

Сообщение t116 » 23.04.2007 (Пн) 21:41

а как узнать lpWindowName рабочего стола?

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 23.04.2007 (Пн) 22:32

Может все таки GetDesktopWindow?
Лучший способ понять что-то самому — объяснить это другому.

nekeda
Постоялец
Постоялец
 
Сообщения: 710
Зарегистрирован: 10.04.2005 (Вс) 23:20

Сообщение nekeda » 24.04.2007 (Вт) 3:48

AVS из винампа использует оверлеи. Так просто на десктопе не порисуешь.

А если при клике спрятать форму, повторотить клик и снова её показать?

Kostyan
Постоялец
Постоялец
 
Сообщения: 439
Зарегистрирован: 20.09.2002 (Пт) 4:14
Откуда: Россия, Уссурийск

Сообщение Kostyan » 24.04.2007 (Вт) 7:42

Идея проста, создаешь 2 прямоугольных региона. Один размером с форму, другой 1x1 приксел в том месте где сейчас находится мышь. Затем вырезаешь из большого региона маленький, и получаешь прямоугольник с дыркой в 1 пиксел, и дырка как раз под указателем мыши. Присваиваешь полученный регион форме и готово.
Код:
Код: Выделить всё
Private Declare Function SetWindowRgn Lib "User32" (ByVal hwnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function CreateRectRgn Lib "gdi32.dll" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function CombineRgn Lib "gdi32.dll" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long
Const RGN_XOR As Long = 3

Public hRgn As Long, WinRgn As Long

Private Sub Form_Load()
WinRgn = CreateRectRgn(0, 0, Me.ScaleWidth, Me.ScaleHeight)
End Sub

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
hRgn = CreateRectRgn(CLng(X), CLng(Y), CLng(X + 1), CLng(Y + 1))
Call CombineRgn(hRgn, WinRgn, hRgn, RGN_XOR)
Call SetWindowRgn(Me.hwnd, hRgn, True)
Call DeleteObject(hRgn)
End Sub

Private Sub Form_Unload(Cancel As Integer)
Call DeleteObject(WinRgn)
End Sub


Единственный недостаток, MouseMove происходит только на форме, поэтому если водить мышью над контролами, дырка образовываться не будет. Но это непроблема, ведь вместо Label можно использовать TextOut. Либо в таймере определять координаты мыши, и отказаться от MouseMove.
Как закрыть такую форму, и как реализовать на ней надписи думай сам :)

P.S. Убери у формы заголовок (BorderStyle=0), и ScaleMode=3.
Нет ничего невозможного для человека с интеллектом.

X-hacker
Обычный пользователь
Обычный пользователь
 
Сообщения: 83
Зарегистрирован: 26.08.2006 (Сб) 1:22
Откуда: Moldova

Сообщение X-hacker » 06.05.2007 (Вс) 21:57

А не проще так?:
Код: Выделить всё
Dim DC As Long

DC=CreateDC("DISPLAY",vbNullstring,vbNullstring,0)'DevMode ставь Long
TransparentBlt( ...Твоё окно и т.п... )

Если я ничего не пропустил, должно работать только придётся форму перерисовывать.
Например после создания такого девайса и заполнением например при помощи SetPixelV (она быстрее SetPixel) у меня прекрасно отображалось меню ( НО на окнах не пробывал, да и им придётся затем WM_Paint посылать.(Но опять же есть более элегантные решения!)

Kostyan
Постоялец
Постоялец
 
Сообщения: 439
Зарегистрирован: 20.09.2002 (Пт) 4:14
Откуда: Россия, Уссурийск

Сообщение Kostyan » 07.05.2007 (Пн) 5:30

X-hacker
Тот код что ты написал просто имитирует прозрачное окно, да и то не самым лучшим образом. Думаю автор вопроса сам знает что грамотно прозрачность ставится функцией SetLayeredWindowAttributes (Win 2000 и старше).
А мой код нужен именно для пропуска кликов сквозь форму, и не больше. Остальное мелочи.
Нет ничего невозможного для человека с интеллектом.

t116
Бывалый
Бывалый
 
Сообщения: 209
Зарегистрирован: 12.01.2007 (Пт) 12:11

Сообщение t116 » 09.07.2007 (Пн) 18:45

Да, разобрался. Уже давно но не мог на форум зайти поблагодарить. Спасибо за помощь всем!

Приблизительно таким же способом, который предложил Kostyan, сделал возможным перемещение невидимого окна с видимыми контролами. Притом что мышкой тыкать в само окно. :)


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот, Yandex-бот и гости: 93

    TopList