Отловить двойное нажатие Ctrl и передать форме фокус

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

Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение sosed213 » 02.04.2012 (Пн) 20:12

Здравствуйте.

1. Пишу программу, которая висит в Tray и что то делает. Для удобства вызова главного окна хочу использовать двойное нажатие Ctrl (НЕ Left Ctrl + Right Ctrl , а именно нажал - отпустил - нажал - отпустил любой Ctrl).

API функцией вряд ли получится зарегистрировать такую комбинацию, а глобальный хук ставить не охото, дабы различные антивирусники не косились на мою прогу.

Единственный вариант (извращенный), который удалось более мение реализовать, это создать что вроде маски ввода:
Есть массив KeyDown(0..3), 0-номер текущей операции. Ячейки 1..3 - по таймеру, в каждом такте таймера записываю состояние клавиши Ctrl (приведенное к виду 1 или 0, где 1-нажата или зажата, 0 - не нажата), и плюсуется действие KeyDown(0)=KeyDown(0)+1.

Когда KeyDown(0)=3, проверяется маска, если KeyDown(1) = 1 и KeyDown(2) = 0 и KeyDown(3) = 1 тогда Мы отловили двойное нажатие Ctrl.

Не правда ли, извращенно?! :oops:

Может у кого получше идеи будут?! Прикладываю пример того что я тут описал.


2. Когда форма была свернута (ну или скрыта "в трее"), и мы ее разворачиваем, не всегда она получает фокус. Как бы с этим разобраться. Видил что этот вопрос поднимался неоднократно, но конкретного решения не нашел.

Особенно если открыты какиенибудь Totalcmd или Skype или браузер какойнибудь, то программа вроде разворачивается, но сделать ее активной, (передать ей фокус) так и не получается. Чтобы например нажал два раза Ctrl, открылась форма и без лишнего щелчка по форме (чтобы дать ей фокус) можно было клавишами курсора перемещаться (например) по ListBox'u.

Что уже пытался сделать: всячески комбинировал SetFocus, ZOrder, SetWindowPos, SetForegroundWindow, SetActiveWindow

Максимум что получается, форма разворачивается, и начинает мигать в панели задач, а фокус остается на окне другой программы в которой работал в данный момент.


Если кто то уже имел такую задачу, поделитесь опытом.
Вложения
Double_Ctrl_Click.zip
(1.46 Кб) Скачиваний: 79
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 02.04.2012 (Пн) 20:51

Код: Выделить всё
Private Declare Function BringWindowToTop Lib "user32" (ByVal hwnd As Long) As Long

Me.Show
BringWindowToTop Me.hwnd

PS: Про то, что способ извращенский промолчу, но он ещё и работает криво. Чтобы форма появилась надо Ctrl с десяток раз нажать :(

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение sosed213 » 02.04.2012 (Пн) 21:15

Десяток раз, это да, потому что по таймеру, да и вообще правильно, криво сделано.

А BringWindowToTop, уже попробовал, тоже не получается. Запускаю программу, сворачиваю. открываю (например) браузер, и нажимаю 2 раза Ctrl форма вроде разворачивается, но позади браузера (или любого другого окна).

Единственно как получилось вытащить форму на "поверхность" то сделать ее поверх всех окон, и сразу вернуть как было, т.е.

Код: Выделить всё
    'Always On Top
    SetWindowPos Me.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
    ' Not Always On Top
    SetWindowPos Me.hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE



Форма становится впереди, но фокус все равно остается на другой программе (например браузере. легко проверить, клавишами курсора вверх/вниз - страница листается )
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 02.04.2012 (Пн) 21:23

sosed213 писал(а):А BringWindowToTop, уже попробовал, тоже не получается.

У меня работает, кажется...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение Хакер » 03.04.2012 (Вт) 4:41

Настаиваю на том, что от такой комбинации нужно отказаться.
У меня наверное каждый час бывает, что я жму Ctrl, тянусь к «X» (чтобы нажать Ctrl+X), потом думаю «А нет, не буду», отпускаю Ctrl, а потом «А нет, всё таки буду», и опять жму Ctrl и жму «X».

И тут каждый раз бы твоя программа вылазила со своим назойливым окном.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение sosed213 » 03.04.2012 (Вт) 5:02

Хех, а ведь и правда :)

Комбинацию клавиш поменяю, остался вопрос про фокус формы.

Мне кажется что когда работаешь в другой программе и нажимаешь какуюнибудь комбинацию клавиш ь, то вероятно на секунду моя программа и получает фокус, но тут же теряет... :roll:
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение Хакер » 03.04.2012 (Вт) 6:31

2-ое
sosed213 писал(а):Максимум что получается, форма разворачивается, и начинает мигать в панели задач, а фокус остается на окне другой программы в которой работал в данный момент.

Это тоже правильно.

Во всём мире кол-во людей, которые печатают, глядя на клавиатуру, а не на экран, хватит чтобы заполнить большую страну. Да и к тем, кто на экран смотрит, это тоже относится. Недопустимо, чтобы при вводе текста в одну программа внезапно открылось чужое окно и весь текст ушёл туда. Никто особо не задумывается насколько это важно, но когда у меня на компьютере появилась программа, которая каждые 2 минуты самооткрывалась и забирала фокус на себя — хотелось поехать в город её создателей и учинить там акцию анархии и терроризма. Потому что это невероятно нервирует.

Показываться и отбирать фокус по хоткею всё-таки можно (пример от самой Windows — WinKey+R).
Но сделать надо полагать, дело в том, что владельцем хоткея является Shell_TrayWnd (таксбар), а он и так был поверх всех окон. Надо покопать.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение sosed213 » 03.04.2012 (Вт) 6:48

Меня тоже раздрожает когда печатаешь текст не глядя на экран, а подняв глаза видишь что весь тескт ушел в другое окно...

Но моя программа сама никогда не вылезет, и там вообще нет текстовых полей ( :oops: )

Была идея сделать цыкл Do .. Loop в котором условие когда моя форма станет активной, а в теле цикла всячески пытаться передавать ей фокус (но на практике оказалась бредово)
Вложения
Mydisk.jpg
Интерфейс моей программы
Mydisk.jpg (43.6 Кб) Просмотров: 3217
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

NashRus
Постоялец
Постоялец
 
Сообщения: 388
Зарегистрирован: 18.03.2006 (Сб) 1:16

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение NashRus » 03.04.2012 (Вт) 7:28

Google Desktop юзает двойной Ctrl.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 03.04.2012 (Вт) 7:40

По поводу двойного Ctrl - должен быть важен не только факт, что Ctrl был нажат 2 раза, но и интервал между ними.

Почему не передаётся фокус, есть немного другая идея. Если Ctrl всё ещё нажат в момент активации окна программы, оно не может стать активным. А если оно уже начало мигать, то BringWindowToTop не помогает. Попробуй отображать его не сразу, а с задержкой в четверть секунды, например.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение Хакер » 03.04.2012 (Вт) 8:59

NashRus писал(а):Google Desktop юзает двойной Ctrl.

Гори они в аду.
Исползовать двойной Ctrl можно только в полноэкранных играх, где Ctrl выполняет функцию прыжка или приседания. А в общем случае: только в не многооконных средах, где Ctrl выполняет функцию, а не служит модификатором и используется в сочетаниях.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение Kostyan » 03.04.2012 (Вт) 9:28

Сейчас попробовал банально сделать форму видимой Me.Visible = True, и форма вылезла поверх всех окон и стала активной, не важно какие окна были при этом активны, браузер, месседжер или видеоплеер. Только если есть окно которое установлено поверх всех, то форма появляется за ним, но фокус ввода всё-равно перехватывает на себя.
Попробуй.
Нет ничего невозможного для человека с интеллектом.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение Хакер » 03.04.2012 (Вт) 9:48

У тебя 9x что-ли? В нормальных системах такого нет.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение Kostyan » 03.04.2012 (Вт) 9:49

Нет, у меня Win7. Форма запускается с Visible=False, и по таймеру Visible=True. Всё работает.
Нет ничего невозможного для человека с интеллектом.

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение sosed213 » 03.04.2012 (Вт) 9:57

Попробовал с задержкой давать фокус форме через SetTimer

Комбинировал
Код: Выделить всё
    'Always On Top
    SetWindowPos hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
    ' Not Always On Top
    SetWindowPos hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
   
    Debug.Print SetForegroundWindow(hwnd)
    Debug.Print BringWindowToTop(hwnd)
    Debug.Print SetFocusAPI(hwnd)
    Debug.Print SetActiveWindow(hwnd)



Пока безрезультатно, максимум, форма выходит на передний план, но все равно мигает, т.е. фокус остается у прежнего окна :(


P.S. Находил много похожих начатых топиков, но решение так и не было, странно... Странно что такой пустяк, а столько заморочки :?
P.S. А еще, пробовал по таймеру, каждые 10 секунд форму показывать, а сам в это время браузер сделал активным (ну чтобы проверять) и тоже ничего.
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

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

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение Kostyan » 03.04.2012 (Вт) 10:06

sosed213 писал(а):каждые 10 секунд форму показывать... и тоже ничего.

Как ты её показываешь? Методом Show? Попробуй Visible=True, у меня работает.
Нет ничего невозможного для человека с интеллектом.

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение sosed213 » 03.04.2012 (Вт) 10:11

В таймере:
Код: Выделить всё
    If Not (Me.WindowState = 0) Then Me.WindowState = 0
    Me.Show
    SetTimerVisible Me.hwnd, 100


В модуле
Код: Выделить всё
Public Sub SetTimerVisible(ByVal hwnd As Long, Optional ByVal kTimer As Long = 0&)
    SetTimer hwnd, 213, kTimer, AddressOf TimerProc
End Sub

Private Sub TimerProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal dwTime As Long)
    KillTimer hwnd, idEvent
    Select Case idEvent
    Case 213

    'Always On Top
    SetWindowPos hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
    ' Not Always On Top
    SetWindowPos hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
   
    Debug.Print SetForegroundWindow(hwnd)
    Debug.Print BringWindowToTop(hwnd)
    Debug.Print SetFocusAPI(hwnd)
    Debug.Print SetActiveWindow(hwnd)

  End Select
 
