如何在c#中创建一个完全透明的交互式窗体?

本文关键字:一个 透明 窗体 交互式 创建 | 更新日期: 2023-09-27 18:19:09

我试图在c#中创建一个完全透明的表单,但不允许点击通过它到下面的其他窗口。我发现了两种很有前途的方法,但都没有达到我想要的结果。

第一种方法是将背景颜色和透明度键设置为相同的值。这给了我一个透明的表单,但是点击可以通过。
this.BackColor = Color.Red;
this.TransparencyKey = Color.Red;

我尝试的另一件事是设置表单的不透明度为1%。这几乎创造了我想要的效果。我得到一个99%透明的形式,但有一个轻微的颜色变化的形式下面。由于我正在制作的应用程序是用于色彩敏感的环境(图形设计等),即使是颜色的微小变化也是不可接受的。所以我向你求助,亲爱的So。这能做到吗?

如何在c#中创建一个完全透明的交互式窗体?

我已经找到了解决方案,我也和你们分享一下。

答案很简单:我设置:this.TransparencyKey = Color.Lime;

然后我使用1x1px的石灰PNG作为背景图像。这样做还有一个额外的好处,那就是不会遮挡表单边框和标题栏。我稍后会删除它们,但现在,知道表单的位置是有用的。

我完全是偶然发现了一个解决方案。

我想通过透明窗口点击,并通过使用这个问题的答案得到它:

c#光标高亮显示/follower

这个答案使用了LightGreen的透明滤镜,但是我想我可能需要使用那个颜色,所以我把它改成了AliceBlue,然后点击就停止工作了。我切换回LightGreen,它又开始工作了

您可以尝试在透明表单上捕获鼠标动作,而不是尝试捕获系统范围内的鼠标动作(点击,移动)并根据需要处理它们。

这可以通过以下方式完成(假设绘制的表单保持最大化)。如果没有,请参阅下面的段落):

  • 截图当前屏幕
  • 创建一个表单,并使用截图作为背景图片。
  • 从表单中删除表单标题,简单地将其作为面板。

虽然上面的解决方案解决了你想要的,但你需要回答这个问题:

  • 用户如何关闭他正在绘制的表单?

如果表单需要调整大小-移动-复杂版本

然而,如果你想要调整这个表单的大小(刚刚注意到你用新的屏幕截图编辑),那么你需要剪掉屏幕截图的一部分,并将其显示为表单的背景。但这还远远不够:你需要在每次窗体被调整大小或移动时都这样做。

我个人倾向于第一种(更简单的)方法。

可以设置hook来捕获鼠标事件。

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    public static extern bool UnhookWindowsHookEx(int idHook);
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
    [StructLayout(LayoutKind.Sequential)]
    public class MouseStruct
    {
        public Point pt;
        public int hwnd;
        public int wHitTestCode;
        public int dwExtraInfo;
    }
    public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam); 
    private int hHook;
    public const int WH_MOUSE_LL = 14;
    public static HookProc hProc;
    public int SetHook()                                        
    {
        hProc = new HookProc(MouseHookProc);
        hHook = SetWindowsHookEx(WH_MOUSE_LL, hProc, IntPtr.Zero, 0);
        return hHook;
    }
    public void UnHook()                                        
    {
        UnhookWindowsHookEx(hHook);
    }
    //callback function, invoked when there is an mouse event
    private int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)              
    {
        var MyMouseStruct = (MouseStruct)Marshal.PtrToStructure(lParam, typeof(MouseStruct));
        if (nCode < 0)
        {
            return CallNextHookEx(hHook, nCode, wParam, lParam);    
        }
        else
        {
            switch wParam{
                case (IntPtr)513:
                    //click
                    //do whatever you want
                case (IntPtr)512:
                    //move
                case (IntPtr)514:
                    //release
                default:
            }
            Cursor.Position = MyMouseStruct.pt;
            //stop the event from passed to other windows.
            return 1;
        }
    }