@@ -57,12 +57,14 @@ int autoTrayListViewCompare(LPARAM, LPARAM, LPARAM);
5757void autoTrayListViewItemAdd (HWND dialogHwnd);
5858void autoTrayListViewItemUpdate (HWND dialogHwnd, int item);
5959void autoTrayListViewItemDelete (HWND dialogHwnd, int item);
60- void autoTrayListViewItemSpy (HWND dialogHwnd);
6160void autoTrayListViewItemEdit (HWND dialogHwnd, int item);
6261void autoTrayListViewUpdateButtons (HWND dialogHwnd);
6362void autoTrayListViewUpdateSelected (HWND dialogHwnd);
64- void spySelectWindowAtPoint (const POINT & point);
65- LRESULT CALLBACK MouseProc (int nCode, WPARAM wParam, LPARAM lParam);
63+ void spyBegin (HWND dialogHwnd);
64+ void spyEnd (HWND dialogHwnd);
65+ void spyEnableIcon (HWND dialogHwnd);
66+ void spyDisableIcon (HWND dialogHwnd);
67+ void spyUpdate (HWND dialogHwnd);
6668std::string getDialogItemText (HWND dialogHwnd, int id);
6769std::string getListViewItemText (HWND listViewHwnd, int item, int subItem);
6870
@@ -75,8 +77,6 @@ bool autoTrayListViewSortAscending_;
7577int autoTrayListViewSortColumn_;
7678#endif
7779bool spyMode_;
78- HWND spyModeHwnd_;
79- HHOOK mouseHhook_;
8080
8181} // anonymous namespace
8282
@@ -110,12 +110,29 @@ INT_PTR settingsDialogFunc(HWND dialogHwnd, UINT message, WPARAM wParam, LPARAM
110110 // DEBUG_PRINTF("wnd %#x, message %#x, wparam %#x, lparam %#x\n", dialogHwnd, message, wParam, lParam);
111111
112112 if (spyMode_) {
113- if (message == WM_LBUTTONDOWN) {
114- POINT point;
115- if (!GetCursorPos (&point)) {
116- WARNING_PRINTF (" GetCursorPos failed: %s\n " , StringUtility::lastErrorString ().c_str ());
117- } else {
118- spySelectWindowAtPoint (point);
113+ switch (message) {
114+ case WM_CAPTURECHANGED:
115+ case WM_LBUTTONUP: {
116+ spyUpdate (dialogHwnd);
117+ spyEnd (dialogHwnd);
118+ break ;
119+ }
120+
121+ case WM_MOUSEMOVE: {
122+ spyUpdate (dialogHwnd);
123+ break ;
124+ }
125+
126+ case WM_SETCURSOR: {
127+ HCURSOR hCursor = LoadCursor (NULL , IDC_CROSS);
128+ if (!hCursor) {
129+ WARNING_PRINTF (" LoadCursor failed: %s\n " , StringUtility::lastErrorString ().c_str ());
130+ } else {
131+ if (!SetCursor (hCursor)) {
132+ WARNING_PRINTF (" SetCursor failed: %s\n " , StringUtility::lastErrorString ().c_str ());
133+ }
134+ }
135+ break ;
119136 }
120137 }
121138
@@ -193,6 +210,8 @@ INT_PTR settingsDialogFunc(HWND dialogHwnd, UINT message, WPARAM wParam, LPARAM
193210 WARNING_PRINTF (" SetDlgItemTextA failed: %s\n " , StringUtility::lastErrorString ().c_str ());
194211 }
195212
213+ spyEnableIcon (dialogHwnd);
214+
196215 autoTrayListViewInit (dialogHwnd);
197216
198217 break ;
@@ -258,7 +277,9 @@ INT_PTR settingsDialogFunc(HWND dialogHwnd, UINT message, WPARAM wParam, LPARAM
258277 break ;
259278 }
260279 case IDC_AUTO_TRAY_ITEM_SPY: {
261- autoTrayListViewItemSpy (dialogHwnd);
280+ if (HIWORD (wParam) == STN_CLICKED) {
281+ spyBegin (dialogHwnd);
282+ }
262283 break ;
263284 }
264285
@@ -670,31 +691,6 @@ void autoTrayListViewItemDelete(HWND dialogHwnd, int item)
670691 autoTrayListViewUpdateSelected (dialogHwnd);
671692}
672693
673- void autoTrayListViewItemSpy (HWND dialogHwnd)
674- {
675- DEBUG_PRINTF (" Spying auto tray\n " );
676-
677- if (!ShowWindow (dialogHwnd, SW_HIDE)) {
678- WARNING_PRINTF (" ShowWindow failed: %s\n " , StringUtility::lastErrorString ().c_str ());
679- }
680-
681- MessageBoxA (
682- dialogHwnd,
683- getResourceString (IDS_SPY_MODE_TEXT).c_str (),
684- getResourceString (IDS_SPY_MODE_TITLE).c_str (),
685- MB_OK);
686-
687- mouseHhook_ = SetWindowsHookEx (WH_MOUSE_LL, MouseProc, nullptr , 0 );
688- if (!mouseHhook_) {
689- WARNING_PRINTF (" Failed to install mouse hook!\n " );
690- } else {
691- DEBUG_PRINTF (" Mouse hook installed.\n " );
692- }
693-
694- spyModeHwnd_ = dialogHwnd;
695- spyMode_ = true ;
696- }
697-
698694void autoTrayListViewItemEdit (HWND dialogHwnd, int item)
699695{
700696 DEBUG_PRINTF (" Editing auto tray item %d\n " , item);
@@ -822,76 +818,126 @@ void setListViewSortIcon(HWND listView, int col, int sortOrder)
822818}
823819#endif
824820
825- void spySelectWindowAtPoint ( const POINT & point )
821+ void spyBegin (HWND dialogHwnd )
826822{
827- DEBUG_PRINTF (" Mouse clicked at: %d, %d \n " , point. x , point. y );
823+ DEBUG_PRINTF (" Spy mode: beginning \n " );
828824
829- HWND hwnd = WindowFromPoint (point);
830- if (!hwnd) {
831- DEBUG_PRINTF (" No window found\n " );
832- } else {
833- DEBUG_PRINTF (" Spy mode: hwnd %#x\n " , hwnd);
825+ spyMode_ = true ;
826+
827+ spyDisableIcon (dialogHwnd);
828+
829+ SetCapture (dialogHwnd);
830+ }
831+
832+ void spyEnd (HWND dialogHwnd)
833+ {
834+ DEBUG_PRINTF (" Spy mode: ended\n " );
835+ if (!ReleaseCapture ()) {
836+ WARNING_PRINTF (" ReleaseCapture failed: %s\n " , StringUtility::lastErrorString ().c_str ());
837+ }
838+
839+ spyEnableIcon (dialogHwnd);
834840
835- HWND rootHwnd = GetAncestor (hwnd, GA_ROOT);
836- if (!rootHwnd) {
837- WARNING_PRINTF (" Failed to get root hwnd, falling back to original\n " );
838- rootHwnd = hwnd;
841+ spyMode_ = false ;
842+ }
843+
844+ void spyEnableIcon (HWND dialogHwnd)
845+ {
846+ HCURSOR hCrossCursor = LoadCursor (NULL , IDC_CROSS);
847+ if (!hCrossCursor) {
848+ WARNING_PRINTF (" LoadCursor failed: %s\n " , StringUtility::lastErrorString ().c_str ());
849+ } else {
850+ if (!SendDlgItemMessage (dialogHwnd, IDC_AUTO_TRAY_ITEM_SPY, STM_SETICON, (WPARAM)hCrossCursor, 0 )) {
851+ WARNING_PRINTF (" SendDlgItemMessage failed: %s\n " , StringUtility::lastErrorString ().c_str ());
839852 }
853+ }
854+ }
840855
841- CHAR executableFullPath[MAX_PATH] = {};
842- DWORD processID;
843- if (!GetWindowThreadProcessId (rootHwnd, &processID)) {
844- WARNING_PRINTF (" GetWindowThreadProcessId() failed: %s\n " , StringUtility::lastErrorString ().c_str ());
845- } else {
846- HandleWrapper process (OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE , processID));
847- if (!process) {
848- WARNING_PRINTF (" OpenProcess() failed: %s\n " , StringUtility::lastErrorString ().c_str ());
849- } else {
850- if (!GetModuleFileNameExA ((HMODULE)(HANDLE)process, nullptr , executableFullPath, MAX_PATH)) {
851- WARNING_PRINTF (" GetModuleFileNameA() failed: %s\n " , StringUtility::lastErrorString ().c_str ());
852- }
853- }
856+ void spyDisableIcon (HWND dialogHwnd)
857+ {
858+ if (!SendDlgItemMessage (dialogHwnd, IDC_AUTO_TRAY_ITEM_SPY, STM_SETICON, 0 , 0 )) {
859+ WARNING_PRINTF (" SendDlgItemMessage failed: %s\n " , StringUtility::lastErrorString ().c_str ());
860+ }
861+
862+ HCURSOR hCursor = LoadCursor (NULL , IDC_CROSS);
863+ if (!hCursor) {
864+ WARNING_PRINTF (" LoadCursor failed: %s\n " , StringUtility::lastErrorString ().c_str ());
865+ } else {
866+ if (!SetCursor (hCursor)) {
867+ WARNING_PRINTF (" SetCursor failed: %s\n " , StringUtility::lastErrorString ().c_str ());
854868 }
855- DEBUG_PRINTF (" Executable full path: '%s'\n " , executableFullPath);
869+ }
870+ }
856871
857- std::string className = getWindowClassName (rootHwnd);
858- DEBUG_PRINTF (" Class name: '%s'\n " , className.c_str ());
872+ void spyUpdate (HWND dialogHwnd)
873+ {
874+ POINT point;
875+ if (!GetCursorPos (&point)) {
876+ WARNING_PRINTF (" GetCursorPos failed: %s\n " , StringUtility::lastErrorString ().c_str ());
877+ return ;
878+ }
879+
880+ DEBUG_PRINTF (" Spy mode: selecting window at: %d, %d\n " , point.x , point.y );
881+
882+ HWND hwnd = WindowFromPoint (point);
883+ if (!hwnd) {
884+ DEBUG_PRINTF (" No window found\n " );
885+ return ;
886+ }
859887
860- std::string title = getWindowText (rootHwnd);
861- DEBUG_PRINTF (" Title: '%s'\n " , title.c_str ());
888+ HWND rootHwnd = GetAncestor (hwnd, GA_ROOT);
889+ if (!rootHwnd) {
890+ WARNING_PRINTF (" Failed to get root hwnd, falling back to original\n " );
891+ rootHwnd = hwnd;
892+ }
862893
863- if (!SetDlgItemTextA (spyModeHwnd_, IDC_AUTO_TRAY_EDIT_EXECUTABLE, executableFullPath)) {
894+ if (rootHwnd == dialogHwnd) {
895+ DEBUG_PRINTF (" Spy mode: own window, clearing\n " );
896+ if (!SetDlgItemTextA (dialogHwnd, IDC_AUTO_TRAY_EDIT_EXECUTABLE, nullptr )) {
864897 WARNING_PRINTF (" SetDlgItemTextA failed: %s\n " , StringUtility::lastErrorString ().c_str ());
865898 }
866- if (!SetDlgItemTextA (spyModeHwnd_ , IDC_AUTO_TRAY_EDIT_WINDOWCLASS, className. c_str () )) {
899+ if (!SetDlgItemTextA (dialogHwnd , IDC_AUTO_TRAY_EDIT_WINDOWCLASS, nullptr )) {
867900 WARNING_PRINTF (" SetDlgItemTextA failed: %s\n " , StringUtility::lastErrorString ().c_str ());
868901 }
869- if (!SetDlgItemTextA (spyModeHwnd_ , IDC_AUTO_TRAY_EDIT_WINDOWTITLE, title. c_str () )) {
902+ if (!SetDlgItemTextA (dialogHwnd , IDC_AUTO_TRAY_EDIT_WINDOWTITLE, nullptr )) {
870903 WARNING_PRINTF (" SetDlgItemTextA failed: %s\n " , StringUtility::lastErrorString ().c_str ());
871904 }
905+ return ;
906+ }
872907
873- if (!ShowWindow (spyModeHwnd_, SW_SHOW)) {
874- WARNING_PRINTF (" ShowWindow failed: %s\n " , StringUtility::lastErrorString ().c_str ());
875- }
876- if (!SetForegroundWindow (spyModeHwnd_)) {
877- WARNING_PRINTF (" SetForegroundWindow failed: %s\n " , StringUtility::lastErrorString ().c_str ());
878- }
908+ DEBUG_PRINTF (" Spy mode: root hwnd %#x\n " , rootHwnd);
879909
880- spyModeHwnd_ = nullptr ;
881- spyMode_ = false ;
910+ CHAR executableFullPath[MAX_PATH] = {};
911+ DWORD processID;
912+ if (!GetWindowThreadProcessId (rootHwnd, &processID)) {
913+ WARNING_PRINTF (" GetWindowThreadProcessId() failed: %s\n " , StringUtility::lastErrorString ().c_str ());
914+ } else {
915+ HandleWrapper process (OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE , processID));
916+ if (!process) {
917+ WARNING_PRINTF (" OpenProcess() failed: %s\n " , StringUtility::lastErrorString ().c_str ());
918+ } else {
919+ if (!GetModuleFileNameExA ((HMODULE)(HANDLE)process, nullptr , executableFullPath, MAX_PATH)) {
920+ WARNING_PRINTF (" GetModuleFileNameA() failed: %s\n " , StringUtility::lastErrorString ().c_str ());
921+ }
922+ }
882923 }
883- }
924+ DEBUG_PRINTF ( " Executable full path: '%s' \n " , executableFullPath);
884925
885- LRESULT CALLBACK MouseProc (int nCode, WPARAM wParam, LPARAM lParam)
886- {
887- if ((nCode == HC_ACTION) && (wParam == WM_LBUTTONDOWN)) {
888- UnhookWindowsHookEx (mouseHhook_);
926+ std::string className = getWindowClassName (rootHwnd);
927+ DEBUG_PRINTF (" Class name: '%s'\n " , className.c_str ());
889928
890- LPMSLLHOOKSTRUCT mouseInfo = (LPMSLLHOOKSTRUCT)lParam;
891- spySelectWindowAtPoint (mouseInfo->pt );
892- }
929+ std::string title = getWindowText (rootHwnd);
930+ DEBUG_PRINTF (" Title: '%s'\n " , title.c_str ());
893931
894- return CallNextHookEx (mouseHhook_, nCode, wParam, lParam);
932+ if (!SetDlgItemTextA (dialogHwnd, IDC_AUTO_TRAY_EDIT_EXECUTABLE, executableFullPath)) {
933+ WARNING_PRINTF (" SetDlgItemTextA failed: %s\n " , StringUtility::lastErrorString ().c_str ());
934+ }
935+ if (!SetDlgItemTextA (dialogHwnd, IDC_AUTO_TRAY_EDIT_WINDOWCLASS, className.c_str ())) {
936+ WARNING_PRINTF (" SetDlgItemTextA failed: %s\n " , StringUtility::lastErrorString ().c_str ());
937+ }
938+ if (!SetDlgItemTextA (dialogHwnd, IDC_AUTO_TRAY_EDIT_WINDOWTITLE, title.c_str ())) {
939+ WARNING_PRINTF (" SetDlgItemTextA failed: %s\n " , StringUtility::lastErrorString ().c_str ());
940+ }
895941}
896942
897943std::string getDialogItemText (HWND dialogHwnd, int id)
0 commit comments