Форум: Форум C++Разное
Новые темы: 00
PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум C++

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Распознание класса окна
 
 автор: Фитч   (27.02.2007 в 19:04)   письмо автору
 
 

Пытаюсь создать программу, определяющую класс окна под курсором
Но код, который вроде бы верен, не работает (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 не изменяется. Отлаживал - причину понять не могу.
Буду благодарен, если кто-нибудь подскажет, что не так. Спасиьо!

  Ответить  
 
 автор: cheops   (27.02.2007 в 20:15)   письмо автору
 
   для: Фитч   (27.02.2007 в 19:04)
 

Не срабатывает GetClassNameA(), причём даже если передать дескриптор текущего окна...

PS А у вас этот код где выполняется и много ли окон имеет приложение? Вы скорее всего не сможете перехватить чужие окна, если только не будете использовать перехват API-вызовов.

  Ответить  
 
 автор: Фитч   (27.02.2007 в 20:33)   письмо автору
 
   для: cheops   (27.02.2007 в 20:15)
 

Приложение имеет одно окно.
А насчет перехвата API-функций - не понял. Разьве WindowFromPoint() не может вернуть чужое окно?
И ещё: перехват АПИ-функций - это, насколько мне известно, обнаружение вызова АПИ функции и возможность поменять ее параметры. Причем он тут?

  Ответить  
 
 автор: cheops   (28.02.2007 в 00:50)   письмо автору
 
   для: Фитч   (27.02.2007 в 20:33)
 

Событие WM_MOUSEMOVE будет не у окна вашего приложения, а у чужого окна - нужно перехватывать событие на уровне операционной системы.

  Ответить  
 
 автор: oleg_alexeev   (28.02.2007 в 08:40)   письмо автору
 
   для: cheops   (28.02.2007 в 00:50)
 

По-моему достаточно вызвать SetCapture для того, чтобы ваше окно получало сообщения от мыши
всегда, т.е. даже при перемещении над другими окнами.

  Ответить  
 
 автор: Фитч   (28.02.2007 в 09:59)   письмо автору
 
   для: oleg_alexeev   (28.02.2007 в 08:40)
 

2 oleg_alexeev:
SetCapture(), как написано в MSDN передает события мыши окну только если нажата кнопка мыши.

Но проблема в том, что класс не могу получить даже для текущего окна - className остается пустым!

  Ответить  
 
 автор: oleg_alexeev   (28.02.2007 в 11:07)   письмо автору
 
   для: Фитч   (28.02.2007 в 09:59)
 

>> SetCapture(), как написано в MSDN передает события мыши окну только если нажата кнопка мыши.

Всё правильно - при нажатии левой кнопки вы вызываете SetCapture и, пока она не отпущена, все
сообщения о перемещении передаются вашему окну. Если нужно что-то другое, то SetCapture не
подходит.

А GetClassName не срабатывает скорее всего из-за того, что className указывает на область памяти,
в которую запрещена запись. Напишите так:


char className[32];


Должно сработать.

  Ответить  
 
 автор: oleg_alexeev   (28.02.2007 в 11:26)   письмо автору
 
   для: Фитч   (28.02.2007 в 09:59)
 

Пардон, я подразумевал, что className объявляется как локальная переменная в функции.
Если className объявлена вне функции то надо сделать так:


LPSTR className;

// и где-то при старте программы:
className = new CHAR[32];

  Ответить  
 
 автор: Фитч   (28.02.2007 в 12:34)   письмо автору
 
   для: oleg_alexeev   (28.02.2007 в 11:26)
 

oleg_alexeev, спасибо тебе! Заработало, но меня кое-что смущает: чужая тулза показывает другие классы. Скажем панель задач - Shell_TrayWnd, в то время как моя - нет.
И еще у меня чувство, что имя класса показывается не для текущей точки, а лежащей где-то выше. Это глюк программы и или WindowFromPoint так и работает? Еще раз спасибо!

  Ответить  
 
 автор: cheops   (28.02.2007 в 12:55)   письмо автору
 
   для: Фитч   (28.02.2007 в 12:34)
 

По WM_MOUSEMOVE вам передаются координаты окна, а не экрана - скорее всего в этом дело.

PS Тулуза скорее всего использует хуки (перехваты API-вызовов) или просто ищет все окна системы и смотрит открыты они или нет и где расположены.

  Ответить  
 
 автор: oleg_alexeev   (28.02.2007 в 13:43)   письмо автору
 
   для: cheops   (28.02.2007 в 12:55)
 

>> По WM_MOUSEMOVE вам передаются координаты окна, а не экрана - скорее всего в этом дело.

Точнее передаются координаты курсора в системе координат клиентской части окна.

А WindowFromPoint принимает координаты в экранной системе координат. Поэтому надо либо
преобразовать полученные координаты при помощи ClientToScreen, либо получить координаты
курсора сразу в экранной системе координат с помощью GetMessagePos или GetCursorPos.

Посмотрел в MSDN про GetClassName. Там не написано про какие-либо ограничения для не своих
окон. Возможно всё дело только в преобразованиях координат. На всякий случай можно проверить
возвращаемый код, и, если он 0, то вызвать GetLastError.

  Ответить  
 
 автор: Фитч   (28.02.2007 в 14:36)   письмо автору
 
   для: oleg_alexeev   (28.02.2007 в 13:43)
 

2 oleg_alexeev: да, так оно и есть. Теперь все как надо

2 cheops: похоже вы правы насчет того, что тулза сначала ищет все окна. Она выдает класс главного окно, а моя того, что под курсором, т.е. класс EDIT для текстового поля и тп.

Всем спасибо за дельные ответы!

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования