Доброго времени суток!
Решил показать, как пользоваться WinAPI функцией
POSTMESSAGE (hwnd, message, wParam, lParam)Что это такое?Windows API (англ. application programming interfaces) — общее наименование целого набора базовых функций интерфейсов программирования приложений операционных систем семейств Microsoft Windows. Или по простому - базовый язык наших любимых окошек(Windows). Остальные языки программирования делают свои функции и процедуры из WinAPI или используют его на прямую.
POSTMESSAGE — функция помещает сообщение в очередь.
Зачем нам оно?Количество функций Clickermann`а неуклонно продолжает расти, но необходимо очень много времени, чтоб можно было сделать свои обертки на все функции Windows. А теперь, когда появилась эта функция мы можем на прямую работать с интерфейсами окошек. И использовать максимум функционала.
Ставим задачуНужно написать код, чтоб можно было кликать в окошке, которое находится позади других.
Невозможно, скажете вы и ошибетесь
. Потому, как мы не будем эмулировать клик мыши, а станем посылать сообщение окну, в котором должен быть произведен клик. Нужно это для разных случаев, но мне пригодилось во флеш игре, в которой необходимо кликать мышкой каждую минуту(даже сейчас она кликает, нервно помигивая кнопкой на панели задач, пока я пишу эту статью).
Что нам понадобитсянам понадобится сама функция
PostMessage(
HWND
hWnd,
UINT
Msg,
WPARAM
wParam,
LPARAM
lParam);
hWnd - Дескриптор окна(грубо говоря - адрес), оконная процедура которого должна принять сообщение.
Если подробнее, то кнопки, поля для ввода текста, раскрывающиеся списки, меню и т.д. - это и есть окна(с точки зрения Микрософт), а не только прямоугольная форма с крестиком, квадратиком и палочкой в правом верхнем углу(как думают большинство). И у каждого этого элемента есть свой hWnd. Означает, что нам нужно мышкой указывать не на форму, в которой находится кнопка, а именно на кнопку, у которой пытаемся узнать hWnd.
Msg - Сообщение, которое должно быть поставлено в очередь. Сообщение цифровое и писать мы будем его цифрами. Есть куча сообщений, которые могут приходить окну. Вот небольшой список:
wm_LButtonDblClk, wm_LButtonDown, wm_LButtonUp, wm_MButtonDblClk, wm_MButtonDown, wm_MButtonUp, wm_MouseMove, wm_NCLButtonDown, wm_NCLButtonUp, wm_NCLButtonDblClk, wm_NCMButtonDown, wm_NCMButtonDblClk, wm_NCMouseMove, wm_NCRButtonDown, wm_NCRButtonUp, wm_NCRButtonDblClk, wm_RButtonDown, wm_RButtonUp, wm_RButtonDblClk и т.п.И каждому такому сообщению выдан свой код(0x0201 — означает шестнадцатиричный вид, например 0x0201 = 513):
WM_LBUTTONDOWN = 0x0201 // Левая кнопка мыши нажата.
WM_LBUTTONUP = 0x0202 // Левая кнопка мыши отпущена.
WM_RBUTTONDOWN = 0x0204 // Правая кнопка мыши нажата.
WM_RBUTTONUP = 0x0205 // Правая кнопка мыши отпущена.
WM_MOUSEMOVE = 0x0200 // Мышь передвинута.
WM_MOUSEWHEEL = 0x020A // Кручение колесика мыши.
wParam и
lParam - Это 32-битовые парaметры. Для каждого случая свои. Но в нашем случае в первом параметре задается нажатые кнопки(если нажато несколько кнопок то они складываются, например нажаты вместе SHIFT и левая кнопка мыши — 0x0004 + 0x0001 = 0x0005):
MK_LBUTTON = 0x0001 // Левая кнопка мыши находится в нажатом состоянии.
MK_RBUTTON = 0x0002 // Правая кнопка мыши находится в нажатом состоянии.
MK_SHIFT = 0x0004 // Клавиша SHIFT находится в нажатом состоянии.
MK_CONTROL = 0x0008 // Клавиша CTRL находится в нажатом состоянии.
MK_MBUTTON = 0x0010 // Средняя кнопка мыши находится в нажатом состоянии.
MK_XBUTTON1 = 0x0020 // Windows 2000/XP: Первая X-кнопка находится в нажатом состоянии.
MK_XBUTTON2 = 0x0040 // Windows 2000/XP: Вторая X-кнопка находится в нажатом состоянии.
Мышкины события и их коды описаны в MSDN(en)
http://msdn.microsoft.com/en-us/library/windows/desktop/ff468877(v=vs.85).aspxКлавиатурные события и их коды описаны в MSDN(en)
http://msdn.microsoft.com/en-us/library/windows/desktop/ff468861(v=vs.85).aspxА во втором параметре координаты курсора мыши. Как же можно в одном числе записать 2 значения
X и
Y? Давольно просто: используя 32 битную операционную систему можно в первых 16 битах передавать
Y, а во второй части —
X. Например координаты (
123 ,
456) в шестнадцатиричнном виде будут выглядеть как (
0x007B ,
0x01C8) и мы получим параметер
lParam = 0x
01C8007B или в десятичном будет непойми что 29 884 539 = 123 + 456 * 65536. Откуда взялась цифра 65536 оставлю на домашнее задание(подсказка: 256*256=65536, 256 — BYTE, 65536 — WORD)
ПрактикаВы дочитали до этих строк и не бросили это нудное дело? Тогда хвала Вам и почет, о любимый мой читатель. А еще лэвэл ап и новый скилл. Копируем и вставляем в Clickermann следующее:
$WM_LBUTTONDOWN = 0x0201 // Левая кнопка мыши нажата.
$WM_LBUTTONUP = 0x0202 // Левая кнопка мыши отпущена.
$MK_LBUTTON = 0x0001 // Левая кнопка мыши находится в нажатом состоянии.
$HWND = 16515858 // изменяется при каждом запуске целевой программы,
// нужно каждый раз вписывать заного
$x = 100 // Координата по X
$y = 100 // Координата по Y
//Отправляем сообщение окну о нажатой левой кнопке мыши
postmessage($HWND, $WM_LBUTTONDOWN, $MK_LBUTTON, $x + ($y*65536))
//Мало-мало ждем, а можно и вообще не ждать,
// т.к. сообщения уходят в список и выполняются по порядку
waitms(50)
//Отправляем сообщение окну, что левую кнопку мыши отпустили
postmessage($HWND, $WM_LBUTTONUP, $MK_LBUTTON, $x + ($y*65536))
// Завершаем программу
halt
Запускаем mspaint — стандартную рисовалку Windows, наводим мышь на белый холст и наблюдаем в редакторе кода за
hWND. Пишем свое число вместо моего
$HWND = и запускаем скрипт(Clickermann). Все. Теперь на холсте паинта стоит точка на расстоянии 100 пикселей от левого края
холста(а не экрана!!!) и 100 пикселей от правого.
ЭпилогВ браузерах обычно сам сайт и все, что в нем есть имеет один hWND. И высчитав количество пикселей сверху, которое занимает панели браузера можно к
Y дописать
$y = 100-61 (61 - высота панели хрома) и задавать координаты без вычислений, но при условии, что форма развернута на весь экран. Если двигать форму по всему экрану то прийдется каждый раз пересчитывать координаты. Т.к. все элементы будут содержать собственные координаты. И угол (0,0) - это не угол экрана в данном случае, а верхний левый угол элемента(будь то кнопка, или поле для ввода текста, или страница в браузере - прокручивание не влияет на координаты на экране монитора).
Удачи!