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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 12.04.2008, 06:39   #11
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Продолжение....
Код:
LRESULT CALLBACK CalcWndProcHook(int nCode, WPARAM wParam, LPARAM lParam)
{
	__try{
		PTHREAD_DATA	pThreadData = TlsGetValue(dwDataIndex);
		if( HC_ACTION == nCode){
			
			// Убедиться лишний раз в том, что хук вызван именно в калькуляторе никогда не вредно
			
			if(bIsCalc){
				CWPSTRUCT *pcwp = (CWPSTRUCT *)lParam;
				
				// Если хук уже нашел главное окно приложения и убедился, что это окно - калькулятор,
				// то идём по сокращщенному пути. В принципе, это можно было бы решить заменой 
				// указателя на функцию в отдельной глобальной переменной и вызывать её здесь - 
				// как всегда, любую задачу можно решить множеством способов
				
				if(hMainWindow){
					if(pcwp->hwnd == hMainWindow){
						if(pcwp->message == WM_COMMAND && LOWORD(pcwp->wParam) == 0x70){
							// 0x70 - это команда калькулятора, вызываемая при нажатии на "="
							// увеличиваем счётчик "срабатываний", 
							InterlockedIncrement(&ulInterceptCount);
							// выставляем глобальный сигнал и выходим
							SetEvent(hCommSignal);
							return 0;
						}
					}
				}
				else {
					
					// По-видимому наш хук ещё не нашел нужное окно или оно ещё не создано, 
					// продолжаем усиленно и разными методами проверять. 
					// Вообще говоря, здесь не помешает счётчик неудачных попыток
					
					if(pcwp->hwnd && GetParent(pcwp->hwnd) == NULL){
						if(GetWindowThreadProcessId(pcwp->hwnd, NULL) == GetCurrentThreadId()){
							if(IsWindowUnicode(pcwp->hwnd)){
								WCHAR wcClassName[32];
								if(GetClassNameW(pcwp->hwnd, wcClassName, 32) > 0){
									if(0 == lstrcmpW(wCalcClassName, wcClassName)) {
										// По-видимому мы нашли нужное окно.
										// Тогда еще перехватываем оконную функцию калькулятора

										OldCalcWndProc = (WNDPROC)SetWindowLongPtrW(
																		pcwp->hwnd, 
																		GWLP_WNDPROC, 
																		(LONG_PTR)CalcSubClassWndProcW);
										hMainWindow = pcwp->hwnd;
										pThreadData->hGMHook = SetWindowsHookExW(
																		WH_GETMESSAGE, 
																		CalcGetMsgHook,
																		GetModuleHandleW(HOOK_DLL_NAMEW),
																		GetCurrentThreadId());
									}
								}
							}
							else {
								CHAR cClassName[32];
								if(GetClassNameA(pcwp->hwnd, cClassName, 32) > 0){
									if(0 == lstrcmpA(aCalcClassName, cClassName)) {
										OldCalcWndProc = (WNDPROC)SetWindowLongPtrA(
																		pcwp->hwnd, 
																		GWLP_WNDPROC, 
																		(LONG_PTR)CalcSubClassWndProcA);
										hMainWindow = pcwp->hwnd;
										pThreadData->hGMHook = SetWindowsHookExA(
																		WH_GETMESSAGE, 
																		CalcGetMsgHook,
																		GetModuleHandleA(HOOK_DLL_NAMEA),
																		GetCurrentThreadId());
									}
								}
							}
						}
					}
				}
			}
		}
		return CallNextHookEx(pThreadData->hCWPHook, nCode, wParam, lParam);
	}
	__except(EXCEPTION_EXECUTE_HANDLER){
		OutputDebugStringA("Exception. *** CalcWndProcHook ***\n");
		return 0;
	}
}

// Это хук для WH_GETMESSAGE
// Блокирует работу "большого" Enter'а и цифр на обычной клавиатуре, 
// оставляет только расширенную

LRESULT CALLBACK CalcGetMsgHook(int nCode, WPARAM wParam, LPARAM lParam)
{
	__try{
		PTHREAD_DATA	pThreadData = TlsGetValue(dwDataIndex);
		if( HC_ACTION == nCode){
			LPMSG pmsg = (LPMSG) lParam;
			if(WM_KEYDOWN == pmsg->message || WM_KEYUP == pmsg->message){
				if(
					(VK_RETURN == pmsg->wParam && !(pmsg->lParam & (1 << 24)))
					||
					(pmsg->wParam >= '0' && pmsg->wParam <= '9')
				){
					FLASHWINFO fwi;

					fwi.cbSize		= sizeof(FLASHWINFO);
					fwi.dwFlags		= FLASHW_CAPTION;
					fwi.uCount		= 3;
					fwi.hwnd		= hMainWindow;
					fwi.dwTimeout	= 200;
					
					FlashWindowEx(&fwi);
					pmsg->message = WM_NULL;
				}
			}
		}
		return CallNextHookEx(pThreadData->hGMHook, nCode, wParam, lParam);
	}
	__except(EXCEPTION_EXECUTE_HANDLER){
		OutputDebugStringA("Exception. *** CalcGetMsgHook ***\n");
		return 0;
	}
}
B_N вне форума Ответить с цитированием
Старый 12.04.2008, 06:40   #12
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Продолжение....

Код:
// Это "пустой" хук, который мы ставим для установщика

LRESULT CALLBACK InstWndProcHook(int nCode, WPARAM wParam, LPARAM lParam)
{
	__try{
		PTHREAD_DATA	pThreadData = TlsGetValue(dwDataIndex);
		return CallNextHookEx(pThreadData->hCWPHook, nCode, wParam, lParam);
	}
	__except(EXCEPTION_EXECUTE_HANDLER){
		OutputDebugStringA("Exception. *** InstWndProcHook ***\n");
		return 0;
	}
}

// Новые оконные функции для главного окна калькулятора.
// Здесь мы можем организовать полную обработку идущих ему сообщений,
// в том числе отправлять сведения о них "куда следует" :).
//
// В данном варианте они просто включают/выключают Num Lock.

LRESULT CALLBACK CalcSubClassWndProcA(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (WM_NCACTIVATE == uMsg){
		BOOL bNumLockToggled = (GetAsyncKeyState(VK_NUMLOCK) & 1);
		if( (wParam && !bNumLockToggled) || (!wParam && bNumLockToggled) ) {
			keybd_event (VK_NUMLOCK, 0, KEYEVENTF_EXTENDEDKEY, NULL);
			keybd_event (VK_NUMLOCK, 0, KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY, NULL);
		}
		if(!wParam) return TRUE;
	}
	return OldCalcWndProc(hWnd, uMsg, wParam, lParam);
}

LRESULT CALLBACK CalcSubClassWndProcW(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (WM_NCACTIVATE == uMsg){
		BOOL bNumLockToggled = (GetAsyncKeyState(VK_NUMLOCK) & 1);
		if( (wParam && !bNumLockToggled) || (!wParam && bNumLockToggled) ) {
			keybd_event (VK_NUMLOCK, 0, KEYEVENTF_EXTENDEDKEY, NULL);
			keybd_event (VK_NUMLOCK, 0, KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY, NULL);
		}
		if(!wParam) return TRUE;
	}
	return OldCalcWndProc(hWnd, uMsg, wParam, lParam);
}

Последний раз редактировалось B_N; 12.04.2008 в 07:28.
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