“隐藏的”是什么;GDI+;钩窗“;在C#中?
每当任何C#应用程序打开其包含进程内控件的第一个窗体时,都会打开一个名为“G”的隐藏窗口,其类名为“GDI+钩子窗口类”,如下所示: 以下是使用的代码:“隐藏的”是什么;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
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应用程序中始终可以看到此窗口。你需要忽略它。