Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 17.04.2015, 13:33
yorri yorri вне форума
Прохожий
 
Регистрация: 17.04.2015
Сообщения: 7
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Переопределение кнопок мышки

Нужно переназначить кнопки мышки (три кнопки: правая, средняя и левая). Например: нажимаем левую - срабатывает, скажем, средняя, среднюю - правая, правую - левая... Тут варианты.
Делаю через хуки.
Но столкнулся с проблемой. Зацикливание. Насколько понял, происходит так. Переназначаю кнопки: левая->средняя, средняя->левая.
Нажимаю левую -> срабатывает обработчик левой кнопки -> генерируется/имитируется нажимание средней кнопки -> далее срабатывает обработчик средней кнопки (так как мы это сами сгенерировали выше)->генерируется/имитируется нажимание левой кнопки... и так по кругу. Не могу справиться с той проблемой.

Вот кусок кода отвечающий за это. Тут для двух кнопок: левая и средняя.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
if (EventStrut.message = WM_LBUTTONDOWN) or (EventStrut.message = WM_LBUTTONDOWN) or
          (EventStrut.message = WM_LBUTTONDBLCLK) then
          begin
 
               GetCursorPos(Pt);
 
               case MouseKey[1] of
               2:begin
                    EventStrut.message:=WM_NULL;
                    Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MIDDLEDOWN, Pt.x, Pt.y, 0, 0);
                    Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MIDDLEUP, Pt.x, Pt.y, 0, 0);
 
                 end;
               3:begin
                    EventStrut.message:=WM_NULL;
                    Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_RIGHTDOWN, Pt.x, Pt.y, 0, 0);
                    Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_RIGHTUP, Pt.x, Pt.y, 0, 0);
 
                 end;
                
               end;//case
 
          end;
 
        if (EventStrut.message = WM_MBUTTONDOWN) or (EventStrut.message = WM_MBUTTONDOWN) or
          (EventStrut.message = WM_MBUTTONDBLCLK) then
          begin
 
               GetCursorPos(Pt);
 
               case MouseKey[2] of
               1:begin
                    EventStrut.message:=WM_NULL;
                    Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN, Pt.x, Pt.y, 0, 0);
                    Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, Pt.x, Pt.y, 0, 0);
 
                 end;
               3:begin
                    EventStrut.message:=WM_NULL;
                    Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_RIGHTDOWN, Pt.x, Pt.y, 0, 0);
                    Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_RIGHTUP, Pt.x, Pt.y, 0, 0);
 
                 end;
                
               end;//case
 
          end;


Тут массив MouseKey содержит настройки переопределения: в первой ячейке номер назначеной кнопки для первой кнопки, во второй - номер назначеной кнопки для второй кнопки....

Спасибо.
Ответить с цитированием
  #2  
Старый 17.04.2015, 13:55
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Всё намного проще
Код:
1
2
3
SwapMouseButton(true); // поменять функции кнопок мышки
...
SwapMouseButton(false); // вернуть всё обратно
Ответить с цитированием
  #3  
Старый 17.04.2015, 14:00
yorri yorri вне форума
Прохожий
 
Регистрация: 17.04.2015
Сообщения: 7
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Всё намного проще
Код:
1
2
3
SwapMouseButton(true); // поменять функции кнопок мышки
...
SwapMouseButton(false); // вернуть всё обратно

SwapMouseButton изменяет на противоположное (инвертирует) или восстанавливает предназначение левых и правых кнопок мыши.
А мне нужно немного не это. А средняя? а Если нужно правую на среднюю, а среднюю на левую...
Ответить с цитированием
  #4  
Старый 17.04.2015, 16:21
Аватар для SCrat.ORS
SCrat.ORS SCrat.ORS вне форума
Активный
 
Регистрация: 20.02.2007
Адрес: Мой адрес не дом и не улица, мой адрес 0x7С00
Сообщения: 208
Версия Delphi: 2006
Репутация: 884
По умолчанию

Может там есть какой-нить идентификатор сообщения? Типа послал сообщение эмуляции, запомнил его идентификатор, и если на следующем круге пришло сообщение с таким-же идентификатором, то игнорировать его... Эт так, мысли в слух.
__________________
Програмистами не рождаются, ими становятся!
Ответить с цитированием
  #5  
Старый 17.04.2015, 16:31
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

абсолютно глобальным флагом блокируй обработчик, пока Mouse_Event выполняются
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #6  
Старый 17.04.2015, 16:35
yorri yorri вне форума
Прохожий
 
Регистрация: 17.04.2015
Сообщения: 7
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от SCrat.ORS
Может там есть какой-нить идентификатор сообщения? Типа послал сообщение эмуляции, запомнил его идентификатор, и если на следующем круге пришло сообщение с таким-же идентификатором, то игнорировать его... Эт так, мысли в слух.

Цитата:
Сообщение от NumLock
абсолютно глобальным флагом блокируй обработчик, пока Mouse_Event выполняются

Да пробовал так. Не работает. Оно все равно зацикливается.
Ответить с цитированием
  #7  
Старый 17.04.2015, 16:55
yorri yorri вне форума
Прохожий
 
Регистрация: 17.04.2015
Сообщения: 7
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Выходит, что
EventStrut.message:=WM_NULL;
работает как то не так...

"Сообщение WM_ NULL не выполняет никакого действия. Приложение отправляет сообщение WM_NULL, если оно желает посылать сообщение, которое окно получатель должно проигнорировать." отсюда брал
Ответить с цитированием
  #8  
Старый 17.04.2015, 18:11
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

