开发者

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?

开发者 https://www.devze.com 2023-04-12 11:30 出处:网络
I have created the following Form and using a techniche suggested in Topmost form, clicking “through” possible?

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_LEFTU开发者_StackOverflow社区P, X, Y, 0, 0);

            this.TopMost = true;
        }
    }
}


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.

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

精彩评论

暂无评论...
验证码 换一张
取 消