У меня есть форма, которая может «кликать», то есть прямые клики в окне ниже Как я могу отменить свои изменения после события? - PullRequest
0 голосов
/ 10 октября 2011

Я создал следующую форму и использовал технику, предложенную в Самая верхняя форма, нажав «через» возможно?

Я сделал форму способной щелкнуть в окне под ней. Проблема в том, что окно было перетаскиваемым и т. Д. До события, но оно не перетаскивалось после события.

Любые предложения о том, как сделать окно перетаскиваемым снова?

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

1 Ответ

1 голос
/ 12 октября 2011

Я не мог перестать смотреть на эту проблему, пока наконец не наткнулся на ответ. Вам просто нужно получить 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;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...