Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Перехват нажатия клавиши Win


Автор: mr.Anderson 18.3.2007, 11:07
Нужно запретить вызов панели Пуска, пока программа запущена. Т.е. до панели добраться "вручную" невозможно, об этом я уже позаботился. Остался только один метод ее вызова - это нажатие юзером кнопки Win. Как можно и этот метод убрать?

Автор: ama_kid 18.3.2007, 11:26
проблема стара, как мир... Его еще можно вызвать по Ctrl+Esc... smile 
Код

int __stdcall KeyboardProc(int nCode, DWORD wParam, DWORD lParam) // Блокировка системных клавиш
{
    static bool KeyStroke;
    static KBDLLHOOKSTRUCT *p;

    if (nCode < 0) return (int)CallNextHookEx(NULL, nCode, wParam, lParam);

    KeyStroke = FALSE;
    if (nCode == HC_ACTION)
    {
        switch(wParam)
        {
        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
        case WM_KEYUP:
        case WM_SYSKEYUP:
            p = (KBDLLHOOKSTRUCT *)lParam;
            KeyStroke = ((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)) ||
                        ((p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN)!=0)) ||
                        ((p->vkCode == VK_ESCAPE) && ((p->flags & LLKHF_ALTDOWN)!=0)) ||
                        ((p->vkCode == VK_ESCAPE) && ((GetKeyState(VK_CONTROL) & 0x8000)!=0)) ||
                        ((p->vkCode ==VK_F4) && ((p->flags & LLKHF_ALTDOWN)!=0));
            
            break;
        default:
            break;
        }
    }
  if (KeyStroke)
    return 666;
  else    
    return (int)CallNextHookEx(0, nCode, wParam, lParam);    

}
// При загрузке программы
...
try        
    {
        hHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)&KeyboardProc, GetModuleHandle(NULL), 0);
    }
    catch(...)
    {
        ;
    }
...

Автор: mr.Anderson 18.3.2007, 14:52
ama_kid, два вопроса.

1. При компиляции - ошибка "неизвестный символ hHook". Он и впрямь неизвестный, мы же его не объявляли?
2. Что значит "при запуске программы" ? В OnCreate формы? или как?

Автор: mr.Anderson 18.3.2007, 15:13
Сам же и отвечаю.

Ошибку hHook исправляем простым стиранием этого присваивания. То есть вместо
Код

try {
 hHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)&KeyboardProc, GetModuleHandle(NULL), 0);
}
catch(...)
{ ; }

Пишем так:
Код

try {
 SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)&KeyboardProc, GetModuleHandle(NULL), 0);
}
catch(...)
{ ; }

А насчет, где это писать - да, надо писать в OnCreate формы. Лучше в самом начале этого обработчика, если у вас там еще какой-нить код есть, имхо.

ama_kid, браво! Код мне не очень понятен, но у него есть три неоспоримых достоинства:

1. Безо всяких DLL. А то говорят, что без них никак.
2. Работает в любой системе (ну, в Windows, по крайней мере, точно).
3. Это превосходно и безотказно работает.

Огромное вам спасибо! От меня плюс в репутацию.

Автор: ama_kid 18.3.2007, 18:10
mr.Anderson
hHook - это значение, возвращаемое функцией SetWindowHookEx - фактически этой указатель на предыдущую функцию в цепочке хуков... Исправить удалением, конечно, в данном случае можно, но вообще правильней это значение (типа HHOOK) использовать в строке 32 моего кода
Код

    return (int)CallNextHookEx(hHook, nCode, wParam, lParam);  

тем самым мы передаем управление другой программе в цепочке, которая, возможно, повесила хук на клавиатуру...  И еще - при выходе из программы желательно делать 
Код

   UnhookWindowsHookEx(hHook);

Этим мы снимаем с клавиатуры низкоуровневый хук, что является хорошей практикой. Здесь тоже нужен этот hHook...
Цитата(mr.Anderson @  18.3.2007,  15:13 Найти цитируемый пост)
1. Безо всяких DLL. А то говорят, что без них никак.

Вообще, для того, чтобы повесить глобальный хук в системе - это обязательно делать через Dll, но для клавиатуры был введен специальный глобальный хук WH_KEYBOARD_LL (LowLevel), который можно вешать в своем процессе. Низкоуровневые хуки можно вешать на клавиатуру и мышь (WH_MOUSE_LL).

Автор: MuForum 31.8.2007, 20:58
#for all - Метод конечно обалденный, мне самому очень понравился, автору респект!

# for ama_kid  smile  

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