C# 在按键上移动窗口+;鼠标(如linux ALT+;鼠标按下)
简单地说,我想移动一个按ALT+鼠标的windows,就像linux操作系统一样(ALT+拖动) 是否可以通过单击将win32 api(移动api)传递给感兴趣的windows 我有一个windows服务钩子键按下(在特定的ALT按钮)。 当按下ALT键并验证鼠标按下事件时,我想将窗口移动到任意位置,而不仅仅是在标题栏上 目前,我以以下方式移动窗体窗口:C# 在按键上移动窗口+;鼠标(如linux ALT+;鼠标按下),c#,winforms,mouse,key,move,C#,Winforms,Mouse,Key,Move,简单地说,我想移动一个按ALT+鼠标的windows,就像linux操作系统一样(ALT+拖动) 是否可以通过单击将win32 api(移动api)传递给感兴趣的windows 我有一个windows服务钩子键按下(在特定的ALT按钮)。 当按下ALT键并验证鼠标按下事件时,我想将窗口移动到任意位置,而不仅仅是在标题栏上 目前,我以以下方式移动窗体窗口: using System.Runtime.InteropServices; [DllImport( "user32.dll", CharSe
using System.Runtime.InteropServices;
[DllImport( "user32.dll", CharSet = CharSet.Auto, SetLastError = false )]
static extern IntPtr SendMessage( IntPtr hWnd, uint Msg, int wParam, int lParam );
[DllImportAttribute( "user32.dll", CharSet = CharSet.Auto, SetLastError = false )]
public static extern bool ReleaseCapture();
private void Form1_MouseDown( object sender, MouseEventArgs e )
{
ReleaseCapture();
SendMessage( this.Handle, 0xa1, 0x2, 0 );
}
如何通过单击并在调用SendMessage()后获取特定窗口的windows句柄
有可能吗?您可以通过捕获Windows发送的WM_NCHITTEST消息来查看单击了窗口的哪个区域。您可以通过返回HTCAPTION来愚弄它,它将尽职尽责地执行您通常在单击窗口标题时获得的鼠标操作。包括移动窗户。将此代码粘贴到表单中:
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
// Trap WM_NCHITTEST when the ALT key is down
if (m.Msg == 0x84 && (Control.ModifierKeys == Keys.Alt)) {
// Translate HTCLIENT to HTCAPTION
if (m.Result == (IntPtr)1) m.Result = (IntPtr)2;
}
}
您可以通过捕获Windows发送的WM_NCHITTEST消息来查看单击了窗口的哪个区域。您可以通过返回HTCAPTION来愚弄它,它将尽职尽责地执行您通常在单击窗口标题时获得的鼠标操作。包括移动窗户。将此代码粘贴到表单中:
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
// Trap WM_NCHITTEST when the ALT key is down
if (m.Msg == 0x84 && (Control.ModifierKeys == Keys.Alt)) {
// Translate HTCLIENT to HTCAPTION
if (m.Result == (IntPtr)1) m.Result = (IntPtr)2;
}
}
我自己解决了这个问题,从我自己的计算中得出了一些有趣的东西,对我来说非常适合,适用于任何窗口(任何活动前景窗口)。有点长,但如果你按照评论进行操作,就很容易理解,希望有帮助:) 它的工作方式是按某个注册的组合键,如Ctrl+Alt+M 鼠标会停留在一个活动窗口的中心,你移动鼠标,窗口跟随它,再次按下相同的组合键,释放,不需要鼠标点击或其他任何操作
public void MoveWindow_AfterMouse()
{
// 1- get a handle to the foreground window (or any window that you want to move).
// 2- set the mouse pos to the window's center.
// 3- let the window move with the mouse in a loop, such that:
// win(x) = mouse(x) - win(width)/2
// win(y) = mouse(y) - win(height)/2
// This is because the origin (point of rendering) of the window, is at its top-left corner and NOT its center!
// 1-
IntPtr hWnd = WinAPIs.GetForegroundWindow();
// 2- Then:
// first we need to get the x, y to the center of the window.
// to do this, we have to know the width/height of the window.
// to do this, we could use GetWindowRect which will give us the coords of the bottom right and upper left corners of the window,
// with some math, we could deduce the width/height of the window.
// after we do that, we simply set the x, y coords of the mouse to that center.
RECT wndRect = new RECT();
WinAPIs.GetWindowRect(hWnd, out wndRect);
int wndWidth = wndRect.right - wndRect.left;
int wndHeight = wndRect.bottom - wndRect.top; // cuz the more you go down, the more y value increases.
Point wndCenter = new Point(wndWidth / 2, wndHeight / 2); // this is the center of the window relative to itself.
WinAPIs.ClientToScreen(hWnd, out wndCenter); // this will make its center relative to the screen coords.
WinAPIs.SetCursorPos(wndCenter.X, wndCenter.Y);
// 3- Moving :)))
while (true)
{
Point cursorPos = new Point();
WinAPIs.GetCursorPos(out cursorPos);
int xOffset = cursorPos.X - wndWidth / 2;
int yOffset = cursorPos.Y - wndHeight / 2;
WinAPIs.MoveWindow(hWnd, xOffset, yOffset, wndWidth, wndHeight, true);
Thread.Sleep(25);
}
}
现在:
int moveCommandToggle = 0;
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0312)
{
int keyID = m.WParam.ToInt32();
if(keyID == some_key_combo_you_registered_for_the_moving)
{
if (moveCommandToggle++ % 2 == 0)
{
mover = new Thread(() => MoveWindow_AfterMouse());
mover.Start();
}
else mover.Abort();
}
}
}
如果您想了解RECT:
public struct RECT
{
public int left; // xCoor of upper left corner.
public int top; // yCoor of upper left corner.
public int right; // xCoor of lower right corner.
public int bottom; // yCoor of lower right corner.
};
WinAPI只是一个静态类,我在其中做了DllImports。我自己解决了这个问题,自己计算出了一些有趣的东西,对任何窗口(任何活动的前景窗口)都非常适合。有点长,但如果你按照评论进行操作,就很容易理解,希望有帮助:) 它的工作方式是按某个注册的组合键,如Ctrl+Alt+M 鼠标会停留在一个活动窗口的中心,你移动鼠标,窗口跟随它,再次按下相同的组合键,释放,不需要鼠标点击或其他任何操作
public void MoveWindow_AfterMouse()
{
// 1- get a handle to the foreground window (or any window that you want to move).
// 2- set the mouse pos to the window's center.
// 3- let the window move with the mouse in a loop, such that:
// win(x) = mouse(x) - win(width)/2
// win(y) = mouse(y) - win(height)/2
// This is because the origin (point of rendering) of the window, is at its top-left corner and NOT its center!
// 1-
IntPtr hWnd = WinAPIs.GetForegroundWindow();
// 2- Then:
// first we need to get the x, y to the center of the window.
// to do this, we have to know the width/height of the window.
// to do this, we could use GetWindowRect which will give us the coords of the bottom right and upper left corners of the window,
// with some math, we could deduce the width/height of the window.
// after we do that, we simply set the x, y coords of the mouse to that center.
RECT wndRect = new RECT();
WinAPIs.GetWindowRect(hWnd, out wndRect);
int wndWidth = wndRect.right - wndRect.left;
int wndHeight = wndRect.bottom - wndRect.top; // cuz the more you go down, the more y value increases.
Point wndCenter = new Point(wndWidth / 2, wndHeight / 2); // this is the center of the window relative to itself.
WinAPIs.ClientToScreen(hWnd, out wndCenter); // this will make its center relative to the screen coords.
WinAPIs.SetCursorPos(wndCenter.X, wndCenter.Y);
// 3- Moving :)))
while (true)
{
Point cursorPos = new Point();
WinAPIs.GetCursorPos(out cursorPos);
int xOffset = cursorPos.X - wndWidth / 2;
int yOffset = cursorPos.Y - wndHeight / 2;
WinAPIs.MoveWindow(hWnd, xOffset, yOffset, wndWidth, wndHeight, true);
Thread.Sleep(25);
}
}
现在:
int moveCommandToggle = 0;
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0312)
{
int keyID = m.WParam.ToInt32();
if(keyID == some_key_combo_you_registered_for_the_moving)
{
if (moveCommandToggle++ % 2 == 0)
{
mover = new Thread(() => MoveWindow_AfterMouse());
mover.Start();
}
else mover.Abort();
}
}
}
如果您想了解RECT:
public struct RECT
{
public int left; // xCoor of upper left corner.
public int top; // yCoor of upper left corner.
public int right; // xCoor of lower right corner.
public int bottom; // yCoor of lower right corner.
};
WinAPI只是一个静态类,我在其中做了DllImports。请不要在标题中重复像“C#”这样的标记。这就是标签的作用。请不要在标题中重复类似“C#”这样的标签。这就是标签的用途。嗯。。。这没关系,但它只移动我的形状。我需要移动其他窗口…将此代码放入基窗体类中。从基类继承其他表单。不,抱歉。。。但我想移动系统窗口,如计算器、记事本、浏览器、任何窗口。。。像这样:嗯。。。这没关系,但它只移动我的形状。我需要移动其他窗口…将此代码放入基窗体类中。从基类继承其他表单。不,抱歉。。。但我想移动系统窗口,如计算器、记事本、浏览器、任何窗口。。。这样地: