Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.04.2008, 00:47   #1
Holis
 
Регистрация: 06.04.2008
Сообщений: 3
По умолчанию Блокировка клавиш в определенном окне

Здравствуйте, уважаемые, программисты, подскажите, пожалуйста, как реализовать выборочную блокировку клавиш в окне чужой программы? Например, у нас есть 2 активных окна, в одном из них надо выборочно заблокировать нажатие клавиш, что б при этом можно было работать в другом активном окне, это надо для того, что б не посылались сообщения окну в том котором мы не работаем. Пробовал сделать это через хук WH_GETMESSAGE, не вышло привязать хук к определенному окну, вышло заблокировать клавиши везде, так как при нажатии клавиш не передается дескриптор окна. Заранее спасибо.
Holis вне форума Ответить с цитированием
Старый 06.04.2008, 01:04   #2
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Цитата:
Сообщение от Holis Посмотреть сообщение
......так как при нажатии клавиш не передается дескриптор окна.
С чего Вы это взяли?


Цитата:
GetMsgProc Function
Код:
LRESULT CALLBACK GetMsgProc(
    int code,
    WPARAM wParam,
    LPARAM lParam
);
Parameters

code
[in] Specifies whether the hook procedure must process the message. If code is HC_ACTION, the hook procedure must process the message. If code is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.
wParam
[in] Specifies whether the message has been removed from the queue. This parameter can be one of the following values.
PM_NOREMOVE
Specifies that the message has not been removed from the queue. (An application called the PeekMessage function, specifying the PM_NOREMOVE flag.)
PM_REMOVE
Specifies that the message has been removed from the queue. (An application called GetMessage, or it called the PeekMessage function, specifying the PM_REMOVE flag.)
lParam
[in] Pointer to an MSG structure that contains details about the message.
Цитата:
MSG Structure
Код:
typedef struct {
    HWND hwnd;
    UINT message;
    WPARAM wParam;
    LPARAM lParam;
    DWORD time;
    POINT pt;
} MSG, *PMSG;
Members

hwnd
Handle to the window whose window procedure receives the message.

message
Specifies the message identifier. Applications can only use the low word; the high word is reserved by the system.
wParam
Specifies additional information about the message. The exact meaning depends on the value of the message member.
lParam
Specifies additional information about the message. The exact meaning depends on the value of the message member.
time
Specifies the time at which the message was posted.
pt
Specifies the cursor position, in screen coordinates, when the message was posted.
B_N вне форума Ответить с цитированием
Старый 06.04.2008, 15:54   #3
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

поясню чтобы не было лишних вопросов
в функции перехватчике в параметре lParam содержится указатель на структуру MSG. В этой структуре в поле hwnd содержится хендл искомого окна.
rpy3uH вне форума Ответить с цитированием
Старый 07.04.2008, 00:04   #4
Holis
 
Регистрация: 06.04.2008
Сообщений: 3
По умолчанию

Теперь понял в чем была ошибка, я не учел что у каждого объекта на форме окна свой дескриптор. Но теперь возникла другая проблема, блокируются не все клавиши, не блокируются основные стрелочки на клавиатуре. В чем может быть проблема? В программе которой я блокирую клавиши класс окна D3D Window. Вот обработка сообщений:

Код:
if (msg.hwnd=Handle) then
begin
          if(msg.message=WM_KEYDOWN)or(msg.message=WM_KEYUP) then
          begin
            msg.message:=0;
          end;
end;
Holis вне форума Ответить с цитированием
Старый 07.04.2008, 08:18   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
В чем может быть проблема?
Например в том что твой хук не является последним установленным.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 07.04.2008, 15:43   #6
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Цитата:
Сообщение от Holis Посмотреть сообщение
класс окна D3D Window
Скорее всего прога использует Direct3D. Если она использует ещё и DirectInput, то вполне можнт быть, что перехват не работает.
Somebody вне форума Ответить с цитированием
Старый 08.04.2008, 00:51   #7
Holis
 
Регистрация: 06.04.2008
Сообщений: 3
По умолчанию

Цитата:
Сообщение от Somebody Посмотреть сообщение
Скорее всего прога использует Direct3D. Если она использует ещё и DirectInput, то вполне можнт быть, что перехват не работает.
А если она использует DirectInput, то возможно как-то другим образом заблокировать клавиши те, что не блокируются через хук?
Holis вне форума Ответить с цитированием
Старый 11.04.2008, 21:14   #8
vitalik007
Дельфист
Форумчанин
 
Аватар для vitalik007
 
Регистрация: 14.08.2007
Сообщений: 317
По умолчанию

У меня похожая проблема.Пишу кейлогер но он должен отлавливать нажатия в определенном окне.
я делаю так
ДЛЛ
Код:
library Project1;


uses
  WinTypes,
  WinProcs,
  Messages;

const
WinTitle='Ozi Keylogger';
keyEvent=WM_USER+1;
var hook:HHOOK;

Function KeyHookProc(code:integer;w:wparam;l:lparam):longint;stdcall;
var
wnd:HWND;
begin
if (Code=Hc_action) and (l <> l or $8000 shl 16)
                      and (l <> l or $8000 shl 15)  then
begin
wnd:=findwindow(wintitle,nil);
sendmessage(wnd,keyEvent,w,l);
end;
result:=CallNextHookEx(hook,code,w,l);
end;

procedure SetKeyHook;export;
begin
Hook:=SetWindowsHookEx(WH_GETMESSAGE,@KeyHookProc,hinstance,0);
end;

procedure DelKeyHook;export;
begin
if Hook<>0 then
UnhookWindowsHookEx(hook);
hook:=0;
end;

exports
SetKeyHook name 'SetKeyHook',
DelkeyHook name 'DelKeyHook';

begin
end.
Сама программа(скарочана-укарочана)
Код:
program Keyloger;

uses
  windows,
  sysutils;

const
WinTitle='Ozi Keylogger';

var
Handle:HWND;
Wndclass:TwndClass;
msg:Tmsg;

function SetKeyHook:longint;external 'Project1.dll' name 'SetkeyHook';
function DelKeyfHook:longint;external 'Project1.dll' name 'DelkeyHook';


function WndProc(h,m,w,l:integer):integer;stdcall;
begin
Result:=DefWindowProc(h, m, w, l);
end;

procedure CW;
begin
 Wndclass.style:=CS_HREDRAW+CS_VREDRAW+CS_DBLCLKS;
  wndclass.lpfnWndProc:=@WndProc;
  wndclass.cbClsExtra:=0;
  wndclass.cbWndExtra:=0;
  wndclass.hInstance:=hinstance;
  wndclass.hIcon:=LoadIcon(hInstance,'MAINICON');
  wndclass.hCursor:=Loadcursor(Hinstance,IDC_ARROW);
  wndclass.hbrBackground:=COLOR_BTNTEXT;
  wndclass.lpszMenuName:='';
  wndclass.lpszClassName:=WinTitle;
  RegisterClass(wndclass);
  handle:=CreateWindowEx(WS_EX_WINDOWEDGE,wintitle,'Keyloger',WS_MINIMIZEBOX or WS_CAPTION or
                         WS_SYSMENU,integer(CW_USEDEFAULT), integer(CW_USEDEFAULT),170,60,0,0,hinstance,nil);
  showWindow(handle,SW_HIDE);
 end;


begin
CW;   //Создается окно
SetkeyHook;
while Getmessage(msg,0,0,0) do
begin
  TranslateMessage(msg);
  dispatchMessage(msg);
end;
end.
но у меня не работает.Бывает даже запустится и остановится на первой строчки основной программы.
И объясните где проверять Является ли окно нужным.проверка будет по GetWindowText.
ICQ-465033557
WINDOWS CE THE BEST

Последний раз редактировалось B_N; 07.07.2008 в 23:50.
vitalik007 вне форума Ответить с цитированием
Старый 12.04.2008, 06:35   #9
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Цитата:
Сообщение от vitalik007 Посмотреть сообщение
...........но у меня не работает.Бывает даже запустится и остановится на первой строчки основной программы.
И объясните где проверять Является ли окно нужным.проверка будет по GetWindowText.
У Вас какая-то крайне загадочная хуковая процедура.
Если интересно, могу предложить пример, на C, разумеется, в котором, в частности реализован хук WH_GETMESSAGE. Пример не совсем оптимальный, писался (но не понадобился) для немного других целей, а вопросов по хукам по-прежнему полным-полно, так что выложу, пожалуй.

1. Установщик хука.
Код:
// hookapp.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

#include "../hookdll/hookdll.h"

HANDLE		hCommSignal			= NULL;
HANDLE		hStopThreadSignal	= NULL;

LRESULT	CALLBACK	MainDlgProcW	(HWND, UINT, WPARAM, LPARAM);
DWORD	WINAPI		BeepThreadProc	(LPVOID lpParameter);


