- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我需要以某种方式允许使用右键单击拖动选项移动窗口。我通过一些我不太喜欢但它有效的狡猾代码完成了此操作。
目前我正在捕获 WM_NCRBUTTONDOWN 消息并设置一个 bool 值来表示我处于移动模式,当收到 WM_NCRBUTTONUP 时重置此变量。在移动模式下,我正在检查 WMNCMouseMove 并自己移动表单。由于跟上快速的鼠标移动速度很慢,因此我还设置了一个计时器来使用 GetCursorPos 执行相同的操作。
我最近发现了 SwapMouseButton 函数,这正是我想要的。不过有一个但是!我需要有条件地交换它,只有当用户右键单击窗口的 CAPTION 区域时。
因此,当我收到 WM_NCRBUTTONDOWN 并在 WM_NCRBUTTONUP 上重置时,我交换鼠标按钮。但是,如果 WM_NCRBUTTONUP 从不重置它,这将适用于后续点击。我认为这是因为点击事件已经发生,所以交换时间很晚,这就是为什么它适用于随后的右键单击命中,但不适用于导致鼠标交换的右键单击和拖动!
任何人都可以解决这个问题。请记住,我需要左键单击功能来关闭、最小化、最大化按钮等。右键单击 onyl 来移动!
请帮忙!!!!!
谢谢,乔
最佳答案
代替手动跟踪鼠标或交换按钮,有一种更简单的方法 - 响应 WM_NCRBUTTONDOWN
,只需通过向窗口发送一个特殊的 WM_SYSCOMMAND 将窗口置于 native 移动模式
消息,然后它将为您处理所有拖动的艰苦工作,例如:
const WPARAM MOUSE_MOVE = SC_MOVE + 2;
case WM_NCRBUTTONDOWN:
{
POINT pt;
GetCursorPos(&pt);
SendMessage(Handle, WM_NCRBUTTONUP, 0, MAKELPARAM(pt.x, pt.y));
SendMessage(Handle, WM_SYSCOMMAND, MOUSE_MOVE, MAKELPARAM(pt.x, pt.y));
break;
}
参见 Q114593了解更多详情。
更新:我无法让 WM_SYSCOMMAND
与右键单击一起工作(尽管在子控件上左键单击时效果很好)。我认为操作系统正在做一些内部处理,这使得它无法正常工作。因此,我采用拦截鼠标移动的方法来手动移动窗口,通过使用 SetCapture()
代替,使其在不使用计时器的情况下通过快速鼠标移动正确运行:
bool RightButton_CanMove = false;
bool RightButton_WindowMoved = false;
POINTS LastPoint;
void __fastcall TForm1::WndProc(TMessage &Message)
{
switch( Message.Msg )
{
case WM_NCRBUTTONDOWN:
LastPoint = MAKEPOINTS(Message.LParam);
RightButton_CanMove = true;
RightButton_WindowMoved = false;
SetCapture(Handle);
Message.Result = 0;
return;
case WM_MOUSEMOVE:
if( (Message.WParam & MK_RBUTTON) && (RightButton_CanMove) )
{
POINT CurPoint;
GetCursorPos(&CurPoint);
SetWindowPos(Handle, NULL, Left + (CurPoint.x - LastPoint.x), Top + (CurPoint.y - LastPoint.y), 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
LastPoint.x = CurPoint.x;
LastPoint.y = CurPoint.y;
RightButton_WindowMoved = true;
}
break;
case WM_RBUTTONUP:
if( RightButton_CanMove )
{
RightButton_CanMove = false;
ReleaseCapture();
if( RightButton_WindowMoved )
{
RightButton_WindowMoved = false;
Message.Result = 0;
return;
}
}
break;
}
TForm::WndProc(Message);
}
代码区分右键单击和右键移动操作。如果用户在不移动鼠标的情况下右击鼠标,允许默认弹出菜单正常出现。如果用户按住鼠标右键并四处移动窗口,则当用户释放右键时不会显示默认弹出窗口。
关于c++ - 使用 SwapMouseButton( TRUE );允许右键单击拖动窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7686220/
我有点困惑。在 : http://delphi.about.com/od/objectpascalide/l/blvkc.htm 它说“Space”的正确键是#20。试过了,但行不通。但是,将其替换为
我有一个 input 的 type="submit" 并且我希望当我点击(右键或左键点击)它时这个元素周围没有蓝色边框。 我在下面的chrome浏览器中添加了OK模式和not OK模式的图片: OK模
我想在右键单击选项卡标题时显示上下文菜单条。 但是,我没有找到检测选项卡标题点击的方法。 有人知道如何做到这一点吗? 最佳答案 Private Sub tab1_MouseClick(sender A
我对编程还很陌生,正在尝试制作扫雷 GUI。游戏完美地右键单击 JToggleButton,在按钮上显示了一个代表炸弹的“B”,但是当我在鼠标监听器中用 setIcon() 替换 setText()
我正在尝试将一个按钮 float 到卡片的右侧。我希望它出现在右下角。 当我正确使用 float 时。它出现在父 div 之外,有没有办法正确定位它?
我正在使用 Struts2 标签和下面的代码使用 JS 计算并检查/验证在文本字段中输入的值。 它还会更新在 textfield 中输入的总数列表,这些由 onblur 处理和 onkeydown事件
我是一名优秀的程序员,十分优秀!