其点击率始终保持在最前面

其点击率始终保持在最前面

本文介绍了透明窗口层,其点击率始终保持在最前面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一些code,我拿起了我试图执行。它的目的是创建一个表单层是透明的,全屏幕,无边框,点击,并总是在其他窗口的顶部。然后,它可以让你画使用的DirectX在它的顶部剩余否则透明。

这是不工作的部分是的点击一部分,而DirectX的渲染。当我运行它,我基本都有一种无形的力量领域的所有其他窗口的前面,必须使用Alt-Tab各地到Visual Studio快速preSS ALT F5和结束调试(这样至少始终在顶部和透明度作品)。我一直在试图找出为什么这些部件不工作,但我的新手C#技能让我失望。希望有人能发现原因并提供了修改。

 使用系统;
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data这;
使用System.Drawing中;
使用System.Text;
使用System.Windows.Forms的;
使用System.Diagnostics程序;
使用了System.Runtime.InteropServices;
使用System.Globalization;
使用Microsoft.DirectX;
使用Microsoft.DirectX.Direct3D;
使用的System.Threading;


命名空间MinimapSpy
{
公共部分类Form1中:形态
{

    私人边距玛格;

    //这是用于指定透明区的界线
    内部结构边距
    {
        公众诠释左,右,上,下​​,
    }

    [的DllImport(user32.dll中,SetLastError =真)

    私人静态外部UInt32的GetWindowLong(IntPtr的的HWND,国际nIndex);

    [的DllImport(user32.dll中)

    静态外部INT的SetWindowLong(IntPtr的的HWND,国际nIndex,IntPtr的dwNewLong);

    [的DllImport(user32.dll中)

    静态外部布尔SetLayeredWindowAttributes(IntPtr的HWND,UINT crKey,字节bAlpha,UINT的dwFlags);

    公共const int的GWL_EXSTYLE = -20;

    公共const int的WS_EX_LAYERED = 0x80000;

    公共const int的WS_EX_TRANSPARENT = 0x20的;

    公共const int的LWA_ALPHA = 0X2;

    公共const int的LWA_CO​​LORKEY =为0x1;

    [的DllImport(dwmapi.dll)]
    静态外部无效DwmExtendFrameIntoClientArea(IntPtr的的HWND,裁判边距pMargins);

    私有设备装置= NULL;



    公共Form1中()
    {

        //使窗口边框完全TRANSPARANT
        SetWindowLong函数(this.Handle,GWL_EXSTYLE,
                (IntPtr的)(GetWindowLong(this.Handle,GWL_EXSTYLE)^ ^ WS_EX_LAYERED WS_EX_TRANSPARENT));

        //设置阿尔法在整个窗口255(固体)
        SetLayeredWindowAttributes(this.Handle,0,255,LWA_ALPHA);

        //初始化的DirectX
        //这个初始化的DirectX设备。它需要做一次。
        //在后备缓冲的alpha通道是至关重要的。
        presentParameters presentParameters =新的presentParameters();
        presentParameters.Windowed = TRUE;
        presentParameters.SwapEffect = SwapEffect.Discard;
        presentParameters.BackBufferFormat = Format.A8R8G8B8;

        this.device =新的设备(0,DeviceType.Hardware,this.Handle,
        CreateFlags.HardwareVertexProcessing,presentParameters);


        螺纹DX =新主题(新的ThreadStart(this.dxThread));
        dx.IsBackground = TRUE;
        dx.Start();
        的InitializeComponent();

    }

   保护覆盖无效的OnPaint(PaintEventArgs的E)
   {
        //创建一个余量(整个表格)
      marg.Left = 0;
     marg.Top = 0;
      marg.Right = this.Width;
      marg.Bottom = this.Height;

        //展开Aero的玻璃效果边框整个表格。
        //因为我们已经有边界看不见我们现在
        从DirectX的开 -  //有一个完全不可见的窗口
        //为黑色不渲染。
     DwmExtendFrameIntoClientArea(this.Handle,参考玛格);

  }
    私人无效Form1_Load的(对象发件人,EventArgs的)
    {

    }
    私人无效dxThread()
    {
        而(真)
        {
            //请在此处更新逻辑
            device.Clear(ClearFlags.Target,Color.FromArgb(0,0,0,0),1.0F,0);
            device.RenderState.ZBufferEnable = FALSE;
            device.RenderState.Lighting = FALSE;
            device.RenderState.CullMode = Cull.None;
            device.Transform.Projection = Matrix.OrthoOffCenterLH(0,this.Width,this.Height,0,0,1);
            device.BeginScene();

            //请在此处呈现逻辑

            device.EndScene();
            //device.$p$psent();
        }

        this.device.Dispose();
        Application.Exit();
    }

}
 

解决方案

下面是一个精致的全样本code制造一个窗口最上面的 - 点击进入 - 透明(= alpha混合)。样品使得它与DirectX,或实际使用XNA 4.0渲染一个旋转色轮,因为我相信微软已经停止开发托管DirectX今天利于XNA。

 使用系统;
使用System.Windows.Forms的;
使用了System.Runtime.InteropServices;
使用Microsoft.Xna.Framework.Graphics;

命名空间ClickThroughXNA
{
    公共部分类Form1中:形态
    {
        // DirectX图形设备
        GraphicsDevice的开发= NULL;
        BasicEffect效果​​= NULL;

        //轮顶点
        VertexPositionColor []ν=新VertexPositionColor [100];

        //轮旋转
        浮腐= 0;

        公共Form1中()
        {
            的InitializeComponent();

            中StartPosition = FormStartPosition.CenterScreen;
            大小=新System.Drawing.Size(500,500);
            FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; //没有国界

            最顶层=真; //之上使窗体始终
            可见=真实; // 重要!如果没有设置,则该形态并没有完全显示

            //设置窗体的点击
            INT initialStyle = GetWindowLong(this.Handle,-20);
            SetWindowLong函数(this.Handle,-20,initialStyle | 0x80000 | 0x20的);

            //创建设备presentation参数
            presentationParameters P =新的presentationParameters();
            p.IsFullScreen = FALSE;
            p.DeviceWindowHandle = this.Handle;
            p.BackBufferFormat = SurfaceFormat.Vector4;
            p presentationInterval = presentInterval.One。

            //创建XNA图形设备
            开发=新的GraphicsDevice(GraphicsAdapter.DefaultAdapter,GraphicsProfile.Reach,P);

            //初始化基本作用
            效果=新BasicEffect(开发);

            //扩展的Aero Glass风格上形式的​​init
            onResize受到(空);
        }


        保护覆盖无效onResize受到(EventArgs的发送)
        {
            INT []利润率=新INT [] {0,0,宽度,高度};

            //扩展的Aero Glass风格,整体形
            DwmExtendFrameIntoClientArea(this.Handle,参考边距);
        }


        保护覆盖无效OnPaintBackground(PaintEventArgs的E)
        {
            //什么也不做来阻止窗口正常的背景画
        }


        保护覆盖无效的OnPaint(PaintEventArgs的E)
        {
            //采用全透明的黑色清除设备
            dev.Clear(新Microsoft.Xna.Framework.Color(0,0,0,0.0));

            //转动轮有点
            腐+ = 0.1F;

            //使车轮顶点和颜色的顶点
            的for(int i = 0; I< v.Length;我++)
            {
                如果(ⅰ%3 == 1)
                    v [电流] .Position =新Microsoft.Xna.Framework.Vector3((浮点)Math.Sin((I + ROT)*(Math.PI * 2F /(浮点)v.Length)),(浮动)数学。 COS((1 + ROT)*(Math.PI * 2F /(浮点)v.Length)),0);
                否则如果(ⅰ%3 == 2)
                    v [电流] .Position =新Microsoft.Xna.Framework.Vector3((浮点)Math.Sin((I + 2 + ROT)*(Math.PI * 2F /(浮点)v.Length)),(浮动) Math.Cos((I + 2 + ROT)*(Math.PI * 2F /(浮点)v.Length)),0);

                v [电流]。颜色=新Microsoft.Xna.Framework.Color(1  - (I /(浮点)v.Length),I /(浮点)v.Length,0,I /(浮点)v.Length);
            }

            //启用彩色位置顶点渲染
            effect.VertexColorEnabled = TRUE;
            的foreach(EffectPass传递effect.CurrentTechnique.Passes)pass.Apply();

            //绘制图元(轮)
            dev.DrawUserPrimitives(PrimitiveType.TriangleList,V,0,v.Length / 3,VertexPositionColor.VertexDeclaration);

            // present设备内容到形式
            开发present()。

            //重绘immediatily
            无效();
        }


        [的DllImport(user32.dll中,SetLastError =真)
        静态外部INT GetWindowLong(IntPtr的的HWND,国际nIndex);

        [的DllImport(user32.dll中)
        静态外部INT的SetWindowLong(IntPtr的的HWND,国际nIndex,INT dwNewLong);

        [的DllImport(dwmapi.dll)]
        静态外部无效DwmExtendFrameIntoClientArea(IntPtr的的HWND,文献INT [] pMargins);

    }
}
 

This is some code that I picked up which I tried to implement. Its purpose is to create a form layer which is transparent, full screen, borderless, clickthrough, and always on top of other windows. It then lets you draw using directx over the top of it remaining otherwise transparent.

The parts that don't work are the click-through part, and the directx render. When I run it I basically have an invisible force field in front of all other windows and have to alt-tab around to visual studio to quickly press ALT F5 and end the debug (so at least the always on top and transparency works). I have been trying to figure out why those parts don't work, but my newbie c# skills fail me. hopefully someone can spot why and provide a modification.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Globalization;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using System.Threading;


namespace MinimapSpy
{
public partial class Form1 : Form
{

    private Margins marg;

    //this is used to specify the boundaries of the transparent area
    internal struct Margins
    {
        public int Left, Right, Top, Bottom;
    }

    [DllImport("user32.dll", SetLastError = true)]

    private static extern UInt32 GetWindowLong(IntPtr hWnd, int nIndex);

    [DllImport("user32.dll")]

    static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

    [DllImport("user32.dll")]

    static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);

    public const int GWL_EXSTYLE = -20;

    public const int WS_EX_LAYERED = 0x80000;

    public const int WS_EX_TRANSPARENT = 0x20;

    public const int LWA_ALPHA = 0x2;

    public const int LWA_COLORKEY = 0x1;

    [DllImport("dwmapi.dll")]
    static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMargins);

    private Device device = null;



    public Form1()
    {

        //Make the window's border completely transparant
        SetWindowLong(this.Handle, GWL_EXSTYLE,
                (IntPtr)(GetWindowLong(this.Handle, GWL_EXSTYLE) ^ WS_EX_LAYERED ^ WS_EX_TRANSPARENT));

        //Set the Alpha on the Whole Window to 255 (solid)
        SetLayeredWindowAttributes(this.Handle, 0, 255, LWA_ALPHA);

        //Init DirectX
        //This initializes the DirectX device. It needs to be done once.
        //The alpha channel in the backbuffer is critical.
        PresentParameters presentParameters = new PresentParameters();
        presentParameters.Windowed = true;
        presentParameters.SwapEffect = SwapEffect.Discard;
        presentParameters.BackBufferFormat = Format.A8R8G8B8;

        this.device = new Device(0, DeviceType.Hardware, this.Handle,
        CreateFlags.HardwareVertexProcessing, presentParameters);


        Thread dx = new Thread(new ThreadStart(this.dxThread));
        dx.IsBackground = true;
        dx.Start();
        InitializeComponent();

    }

   protected override void OnPaint(PaintEventArgs e)
   {
        //Create a margin (the whole form)
      marg.Left = 0;
     marg.Top = 0;
      marg.Right = this.Width;
      marg.Bottom = this.Height;

        //Expand the Aero Glass Effect Border to the WHOLE form.
        // since we have already had the border invisible we now
        // have a completely invisible window - apart from the DirectX
        // renders NOT in black.
     DwmExtendFrameIntoClientArea(this.Handle, ref marg);

  }
    private void Form1_Load(object sender, EventArgs e)
    {

    }
    private void dxThread()
    {
        while (true)
        {
            //Place your update logic here
            device.Clear(ClearFlags.Target, Color.FromArgb(0, 0, 0, 0), 1.0f, 0);
            device.RenderState.ZBufferEnable = false;
            device.RenderState.Lighting = false;
            device.RenderState.CullMode = Cull.None;
            device.Transform.Projection = Matrix.OrthoOffCenterLH(0, this.Width, this.Height, 0, 0, 1);
            device.BeginScene();

            //Place your rendering logic here

            device.EndScene();
            //device.Present();
        }

        this.device.Dispose();
        Application.Exit();
    }

}
解决方案

Here's a refined full sample code for making a window topmost - click through - transparent (= alpha blended). The sample makes a rotating color wheel which is rendered with DirectX, or actually with XNA 4.0, because I believe Microsoft has discontinued developing the managed directx and favours XNA today.

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.Xna.Framework.Graphics;

namespace ClickThroughXNA
{
    public partial class Form1 : Form
    {
        // Directx graphics device
        GraphicsDevice dev = null;
        BasicEffect effect = null;

        // Wheel vertexes
        VertexPositionColor[] v = new VertexPositionColor[100];

        // Wheel rotation
        float rot = 0;

        public Form1()
        {
            InitializeComponent();

            StartPosition = FormStartPosition.CenterScreen;
            Size = new System.Drawing.Size(500, 500);
            FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;  // no borders

            TopMost = true;        // make the form always on top
            Visible = true;        // Important! if this isn't set, then the form is not shown at all

            // Set the form click-through
            int initialStyle = GetWindowLong(this.Handle, -20);
            SetWindowLong(this.Handle, -20, initialStyle | 0x80000 | 0x20);

            // Create device presentation parameters
            PresentationParameters p = new PresentationParameters();
            p.IsFullScreen = false;
            p.DeviceWindowHandle = this.Handle;
            p.BackBufferFormat = SurfaceFormat.Vector4;
            p.PresentationInterval = PresentInterval.One;

            // Create XNA graphics device
            dev = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, GraphicsProfile.Reach, p);

            // Init basic effect
            effect = new BasicEffect(dev);

            // Extend aero glass style on form init
            OnResize(null);
        }


        protected override void OnResize(EventArgs e)
        {
            int[] margins = new int[] { 0, 0, Width, Height };

            // Extend aero glass style to whole form
            DwmExtendFrameIntoClientArea(this.Handle, ref margins);
        }


        protected override void OnPaintBackground(PaintEventArgs e)
        {
            // do nothing here to stop window normal background painting
        }


        protected override void OnPaint(PaintEventArgs e)
        {
            // Clear device with fully transparent black
            dev.Clear(new Microsoft.Xna.Framework.Color(0, 0, 0, 0.0f));

            // Rotate wheel a bit
            rot+=0.1f;

            // Make the wheel vertexes and colors for vertexes
            for (int i = 0; i < v.Length; i++)
            {
                if (i % 3 == 1)
                    v[i].Position = new Microsoft.Xna.Framework.Vector3((float)Math.Sin((i + rot) * (Math.PI * 2f / (float)v.Length)), (float)Math.Cos((i + rot) * (Math.PI * 2f / (float)v.Length)), 0);
                else if (i % 3 == 2)
                    v[i].Position = new Microsoft.Xna.Framework.Vector3((float)Math.Sin((i + 2 + rot) * (Math.PI * 2f / (float)v.Length)), (float)Math.Cos((i + 2 + rot) * (Math.PI * 2f / (float)v.Length)), 0);

                v[i].Color = new Microsoft.Xna.Framework.Color(1 - (i / (float)v.Length), i / (float)v.Length, 0, i / (float)v.Length);
            }

            // Enable position colored vertex rendering
            effect.VertexColorEnabled = true;
            foreach (EffectPass pass in effect.CurrentTechnique.Passes) pass.Apply();

            // Draw the primitives (the wheel)
            dev.DrawUserPrimitives(PrimitiveType.TriangleList, v, 0, v.Length / 3, VertexPositionColor.VertexDeclaration);

            // Present the device contents into form
            dev.Present();

            // Redraw immediatily
            Invalidate();
        }


        [DllImport("user32.dll", SetLastError = true)]
        static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll")]
        static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        [DllImport("dwmapi.dll")]
        static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, ref int[] pMargins);

    }
}

这篇关于透明窗口层,其点击率始终保持在最前面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-07 02:26