// Особого интереса это приложение не представляет, его основная задача - 
// инициировать установку хука (просто путём загрузки "hookdll.dll" и "пищать"
// в ответ нажатие кнопки "=" во всех возможных калькуляторах
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
	HMODULE hHookDll	= LoadLibraryW(L"hookdll.dll");
	hCommSignal			= CreateEventW(NULL, FALSE, FALSE, SIGNAL_NAME);
	hStopThreadSignal	= CreateEventW(NULL, FALSE, FALSE, NULL);

	if(hCommSignal && hStopThreadSignal){
		HANDLE hBeepThread = CreateThread(NULL, 0, BeepThreadProc, 0, 0, NULL);

		if(hBeepThread){
			DialogBoxW(hInstance, (LPCWSTR)IDD_DIALOG1, GetDesktopWindow(), (DLGPROC)MainDlgProcW);
			SetEvent(hStopThreadSignal);
			WaitForSingleObject(hBeepThread, 5000);
			CloseHandle(hBeepThread);
		}
		CloseHandle(hCommSignal);
		CloseHandle(hStopThreadSignal);
	}
	FreeLibrary(hHookDll);
	return 0;
}

DWORD WINAPI BeepThreadProc(LPVOID lpParameter)
{
	if(hStopThreadSignal && hCommSignal){
		DWORD dwResult;
		HANDLE Signals[2] = {hStopThreadSignal, hCommSignal};
		for(;;){
			dwResult = WaitForMultipleObjectsEx(2, Signals, FALSE, INFINITE, FALSE);
			if(WAIT_OBJECT_0 + 0 == dwResult){ // Signals[0] (hStopThreadSignal)
				break;
			}
			else if(WAIT_OBJECT_0 + 1 == dwResult){ // Signals[1] (hCommSignal)
				Beep(1200, 30);
			}
		}
	}
	return 0;
}

LRESULT CALLBACK MainDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg) {
	case WM_INITDIALOG:
		return TRUE;
	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
			EndDialog(hDlg, LOWORD(wParam));
			return TRUE;
		}
		break;
	}
	return FALSE;
}
B_N вне форума Ответить с цитированием
Старый 12.04.2008, 06:37   #10
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

2. DLL

Код:
// hookdll.h
#ifdef HOOKDLL_EXPORTS
#define HOOKDLL_API __declspec(dllexport)
#else
#define HOOKDLL_API __declspec(dllimport)
#endif

#define SIGNAL_NAME		L"___HOOK___SIGNAL___"

#ifdef __cplusplus
extern "C" {
#endif
////////////////

#ifdef __cplusplus
}
#endif
---------------------------------------------
Код:
// hookdll.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "hookdll.h"
#include <stdio.h>

#define HOOK_DLL_NAMEA	"hookdll.dll"
#define HOOK_DLL_NAMEW	L"hookdll.dll"

BOOL	SetHook			();
VOID	RemoveHook		();

LRESULT CALLBACK CalcWndProcHook(int, WPARAM, LPARAM);
LRESULT CALLBACK CalcGetMsgHook(int, WPARAM, LPARAM);
LRESULT CALLBACK InstWndProcHook(int, WPARAM, LPARAM);

LRESULT CALLBACK CalcSubClassWndProcA(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK CalcSubClassWndProcW(HWND, UINT, WPARAM, LPARAM);

typedef struct _THREAD_DATA{
	HHOOK		hCWPHook;
	HHOOK		hGMHook;
}THREAD_DATA, *PTHREAD_DATA;


//////////////////////////
DWORD				dwDataIndex;

BOOL				bIsCalc				= FALSE;
BOOL				bIsInstaller		= FALSE;
HANDLE				hCommSignal			= NULL;
HWND				hMainWindow			= NULL;
ULONG				ulInterceptCount	= 0;
HMODULE				hHookDll			= NULL;
WNDPROC				OldCalcWndProc		= NULL;

static const CHAR	aCalcClassName[]	= "SciCalc";
static const WCHAR	wCalcClassName[]	= L"SciCalc";

static const CHAR	aCalcImageName[]	= "calc.exe";
static const WCHAR	wCalcImageName[]	= L"calc.exe";

static const CHAR	aHookAppImageName[]	= "hookapp.exe";
static const WCHAR	wHookAppImageName[] = L"hookapp.exe";


///////////////////////////////

BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
	PTHREAD_DATA pThreadData;

	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		dwDataIndex = TlsAlloc();
		hCommSignal = CreateEventW(NULL, FALSE, FALSE, SIGNAL_NAME);
		// !!! No "break" here!
	case DLL_THREAD_ATTACH:
		pThreadData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(THREAD_DATA));
		TlsSetValue(dwDataIndex, pThreadData);
		SetHook();
		break;
	case DLL_THREAD_DETACH:
		RemoveHook();
		pThreadData = TlsGetValue(dwDataIndex);
		HeapFree(GetProcessHeap(), 0, pThreadData);
		TlsSetValue(dwDataIndex, NULL);
		break;
	case DLL_PROCESS_DETACH:
		CloseHandle(hCommSignal);
		TlsFree(dwDataIndex);
		break;
	}
    return TRUE;
}

