28_SELECTANY HHOOK s_hTnbRmwLowMouse = NULL;
102 m_in.m_pListener = P;
111 return m_in.m_devsList.GetSize();
122 if ( m_win.
Create(&m_in) )
127 rid.dwFlags = RIDEV_INPUTSINK;
128 rid.hwndTarget = m_win;
129 if ( ::RegisterRawInputDevices(&rid, 1,
sizeof(rid)) )
157 _spec = m_in.m_devsList[index].specified;
172 return m_in.m_devsList[index].name;
186 return m_in.Refresh();
204 if ( s_hTnbRmwLowMouse == NULL )
208 return s_hTnbRmwLowMouse != NULL;
211 if ( s_hTnbRmwLowMouse != NULL )
213 ::UnhookWindowsHookEx(s_hTnbRmwLowMouse);
214 s_hTnbRmwLowMouse = NULL;
216 return s_hTnbRmwLowMouse == NULL;
230 static void MouseEvent(DWORD flags, DWORD dx = 0,DWORD dy = 0, DWORD data = 0)
232 ::mouse_event(flags, dx, dy, data, COOKIE);
253 HWND hWnd = ::GetForegroundWindow();
254 TTRACE1(
"GetForegroundWindow = %08X\n", hWnd);
256 DWORD dwCurrentThreadId = ::GetCurrentThreadId();
257 DWORD dwActiveProcessId;
258 DWORD dwActiveThreadId = ::GetWindowThreadProcessId(hWnd, &dwActiveProcessId);
259 if ( ::AttachThreadInput(dwCurrentThreadId, dwActiveThreadId, TRUE) )
264 LONG style = ::GetWindowLong(hWnd, GWL_STYLE);
265 bool hasScrollBar = (style & WS_HSCROLL) != 0;
268 ::GetClassName(hWnd, s.
GetBuffer(100), 100);
270 TTRACE3(
" GetFocus = %08X %d, [%s]\n", hWnd, hasScrollBar, s);
273 if ( ! hasScrollBar )
276 isDisp = ms_SubWheel(hWnd, delta);
280 HWND h = ::GetWindow(hWnd, GW_CHILD);
281 isDisp = ms_SubWheel(h, delta);
286 ms_PostWheel(hWnd, NULL, delta);
290 ::AttachThreadInput(dwCurrentThreadId, dwActiveThreadId, FALSE);
306 RID_DEVICE_INFO_MOUSE specified;
307 TInfo(
void) : handle(INVALID_HANDLE_VALUE)
310 virtual INT_PTR
Compare(
const TInfo& t)
const
321 CInner(
void) : m_pListener(NULL), m_lastHandle(INVALID_HANDLE_VALUE)
329 virtual bool OnWindowMessage(LRESULT& _result, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
331 if ( m_pListener != NULL )
333 if ( message == WM_DEVICECHANGE && wParam == DBT_DEVNODES_CHANGED )
336 if ( Collect(newInf) )
338 loop ( i, m_devsList )
340 INDEX idx = newInf.
Find(m_devsList[i]);
341 if ( idx != INVALID_INDEX )
344 if ( m_devsList[i].handle == INVALID_HANDLE_VALUE )
346 m_devsList[i] = newInf[idx];
347 m_pListener->OnMultiMouseDevice(i, _super::IListener::Device_Reconnect);
353 if ( m_devsList[i].handle != INVALID_HANDLE_VALUE )
355 m_devsList[i].handle = INVALID_HANDLE_VALUE;
356 m_pListener->OnMultiMouseDevice(i, _super::IListener::Device_Remove);
362 INDEX idx = m_devsList.Find(newInf[i]);
363 if ( idx == INVALID_INDEX )
366 int x = m_devsList.Add(newInf[i]);
367 m_pListener->OnMultiMouseDevice(x, _super::IListener::Device_Connect);
372 else if ( message == WM_INPUT )
376 ::GetRawInputData(
reinterpret_cast<HRAWINPUT
>(lParam), RID_INPUT, w, &size,
sizeof(RAWINPUTHEADER));
377 RAWINPUT* P =
reinterpret_cast<RAWINPUT*
>(w.Ref());
378 if ( P->header.dwType == RIM_TYPEMOUSE )
380 INDEX idx = INVALID_INDEX;
381 if ( m_lastHandle == P->header.hDevice )
387 loop ( i, m_devsList.GetSize() )
389 if ( m_devsList[i].handle == P->header.hDevice )
392 m_lastHandle = P->header.hDevice;
398 if ( idx != INVALID_INDEX )
400 m_pListener->OnMultiMouseEvent(idx, P->data.mouse);
410 m_lastHandle = INVALID_HANDLE_VALUE;
411 return Collect(m_devsList);
418 UINT rr = ::GetRawInputDeviceList(NULL, &count,
sizeof(RAWINPUTDEVICELIST));
425 UINT d2 = ::GetRawInputDeviceList(devs, &count,
sizeof(RAWINPUTDEVICELIST));
430 loop ( i, devs.GetSize() )
432 if ( devs[i].dwType != RIM_TYPEMOUSE )
437 info.handle = devs[i].hDevice;
440 UINT size =
sizeof(RID_DEVICE_INFO);
441 if ( ::GetRawInputDeviceInfo(info.handle, RIDI_DEVICEINFO, &dev, &size) > 0 )
443 info.specified = dev.mouse;
445 if ( ::GetRawInputDeviceInfo(info.handle, RIDI_DEVICENAME, NULL, &size) == 0 )
449 int r = ::GetRawInputDeviceInfo(info.handle, RIDI_DEVICENAME, name, &size);
452 info.name = name.Ref();
460 IParentListener* m_pListener;
462 mutable HANDLE m_lastHandle;
463 mutable INDEX m_lastIndex;
469 static LRESULT CALLBACK ms_OnLowLevelMouseProc(
int nCode, WPARAM wParam, LPARAM lParam)
471 if ( nCode == HC_ACTION )
473 MSLLHOOKSTRUCT* P =
reinterpret_cast<MSLLHOOKSTRUCT*
>(lParam);
474 TTRACE3(
"OnLowLevelMouseProc msg=0x%X, x=%d, y=%d\n", wParam, P->pt.x, P->pt.y);
475 TTRACE3(
" data=%d, flags=0x%X, ex-info=%d\n", P->mouseData, P->flags, P->dwExtraInfo);
476 if ( P->dwExtraInfo != COOKIE )
481 return ::CallNextHookEx(s_hTnbRmwLowMouse, nCode, wParam, lParam);
484 static bool ms_IsScrollBar(LPCTSTR P)
486 const TCHAR src[] = _T(
"ScrollBar");
487 loop ( i,
sizeof(src) )
489 if ( src[i] != P[i] )
497 static void ms_PostWheel(HWND hTargetWnd, HWND hCtrlWnd,
int delta)
499 UINT msg = WM_HSCROLL;
500 WPARAM wp = (delta < 0) ? SB_LINELEFT : SB_LINERIGHT;
501 LPARAM lp =
reinterpret_cast<LPARAM
>(hCtrlWnd);
502 int l = ((delta < 0) ? -delta : delta) / WHEEL_DELTA;
505 ::PostMessage(hTargetWnd, msg, wp, lp);
507 ::PostMessage(hTargetWnd, msg, SB_ENDSCROLL, lp);
510 static bool ms_SubWheel(HWND hWnd,
int delta)
513 HWND h = ::GetWindow(hWnd, GW_HWNDNEXT);
516 ::GetClassName(h, buf, 100);
517 LONG style = ::GetWindowLong(h, GWL_STYLE);
518 bool isVisible = (style & WS_VISIBLE) != 0;
519 bool isHorz = (style & (SBS_VERT | SBS_SIZEBOX)) == 0;
520 if ( ms_IsScrollBar(buf) && isVisible && isHorz )
522 TTRACE2(
" Found ScrollBar = %08X, [%s]\n", h, buf.Ref());
523 HWND h2 = ::GetParent(h);
527 ms_PostWheel(h2, h, delta);
531 h = ::GetWindow(h, GW_HWNDNEXT);
#define loop(VAR, CNT)
loop構文.
void Destroy(void)
[操作] ウィンドウの破棄.
bool Create(CDummyWindow::IListener *I, LPCTSTR lpszTitle=NULL, LPCTSTR lpszClassName=NULL, DWORD dwStyle=WS_OVERLAPPEDWINDOW, HMENU hMenu=NULL, HWND hParent=NULL)
[操作] ウィンドウの作成.
virtual void Stop(void)
[設定] 監視停止.
static bool EnableMouseCursor(bool isEnable)
[設定] システムマウス有効無効設定.
bool GetMouseSpecified(RID_DEVICE_INFO_MOUSE &_spec, INDEX index) const
[取得] マウススペック取得.
virtual void SetListener(IMultiMouseWatcher::IListener *P)
[登録] リスナー登録.
static void HorizontalWheelEvent(int delta)
[設定] システム水平ホイールイベント.
bool Refresh(void)
[設定] 再検索.
CRawMouseWatcher(void)
コンストラクタ
static void MouseEvent(DWORD flags, DWORD dx=0, DWORD dy=0, DWORD data=0)
[設定] システムマウスイベント.
CStr GetMouseName(INDEX index) const
[取得] マウスデバイス名取得.
virtual size_t GetMouseCount(void) const
[取得] マウス数取得.
virtual bool Start(void)
[設定] 監視開始.
int Compare(const TYP *lpszSubject) const
[確認] 文字列比較
void ReleaseBuffer(void)
[操作] 割り当てたバッファを開放.
TYP * GetBuffer(size_t iLength=0)
[操作] 書き込みバッファ要求.
virtual bool RemoveAll(void)
[削除] 空化
virtual INDEX Add(const TYP &t)
[追加] 要素一つ追加.
int Compare(LPCSTR P1, LPCSTR P2, INT_PTR len=-1, DWORD dwCmpFlags=0)
[比較] 文字列比較(ASCII/SJIS用)
HINSTANCE GetInstanceHandleByTnb(EInstanceType type=EI_Process)
[取得] インスタンスハンドル取得.
INDEX Find(const IChecker &checker, INDEX startIndex=0, bool boIsReverse=false) const
[検索] 条件一致要素の検索.