C#学习教程:使用dllimport从user32.dll返回零句柄和错误代码127使用DLLImport属性处理Windows计算器并将user32.dll函数导入C#托管应用程序的示例。应用程序正在运行,我正在获取主窗口的句柄,即计算器本身,但以下代码不起作用。FindWindowEx方法不会返回计算器子项的句柄,例如按钮和文本框。我尝试在DLLImport上使用SetLastError=True并发现我收到错误代码127,即“找不到过程”。这是我从中获得示例应用程序的链接:http://www.codeproject.com/script/Articles/ArticleVersion.aspx?aid=14519&av=34503如果有人知道如何修复它,请提供帮助。更新:DLLImport是:[DllImport("user32.dll",SetLastError=true)]publicstaticexternIntPtrFindWindowEx(IntPtrparentHandle,IntPtrchildAfter,stringclassName,stringwindowTitle);不起作用的代码是:hwnd=FindWindow(null,"Calculator");//这是有效的,我正在获取计算器的句柄//以下无效,我正在获取hwndChild=0和err=127hwndChild=FindWindowEx((IntPtr)hwnd,IntPtr.Zero,"Button","1");Int32err=Marshal.GetLastWin32Error();您尝试的代码依赖于各个按钮的标题来识别它们。例如,它使用以下代码获取“1”按钮的句柄:hwndChild=FindWindowEx((IntPtr)hwnd,IntPtr.Zero,"Button","1");其中窗口类名称是“Button”,窗口名称是“1”(或者,在按钮的情况下,显示在按钮本身上的相同标题文本)。此代码在WindowsXP(和以前的版本)下工作正常,其中计算器按钮用文本标题标识。“1”按钮的窗口名称是“1”,所以显示“1”作为按钮的标题。但是,看起来情况在Windows7下发生了变化(并且可能在Vista下也发生了变化,尽管我无法验证这一点,因为我无权访问此类系统)。使用Spy++调查计算器窗口确认“1”按钮不再具有窗口名称“1”。事实上,它根本没有窗口名称;标题为NULL。据推测,计算器的新外观需要自定义绘制按钮,因此不再需要字幕来指示哪个按钮对应哪个功能。自定义绘图例程负责绘制必要的标题。窗口句柄返回值0(NULL),因为没有找到您指定的窗口文本的按钮。FindWindowEx函数的文档表明您可以为lpszWindow参数指定NULL,但这当然会匹配指定类的所有窗口。在这种情况下可能不是您想要的,因为计算器应用程序有一堆按钮。我不知道有什么好的解决方法。计算器并非设计为以这种方式“自动化”,并且Microsoft从未保证它们不会改变其内部工作方式。使用此方法混淆其他应用程序的窗口是有风险的。编辑:您链接到的代码在另一个相当严重的方面也是错误的,即使在早期版本的Windows上也是如此。它将hwnd变量声明为int类型,而不是IntPtr。由于窗口句柄是指针,因此它们应始终存储为IntPtr类型。这也修复了本应发送红旗的FindWindowEx函数调用中的丑陋转换。您还需要修复SendMessage的声明,使其第一个参数的类型为IntPtr。代号应该是这样写的:IntPtrhwnd=IntPtr.Zero;IntPtrhwndChild=IntPtr.Zero;//获取计算器应用程序主窗口的句柄hwnd=FindWindow(null,"Calculator");if(hwnd==IntPtr.Zero){if(MessageBox.Show("找不到计算器"+"应用程序。你想启动它吗?","TestWinAPI",MessageBoxButtons.YesNo)==DialogResult.Yes){System.Diagnostics.Process.Start("计算器");}}else{//获取“1”按钮的句柄hwndChild=FindWindowEx(hwnd,IntPtr.Zero,"Button","1");//发送BN_CLICKED消息SendMessage(hwndChild,BN_CLICKED,0,IntPtr.Zero);//获取“+”按钮的句柄hwndChild=FindWindowEx(hwnd,IntPtr.Zero,"Button","+");//发送BN_CLICKED消息SendMessage(hwndChild,BN_CLICKED,0,IntPtr.Zero);//获取“2”按钮的句柄hwndChild=FindWindowEx(hwnd,IntPtr.Zero,"Button","2");//发送BN_CLICKED消息SendMessage(hwndChild,BN_CLICKED,0,IntPtr.Zero);//获取“=”按钮hwnd的句柄Child=FindWindowEx(hwnd,IntPtr.Zero,“按钮”,“=”);//发送BN_CLICKED消息SendMessage(hwndChild,BN_CLICKED,0,IntPtr.Zero);以下代码适用于Windows7的Caculator经典主题Normal(不适用于Basic或Aero主题):=========================================================IntPtrhwndFrame=FindWindowEx(hwnd,IntPtr.Zero,"CalcFrame",null);IntPtrhwndDialog=FindWindowEx(hwndFrame,IntPtr.Zero,"#32770",null);IntPtrhwndDialog2=FindWindowEx(hwndFrame,(IntPtr)hwndDialog,"#32770",null);IntPtrhwndThree=FindWindowEx(hwndDialog2,IntPtr.Zero,"Button","3");SendMessage((int)hwndThree,BN_CLICKED,0,IntPtr.Zero);IntPtrhwndPlus=FindWindowEx(hwndDialog2,IntPtr.Zero,"按钮","+");SendMessage((int)hwndPlus,BN_CLICKED,0,IntPtr.Zero);IntPtrhwndOne=FindWindowEx((IntPtr)hwndDialog2,IntPtr.Zero,“按钮”,“1”);SendMessage((int)hwndOne,BN_CLICKED,0,IntPtr.Zero);IntPtrhwndEqual=FindWindowEx(hwndDialog2,IntPtr.Zero,“按钮”,“=”);SendMessage((int)hwndEqual,BN_CLICKED,0,IntPtr.Zero);我能够在Win7Pro上重现此问题您的问题很可能是按钮上的标签是由计算器的主题绘制的,而不是标题。当主题服务运行时,启动计算器会变成一个没有标题的按钮。为了获得正确的按钮标题,您必须:停止Themes服务(从提升的命令提示符运行netstopthemes或使用服务管理工具)。启动计算器。如果在主题服务停止时运行计算器,您会注意到它的所有按钮都变成空白。以上就是C#学习教程:FindWindowExfromuser32.dllusesdllimporttoreturnzerohandleanderrorcode127,如果对大家有用,需要详细了解C#学习教程,希望大家多多关注——这篇文章来自网络收藏,不代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
