Code:
#include <windows.h>
#include <vector>
#include <algorithm>
using namespace std;
#include "XMouseHook.h"
#include "../XimaSSS/WinMessages.hpp"
#include "MMTimer.h"
static HINSTANCE gInst;
HWND hWnd;
int __stdcall DllMain(HINSTANCE hInst, unsigned long,void*)
{
gInst = hInst;
hWnd = FindWindow("XimaSSS", "");
return 1;
}
/* */
/* Window Section */
/* */
class Blinker : public CMMTimerListener
{
public:
CMMTimer timer;
static const int n = 13;
bool state;
HWND hPrev;
Blinker(void) : state(true)
{
}
void fill(void)
{
RECT _bounds;
GetWindowRect(this->hPrev, &_bounds);
_bounds.bottom -= _bounds.top; _bounds.top = 0;
_bounds.right -= _bounds.left; _bounds.left = 0;
RECT rect;
HDC _dc = GetWindowDC(this->hPrev);
rect.top = 0; rect.left = 0; rect.bottom = _bounds.bottom; rect.right = this->n;
InvertRect(_dc, &rect);
rect.left = this->n; rect.bottom = this->n; rect.right = _bounds.right;
InvertRect(_dc, &rect);
rect.top = this->n; rect.left = rect.right - this->n; rect.bottom = _bounds.bottom;
InvertRect(_dc, &rect);
rect.left = this->n; rect.right -= this->n; rect.top = rect.bottom - this->n;
InvertRect(_dc, &rect);
ReleaseDC(hPrev, _dc);
state = false;
}
void clear(void)
{
RECT _bounds;
GetWindowRect(this->hPrev, &_bounds);
_bounds.bottom -= _bounds.top; _bounds.top = 0;
_bounds.right -= _bounds.left; _bounds.left = 0;
RECT rect;
HDC _dc = GetWindowDC(this->hPrev);
rect.top = 0; rect.left = 0; rect.bottom = _bounds.bottom; rect.right = this->n;
InvertRect(_dc, &rect);
rect.left = this->n; rect.bottom = this->n; rect.right = _bounds.right;
InvertRect(_dc, &rect);
rect.top = this->n; rect.left = rect.right - this->n; rect.bottom = _bounds.bottom;
InvertRect(_dc, &rect);
rect.left = this->n; rect.right -= this->n; rect.top = rect.bottom - this->n;
InvertRect(_dc, &rect);
ReleaseDC(hPrev, _dc);
state = true;
}
void change(HWND _hwnd)
{
timer.Stop();
if(!state)
clear();
state = true;
hPrev = _hwnd;
timer.Reset();
timer.Start(250, 0);
}
void Update(CMMTimer&)
{
if(state)
this->fill();
else
this->clear();
}
} blinker;
class Checker : public CMMTimerListener
{
public:
CMMTimer timer;
void Update(CMMTimer&)
{
POINT pt;
GetCursorPos(&pt);
HWND _hwnd = WindowFromPoint(pt);
if(_hwnd == 0 || _hwnd == blinker.hPrev)
return;
blinker.change(_hwnd);
}
} checker;
struct kbstruct {unsigned long vkCode;};
HHOOK WindowMouseHook;
HHOOK WindowKBHook;
LRESULT __stdcall WindowHookProc(int nCode, unsigned int _wParam, long _lParam)
{
if(nCode != HC_ACTION)
return CallNextHookEx(WindowMouseHook, nCode, _wParam, _lParam);
switch(_wParam)
{
case WM_KEYDOWN:
switch(reinterpret_cast<kbstruct*>(_lParam)->vkCode)
{
case VK_SPACE:
PostMessage(hWnd, CW_WindowSelected, 0, 0);
break;
case VK_ESCAPE:
PostMessage(hWnd, CW_Abort, 0, 0);
break;
case VK_UP:
mouse_event(MOUSEEVENTF_MOVE, 0, -5, 0, 0);
break;
case VK_DOWN:
mouse_event(MOUSEEVENTF_MOVE, 0, 5, 0, 0);
break;
case VK_RIGHT:
mouse_event(MOUSEEVENTF_MOVE, 5, 0, 0, 0);
break;
case VK_LEFT:
mouse_event(MOUSEEVENTF_MOVE, -5, 0, 0, 0);
break;
default:
break;
}
break;
case WM_LBUTTONUP:
PostMessage(hWnd, CW_WindowSelected, 0, 0);
break;
case WM_RBUTTONUP:
PostMessage(hWnd, CW_Abort, 0, 0);
break;
case WM_SYSKEYUP:
case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_HOTKEY:
break;
default:
return CallNextHookEx(WindowMouseHook, nCode, _wParam, _lParam);
}
return 1;
}
API bool __stdcall BeginWindowSelection(void)
{
WindowMouseHook = SetWindowsHookEx(14, WindowHookProc, gInst, 0);
WindowKBHook = SetWindowsHookEx(13, WindowHookProc, gInst, 0);
POINT pt;
GetCursorPos(&pt);
blinker.hPrev = WindowFromPoint(pt);
checker.timer.AttachListener(checker);
blinker.timer.AttachListener(blinker);
checker.timer.Start(100, 0);
blinker.timer.Start(250, 0);
return (WindowMouseHook != 0 && WindowKBHook != 0) ? true : false;
}
API HWND __stdcall EndWindowSelection(void)
{
blinker.timer.Stop();
checker.timer.Stop();
blinker.timer.DetachListener(blinker);
checker.timer.DetachListener(checker);
if(!blinker.state)
blinker.clear();
if(!UnhookWindowsHookEx(WindowMouseHook) || !UnhookWindowsHookEx(WindowKBHook))
return 0;
WindowMouseHook = 0;
WindowKBHook = 0;
return blinker.hPrev;
}