P /调用RemoveMenu SetLastError不起作用

问题描述 投票:0回答:1

我的代码:

[DllImport("user32.dll", SetLastError = true)]
static extern bool RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags);

static void RemoveMenu(IntPtr hMenu, int item, bool byPosition)
{
    if (!RemoveMenu(hMenu, (uint)item, (uint)(byPosition ? 0x400 : 0)))
    {
        throw new Win32Exception();
    }
}

RemoveMenu(xxx, -1, false); //got exception and it's message is: The operation completed successfully.

这意味着API失败时未设置LastError。为什么和如何?

[RemoveMenu API文档。

c# .net winapi pinvoke
1个回答
0
投票

从技术上讲,行为没有错。文档仅说失败时调用GetLastError(),但没有说GetLastError()不能返回0作为原因。实际上,至少根据CMenu::RemoveMenu  is failing,实际上报告的是0(尽管像ERROR_MENU_ITEM_NOT_FOUND这样的说法更有意义)。

这很容易解决,在抛出Marshal.GetLastWin32Error()之前使用Win32Exception

[DllImport("user32.dll", SetLastError = true)]
static extern bool RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags);

static void RemoveMenu(IntPtr hMenu, int item, bool byPosition)
{
    if (!RemoveMenu(hMenu, (uint)item, (uint)(byPosition ? 0x400 : 0)))
    {
        int err = Marshal.GetLastWin32Error();
        if (err != 0)
            throw new Win32Exception(err);
    }
}

RemoveMenu(xxx, -1, false);
© www.soinside.com 2019 - 2024. All rights reserved.