C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Как перехватить нажатие юзером Ctrl+Alt+Del?
** genchik
Отправлено: 16.04.2005, 07:15


Не зарегистрирован







как можно определить и перехватить нажатие пользователем клавиш Ctrl+Alt+Del, чтобы можно было до стандарного вызова таскмесенджера выполнить нужный код? есть хук, который позволяет залочить клаву и мышь, но по нажатию на эти клавиши все на смарку sad.gif.

Подскажите плиз!!! sad.gif
FataLL
Отправлено: 16.04.2005, 07:52


Дежурный стрелочник

Группа: Участник
Сообщений: 37



Этот хук должен быть в длл. Это так?
Sl@Sh
Отправлено: 16.04.2005, 19:06


Мастер участка

Группа: Участник
Сообщений: 383



В заголовочном файле :
CODE

#define WM_KEYPRESS WM_HOTKEY
//....
private : int KeyAtom;
void __fastcall OnHotKeyPress(TMessage &Message);

public :
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_KEYPRESS, TMessage, OnHotKeyPress)
END_MESSAGE_MAP(TComponent)


В модуле :
CODE

//Где-то, например в OnCreate
KeyAtom = GlobalAddAtom("HotKey");
RegisterHotKey(Handle, KeyAtom, MOD_CONTROL | MOD_ALT, VK_DELETE);

//.....

//Обработчик сообщения
void __fastcall TfmMain::OnHotKeyPress(TMessage &Message)
{
unsigned char VirtualKey;
UINT Mod1, Mod2, ModKey;

ModKey = LOWORD(Message.LParam);
VirtualKey = HIWORD(Message.LParam);

if ((ModKey == MOD_ALT | MOD_CONTROL)) & (VirtualKey == VK_DELETE))
{
//..........
}
}

//Где-то, например в OnDestroy
UnregisterHotKey(Handle, KeyAtom);
GlobalDeleteAtom(KeyAtom);


Поидее всё. Конечно это не лучший вариант, но должен работать. Кстати без какой-либо библиотеки

Удачи !

Отредактировано Sl@Sh — 16/04/2005, 19:08
FataLL
Отправлено: 17.04.2005, 12:34


Дежурный стрелочник

Группа: Участник
Сообщений: 37



Хотелось бы пояснений. Вот, что у меня:
Unit1.h
CODE

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>

#define WM_KEYPRESS WM_HOTKEY
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
   void __fastcall FormCreate(TObject *Sender);
   void __fastcall FormDestroy(TObject *Sender);
private: // User declarations
public:  // User declarations
   __fastcall TForm1(TComponent* Owner);
private:
   int KeyAtom;
   void __fastcall OnHotKeyPress(TMessage &Message);

public:
   BEGIN_MESSAGE_MAP
       MESSAGE_HANDLER( WM_KEYPRESS, TMessage, OnHotKeyPress )
   END_MESSAGE_MAP(TComponent)
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------

Unit1.cpp
CODE

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
   : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
   KeyAtom = GlobalAddAtom( "HotKey" );
   RegisterHotKey( Handle, KeyAtom, MOD_CONTROL | MOD_ALT, VK_DELETE );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
   UnregisterHotKey( Handle, KeyAtom );
   GlobalDeleteAtom( KeyAtom );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::OnHotKeyPress( TMessage &Message )
{
   unsigned char VirtualKey;
   UINT ModKey;

   ModKey = LOWORD( Message.LParam );
   VirtualKey = HIWORD( Message.LParam );

   if( (ModKey == MOD_ALT | MOD_CONTROL) & (VirtualKey == VK_DELETE) )
   {
       MessageBox(
               0,
               "Ctrl + Alt + Del pressed!!!",
               "GlobalHook",
               MB_ICONEXCLAMATION | MB_OK
           );
   }
}
//---------------------------------------------------------------------------

не работает! В ХР, по крайней мере... Таскмэнеджер все равно появляется. sad.gif
FataLL
Отправлено: 17.04.2005, 13:29


Дежурный стрелочник

Группа: Участник
Сообщений: 37



Проверил. Не работает здесь
CODE

if( !RegisterHotKey( Handle, KeyAtom, MOD_CONTROL | MOD_ALT, VK_DELETE ) )
{
MessageBox( 0, "XpeH", "Bom", MB_OK );
}

Выводится сообщение. Так я, почему-то, и думал сразу. Кстати, OnHotKeyPress под ХР вообще не срабатывает. На 9х не пробовал, нету. Может, это только для ХР справедливо wink.gif И, на самом деле, не понимаю вообще взаимосвязь между регистрированием атома и объявлением своей функции обработки нажатия клавиш cool.gif

Отредактировано FataLL — 17/04/2005, 13:35
Sl@Sh
Отправлено: 17.04.2005, 17:48


Мастер участка

Группа: Участник
Сообщений: 383



QUOTE (FataLL @ 17/04/2005, 13:29)
И, на самом деле, не понимаю вообще взаимосвязь между регистрированием атома и объявлением своей функции обработки нажатия клавиш cool.gif

ID горячей клавиши может лежать в разных диапазонах. Всё зависит от того, где его используют. Функция GlobalAddAtom (а точнее её возвращ. значение) используеться, чтобы избежать конфликтов между гор. клавишами различных процессов.

Кстати, у меня ХР, и всё работает нормально smile.gif
Sl@Sh
Отправлено: 17.04.2005, 17:55


Мастер участка

Группа: Участник
Сообщений: 383



QUOTE (FataLL @ 17/04/2005, 12:34)
не работает! В ХР, по крайней мере... Таскмэнеджер все равно появляется. sad.gif

А кто вам сказал, что он должен появиться ? biggrin.gif
Я написал пример перехвата клавиш, а дальше дело за вами.
В постановке вопроса именно это и было.

to genchik
Совсем не обязательно горячую клавишу отлавливать. Тем более, что диспетчер задач может запуститься раньше (я не проверял, но поидее так будет), чем ваша прога среагирует.

Можно просто ловить окно диспетчера, а когда словили — временно (пока ваш код выполняется), спрятать. Потом только показать

Успехов вам и genchik и FataLL !
FataLL
Отправлено: 18.04.2005, 10:29


Дежурный стрелочник

Группа: Участник
Сообщений: 37



2Sl@Sh
Еще раз официально заявляю: КОД НЕ РАБОТАЕТ. Пробовал на другой машине с ХР. GetLastError сообщает, что "такая комбинация клавиш уже используется". Это именно для Ctrl+Alt+Del. Другие комбинации работают. Так что вопрос открыт.

Предлагаю все-таки начать с длл. Так написано в хэлпе от МС.

Отредактировано FataLL — 18/04/2005, 10:30
Konstantine
Отправлено: 18.04.2005, 11:56


Мастер участка

Группа: Модератор
Сообщений: 545



а вообще, если верить мелкософту, то Ctrl+Alt+Del не перехватываются... — для этого и заставляет перед вводом пассворда при входже в систему (для nt/2k/xp) нажимать сию комбинацию cool.gif
Sl@Sh
Отправлено: 18.04.2005, 17:03


Мастер участка

Группа: Участник
Сообщений: 383



to FataLL
Вы правы, извините. Просто я не тестировал код именно на этих клавишах.
Похоже винда не даёт перехватить клавиши. Я уже даже пробовал их таймером "словить", всё равно глухо sad.gif

Вот правда можно так обойти :
Запретить винде реакцию на клавиши, тогда отловить их и после своего кода уже запустить диспетчер.

Чтобы запретить реакцию на CTRL + ALT + DEL можно использовать
вот эту функцию — SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1, 0, 0);

Однако у меня она ничего не запрещает sad.gif
Может в других ОС (не ХР) работает ?
genchik
  Отправлено: 19.04.2005, 02:07


Ученик-кочегар

Группа: Участник
Сообщений: 8



Спасибо за активное участие. Хорошо было бызапихать перехват в ДЛЛ. В принципе суть не в том, чтобы залочить эти клавиши. Надо просто компы лочить в салоне, но процесс программы можно убить в таксмесенжере, для этого и понадобилось перехватывать эти нажатия. Может есть варианты для другой блокировки? скрывать процесс нельзя по некоторым соображениям sad.gif
olegenty
Отправлено: 19.04.2005, 07:02


Ветеран

Группа: Модератор
Сообщений: 2412



а пользователя бесправным сделать не судьба? не пробовал у него права администратора отбирать? так попробуй. ты сам удивишься, как это эффективно: он не только задачи из таск-менеджера удалять не сможет, а ещё много чего. странно, что это всё ещё не сделано. админа — на мыло. smile.gif
Георгий
Отправлено: 19.04.2005, 10:23


Почетный железнодорожник

Группа: Модератор
Сообщений: 874



у нас где то в FAQ было как сделать программу не убиваемой. там предлагалось получив сообщение от винды о закрытии программы запускать свою копию.
genchik
Отправлено: 22.04.2005, 01:54


Ученик-кочегар

Группа: Участник
Сообщений: 8



For olegenty:
программа создается не для конкретного заведения, а для самых различных и там может не быть такого умного (я не ерничаю) человека как ты! smile.gif

Теперь насчет неубиваемости. она (программа) неубиваема уже smile.gif , но это не решает некоторых проблемм

Отредактировано genchik — 22/04/2005, 01:55

Вернуться в Вопросы программирования в C++Builder