转换为C++;C#:SendMessageTimeout()的代码

转换为C++;C#:SendMessageTimeout()的代码,c#,c++,sendmessage,C#,C++,Sendmessage,首先,SendMessageTimeout的文档: 我有这个C++代码,我想把它转换成c*::/p> 我在C所做的: 为了你的问题 is0xFFFF不是0xFFFFFF 您必须使用手动为LPARAM值分配内存,然后在调用后使用释放内存。您必须释放此内存,否则它将泄漏。封送处理的内存不会被垃圾收集 对于lpdwResult只需创建一个IntPtr变量并传入即可。你可以忽略它的价值 代码应该是这样的: IntPtr result = IntPtr.Zero; IntPtr setting = Ma

首先,SendMessageTimeout的文档:

我有这个C++代码,我想把它转换成c*::/p> 我在C所做的:

为了你的问题

  • is
    0xFFFF
    不是
    0xFFFFFF
  • 您必须使用手动为LPARAM值分配内存,然后在调用后使用释放内存。您必须释放此内存,否则它将泄漏。封送处理的内存不会被垃圾收集
  • 对于
    lpdwResult
    只需创建一个
    IntPtr
    变量并传入即可。你可以忽略它的价值
  • 代码应该是这样的:

    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);
    

    通常,在释放传递给
    SendMessage
    调用的内存时需要小心,因为您不知道接收窗口将如何处理传递给它的指针。但是,由于
    WM\u SETTINGCHANGE
    是一个内置的Windows消息,Windows将为您处理此指针。

    SendMessage由于使用了非描述性参数类型,因此有点痛苦。因为它需要做很多工作。在C语言中是必需的,但在C语言中不是。这里要做的是利用支持重载的C语言。IntPtr参数只能是引用类型的引用,pinvoke封送器将正确地将它们转换为指针,并解决内存管理方面的麻烦。因此,只需制作另一个与您想要的使用方式兼容的:

    [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
    );
    
    现在您可以使用:

     SendMessageTimeout((IntPtr)0xffff, 0x001A, IntPtr.Zero, "Environment", 
                        2, 5000, IntPtr.Zero);
    

    查看封送c字符串与Marshal.StringToHGlobalUni+FreeHGlobal的比较。对于最后一部分,只需定义一个本地文件并将其传入。您好,这可以避免我必须重新启动系统才能使更改生效。但我仍然需要重新启动CMD/Powershell。你也知道预防这种情况的方法吗?
    [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
    );
    
     SendMessageTimeout((IntPtr)0xffff, 0x001A, IntPtr.Zero, "Environment", 
                        2, 5000, IntPtr.Zero);