End Sub



А Me.Visible=True , сдесь точно не вариант (имхо)
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

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

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение Kostyan » 03.04.2012 (Вт) 11:32

А вообще есть ли разница между Form.Visible=True и Form.Show ?
Интуитивно я понимаю что должна быть, но MSDN для .Net говорит что это равнозначно. Для VB6 подобного разъяснения не нашел.
Нет ничего невозможного для человека с интеллектом.

VBTerminator
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 415
Зарегистрирован: 19.11.2008 (Ср) 20:10

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение VBTerminator » 03.04.2012 (Вт) 12:59

sosed213 писал(а):Изображение

"Refrash" и "Ejeckt" убили наповал. Вообще-то "Refresh" и "Eject".

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение sosed213 » 03.04.2012 (Вт) 13:13

VBTerminator , спс. :oops:
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 03.04.2012 (Вт) 13:43

sosed213 писал(а):Debug.Print SetForegroundWindow(hwnd)

Зачем ты это вызываешь? Убери и проверь ещё раз.

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение sosed213 » 03.04.2012 (Вт) 14:08

Убрал, все равно эффект FlashWindows (форма начинает мигать).

Вот хороший пример реализации: AIMP весит в трее, у меня настроено что по Ctrl + 0 (Ins) , он сворачивается/разворачивается. Вот хочу такого же эффекта добиться, находясь в любой программе (Word, Chrom, ....) .
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение Хакер » 03.04.2012 (Вт) 14:29

Возьми отладчик и посмотри, как он это делает.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение sosed213 » 03.04.2012 (Вт) 14:38

Я не умею "Дебугеть" чужие приложения (готовые exe-файлы). Пробовал Spy++ , но как то не разобрался :oops:
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение Хакер » 03.04.2012 (Вт) 15:23

Spy++ не имеет ничего общего с отладкой.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение sosed213 » 03.04.2012 (Вт) 15:29

Вот и я о том, не умею "Дебугеть"
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение ger_kar » 03.04.2012 (Вт) 16:09

Ну потихоньку надо этому учится. Во первых это просто интересно, во вторых это очень помогает в работе, в третьих можно запросто подсмотреть чужие тайны. Если хочешь этим заняться начни пожалуй с этого
По возможности прочитай все это, а
для начала прочти
это
Бороться и искать, найти и перепрятать

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение sosed213 » 03.04.2012 (Вт) 20:01

Попробовал, при разворачивании формы, послать

Код: Выделить всё
iResult = SendMessage(lnghWND, WM_LBUTTONDOWN, 0&, ByVal lParam)
iResult = SendMessage(lnghWND, WM_LBUTTONUP, 0&, ByVal lParam)


(ну думал съэмитировать нажатие мышки), и опять пока получилось
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение Хакер » 03.04.2012 (Вт) 20:19

sosed213. Ты же нашёл способ с временным TOPMOST-ом. Полагаю, что и остальные «нарушители порядка» так делают.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

VBTerminator
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 415
Зарегистрирован: 19.11.2008 (Ср) 20:10

Re: Отловить двойное нажатие Ctrl и передать форме фокус

Сообщение VBTerminator » 03.04.2012 (Вт) 20:34

sosed213 писал(а):Вот хочу такого же эффекта добиться, находясь в любой программе (Word, Chrom, ....) .


Хакер, зачем мучить человека страшными словами "отладка" и "ассемблер"?


sosed213, делаем проще:

1. Рассуждаем. Если AIMP реагирует на глобальные сочетания клавиш, значит он где-то их регистрирует с помощью WinAPI (а иначе нельзя).

2. Если используется API-функции, значит их имена прописаны в таблице импорта программы. Но это только в том случае, если программа не подобна Скайпу, поэтому скрестим пальцы на удачу. :)

3. Из вышесказанного следует, что нам нужна утилита, показывающая импорты исполняемых файлов. Возьмём, например, Dependency Walker, загрузим в неё AIMP и поищем функции, связанные с сочетаниями клавиш (hotkey). Находим аж две:

Изображение

4. Ищем описание этих функций в MSDN и выясняем, что эти функции (RegisterHotKey и UnregisterHotKey) прицепляют и отцепляют глобальное сочетание клавиш на/от окно. Помимо этого смотрим объявление, прототип и описание аргументов.

5. Для обработки сочетаний клавиш необходимо получать оконные сообщения. Значит, смотрим ещё в сторону SetWindowLong и WindowProc для обработки сообщений о нажатии горячих клавиш.

6. Используем полученные знания. Да, согласен, что без знания английского в компьютерных науках делать нечего.


Пример использования - во вложении.
Вложения
HotkeysTest.zip
Регистратор глобальных клавиш.
(3.13 Кб) Скачиваний: 85
Последний раз редактировалось VBTerminator 03.04.2012 (Вт) 21:08, всего редактировалось 5 раз(а).

След.

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

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

Сейчас этот форум просматривают: AhrefsBot и гости: 74

    TopList