本文介绍了将C ++代码转换为C#:SendMessageTimeout()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先是SendMessageTimeout的文档:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644952%28v = vs.85%29.aspx

First of all docu for SendMessageTimeout:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644952%28v=vs.85%29.aspx

我有此C ++代码,我想将其转换为C#:

i have this C++ code and i want to convert it to C#:

LRESULT success = SendMessageTimeout(
    HWND_BROADCAST,
    WM_SETTINGCHANGE,
    0,
    (LPARAM) "Environment",
    SMTO_ABORTIFHUNG,
    5000,
    NULL
);

我在C#中所做的事情:

What i did in C#:

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

推荐答案

针对您的问题.

  1. HWND_BROADCAST 0xFFFF 而不是 0xFFFFFFFF
  2. 您将必须使用 Marshal.StringToHGlobalUni ,然后在通话后使用 Marshal.FreeHGlobal .您必须释放此内存,否则它将泄漏.元帅的记忆不是垃圾收集.
  3. 对于 lpdwResult ,只需创建一个 IntPtr 变量并将其传递.您可以忽略其值.
  1. HWND_BROADCAST is 0xFFFF not 0xFFFFFFFF
  2. You will have to allocate memory for the LPARAM value manually using Marshal.StringToHGlobalUni and then free it after the call using Marshal.FreeHGlobal. You must free this memory or it will leak. Marshal'd memory is not garbage collected.
  3. For lpdwResult just create an IntPtr variable and pass that in. You can just ignore its value.

代码应如下所示:

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_SETTINGCHANGE 是Windows的内置消息,因此Windows将为您处理此指针.

In general you need to be careful when freeing memory that you pass to a SendMessage call since you don't know what the receving window will do with the pointer that you pass to it. Howerver since WM_SETTINGCHANGE is a built in Windows message, Windows will handle this pointer for you.

这篇关于将C ++代码转换为C#:SendMessageTimeout()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 16:46
查看更多