Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“隐藏的”是什么;GDI+;钩窗“;在C#中?_C#_Windows_Winforms_Gdi+ - Fatal编程技术网

“隐藏的”是什么;GDI+;钩窗“;在C#中?

“隐藏的”是什么;GDI+;钩窗“;在C#中?,c#,windows,winforms,gdi+,C#,Windows,Winforms,Gdi+,每当任何C#应用程序打开其包含进程内控件的第一个窗体时,都会打开一个名为“G”的隐藏窗口,其类名为“GDI+钩子窗口类”,如下所示: 以下是使用的代码: using System; using System.Text; using System.Diagnostics; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; namespace WindowsFormsAp

每当任何C#应用程序打开其包含进程内控件的第一个窗体时,都会打开一个名为“G”的隐藏窗口,其类名为“GDI+钩子窗口类”,如下所示:

以下是使用的代码:

using System;
using System.Text;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1 {
    public class Form1 : Form {
        private delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);
        private EnumThreadDelegate showWindowName;
        private Button button1;
        private string windowList = string.Empty;
        private Button button2;
        private int increment;

        [DllImport("user32.dll")]
        private static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);

        [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = false)]
        private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

        public Form1() {
            showWindowName = ShowWindowName;
            InitializeComponent();
            SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
        }

        [STAThread]
        public static void Main() {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }

        protected override void OnShown(EventArgs e) {
            base.OnShown(e);
            button1_Click(null, null);
        }

        private bool ShowWindowName(IntPtr hWnd, IntPtr lParam) {
            increment++;
            StringBuilder windowName = new StringBuilder(65535);
            GetWindowText(hWnd, windowName, 65535);
            StringBuilder className = new StringBuilder(65535);
            GetClassName(hWnd, className, 65535);
            windowList += "Window " + increment + ":\n\tTitle: " + windowName + "\n\tClass Name: " + className + "\n\n";
            Invalidate(false);
            return true;
        }

        protected override void OnPaint(PaintEventArgs e) {
            base.OnPaint(e);
            e.Graphics.DrawString(windowList, Font, Brushes.Black, PointF.Empty);
        }

        private void button1_Click(object sender, EventArgs e) {
            increment = 0;
            windowList = string.Empty;
            foreach (ProcessThread thread in Process.GetCurrentProcess().Threads)
                EnumThreadWindows(thread.Id, showWindowName, IntPtr.Zero);
        }

        private void button2_Click(object sender, EventArgs e) {
            foreach (ProcessThread thread in Process.GetCurrentProcess().Threads)
                EnumThreadWindows(thread.Id, (hwnd, lParam) => {
                    StringBuilder windowName = new StringBuilder(65535);
                    GetWindowText(hwnd, windowName, 65535);
                    if (windowName.ToString() == "G")
                        SendMessage(hwnd, 0x10, IntPtr.Zero, IntPtr.Zero);
                    return false;
                }, IntPtr.Zero);
            button1_Click(null, null);
        }

        private void InitializeComponent() {
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.button1.Location = new System.Drawing.Point(0, 379);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(504, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "Reload";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // button2
            // 
            this.button2.Dock = System.Windows.Forms.DockStyle.Right;
            this.button2.Location = new System.Drawing.Point(429, 0);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(75, 379);
            this.button2.TabIndex = 1;
            this.button2.Text = "Kill G Window";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // 
            // Form1
            // 
            this.ClientSize = new System.Drawing.Size(504, 402);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }
    }
}
如果我以编程方式关闭该窗口(通过单击“Kill G window”按钮),窗口将关闭,但程序的窗体仍按预期运行,似乎完全不受影响


这个神秘窗口的用途和功能是什么?

它可能是WinSpy++的东西吗?不,
EnumWindows()
即使没有WinSpy也会列出它。()您是否可以显示代码和生成的输出,而不是显示屏幕截图?同时,我又懒又懒。我可以复制“Gefault IME”,但我认为这是WinSpy++弄乱某些东西的产物,使用Microsoft的Spy++时,同一窗口的标题是“默认IME”,这就不那么神秘了。它是gdiplus.dll的管道,它为GDI+使用的后台线程提供同步。GdiplusStartup()的文档谈到了它们,但它们到底做了什么还不清楚。由于System.Drawing依赖于gdiplus.dll来完成工作,因此在Winforms应用程序中始终可以看到此窗口。你需要忽略它。