Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 | 2 |

 

  Вопрос: Запуск проги по hotkey Добавлено: 06.09.02 10:17  

Автор вопроса:  Comanche

См. сабж.

Хотелось бы отдать "Ctrl" + "Scroll Lock" (к примеру) под запуск одного EXE-файла. Если на рабочем столе есть иконка к этой проге, то никаких проблем (параметр свойств иконки "Быстрый вызов"). А если на столе нет иконки?!

Вроде где-то было на эту тему, но не помню где ...

Заранее всем спасибо.

PS: Проге нельзя делать иконку на десктопе даже за пределами экранной области!

Ответить

  Ответы Всего ответов: 16  

Номер ответа: 1
Автор ответа:
 POST



Вопросов: 14
Ответов: 269
 Web-сайт: www.vbnet.ru
 Профиль | | #1
Добавлено: 06.09.02 11:10

Два зла:

1) Ярлык.

2) Сидеть резидентно в памяти и отлавливать клаву.

Ответить

Номер ответа: 2
Автор ответа:
 Comanche



Вопросов: 87
Ответов: 459
 Профиль | | #2 Добавлено: 06.09.02 11:52

2POST:

То, что есть эти два пути - мне понятно.

Как сидеть "резидентно" в памяти - ещё могу представить; тупой вариант - форма, которую Load, но никак не Show, а в ней - While..Wend с кучей DoEvents внутри него. Хотя наверняка это можно (и нужно) сделать как-то корректнее (если знаешь как - подскажи, плз).

А вот как "отлавливать клаву" - ваще не знаю: вертится в башке кусок из какого-то форумного топика, типа "вешай хук" и т.д., но точно не помню. Наверняка через API...

Так что по-прежнему прошу помощи!!!

Ответить

Номер ответа: 3
Автор ответа:
 POST



Вопросов: 14
Ответов: 269
 Web-сайт: www.vbnet.ru
 Профиль | | #3
Добавлено: 06.09.02 11:57

Ок. Тяни отсюда архив форума (он по-моему есть в полезных программах), там ищи тему "Кому нужен клаиватурный шпион" автора User Unknown. Это тот самый API и есть. Без всяких Whilе'ов и прочих напряжных для системы вещей.....

Ответить

Номер ответа: 4
Автор ответа:
 Comanche



Вопросов: 87
Ответов: 459
 Профиль | | #4 Добавлено: 06.09.02 14:22

Архив стянул. Причём - "полный" вариант. Дал в нём поиск по самым разным ключам - User Unknown, клавиатур*, шпион*, хук, hook и т.д. и т.п. - ничего не нашёл. М.б., проблема в том, что даже "полный" архив начинается только с января 2002 г.?! Ты не помнишь, примерно когда был этот топик?

Расширенный поиск Яндексом, с фокусировкой по VB-шным сайтам Рунета, тоже ничего не дал. Разве что опять: "пиши DLL и вешай хук WH_KEYBOARD" или что-то типа этого...

Ответить

Номер ответа: 5
Автор ответа:
 root



Вопросов: 12
Ответов: 147
 Web-сайт: www.vbnet.ru
 Профиль | | #5
Добавлено: 06.09.02 15:07

Declare Function RegisterHotKey Lib "user32" Alias "RegisterHotKey" (ByVal hwnd As Long, ByVal id As Long, ByVal fsModifiers As Long, ByVal vk As Long) As Long

 

· hWnd
Identifies the window that will receive WM_HOTKEY messages generated by the hot key. If this parameter is NULL, WM_HOTKEY messages are posted to the message queue of the calling thread and must be processed in the message loop.

· id
Specifies the identifier of the hot key. No other hot key in the calling thread should have the same identifier. An application must specify a value in the range 0x0000 through 0xBFFF. A shared dynamic-link library (DLL) must specify a value in the range 0xC000 through 0xFFFF (the range returned by the GlobalAddAtom function). To avoid conflicts with hot-key identifiers defined by other shared DLLs, a DLL should use the GlobalAddAtom function to obtain the hot-key identifier.

· fsModifiers
Specifies keys that must be pressed in combination with the key specified by the nVirtKey parameter in order to generate the WM_HOTKEY message. The fsModifiers parameter can be a combination of the following values:
MOD_ALT
 Either ALT key must be held down.
MOD_CONTROL
 Either CTRL key must be held down.
MOD_SHIFT
 Either SHIFT key must be held down.

· vk
Specifies the virtual-key code of the hot key.

 

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Ответить

