@@ -82,22 +82,29 @@ MessageInput::~MessageInput()
8282 }
8383}
8484
85- void MessageInput::send_activate ()
85+ HWND MessageInput::send_activate ()
8686{
87+ HWND target = get_active_hwnd ();
8788 bool use_post = (config_.mode == Mode::PostMessage);
88- ::MaaNS::CtrlUnitNs::send_activate_message (hwnd_, use_post);
89+ ::MaaNS::CtrlUnitNs::send_activate_message (target, use_post);
90+ return target;
8991}
9092
91- bool MessageInput::send_or_post_w (UINT message, WPARAM wParam, LPARAM lParam)
93+ bool MessageInput::send_or_post_w (HWND target, UINT message, WPARAM wParam, LPARAM lParam)
9294{
95+ if (!target || !IsWindow (target)) {
96+ LogError << " Invalid target window" << VAR (target) << VAR (message);
97+ return false ;
98+ }
99+
93100 bool success = false ;
94101
95102 if (config_.mode == Mode::PostMessage) {
96- success = PostMessageW (hwnd_ , message, wParam, lParam) != 0 ;
103+ success = PostMessageW (target , message, wParam, lParam) != 0 ;
97104 }
98105 else {
99- SendMessageW (hwnd_ , message, wParam, lParam);
100- success = true ; // SendMessage 总是返回,除非窗口句柄无效
106+ SendMessageW (target , message, wParam, lParam);
107+ success = true ;
101108 }
102109
103110 if (!success) {
@@ -108,6 +115,37 @@ bool MessageInput::send_or_post_w(UINT message, WPARAM wParam, LPARAM lParam)
108115 return success;
109116}
110117
118+ HWND MessageInput::get_active_hwnd ()
119+ {
120+ HWND root = GetAncestor (hwnd_, GA_ROOTOWNER);
121+ if (!root) {
122+ LogWarn << " GetAncestor returned nullptr, hwnd_ may be invalid" << VAR (hwnd_);
123+ return hwnd_;
124+ }
125+ HWND popup = GetLastActivePopup (root);
126+ if (popup && popup != hwnd_ && IsWindowVisible (popup)) {
127+ return popup;
128+ }
129+ return hwnd_;
130+ }
131+
132+ LPARAM MessageInput::make_mouse_lparam (HWND target, int x, int y)
133+ {
134+ if (target == hwnd_) {
135+ return MAKELPARAM (x, y);
136+ }
137+ POINT pt = { x, y };
138+ if (!ClientToScreen (hwnd_, &pt)) {
139+ LogError << " ClientToScreen failed in make_mouse_lparam" << VAR (hwnd_) << VAR (GetLastError ());
140+ return MAKELPARAM (x, y);
141+ }
142+ if (!ScreenToClient (target, &pt)) {
143+ LogError << " ScreenToClient failed in make_mouse_lparam" << VAR (target) << VAR (GetLastError ());
144+ return MAKELPARAM (x, y);
145+ }
146+ return MAKELPARAM (pt.x , pt.y );
147+ }
148+
111149POINT MessageInput::client_to_screen (int x, int y)
112150{
113151 POINT point = { x, y };
@@ -708,24 +746,27 @@ bool MessageInput::touch_down(int contact, int x, int y, int pressure)
708746 return false ;
709747 }
710748
711- send_activate ();
749+ HWND target = send_activate ();
750+ gesture_target_ = target;
712751
713752 check_and_block_input ();
714753
715754 save_pos ();
716755
717- // 准备位置并发送 MOVE 消息
718- LPARAM lParam = prepare_mouse_position (x, y);
756+ prepare_mouse_position (x, y);
719757
720- if (!send_or_post_w (move_info.message , move_info.w_param , lParam)) {
758+ LPARAM lParam = make_mouse_lparam (target, x, y);
759+
760+ if (!send_or_post_w (target, move_info.message , move_info.w_param , lParam)) {
761+ gesture_target_ = nullptr ;
721762 finish_pos ();
722763 return false ;
723764 }
724765
725766 std::this_thread::sleep_for (std::chrono::milliseconds (10 ));
726767
727- // 发送 DOWN 消息
728- if (! send_or_post_w (down_info. message , down_info. w_param , lParam)) {
768+ if (! send_or_post_w (target, down_info. message , down_info. w_param , lParam)) {
769+ gesture_target_ = nullptr ;
729770 finish_pos ();
730771 return false ;
731772 }
@@ -754,10 +795,13 @@ bool MessageInput::touch_move(int contact, int x, int y, int pressure)
754795 return false ;
755796 }
756797
757- // 准备位置并发送 MOVE 消息
758- LPARAM lParam = prepare_mouse_position (x, y);
798+ prepare_mouse_position (x, y);
799+
800+ HWND target = (gesture_target_ && IsWindow (gesture_target_)) ? gesture_target_ : get_active_hwnd ();
801+ LPARAM lParam = make_mouse_lparam (target, x, y);
759802
760- if (!send_or_post_w (msg_info.message , msg_info.w_param , lParam)) {
803+ if (!send_or_post_w (target, msg_info.message , msg_info.w_param , lParam)) {
804+ gesture_target_ = nullptr ;
761805 return false ;
762806 }
763807
@@ -776,19 +820,27 @@ bool MessageInput::touch_up(int contact)
776820 return false ;
777821 }
778822
779- send_activate ();
823+ bool reuse_gesture = gesture_target_ && IsWindow (gesture_target_);
824+ HWND target = reuse_gesture ? gesture_target_ : send_activate ();
825+ gesture_target_ = nullptr ;
780826
781827 OnScopeLeave ([this ]() { unblock_input (); });
782828
829+ if (reuse_gesture) {
830+ bool use_post = (config_.mode == Mode::PostMessage);
831+ ::MaaNS::CtrlUnitNs::send_activate_message (target, use_post);
832+ }
833+
783834 MouseMessageInfo msg_info;
784835 if (!contact_to_mouse_up_message (contact, msg_info)) {
785836 LogError << VAR (config_.mode ) << VAR (config_.with_cursor_pos ) << VAR (config_.with_window_pos ) << " contact out of range"
786837 << VAR (contact);
787838 return false ;
788839 }
789-
790840 auto target_pos = get_target_pos ();
791- if (!send_or_post_w (msg_info.message , msg_info.w_param , MAKELPARAM (target_pos.first , target_pos.second ))) {
841+ LPARAM lParam = make_mouse_lparam (target, target_pos.first , target_pos.second );
842+
843+ if (!send_or_post_w (target, msg_info.message , msg_info.w_param , lParam)) {
792844 finish_pos ();
793845 return false ;
794846 }
@@ -823,13 +875,12 @@ bool MessageInput::input_text(const std::string& text)
823875 return false ;
824876 }
825877
826- send_activate ();
878+ HWND target = send_activate ();
827879
828880 bool success = true ;
829881
830- // 文本输入仅发送 WM_CHAR
831882 for (const auto ch : to_u16 (text)) {
832- success &= send_or_post_w (WM_CHAR, static_cast <WPARAM>(ch), 0 );
883+ success &= send_or_post_w (target, WM_CHAR, static_cast <WPARAM>(ch), 0 );
833884 std::this_thread::sleep_for (std::chrono::milliseconds (50 ));
834885 }
835886 return success;
@@ -844,10 +895,10 @@ bool MessageInput::key_down(int key)
844895 return false ;
845896 }
846897
847- send_activate ();
898+ HWND target = send_activate ();
848899
849900 LPARAM lParam = make_keydown_lparam (key);
850- return send_or_post_w (WM_KEYDOWN, static_cast <WPARAM>(key), lParam);
901+ return send_or_post_w (target, WM_KEYDOWN, static_cast <WPARAM>(key), lParam);
851902}
852903
853904bool MessageInput::key_up (int key)
@@ -859,10 +910,10 @@ bool MessageInput::key_up(int key)
859910 return false ;
860911 }
861912
862- send_activate ();
913+ HWND target = send_activate ();
863914
864915 LPARAM lParam = make_keyup_lparam (key);
865- return send_or_post_w (WM_KEYUP, static_cast <WPARAM>(key), lParam);
916+ return send_or_post_w (target, WM_KEYUP, static_cast <WPARAM>(key), lParam);
866917}
867918
868919bool MessageInput::scroll (int dx, int dy)
@@ -874,7 +925,7 @@ bool MessageInput::scroll(int dx, int dy)
874925 return false ;
875926 }
876927
877- send_activate ();
928+ HWND target = send_activate ();
878929
879930 check_and_block_input ();
880931 OnScopeLeave ([this ]() { unblock_input (); });
@@ -883,21 +934,19 @@ bool MessageInput::scroll(int dx, int dy)
883934
884935 save_pos ();
885936
886- // prepare_mouse_position 用于移动光标/窗口(副作用),但 WM_MOUSEWHEEL 的 lParam 需要屏幕坐标
887937 prepare_mouse_position (target_pos.first , target_pos.second );
888938 POINT screen_pos = client_to_screen (target_pos.first , target_pos.second );
889939 LPARAM lParam = MAKELPARAM (screen_pos.x , screen_pos.y );
890-
891940 bool success = true ;
892941
893942 if (dy != 0 ) {
894943 WPARAM wParam = MAKEWPARAM (0 , static_cast <short >(dy));
895- success &= send_or_post_w (WM_MOUSEWHEEL, wParam, lParam);
944+ success &= send_or_post_w (target, WM_MOUSEWHEEL, wParam, lParam);
896945 }
897946
898947 if (dx != 0 ) {
899948 WPARAM wParam = MAKEWPARAM (0 , static_cast <short >(dx));
900- success &= send_or_post_w (WM_MOUSEHWHEEL, wParam, lParam);
949+ success &= send_or_post_w (target, WM_MOUSEHWHEEL, wParam, lParam);
901950 }
902951
903952 if (config_.with_window_pos ) {
0 commit comments