stack overflow что-ли?
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #9  
Старый 17.04.2015, 19:07
yorri yorri вне форума
Прохожий
 
Регистрация: 17.04.2015
Сообщения: 7
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от NumLock
stack overflow что-ли?
Да нет. Просто шпарит нажатия двух кнопок попеременно. Онибок никаких. (Кликер какойто)
Ответить с цитированием
  #10  
Старый 17.04.2015, 19:17
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

А у меня и переполнение вылезало минут через пяток с вашим кодом Есть предложение сначало глушить реакцию на мышь, может и так даже
Код:
1
2
3
4
5
6
7
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
begin
 Handled := (msg.wParam = vk_lButton) or
            (msg.wParam = vk_rButton) or
            (msg.wParam = vk_mButton);
end;
а затем в низкоуровневой LowLevelMouseProc (она продолжает работать и при блокировке) ловить и обрабатывать нажатия самостоятельно, но это правда ещё тот гимор
Ответить с цитированием
  #11  
Старый 18.04.2015, 12:21
yorri yorri вне форума
Прохожий
 
Регистрация: 17.04.2015
Сообщения: 7
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Думаю это не подойдет, мне нужно работать/отлавливать сообщения от мышки глобально, то есть, не только в рамках этого приложения, а касательно всей системы виндовс...
Ответить с цитированием
  #12  
Старый 21.04.2015, 12:12
yorri yorri вне форума
Прохожий
 
Регистрация: 17.04.2015
Сообщения: 7
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Зацикливание поборол :-). Все как бы работает, но...

Меняю левую на среднюю, среднюю на леву. При нажатии на левую она работает как левая+средняя, а при нажатии на среднюю - средняя+левая.

То есть система не полностью мной контролируется...

Мож в другом месте чета напортачил?...
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
function JournalProc(Code, wParam: Integer; var EventStrut: TEventMsg): Integer; stdcall;
 var
    
   Pt: TPoint;
  
 begin
 
   Result := CallNextHookEx(JHook, Code, wParam, Longint(@EventStrut));
 
   if Code < 0 then Exit;
 
   if Code = HC_SYSMODALON then Exit;
 
   if Code = HC_ACTION then
   begin
 
//===============================================WM_LBUTTON==========================
 
        if (EventStrut.message = WM_LBUTTONDOWN)  then
          begin
 
               GetCursorPos(Pt);
            
               case MouseKey[1] of
               2:begin
                    if ll=0 then
                    begin
 
                    EventStrut.message:=WM_NULL;
 
                    Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MIDDLEDOWN, Pt.x, Pt.y, 0, 0);
                     
                    ll:=1;
                    exit;
                    end else
                    begin
                    EventStrut.message:=WM_NULL;
                    ll:=0;
                    exit;
                    end;
 
                 end;
 
               end;//case
          end;
 
if (EventStrut.message = WM_LBUTTONUP) then
          begin
  
               GetCursorPos(Pt);
 
               case MouseKey[1] of
               2:begin
                    if rr=0 then
                    begin
 
                    EventStrut.message:=WM_NULL;
 
                    Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MIDDLEUP, Pt.x, Pt.y, 0, 0);
 
                    rr:=1;
                    exit;
                    end else
                    begin
                    EventStrut.message:=WM_NULL;
                    rr:=0;
                    exit;
                    end;
 
                 end;
 
               end;//case
          end;
//======================================WM_MBUTTO===============================================================
 
        if (EventStrut.message = WM_MBUTTONDOWN)  then
          begin
               GetCursorPos(Pt);
                
               case MouseKey[2] of
               1:begin
                    if ll=0 then
                    begin
 
                    Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN, Pt.x, Pt.y, 0, 0);
 
                    ll:=1;
                    exit;
                    end else
                    begin
                    EventStrut.message:=WM_NULL;
                    ll:=0;
                    exit;
                    end;
 
                 end;
 
               end;//case
 
          end;
 
        if (EventStrut.message = WM_MBUTTONUP) then
          begin
              
               GetCursorPos(Pt);
                
               case MouseKey[2] of
               1:begin
                    if rr=0 then
                    begin
                     
                    Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, Pt.x, Pt.y, 0, 0);
                     
                    rr:=1;
                    exit;
                    end else
                    begin
                    EventStrut.message:=WM_NULL;
                    rr:=0;
                    exit;
                    end;
 
                 end;
               end;//case
 
          end;
       
   end;
 
  
 end;
 
 procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
   var Handled: Boolean);
 begin
 
   Handled := False;
   if (Msg.message = WM_CANCELJOURNAL) and FHookStarted then
     JHook := SetWindowsHookEx(WH_JOURNALRECORD, @JournalProc, 0, 0);
 end;
 
procedure TForm1.BitBtn1Click(Sender: TObject);
var
  MyMouse: TPoint;
 
begin
if FHookStarted then
   begin
     ShowMessage('Mouse is already being Journaled, can not restart');//Mouse is already being Journaled, can not restart');
     Exit;
   end;
   JHook := SetWindowsHookEx(WH_JOURNALRECORD, @JournalProc, hInstance, 0);
   {SetWindowsHookEx starts the Hook}
   if JHook > 0 then
   begin
     FHookStarted := True;
      
   end
   else
     ShowMessage('No Journal Hook availible');
end;
 
 procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
 begin
    
   if FHookStarted then
     UnhookWindowsHookEx(JHook);
end;
 
procedure TForm1.BitBtn2Click(Sender: TObject);
begin
   FHookStarted := False;
   UnhookWindowsHookEx(JHook);
   JHook := 0;
  
end;
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 21:49.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025