我尝试通过调用GetClassName()
hWnd
上的FindWindowByCaption()
来确定窗口的类名。但它不起作用;我看到的所有类名都是垃圾字符(特别是四个问号,然后是一些奇怪的非字母数字字符)。 {I}据我所知,GetClassName()
将数据写入调用者的缓冲区。
这是我的代码:
[DllImport("user32.dll", SetLastError = true)]
static extern System.IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern System.IntPtr FindWindowByCaption(System.IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.dll")]
static extern int GetClassName(System.IntPtr hWnd,
[param: MarshalAs(UnmanagedType.LPTStr)]
System.Text.StringBuilder lpClassName, int nMaxCount);
...
System.IntPtr hWndMyWindow = FindWindowByCaption(System.IntPtr.Zero, "My Window");
if (hWndMyWindow != null)
{
System.Console.WriteLine("hWndMyWindow = {0}", hWndMyWindow);
System.Text.StringBuilder lpClassName = new System.Text.StringBuilder(256);
lpClassName.Length = lpClassName.Capacity - 2;
int len = GetClassName(hWndMyWindow, lpClassName, lpClassName.Length - 2);
lpClassName.Length = len; // set length to the actual length of the classname
System.Console.WriteLine("hWndMyWindow = {0}, classname = {1}", hWndMyWindow, lpClassName.ToString());
}
else
{
System.Console.WriteLine("No such window.");
}
我做错了什么? lpClassName
的{{1}}参数是输出...我希望GetClassName()
将类名写入GetClassName()
,但它无法正常工作。
答案 0 :(得分:1)
[param: MarshalAs(UnmanagedType.LPTStr)]
LPTStr并不意味着你的想法。通过编写这些声明的方式,只有UnmanagedType.LPStr可以工作。或者更好的是,完全省略了这个属性,根本没有必要,pinvoke marshaller已经理解了StringBuilder。
您使用这些声明调用了20世纪90年代,您正在使用这些winapi函数的“Ansi”版本。不幸的是[DllImport]的默认值。使用它们没有意义,没有人再运行Windows 98了。 Windows是一个以Unicode操作系统为核心,编写声明以匹配:
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern System.IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int GetClassName(System.IntPtr hWnd,
StringBuilder lpClassName, int nMaxCount);
FindWindowByCaption()有点太可爱,只是不要,将null
作为第一个参数传递。请注意,您的错误处理存在错误,FindWindow使用IntPtr.Zero失败,而不是null。并且不要忽略GetClassName()的错误处理。只需通过抛出System.ComponentModel.Win32Exception来发出响亮的声音。