Переместите окно на нажатие клавиши + мышь (как linux ALT + мышь вниз) - PullRequest
1 голос
/ 23 июня 2010

Просто, я хочу переместить окна, нажав ALT + MOUSE, как Linux OS (ALT + перетаскивание).

Возможно ли передать win32 api (переместить api) в заинтересованные окна, щелкнув по нему?

У меня есть службы Windows, которые нажимают клавишу (в частности, кнопку ALT). Когда нажата кнопка ALT и подтверждено событие мыши вниз , я хочу переместить щелчок окна в любом месте, а не только в строке заголовка!

В настоящее время я перемещаю окна формы следующим образом:

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 () на нем?

Это возможно?

Ответы [ 2 ]

1 голос
/ 23 июня 2010

Вы можете сделать это, перехватывая сообщение WM_NCHITTEST, которое отправляет Windows, чтобы увидеть, какая область окна была нажата.Вы можете обмануть его, вернув 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;
        }
    }
0 голосов
/ 30 января 2013

Я разработал это сам, придумал что-то интересное из моих собственных расчетов, отлично работал для меня, для любого окна (любого активного окна переднего плана).Вроде бы долго, но очень легко понять, если вы будете следовать комментариям, надеюсь, это поможет :) То, как это работает, заключается в том, что вы нажимаете определенную зарегистрированную комбинацию клавиш, например 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.

...