代码之家  ›  专栏  ›  技术社区  ›  Aaron

实现拖动窗口选项

  •  1
  • Aaron  · 技术社区  · 17 年前

    注:

    • 使用Windows窗体
    • 最好是C.NET

    问题:

    • 最佳方法 实施 拖动窗口 工具,类似于 process explorer ,为了 获得 这个 进程标识 对应于 选定窗口
    1 回复  |  直到 17 年前
        1
  •  1
  •   Fredrik Mörk    17 年前

    我认为最简单的方法是在窗体上放置一个用作起始点的控件;在窗体上按一个鼠标按钮,然后在按下按钮的同时将其移到屏幕上,并获取所指向的对象的进程ID。我的例子是,我使用了一个面板(称为“AIM”)。

    首先,我们设置鼠标事件:

    private void Panel_MouseDown(object sender, MouseEventArgs e)
    {
         // make all mouse events being raised in the _aim panel
         // regardless of whether the mouse is within the control's
         // bounds or not
        _aim.Capture = true;
    }
    
    private void Panel_MouseMove(object sender, MouseEventArgs e)
    {
        if (_aim.Capture)
        {   
            // get the process id only if we have mouse capture 
            uint processId = GetProcessIdFromPoint(
                _aim.PointToScreen(e.Location)).ToString();
            // do something with processId (store it for remembering the 
            // last processId seen, to be used as MouseUp for instance)
        }
    }
    private void Panel_MouseUp(object sender, MouseEventArgs e)
    {
        if (_aim.Capture)
        {
            // release capture if we have it
            _aim.Capture = false;
            // perhaps do something more (fetch info about last seen
            // process id, if we stored it during MouseMove, for instance)
        }
    }
    

    GetProcessIDFromPoint方法如下:

    private uint GetProcessIdFromPoint(Point point)
    {
        uint procId;
        WinApi.GetWindowThreadProcessId(WinApi.WindowFromPoint(point), out procId);
        return procId;
    }
    

    最后是Windows API的内容(从 pinvoke.net ):

    public static class WinApi
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int X;
            public int Y;
    
            public POINT(int x, int y)
            {
                this.X = x;
                this.Y = y;
            }
    
            public static implicit operator System.Drawing.Point(POINT p)
            {
                return new System.Drawing.Point(p.X, p.Y);
            }
    
            public static implicit operator POINT(System.Drawing.Point p)
            {
                return new POINT(p.X, p.Y);
            }
        }
    
        [DllImport("user32.dll")]
        public static extern IntPtr WindowFromPoint(POINT Point);
    
        [DllImport("user32.dll", SetLastError = true)]
        public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
    }
    
    推荐文章