BOOL SetHook()
{
    WCHAR			buf[256]; 
	WCHAR			*pLastSlash;
	PTHREAD_DATA	pThreadData = TlsGetValue(dwDataIndex);

	__try{
		wsprintfW(
			buf, 
			L"*** SetHook Called *** Process ID: %d, Thread ID : %d\n",
			GetCurrentProcessId(),
			GetCurrentThreadId()); 
		OutputDebugStringW(buf); 

		if(pThreadData && !pThreadData->hCWPHook){
			// Получаем имя стартовавшего модуля.
			// Не самая надежная проверка, но для примера сойдёт. :)
			GetModuleFileNameW(NULL, buf, 256);
			pLastSlash = wcsrchr(buf, L'\\');

			if(pLastSlash){
				pLastSlash ++;

				OutputDebugStringW(pLastSlash); 

				// Выясняем, является ли стартовавшее приложение
				// а) установщиком хука
				// б) калькулятором
				// в других случаях хук ставить не будем вообще. В таком случае наш 
				// хук будет держаться в системе пока работает установщик или
				// хотя бы один из калькуляторов с хуком. (Удобно при отладке хука и 
				// меньше тормозит систему). Поскольку действия, предпринимаемые хуком
				// разнятся в зависимости от его "владельца", ставим в каждом типе 
				// приложений свой хук
				
				bIsInstaller = (0 == wcsicmp(wHookAppImageName, pLastSlash));
				if(!bIsInstaller) bIsCalc = (0 == wcsicmp(wCalcImageName, pLastSlash));

				if(bIsCalc){
					pThreadData->hCWPHook = SetWindowsHookExW(
												WH_CALLWNDPROC, 
												CalcWndProcHook, 
												GetModuleHandleW(HOOK_DLL_NAMEW),
												0);
				}
				else if(bIsInstaller){
					pThreadData->hCWPHook = SetWindowsHookExW(
												WH_CALLWNDPROC, 
												InstWndProcHook, 
												GetModuleHandleW(HOOK_DLL_NAMEW),
												0);
				}
			}
			else { 
				OutputDebugStringA("Can't get filename"); 
			}
			OutputDebugStringA( pThreadData->hCWPHook ? "\nHook Installed\n" : "\nHook Not Installed\n");
		}
		return (pThreadData->hCWPHook != NULL);
	}
	__except(EXCEPTION_EXECUTE_HANDLER){
		OutputDebugStringA("Exception. *** SetHook ***\n");
		return FALSE;
	}
}

VOID RemoveHook()
{
	PTHREAD_DATA	pThreadData = TlsGetValue(dwDataIndex);
	__try{
		if(pThreadData){
			if(pThreadData->hCWPHook){
				UnhookWindowsHookEx(pThreadData->hCWPHook);
				pThreadData->hCWPHook = NULL;
			}
			if(pThreadData->hGMHook){
				UnhookWindowsHookEx(pThreadData->hGMHook);
				pThreadData->hGMHook = NULL;
			}
		}
	}
	__except(EXCEPTION_EXECUTE_HANDLER){
		OutputDebugStringA("Exception. *** RemoveHook ***\n");
	}
}

Последний раз редактировалось B_N; 12.04.2008 в 09:26.
B_N вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как сделать чтобы файл автоматически создался в определенном месте? DM_bite Помощь студентам 6 04.08.2008 19:11
как заставить работать макрос при определенном значении ячейки? Град Microsoft Office Excel 5 30.05.2008 16:06
Блокировка процессов Zeraim Операционные системы общие вопросы 5 17.04.2008 13:02
Блокировка точки !! ***СкаЙ*** Помощь студентам 1 13.06.2007 14:14