我有一个表单,可以“点击”,即直接点击到下面的窗口.如何在事件发生后撤消更改

本文关键字:事件 窗口 撤消 点击 可以 表单 有一个 | 更新日期: 2023-09-27 18:10:55

我创建了以下表单,并使用Topmost表单中建议的技术,点击"通过"可能吗?

我已经使表单能够点击它下面的窗口。问题是,在事件发生之前,窗口是可拖动的,但在事件发生之后,它就不可拖动了。

关于如何使窗口再次可拖动有什么建议吗?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo); 
        private const int MOUSEEVENTF_LEFTDOWN = 0x02;
        private const int MOUSEEVENTF_LEFTUP = 0x04;
        public enum GWL
        {
            ExStyle = -20,
            HINSTANCE = -6,
            ID = -12,
            STYLE = -16,
            USERDATA = -21,
            WNDPROC = -4
        }
        public enum WS_EX
        {
            Transparent = 0x20,
            Layered = 0x80000
        }
        public enum LWA
        {
            ColorKey = 0x1,
            Alpha = 0x2
        }
        [DllImport("user32.dll", EntryPoint = "GetWindowLong")]
        public static extern int GetWindowLong(IntPtr hWnd, GWL nIndex);
        [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
        public static extern int SetWindowLong(IntPtr hWnd, GWL nIndex, int dwNewLong);
        [DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")]
        public static extern bool SetLayeredWindowAttributes(IntPtr hWnd, int crKey, byte alpha, LWA dwFlags);

        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            base.OnShown(e);
            int wl = GetWindowLong(this.Handle, GWL.ExStyle);
            wl = wl | 0x80000 | 0x20;
            SetWindowLong(this.Handle, GWL.ExStyle, wl);
            int X = Cursor.Position.X;
            int Y = Cursor.Position.Y;
            mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
            this.TopMost = true;
        }
    }
}

我有一个表单,可以“点击”,即直接点击到下面的窗口.如何在事件发生后撤消更改

我无法停止看这个问题,直到我终于偶然发现了一个答案。你只需要GetWindowLong,在你做任何改变之前,然后在你完成后把SetWindowLong设置回原来的值。

我仍然不确定为什么我需要Thread.Sleep(50);如果有人能提出一个更优雅的解决方案,那就太好了,但这个对我来说很有效。

        private void Form1_MouseDoubleClick(object sender, MouseEventArgs e)
    {
        base.OnShown(e);
        int originalStyle = GetWindowLong(this.Handle, GWL.ExStyle);
        int wl = GetWindowLong(this.Handle, GWL.ExStyle);
        wl = wl | 0x80000 | 0x20;
        SetWindowLong(this.Handle, GWL.ExStyle, wl);
        int X = Cursor.Position.X;
        int Y = Cursor.Position.Y;
        mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
        System.Threading.Thread.Sleep(50);
        SetWindowLong(this.Handle, GWL.ExStyle, originalStyle);
        this.TopMost = true;
    }