Конференция "WinAPI" » Cобытия курсора мышки.
 
  • hub00 © (31.05.08 17:43) [0]
    Вопрос.
    Во время перемещения курсора мышки над текстом,ссылкой или кнопкой в окне любой программы, курсор меняет иконку (стрелка, рука, итд) происходит событие.
    Как можно выполнить еще что-то кроме изменения иконки?
    Другое действие, которое нужно мне.
    Какая функция за это отвечает?
    Спасибо.
  • {RASkov} © (31.05.08 19:26) [1]
    Вопрос из ряда нестандартных и непонятных... Может объяснишь подробнее задачу? Возможно и варианты легче решаемые будут....

    > Какая функция за это отвечает?

    Вот прямо такой, какой тебе хочется - нет.)
    Вот даже смотри.... как ты ее у себя в программе будешь вызывать? по таймеру?

    Другие варианты: есть сообщения виндовс, есть хуки..... но может и не так все сложно... зависит от задачи..
  • DVM © (31.05.08 19:45) [2]

    > Во время перемещения курсора мышки над текстом,ссылкой или
    > кнопкой в окне любой программы, курсор меняет иконку (стрелка,
    >  рука, итд) происходит событие.

    Событие возникает для того окна, над которым указатель мыши перемещается. Это окно и меняет вид указателя. Т.е. все наоборот - сначала событие, потом смена вида указателя. Собственно все эти события (приход сообщений мыши в окно) можно перехватывать с помощью ловушек (Hooks) на сообщения мыши.
  • hub00 © (31.05.08 19:48) [3]
    Нужно сделать так.
    Запускается справка windows, курсор мышки произвольно начинает двигаться в этом окне, после того как он будет над ссылкой, нужно сделать щелочек мышкой, перейти по этой ссылке.
    Хочется чтоб щелчок выполнялся тогда, когда курсор над ссылкой.
  • hub00 © (31.05.08 19:50) [4]
    Ловушка. Как её использовать? Можно пример?
  • DVM © (31.05.08 19:56) [5]

    > hub00 ©   (31.05.08 19:50) [4]

    в гугле пишешь WH_MOUSE ищешь пример
  • hub00 © (31.05.08 20:16) [6]
    А как я узнаю какое событие в этот момент происходит?
    Я немогу понять что мне вылавливать?
    Какое сообщение windows шлет в тот момент когда мышка над ссылкой?
  • DVM © (31.05.08 20:48) [7]
    Зачем все это надо? Запуск справки перемещения курсора и т.д.? Может есть другой путь. Тот путь, что ты выбрал - гиблый.


    > Я немогу понять что мне вылавливать?

    вот и я не пойму, что ты ловить будешь.


    > Какое сообщение windows шлет в тот момент когда мышка над
    > ссылкой?

    WM_MOUSEMOVE
  • {RASkov} © (31.05.08 20:54) [8]
    > [6] hub00 ©   (31.05.08 20:16)
    > Какое сообщение windows шлет в тот момент когда мышка над ссылкой?

    Ну, наверное, ответ - никакого. т.е. не для твоих интересов...
    Еще раз прочитай [2]. Приложения, как правило, сами решают как реагировать на, например, WM_MOUSEMOVE...
  • hub00 © (31.05.08 20:55) [9]
    Справка это пример, мне нужно чтоб мышка нажимала на ссылку.
    Но чтоб нажимала тогда, когда она над ней.
  • {RASkov} © (31.05.08 20:59) [10]
    > [9] hub00 ©   (31.05.08 20:55)

    Т.е.? ...Т.е. я "тащу" мышку над ссылкой, а она сама "квакает" по ней? :)
    Брось ты это гиблое и неблагородное дело)
  • DVM © (31.05.08 21:00) [11]

    > Справка это пример, мне нужно чтоб мышка нажимала на ссылку.

    Ссылка это просто картинка. Окно справки само знает, что вот тот прямоугольник с координатами x1,y1,x2,y2 - ссылка и перерисовывает его соответственно тогда, когда мышь входит в этот прямоугольник. Окну где расположена ссылка приходят только многочисленные WM_MOUSEMOVE. Узнать, где у приложения ссылка не выйдет, т.к. это его внутренняя кухня.

    Единственно, если справка основана на движке Internet Explorer, то можно попробовать действовать через его объектную модель документа, тогда вобщем то до ссылок можно добраться, но имхо не справишься, много работы больно.
  • hub00 © (01.06.08 01:19) [12]
    Ребята, вы не так поняли меня.
    Мышкой водить я не буду. Она сама рандомно будет гулять в окне.
    Гулять до тех пор, пока не проскочит над какой-то ссылкой.
    Вот в тот момент когда она будет над ней (ссылкой), программно сделать нажатие кнопки и перейти.
  • hub00 © (01.06.08 01:25) [13]
    Я думал иначе сделать, сначало Tab`ом выделять (подсвечивать) ссылки (рандомно) к примеру 10 нажатий и оказался б я на 10-й ссылке.  
    Потом как-то узнать то место где остановился Tab (10-я ссылка) перевести туда курсор мышки и кликнуть по ней.
  • Германн © (01.06.08 01:36) [14]

    > hub00 ©   (01.06.08 01:19) [12]
    >
    > Ребята, вы не так поняли меня.
    > Мышкой водить я не буду. Она сама рандомно будет гулять
    > в окне.
    > Гулять до тех пор, пока не проскочит над какой-то ссылкой.
    >
    > Вот в тот момент когда она будет над ней (ссылкой), программно
    > сделать нажатие кнопки и перейти.
    >

    А как тебя понять, Саид? Сама мышка никогда не блуждает.
  • hub00 © (01.06.08 01:47) [15]
    А если я буду программно менять её координаты, она не будет произвольно двигаться?
  • Германн © (01.06.08 02:18) [16]

    > hub00 ©   (01.06.08 01:47) [15]
    >
    > А если я буду программно менять её координаты, она не будет
    > произвольно двигаться?
    >

    Чьи координаты? Мышки? На твоём столе?
    Но уж точно! Программно мышку нельзя передвинуь!
  • hub00 © (01.06.08 09:37) [17]
    Да, Германн представь, координаты курсора мышки на "Рабочем столе".
    Фантастика.
  • hub00 © (01.06.08 11:16) [18]
    Копался в сети нашел этот это

    Как автоматически помещать курсор мышки в центр контрола получившего фокус
    procedure MoveMouseOverControl(Sender: TObject);
    var
     Point: TPoint;
    begin
     with TControl(Sender) do
     begin
       Point.X := Left + (Width  div 2);
       Point.Y := Top +  (Height div 2);
       Point := Parent.ClientToScreen(Point);
       SetCursorPos(Point.X, Point.Y);
     end;
    end;

    Хотел запускать через таймер, вылетает ошибка. В чем может быть проблема?
  • {RASkov} © (01.06.08 12:04) [19]
    > [18] hub00 ©   (01.06.08 11:16)
    > Как автоматически помещать курсор мышки в центр контрола
    > получившего фокус

    Код в [18] - это не то что ты думаешь.... там даже ни одной инструкции нет связанной с фокусом ввода...
    Ошибка-то какая? AV небось)...
    Кстати, почему не показываешь как вызываешь данную процедуру?
    ЗЫ: Копайся далее.... Неблагородными делами занимаешься) И, главное, не хочешь понять, что занимаешься не тем...
  • hub00 © (01.06.08 14:17) [20]
    Вот. Если я вызываю процедуру через нажатие кнопки, то мышка переходит в область фокуса, но если через таймер. то ошибка. "Project1.exe of adress 00003E8. Process stopped. Use step or run to continue."

    procedure MoveMouseOverControl(Sender: TObject);
    var
     Point: TPoint;
    begin
     with TControl(Sender) do
     begin
       Point.X := Left + (Width  div 2);
       Point.Y := Top +  (Height div 2);
       Point := Parent.ClientToScreen(Point);
       SetCursorPos(Point.X, Point.Y);
     end;
    end;

    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
    MoveMouseOverControl(Sender);
    end;
  • Leonid Troyanovsky © (01.06.08 14:48) [21]

    > hub00 ©   (01.06.08 14:17) [20]

    >  with TControl(Sender) do
    >  begin
    >    Point.X := Left + (Width  div 2);
    >    Point.Y := Top +  (Height div 2);
    >    Point := Parent.ClientToScreen(Point);

    У таймера не может быть парента, да и, во-ще, он не контрол.

    --
    Regards, LVT.
  • {RASkov} © (01.06.08 14:49) [22]
    > [20] hub00 ©   (01.06.08 14:17)

    У Таймера нет свойст Left, Top, Width, Height.... Это раз. Тыж в событии таймера передаешь сам таймер в процедуру, где пытаешься из него сделать несуществующий контрол...
    Во вторых - это тебе кажется, что "по кнопке" мышь переходит в центр активного контрола.... ну да кнопка-то становится активной :)
    Процедура в [18] да, центрирует мышь по центру переданного в нее "контрола", а ты туда что передаешь?
    И узнай обязательно, что такое Sender)
  • hub00 © (01.06.08 15:08) [23]
    http://delphiworld.narod.ru/base/mouse_to_control_center.html
    вот этот пример описывается.
    Может не таймер использовать тогда?
    Как тогда можно сделать чтоб к примеру программно я нажимаю клавишу Tab, выделяется ссылка после чего я думал использовать эту процедуру и перевести в центр фокуса курсор мышки.Когда он там окажется программно нажать левую кнопку (мышки). Думал постоянно таймером вызывать её к примеру каждые 3 секунды, а за эти 3 секунды переводить фокус tab`ом.
  • {RASkov} © (01.06.08 15:35) [24]
    > [23] hub00 ©   (01.06.08 15:08)
    > вот этот пример описывается.

    Там не верно задан заголовок... нет в этом примере ничего про фокус)
    Тебе зачем вообще все это нужно? Для чего хочешь заставить мышку бегать рандомно, сломя голову по форме, да еще и кликать направо и налево....
    Что же такое ты делаешь?)
  • hub00 © (01.06.08 15:51) [25]
    Жаль что ничего не вышло, звыняйте за потраченное ваше время. :(
  • hub00 © (01.06.08 21:04) [26]
    Русские не сдаются.
    Другой вариант для решения моей задачи. Еще извратнее.

    Какое сообщение посылает виндовс когда меняется курсор мышки?
  • SergeyIT (01.06.08 21:22) [27]

    > Какое сообщение посылает виндовс когда меняется курсор мышки?

    Если очень хочется поизучать сообщения от мыши - поизучайте SetWindowsHookEx и
     WH_JOURNALRECORD
     WH_JOURNALPLAYBACK
    и попрограммируйте.
    Очень многое узнаете.
    (Только не надейтесь на быстрый результат)
  • DVM © (01.06.08 21:38) [28]

    > Какое сообщение посылает виндовс когда меняется курсор мышки?

    WM_SETCURSOR или никаких, если окно само меняет вид своего указателя (кстати твой случай).
  • hub00 © (01.06.08 22:12) [29]
    Собрал эту программу "Мониторинг сообщений"
    http://delphiworld.narod.ru/base/messages_monitor.html
    Отловил нужное сообщение мышки. Это WM_SETCURSOR. Очем и сказал DVM ©.
    Действительно, windows посылает это сообщение.

    Взял эту программу "Как перехватывать события, посланные другим приложениям"
    http://delphiworld.narod.ru/base/catch_another_events.html
    Добавил нужное сообщение и пытаюсь его поймать.
    А оно не ловится. Точнее нет никаких действий. Что может быть ?

    Вот листинг измененный (нужный мне)

    function HookProc(Code: integer; WParam: word; LParam: Longint): Longint; stdcall;
    var
     msg: PEVENTMSG;
    begin
     if Code >= 0 then begin
       result := 0;
       msg := Pointer(LParam);
       with Form1 do
         case msg.message of
           WM_MOUSEMOVE: Caption := IntToStr(msg.ParamL) + #32 + IntToStr(msg.ParamH);
           WM_LBUTTONDOWN: CheckBox1.Checked := true;
           WM_LBUTTONUP: CheckBox1.Checked := false;
           WM_RBUTTONDOWN: CheckBox2.Checked := true;
           WM_RBUTTONUP: CheckBox2.Checked := false;
           WM_KEYUP: CheckBox3.Checked := false;
           WM_KEYDOWN: CheckBox3.Checked := true;
           WM_SETCURSOR: CheckBox3.Checked := true;
         end;
     end else
       result := CallNextHookEx(HookHandle, code, WParam, LParam);
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    Form1.FormStyle := fsStayOnTop;
     CheckBox1.Enabled := false;
     CheckBox1.Caption := 'left button';
     CheckBox2.Enabled := false;
     CheckBox2.Caption := 'right button';
     CheckBox3.Enabled := false;
     CheckBox3.Caption := 'keyboard';
     CheckBox4.Enabled := false;
     CheckBox4.Caption := 'mouse';
     HookHandle := SetWindowsHookEx(WH_JOURNALRECORD, @HookProc, HInstance, 0);
    end;
  • hub00 © (01.06.08 22:15) [30]
    или так пытался      WM_SETCURSOR: Label1.Caption:='Сообщение перехвачено';
    че за непонятнось.... :(
  • имя (01.06.08 22:30) [31]
    Удалено модератором
  • SergeyIT (01.06.08 22:44) [32]

    >  WM_SETCURSOR

    Этим хуком это сообщение не перехватывается
  • hub00 © (01.06.08 22:47) [33]
    Ну не работает оно с табом и все.
    Я что против.
  • hub00 © (01.06.08 22:48) [34]
    SergeyIT, а каким?
  • имя (01.06.08 22:56) [35]
    Удалено модератором
  • SergeyIT (01.06.08 23:08) [36]

    > а каким?

    Ищите...
  • hub00 © (01.06.08 23:15) [37]
    CURSOR, ты прав для этого. Поделись пожалуйста.
    (И причем тут кривые руки как умею так и делаю.)
    SergeyIT, ок.
  • SergeyIT (01.06.08 23:35) [38]
    Для проверки хуков у MS была программка (hooktest как-то) - в ней можно было все попробовать.
    Я подобное делал через playback (для выставки - демонстрация работы связки нескольких программ под Вин3.11, давно было)
    Вообще-то решение зависит от условий задачи, которые нам неизвестны.
    Что за программа, ссылки? Если нажать на ссылку ведь может появиться новое окно, программа/диалог и что тогда делать?
  • имя (01.06.08 23:39) [39]
    Удалено модератором
  • hub00 © (01.06.08 23:54) [40]
    "Если работаем в нашей проге, то устанавливаем фокус для страницы, загрузившейся в TWebbrowser:
    Webbrowser1.SetFocusToDoc;"

    А если к примеру не в нашей программе (Mozilla)?
    Как тогда?
  • имя (01.06.08 23:57) [41]
    Удалено модератором
  • hub00 © (02.06.08 00:04) [42]
    Способ замечательный. Спасибо большое ничего сказать!
    Есть такие сайты которые могут ругаться на версию браузера или его название.
    В свойствах вроде нет поля userAgent так бы вписал что нужно и хорошо.
  • hub00 © (02.06.08 00:08) [43]
    А если в связке использовать компонент idHTTP там все можно вписать что хочется.
  • имя (02.06.08 00:15) [44]
    Удалено модератором
  • SergeyIT (02.06.08 00:20) [45]

    > что ж это за сайт такой интересный?

    Очень странная задачка
  • hub00 © (02.06.08 00:33) [46]
    А лучше все удалите? Реально стоящие вещи человек изложил.
    Я не понимаю такого...
  • SergeyIT (02.06.08 00:40) [47]

    > Реально стоящие вещи человек изложил.

    Для нереальных задач...
  • hub00 © (02.06.08 00:45) [48]
    Выходит нет ничего не реального.
  • hub00 © (03.06.08 15:18) [49]
    Ошибка чтения памяти. Вылетают все приложения которые были активны.

    Листинг :
    var
    HookHandle: hHook;

    function HookProc(Code: integer; WParam: word; LParam: Longint): Longint; stdcall;
    begin
    if Code >= 0 then begin
    result := 0;
    with Form1 do
       case TMsg(Pointer(lParam)^).message of
       WM_SETCURSOR : ShowMessage('Сообщение получено.');
       end;
    end;    
    result := CallNextHookEx(HookHandle, code, WParam, LParam);
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    HookHandle := SetWindowsHookEx(WH_CALLWNDPROCRET, @HookProc, HInstance, 0);
    end;

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    if HookHandle <> 0 then
     UnhookWindowsHookEx(HookHandle);
    end;
  • Игорь Шевченко © (03.06.08 18:05) [50]

    > procedure TForm1.FormCreate(Sender: TObject);
    > begin
    > HookHandle := SetWindowsHookEx(WH_CALLWNDPROCRET, @HookProc,
    >  HInstance, 0);
    > end;



    > with Form1 do
    >    case TMsg(Pointer(lParam)^).message of
    >    WM_SETCURSOR : ShowMessage('Сообщение получено.');
    >    end;
    > end;    


    Статьи про хуки прочитай, чего там можно, а чего нельзя
  • Leonid Troyanovsky © (03.06.08 18:27) [51]

    > hub00 ©   (03.06.08 15:18) [49]

    > Ошибка чтения памяти. Вылетают все приложения которые были
    > активны.

    Любопытно.
    А как же их всех угораздило быть активными?

    > function HookProc(Code: integer; WParam: word; LParam: Longint):
    >  Longint; stdcall;
    > begin
    > if Code >= 0 then begin
    > result := 0;
    > with Form1 do

    Ловко придумано,
    но непонятно: зачем же тут Form1.
  • Leonid Troyanovsky © (03.06.08 18:29) [52]

    > Leonid Troyanovsky ©   (03.06.08 18:27) [51]

    Sorry, хотел продолжить, но промахнулся.

    > HookHandle := SetWindowsHookEx(WH_CALLWNDPROCRET, @HookProc,
    >  HInstance, 0);

    Почему же 0? Ну, или, сажем, HInstance.

    --
    Regards, LVT.
 
Конференция "WinAPI" » Cобытия курсора мышки.
Есть новые Нет новых   [134433   +22][b:0][p:0.001]