Номер ответа: 6
Автор ответа:
 POST



Вопросов: 14
Ответов: 269
 Web-сайт: www.vbnet.ru
 Профиль | | #6
Добавлено: 06.09.02 15:54

BD, неужто снесли? Непустили в архив клавшпиёна?:о) Только честно.

Ответить

Номер ответа: 7
Автор ответа:
 root



Вопросов: 12
Ответов: 147
 Web-сайт: www.vbnet.ru
 Профиль | | #7
Добавлено: 06.09.02 16:15
Не знаю. Помойму я не удалял...

Ответить

Номер ответа: 8
Автор ответа:
 Comanche



Вопросов: 87
Ответов: 459
 Профиль | | #8 Добавлено: 06.09.02 16:35

2BD:

Thanks a lot, буду разбираться с энтой АПИ-функцией.

Может, заодно посоветуете, как ПРАВИЛЬНО сделать резидентную программу? Т.е. НЕ так, как описано выше (с циклом While...Wend).

Ответить

Номер ответа: 9
Автор ответа:
 Comanche



Вопросов: 87
Ответов: 459
 Профиль | | #9 Добавлено: 06.09.02 19:29

Насколько я смог понять, поэкспериментировав немного, функция RegisterHotKey мне не подходит, т.к. она завязана на hWnd конкретного окна, в которое посылаются нажатия "горячих клавиш". Мне же нужно, чтобы вне зависимости от того, какое окно в настоящий момент имеет фокус (и принимает нажатия), происходил бы анализ нажатий.

Я попробовал поиграться с функцией PeekMessage, но у неё та же беда (завязана на конкретное окно). Если при её вызове вместо hWnd поставить NULL (а в MSDN написано, что так можно делать, если хотим анализировать нажатия, адресованные ВСЕМ), то компилятор VB ругается: мол, недопустимое использование пустого указателя! Да даже если этот NULL не ставить, а оставить для простоты (на время отладки) Me.hWnd, то в нижеследующем примере получается забавная штука:

[code]

Private Const WM_KEYUP = &H101

Private Const PM_NOREMOVE = &H0

Private bCancel as Boolean

Private Sub Form_Load()

Dim Message As Msg

Me.Show

bCancel = False

Do While Not (bCancel)

If PeekMessage(Message, Me.hWnd, WM_KEYUP, WM_KEYUP, PM_NOREMOVE) Then

st = st + Chr(Message.wParam)

End If

DoEvents

Loop

End Sub

Private Sub Form_Unload(Cancel As Integer)

bCancel = True

Debug.Print st

End Sub


[/code]

- в переменной st накапливаются НЕ ВСЕ нажимаемые символы (особенно, если нажимать

быстро)!

Я, наверное, чего-то не догоняю принципиально. Хотя вроде смотрел всё в MSDN-е ...

Ответить

Номер ответа: 10
Автор ответа:
 root



Вопросов: 12
Ответов: 147
 Web-сайт: www.vbnet.ru
 Профиль | | #10
Добавлено: 06.09.02 21:00

Мона через подкласс или так:

 

Private Const MOD_ALT = &H1
Private Const MOD_CONTROL = &H2
Private Const MOD_SHIFT = &H4
Private Const PM_REMOVE = &H1
Private Const WM_HOTKEY = &H312
Private Type POINTAPI
    x As Long
    y As Long
End Type
Private Type Msg
    hWnd As Long
    Message As Long
    wParam As Long
    lParam As Long
    time As Long
    pt As POINTAPI
End Type
Private Declare Function RegisterHotKey Lib "user32" (ByVal hWnd As Long, ByVal id As Long, ByVal fsModifiers As Long, ByVal vk As Long) As Long
Private Declare Function UnregisterHotKey Lib "user32" (ByVal hWnd As Long, ByVal id As Long) As Long
Private Declare Function PeekMessage Lib "user32" Alias "PeekMessageA" (lpMsg As Msg, ByVal hWnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long, ByVal wRemoveMsg As Long) As Long
Private Declare Function WaitMessage Lib "user32" () As Long
Private bCancel As Boolean
Private Sub ProcessMessages()
    Dim Message As Msg
    'loop until bCancel is set to True
    Do While Not bCancel
        'wait for a message
        WaitMessage
        'check if it's a HOTKEY-message
        If PeekMessage(Message, Me.hWnd, WM_HOTKEY, WM_HOTKEY, PM_REMOVE) Then
            'minimize the form
            WindowState = vbMinimized
        End If
        'let the operating system process other events
        DoEvents
    Loop
End Sub
Private Sub Form_Load()
    'KPD-Team 2000
    'URL: http://www.allapi.net/
    'E-Mail: KPDTeam@Allapi.net
    Dim ret As Long
    bCancel = False
    'register the Ctrl-F hotkey
    ret = RegisterHotKey(Me.hWnd, &HBFFF&, MOD_CONTROL, vbKeyF)
    'show some information
    Me.AutoRedraw = True
    Me.Print "Press CTRL-F to minimize this form"
    'show the form and
    Show
    'process the Hotkey messages
    ProcessMessages
End Sub
Private Sub Form_Unload(Cancel As Integer)
    bCancel = True
    'unregister hotkey
    Call

Ответить

Номер ответа: 11
Автор ответа:
 Comanche



Вопросов: 87
Ответов: 459
 Профиль | | #11 Добавлено: 06.09.02 22:06

Между прочим, энтот пример я и использовал при своих экспериментах. И именно на нём я и наступил на грабли, что у RegisterHotKey() обязательно должен быть какой-нить hWnd, а NULL (обещанный MSDN-ом) - не срабатывает ... Так что этот пример - не в тему, уж не обессудь.

Постой - постой ... минуточку ... А что если я внутри цикла (или по таймеру) буду через АПИ опрашивать, какое окно сейчас активно, и именно егойный hWnd скармливать RegisterHotKey ?!

Что скажете?! Правда, я не знаю, как это сделать, но если уж в VB есть AppActivate, то и АПИ должна быть похожая.

Вообще говоря, мой вопрос сможет решить, наверное, только человек, съевший собаку на PeekMessage() - нутром чую, что через неё должно решаться!

PS: А как это у вас так ловко получается вставить в топик VB-код с сохранением всего форматирования из VB IDE? Поделитесь, плиз!

 

Ответить

Номер ответа: 12
Автор ответа:
 MAGNUS



Вопросов: 12
Ответов: 430
 Профиль | | #12 Добавлено: 06.09.02 22:23

Странно... Я думал что ты именно активные окна и скармливал, а оно все равно не получалось :) Конечно активное!

Public Declare Function GetActiveWindow Lib "user32" Alias "GetActiveWindow" () As Long
Ета фукция получает хендл активного окно которое имеет фокус ввода, ИМХО именно ето тебе и нужно :).

И параметров никаких не надо, просто возвращает хендл.

Ответить

Номер ответа: 13
Автор ответа:
 MAGNUS



Вопросов: 12
Ответов: 430
 Профиль | | #13 Добавлено: 06.09.02 22:34

Только вот в етом случае будет у тебя проблема если откритич окон нет, тогда есть идея использовать хендл рабочего стола как окна верхнего уровня, не зная сработает ли , но попробовать можно.

Public Declare Function GetDesktopWindow Lib "user32" () As Long

hwnd = GetDesktopWindow()

Попробуй.

Ответить

Номер ответа: 14
Автор ответа:
 root



Вопросов: 12
Ответов: 147
 Web-сайт: www.vbnet.ru
 Профиль | | #14
Добавлено: 07.09.02 07:52

Comanche :
> Между прочим, энтот пример я и использовал при своих экспериментах. И именно на нём я и наступил на грабли, что у RegisterHotKey() обязательно должен быть какой-нить hWnd.

Hwnd нужен того окна, которому надо сообщить о нажатии на комбинацию кнопок. А как ты собрался получить событие, если передаешь NULL? Твоему окну придет сообщение WM_HOTKEY - т.е. делай подкласс и отлавливай мессаги СВОЕГО окна, а не лезь к чужим.

Ответить

Номер ответа: 15
Автор ответа:
 Comanche



Вопросов: 87
Ответов: 459
 Профиль | | #15 Добавлено: 07.09.02 10:03

Всем спасибо,

ларчик открывался гораздо проще, чем я думал - в другом форуме посоветовали использовать ... как вы думаете, что? - GetAsyncKeyState() !!! вот уж действительно - "незаслуженно забытую". Она не ловит сложных комбинаций, как я мог заметить (где более одной клавиши-modifier), но для моей задачи вполне сойдёт. Воткнул её в событие Timer таймера и теперь наслаждаюсь.

Но вопрос про то, как КОРРЕКТНО сделать резидентную программу, - оставляю открытым. Или, может, его лучше выделить в отдельный топик, как думаете?

Ответить

Страница: 1 | 2 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам