我有一个可以“点击"的表单,即直接点击下面的窗口.活动结束后如何撤消更改? [英] I have a form that can "click through", i.e. direct clicks to the window below. How can I undo my changes after the event?

查看:19
本文介绍了我有一个可以“点击"的表单,即直接点击下面的窗口.活动结束后如何撤消更改?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have created the following Form and using a techniche suggested in Topmost form, clicking "through" possible?

我已经让表单能够点击它下面的窗口.问题是该窗口在事件之前可以拖动等,但在事件之后不可拖动.

I have made the form able to click on the window below it. The problem is that the window was draggable etc before the event but it's not draggable after the event.

关于如何使窗口再次可拖动的任何建议?

Any suggestions on how to make the window draggable again?

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 恢复为原始值.

I was unable to stop looking at this problem until I had finally stumbled across an answer. You just need to GetWindowLong, before you make any changes then SetWindowLong back to that original value once you're finished.

唯一的部分我仍然不确定为什么我需要 Thread.Sleep(50);如果有人可以提出一个更优雅的解决方案,那就太好了,但这对我有用.

The only part I'm still not sure about it why I need to Thread.Sleep(50); If anyone can suggest a more elegant solution that would be great, but this one works for me.

        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;
    }

这篇关于我有一个可以“点击"的表单,即直接点击下面的窗口.活动结束后如何撤消更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