簡體   English   中英

如何在C#中創建一個完全透明的winform,它是交互式的?

[英]How do I create a fully transparent winform in C# that is interactive?

我正在嘗試在C#中創建一個完全透明的表單,但不允許點擊通過它到下面的其他窗口。 我發現有兩種方法很有希望,但沒有達到我想要的效果。

第一種方法是將背景顏色和透明度鍵設置為相同的值。 這給了我透明的表單,但點擊進入。

this.BackColor = Color.Red;
this.TransparencyKey = Color.Red;

我嘗試的另一件事是將表單的不透明度設置為1%。 這創造了我想要的效果 - 幾乎。 我得到一個99%透明的形式,但是對於窗體下面的任何東西都有輕微的顏色變化。 由於我正在制作的應用程序旨在用於顏色敏感的上下文(圖形設計等),即使是顏色的微小改變也是不可接受的。 親愛的,所以我轉向你。 可以這樣做嗎?

我找到了解決方案,我也和你們分享了。

答案很簡單:我設置: this.TransparencyKey = Color.Lime;

然后我使用1x1px Lime PNG作為背景圖像。 這還有一個額外的好處,就是不會模糊表單邊框和標題欄。 我稍后會刪除它們,但此刻,了解表單的位置很有用。

我完全意外地找到了解決方案。

我想通過透明窗口點擊並使用此SO問題中的答案得到它:

C#光標突出顯示/關注者

那個答案使用LightGreen的透明度過濾器,但我認為我可能需要使用該顏色,所以我將其更改為AliceBlue並點擊停止工作。 我換回LightGreen,它又開始工作了。

您可以嘗試在系統范圍內捕獲鼠標操作(點擊,移動)並根據需要處理它們,而不是嘗試在透明表單上捕獲鼠標操作。

這可以通過以下方式完成(假設繪制的表格保持最大化。如果沒有,請參閱下面的下一段):

  • 截取當前屏幕的截圖。
  • 創建表單並使用屏幕截圖作為背景圖像。
  • 從表單中刪除表單標題,只需將其作為面板。

雖然上面的解決方案解決了您的需求,但您需要回答以下問題:

  • 用戶將如何關閉他正在繪制的表單?

如果表單需要調整大小 - 移動 - 復雜的版本

但是,如果您想要調整此表單的大小(只是注意到您使用新屏幕截圖進行編輯),那么您需要剪切截屏的部分並將其顯示為表單的背景。 但是這更進一步:每次調整表單大小或移動時都需要這樣做。

我個人會采取第一種(更簡單)的方法。

您可以設置鈎子來捕獲鼠標事件。

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

MSDN上的更多細節。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM