

お世話になります。

C#でデスクトップアクセサリを作ろうとして躓きました。  
フォームのTransparencyKeyをフォームのBackColorに設定して、  
BorderStyleをNoneにし、マスコットキャラ的なところまでを  
作るには完成しました。

その後、常に最背面に表示させたくて、ネットのサンプルを見て、  
下記のように追加しました。

[code]

    public class Form1 : System.Windows.Forms.Form
    {
    
        // FindWindow 関数
        [DllImport("USER32.DLL", CharSet = CharSet.Auto)]
        private static extern System.IntPtr FindWindow(
            string lpClassName,
            string lpWindowName
        );
    
    
        // SetParent 関数
        [DllImport("USER32.DLL", CharSet = CharSet.Auto)]
        private static extern System.IntPtr SetParent(
            System.IntPtr hWndChild,
            System.IntPtr hWndNewParent
        );
    
    
        private void button1_Click(object sender, System.EventArgs e)
        {
            // Program Manager のハンドルを取得する
            System.IntPtr hProgramManagerHandle = FindWindow(null, "Program Manager");
    
            // 正しく取得できた場合は、Program Manager を親ウィンドウに設定する
            if (!hProgramManagerHandle.Equals(System.IntPtr.Zero))
            {
                SetParent(this.Handle, hProgramManagerHandle);
            }
        }
    }
    
[/code]

このコードを実行したところ、最背面に表示するどころか、フォーム自体が完全に  
非表示になってしまいます。おまけにタスクバーにも表示されなくなるため、手動で  
閉じることもできなくなります。

フォームを透過させてしまうと、最背面に指定することはできなるなるのでしょうか。

もし、実現する方法があれば、教えていただけないでしょうか。

よろしくお願いいたします。


CC BY-SA 3.0
2015-05-25T02:58:43.687
10572
2015-05-27T07:33:00.327
2015-05-26T03:21:10.147
8870
9374
question
c# winforms
C# 透過したフォームを最背面にしたいのだが…


Windows 8.1 C# Windows Form .NetFramework4.5で以下のコードで透過フォームを最背面に配置できました。

[code]

    public partial class Form1 : Form
    {
        public delegate bool EnumWindowCallBack(IntPtr hwnd, IntPtr lParam);
    
        [DllImport("USER32.DLL", EntryPoint = "FindWindowEx")]
        private static extern IntPtr FindWindowEx(IntPtr hWnd1, IntPtr hWnd2, string lpsz1, string lpsz2);
    
        // SetParent 関数
        [DllImport("USER32.DLL", CharSet = CharSet.Auto)]
        private static extern System.IntPtr SetParent(
            System.IntPtr hWndChild,
            System.IntPtr hWndNewParent
        );
    
        [DllImport("USER32.Dll")]
        static extern int EnumWindows(EnumWindowCallBack x, IntPtr y);
    
        [DllImport("User32.Dll", CharSet = CharSet.Unicode)]
        public static extern int GetClassName(IntPtr hWnd, StringBuilder s, int nMaxCount);
    
    
        public Form1()
        {
            InitializeComponent();
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
        }
    
        protected override void OnPaintBackground(PaintEventArgs e)
        {
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            EnumWindows(EnumerateWindow, IntPtr.Zero);
        }
    
        // ウィンドウを列挙するためのコールバックメソッド
        private bool EnumerateWindow(IntPtr hWnd, IntPtr lParam)
        {
            StringBuilder sbClassName = new StringBuilder(256);
            int result = GetClassName(hWnd, sbClassName, 256);
            string className = sbClassName.ToString();
            if (className.Equals("WorkerW") || className.Equals("Progman"))
            {
                IntPtr hDt = FindWindowEx(hWnd, IntPtr.Zero, "SHELLDLL_DefView", null);
                if (hDt != null && hDt != IntPtr.Zero)
                {
                    SetParent(this.Handle, hDt);
                }
            }
            return true;
        }
    }
    
[/code]

タスクバーに表示はされないようなので、フォーム上の表示されているコントロールの右クリックでコンテキストメニューを表示させて閉じるなどを実装してみてはどうでしょうか。


CC BY-SA 3.0
2015-05-27T07:33:00.327
10673
2015-05-27T07:33:00.327
8350
10572
answer