convert C++ code to C#: SendMessageTimeout()
首先为SendMessageTimeout编写文档:
http://msdn.microsoft.com/zh-cn/library/windows/desktop/ms644952(v = vs.85).aspx
我有这个C代码,我想将其转换为C#:
1 2 3 4 5 6 7 8 9 | LRESULT success = SendMessageTimeout( HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_ABORTIFHUNG, 5000, NULL ); |
我在C#中所做的工作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern IntPtr SendMessageTimeout( IntPtr hWnd, uint Msg, UIntPtr wParam, IntPtr lParam, uint fuFlags, uint uTimeout, out UIntPtr lpdwResult ); SendMessageTimeout( (IntPtr)0xFFFFFFFF, //HWND_BROADCAST 0x001A, //WM_SETTINGCHANGE (UIntPtr)0, (IntPtr)"Environment", // ERROR_1: can't convert string to IntPtr 0x0002, // SMTO_ABORTIFHUNG 5000, out UIntPtr.Zero // ERROR_2: a static readonly field can not be passed ref or out ); |
SendMessage由于使用了非描述符参数类型而有些痛苦。必要的,因为它需要完成许多工作。使用C语言是必需的,但不是使用C#。您在这里要做的是利用支持重载的C#语言。 IntPtr参数只能是引用类型引用,pinvoke编组器会将它们正确转换为指针,并解决了内存管??理的麻烦。因此,只需制作另一个与您要使用的方式兼容的方式即可:
1 2 3 4 5 6 7 8 9 10 | [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern IntPtr SendMessageTimeout( IntPtr hWnd, int Msg, IntPtr wParam, string lParam, int fuFlags, int uTimeout, IntPtr lpdwResult ); |
现在您可以使用:
1 2 | SendMessageTimeout((IntPtr)0xffff, 0x001A, IntPtr.Zero,"Environment", 2, 5000, IntPtr.Zero); |
针对您的问题。
代码应如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | IntPtr result = IntPtr.Zero; IntPtr setting = Marshal.StringToHGlobalUni("Environment"); SendMessageTimeout( (IntPtr)0xFFFF, //HWND_BROADCAST 0x001A, //WM_SETTINGCHANGE (UIntPtr)0, (IntPtr)setting, 0x0002, // SMTO_ABORTIFHUNG 5000, out result ); Marshal.FreeHGlobal(setting); |
通常,在释放传递给