|
|
|
| Пытаюсь создать программу, определяющую класс окна под курсором
Но код, который вроде бы верен, не работает (VS 2005):
/* ... */
LPSTR className = " "; // suda imia klassa nuzhno vpisat
HWND hOut = CreateWindow(...); // tekstovoe pole
POINT pt; // tochka s tekuschimi koordinatami
HWND hCurrent; // okno pod kursorom
/* ... */
case WM_MOUSEMOVE:
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
hCurrent = WindowFromPoint(pt);
GetClassNameA(hCurrent,className,32);
SetWindowTextA(hOut,className);
break;
|
Но значение className не изменяется. Отлаживал - причину понять не могу.
Буду благодарен, если кто-нибудь подскажет, что не так. Спасиьо! | |
|
|
|
|
|
|
|
для: Фитч
(27.02.2007 в 19:04)
| | Не срабатывает GetClassNameA(), причём даже если передать дескриптор текущего окна...
PS А у вас этот код где выполняется и много ли окон имеет приложение? Вы скорее всего не сможете перехватить чужие окна, если только не будете использовать перехват API-вызовов. | |
|
|
|
|
|
|
|
для: cheops
(27.02.2007 в 20:15)
| | Приложение имеет одно окно.
А насчет перехвата API-функций - не понял. Разьве WindowFromPoint() не может вернуть чужое окно?
И ещё: перехват АПИ-функций - это, насколько мне известно, обнаружение вызова АПИ функции и возможность поменять ее параметры. Причем он тут? | |
|
|
|
|
|
|
|
для: Фитч
(27.02.2007 в 20:33)
| | Событие WM_MOUSEMOVE будет не у окна вашего приложения, а у чужого окна - нужно перехватывать событие на уровне операционной системы. | |
|
|
|
|
|
|
|
для: cheops
(28.02.2007 в 00:50)
| | По-моему достаточно вызвать SetCapture для того, чтобы ваше окно получало сообщения от мыши
всегда, т.е. даже при перемещении над другими окнами. | |
|
|
|
|
|
|
|
для: oleg_alexeev
(28.02.2007 в 08:40)
| | 2 oleg_alexeev:
SetCapture(), как написано в MSDN передает события мыши окну только если нажата кнопка мыши.
Но проблема в том, что класс не могу получить даже для текущего окна - className остается пустым! | |
|
|
|
|
|
|
|
для: Фитч
(28.02.2007 в 09:59)
| | >> SetCapture(), как написано в MSDN передает события мыши окну только если нажата кнопка мыши.
Всё правильно - при нажатии левой кнопки вы вызываете SetCapture и, пока она не отпущена, все
сообщения о перемещении передаются вашему окну. Если нужно что-то другое, то SetCapture не
подходит.
А GetClassName не срабатывает скорее всего из-за того, что className указывает на область памяти,
в которую запрещена запись. Напишите так:
Должно сработать. | |
|
|
|
|
|
|
|
для: Фитч
(28.02.2007 в 09:59)
| | Пардон, я подразумевал, что className объявляется как локальная переменная в функции.
Если className объявлена вне функции то надо сделать так:
LPSTR className;
// и где-то при старте программы:
className = new CHAR[32];
|
| |
|
|
|
|
|
|
|
для: oleg_alexeev
(28.02.2007 в 11:26)
| | oleg_alexeev, спасибо тебе! Заработало, но меня кое-что смущает: чужая тулза показывает другие классы. Скажем панель задач - Shell_TrayWnd, в то время как моя - нет.
И еще у меня чувство, что имя класса показывается не для текущей точки, а лежащей где-то выше. Это глюк программы и или WindowFromPoint так и работает? Еще раз спасибо! | |
|
|
|
|
|
|
|
для: Фитч
(28.02.2007 в 12:34)
| | По WM_MOUSEMOVE вам передаются координаты окна, а не экрана - скорее всего в этом дело.
PS Тулуза скорее всего использует хуки (перехваты API-вызовов) или просто ищет все окна системы и смотрит открыты они или нет и где расположены. | |
|
|
|
|
|
|
|
для: cheops
(28.02.2007 в 12:55)
| | >> По WM_MOUSEMOVE вам передаются координаты окна, а не экрана - скорее всего в этом дело.
Точнее передаются координаты курсора в системе координат клиентской части окна.
А WindowFromPoint принимает координаты в экранной системе координат. Поэтому надо либо
преобразовать полученные координаты при помощи ClientToScreen, либо получить координаты
курсора сразу в экранной системе координат с помощью GetMessagePos или GetCursorPos.
Посмотрел в MSDN про GetClassName. Там не написано про какие-либо ограничения для не своих
окон. Возможно всё дело только в преобразованиях координат. На всякий случай можно проверить
возвращаемый код, и, если он 0, то вызвать GetLastError. | |
|
|
|
|
|
|
|
для: oleg_alexeev
(28.02.2007 в 13:43)
| | 2 oleg_alexeev: да, так оно и есть. Теперь все как надо
2 cheops: похоже вы правы насчет того, что тулза сначала ищет все окна. Она выдает класс главного окно, а моя того, что под курсором, т.е. класс EDIT для текстового поля и тп.
Всем спасибо за дельные ответы! | |
|
|
|