Tag: winapi

.Net中的同步ListView

我正在使用一个控件将视图从一个ListView绑定到另一个ListView,以便在滚动主ListView时,更新子ListView视图以匹配。 到目前为止,我已经能够让孩子ListViews在点击主滚动条按钮时更新他们的视图。 问题是当单击并拖动ScrollBar本身时,子ListViews不会更新。 我查看了使用Spy ++发送的消息,并发送了正确的消息。 这是我目前的代码: public partial class LinkedListViewControl : ListView { [DllImport(“User32.dll”)] private static extern bool SendMessage(IntPtr hwnd, UInt32 msg, IntPtr wParam, IntPtr lParam); [DllImport(“User32.dll”)] private static extern bool ShowScrollBar(IntPtr hwnd, int wBar, bool bShow); [DllImport(“user32.dll”)] private static extern int SetScrollPos(IntPtr hWnd, int wBar, int nPos, bool bRedraw); private const int WM_HSCROLL = […]

C#P / Invoke Win32函数RegQueryInfoKey

我试图移植以下C ++代码: BOOL SyskeyGetClassBytes(HKEY hKeyReg,LPSTR keyName,LPSTR valueName,LPBYTE classBytes) { HKEY hKey,hSubKey; DWORD dwDisposition=0,classSize; BYTE classStr[16]; LONG ret; BOOL isSuccess = FALSE; ret = RegCreateKeyEx(hKeyReg,keyName,0,NULL,REG_OPTION_NON_VOLATILE,KEY_QUERY_VALUE,NULL,&hKey,&dwDisposition); if(ret!=ERROR_SUCCESS) return FALSE; else if(dwDisposition!=REG_OPENED_EXISTING_KEY) { RegCloseKey(hKey); return FALSE; } else { if(RegOpenKeyEx(hKey,valueName,0,KEY_READ,&hSubKey)==ERROR_SUCCESS) { classSize = 8+1; ret = RegQueryInfoKey(hSubKey,(LPTSTR)classStr,&classSize,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); if((ret==ERROR_SUCCESS)&&(classSize==8)) { classBytes[0]= (HexDigitToByte(classStr[0]) << 4) | HexDigitToByte(classStr[1]); classBytes[1]= (HexDigitToByte(classStr[2]) << […]

SendMessage模拟右键单击崩溃目标应用程序

我正在编写一个C#自动化工具。 由于Microsoft UI Automation不提供任何模拟右键单击或提升上下文菜单的方法,因此我使用SendMessage来执行此操作。 我宁愿不使用SendInput因为我不想抓住焦点。 但是,当我调用SendMessage时,它会崩溃目标应用程序。 这是我的代码: [DllImport(“user32.dll”, CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); public void RightClick(T element) where T: AutomationElementWrapper { const int MOUSEEVENTF_RIGHTDOWN = 0x0008; /* right button down */ const int MOUSEEVENTF_RIGHTUP = 0x0010; /* right button up */ var point = element.Element.GetClickablePoint(); var […]

如果它在本地堆上分配,为什么称它为Marshal.AllocHGlobal?

从Marshal.AllocHGlobal的MSDN文档中: AllocHGlobal是Marshal类中的两种内存分配方法之一。 此方法从Kernel32.dll公开Win32 LocalAlloc函数。 考虑到有一个GlobalAlloc API在全局堆上而不是本地堆上分配内存,这个方法的名称不是误导吗? 是否有理由将其命名为AllocHGlobal ,而不是AllocHLocal ? 更新: Simon在评论中指出,Windows中不再存在全局堆,而GlobalAlloc和LocalAlloc API仅用于遗留目的。 目前, GlobalAlloc API不再是LocalAlloc的包装器。 这解释了为什么API根本不调用GlobalAlloc ,但它没有解释为什么API在没有(不能)使用全局堆时也被命名为AllocHGlobal ,甚至也没有调用GlobalAlloc 。 命名不可能是出于遗留原因,因为直到16位支持被删除后才会引入.NET 2.0。 所以,问题仍然存在:为什么Marshal.AllocHGlobal如此误导地命名?

如何从Win32句柄获取System.Windows.Form实例?

以下代码实现了一个简单的单例,确保只能运行我的应用程序的一个实例。 但是,如果启动了另一个实例,我需要能够获取该实例的命令行参数,将它们传递给初始实例,然后终止第二个实例。 当我试图获取应用程序的第一个实例时,会出现此问题。 一旦我找到该实例的主窗体的句柄,我将它传递给Control.FromHandle()方法,期望得到一个MainForm 。 相反,返回值始终为null 。 ( Control.FromChildHandle()给出相同的结果。) 因此,我的问题很简单:我做错了什么? 这在.NET中甚至可能吗? public class MainForm : Form { [DllImport(“user32”)] extern static int ShowWindowAsync(IntPtr hWnd, int nCmdShow); [DllImport(“user32”)] extern static bool SetForegroundWindow(IntPtr hWnd); private Mutex singletonMutex; private void MainForm_Load(object sender, EventArgs e) { bool wasCreated; singletonMutex = new Mutex(false, Application.ProductName + “Mutex”, out wasCreated); // returns false […]

在没有InvokePattern或clickablePoint的情况下使用UI Automation调用单击按钮

我尝试向另一个应用程序中的按钮发送单击消息(或调用)。 我使用UISpy.exe,可以找到我需要的元素。 但它没有id,没有clickablePoint,也没有Invoke模式。 我试过以下代码: var processStartInfo = new ProcessStartInfo(@”tdesktop\Program.exe”); var proc = Process.Start(processStartInfo); Thread.Sleep(3000); AutomationElement mainWin = AutomationElement.RootElement.FindChildByProcessId(proc.Id); List elmList= GetChildren(mainWin); //MessageBox.Show(elmList.Count.ToString()); if (elmList.Count == 7) { List menubar= GetChildren(elmList[6]); AutomationElement elementNode = menubar[1]; double x = elementNode.GetClickablePoint().X; double y = elementNode.GetClickablePoint().Y; win32 w = new win32(); w.move_left_click((UInt32)x, (UInt32)y); } 它在elementNode.GetClickablePoint()。X中引发exception,即Autumation元素没有可点击的点。 我也试过TryGetInvokePattern()但仍然抛出execption它没有InvokePattern。 我使用VS2012和.net 4.5 有没有办法做到这一点?

使用Powershell以编程方式清除回收站

我必须做的最困难的事情之一是使用PowerShell访问Windows API。 我想使用Shell32.dll中的API擦除回收站。 还有其他方法,但它们通常绕过正常的Windows进程,在这种情况下,我想以“正确”的方式做到这一点。

我如何获得winform的GUI线程?

我有一个带有多个GUI线程的winforms应用程序。 我希望他们能够访问彼此的线程对象,而无需单独跟踪这些信息。 .NET中是否有一个函数可以提供winforms控件或窗口对象,然后返回线程? 或者API中的一个函数我可以为threadID设置pinv? (请不要发表评论说我应该采取另一种方式……这也不是关于跨线程窗口操作。) 谢谢! 编辑 对于那些由于某种原因相信我的斜体文字,祝贺你的人 , 你被录用了!! 这是问题所在: “应用程序通过完全锁定在野外崩溃,也就是说,它停止响应。非常间歇性,并试图调试它,似乎永远不会发生。” 那怎么办? 在程序中安装一个选项,用户可以在我们的指导下激活,从同一应用程序中的另一个GUI线程,在主GUI线程上执行thread.abort,然后我们可以在错误日志中查看调用堆栈。 Viola,在不到一天的时间内发现无法调试错误。 (现在停止,它与滥用multithreading无关:-) 我承认我几乎没有问这个,我做的原因是我可以看到主要表单的对象引用,但是没有任何针对它的线程。 我给Chris Shain答案a / c这是一个快速的方法,不幸的是当线程挂起时,我将无法进行调用(它也会挂起)。 更多挖掘揭示了GetWindowThreadProcessId API调用。 但它是一个非托管的线程ID,显然有并发症将其转化为托管线程ID。 所以我咬了一下子弹,并对主UI线程进行了全局引用。 本来会发布它,但尚未写出来。 现在,如果你原谅VB …… 在主公共模块/静态类中: Public GUIThread As Threading.Thread Sub Main() ” // Create app main window ShellForm = New frmShell ” // Save main GUI Thread for abort routine GUIThread […]

Windows窗体作为非托管应用程序的子窗口

我正在寻找一种方法来嵌入用C#编写的Windows窗体应用程序在C ++窗口应用程序中。 本机应用程序主窗口细分为多个窗格。 C#app应该出现在其中一个窗格中,即C#组件的根窗口(最外面的窗体)必须是主应用程序的子窗口。 可以这样做吗? 如果是这样,怎么样? 一些额外的背景:据我所知,有两种方法可以解决这个问题。 首先,使用.net托管API(ICLRRuntimeHost等)在本机应用程序中托管CLR。 其次,通过将Windows窗体放在ActiveX控件中来托管CLR。 关于第一种方法,我设法启动CLR并加载C#程序集(主要归功于MattiasHögström )。 在我遇到障碍的地方是我看不出如何告诉我在CLR中运行的组件它需要是从C ++端传入的窗口的子代。 我还尝试了第二种方法(使用ActiveX并感谢Daniel Yanovsky )。 它几乎,但只是差不多,适合我的目的。 我可以让任意Windows窗体组件在本机应用程序的子窗格中运行。 但它们总是在主应用程序的主线程上运行。 这意味着他们使用主应用程序的Windows消息循环。 MSDN说这不会可靠地工作,因为标准的Windows消息循环不符合Windows窗体的要求(我想在这里发布到MSDN的链接,但已经用完了我的新用户双链接分配)。 根据MSDN,Internet Explorer和MFC应用程序的消息循环问题的例外情况。 我作为主机使用的本机应用程序绝对不是Internet Explorer。 此外,它使用由wxWidgets包装的Windows API,因此MFC不是(或至少不是受欢迎的)选项。 Microsoft提出的解决方案涉及让C#组件在自己的线程上运行自己的消息循环。 至少据我所知,这必然会导致回到上面提到的第一种方法。 所以我回到了让Windows窗体在传入的父窗口下工作的问题。 同样,我对任何澄清子窗口问题的输入感兴趣,与我在此处提到的方法无关。 但根据上下文,我可以将一般问题减少到两个具体问题(我只需要回答其中一个问题): 给定一个ActiveX控件中托管的Windows窗体,如何允许窗体在自己的线程上自己的消息循环中运行? 要么 鉴于在本机应用程序托管的CLR中运行的Windows窗体,如何使窗体成为本机应用程序中窗口的子窗口?

可以使用Winkey + L的低级键盘挂钩/ SendInput? (工作站锁定在Vista及更高版本中被截获)

我正在开展一个名为UAWKS (非官方Apple无线键盘支持)的项目,帮助Windows用户使用Apple的蓝牙键盘。 UAWKS的主要目标之一是使用Ctrl交换Cmd键(在Windows中表现为Winkey ),允许用户为复制执行Cmd + C ,为新选项卡执行Cmd + T等。 它目前使用AutoHotkey开发,在Windows XP下运行良好。 但是,在Vista和Windows 7上, Cmd + L会导致问题: 无论低级键盘挂钩如何, Win + L总是被Windows拦截并且通常锁定工作站…… 您可以使用此注册表黑客禁用工作站锁定,但按下Win + L仍然无法在AHK中反弹 按下Win + L将Winkey保持在Keydown状态,直到下一个(额外的)Winkey Up。 模拟Keyup事件似乎也不起作用! 似乎Win + L是一个特殊的和弦,让其他一切混乱。 我查看了AHK源代码,他们试图在keyboard_mouse.cpp中的SendKey()中解决这个问题(在SendKey()中的第883行附近),但它不起作用。 我在C#中编写了自己的低级键盘钩子应用程序,我也看到了同样的问题。 有没有其他人遇到这个? 有解决方法吗?