UpdateResource不能将lpType用作字符串

时间:2014-05-22 20:34:54

标签: c# .net vb.net winapi

P / Invoke声明:

[DllImport("kernel32.dll")]
static extern bool UpdateResource(IntPtr hUpdate, IntPtr lpType, IntPtr lpName, ushort wLanguage, byte[] lpData, uint cbData);
[DllImport("kernel32.dll")]
static extern bool UpdateResource(IntPtr hUpdate, string lpType, int lpName, ushort wLanguage, byte[] lpData, uint cbData);
[DllImport("kernel32.dll")]
static extern IntPtr BeginUpdateResource(string pFileName, bool bDeleteExistingResources);
[DllImport("kernel32.dll")]
static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);

我的代码:

var hUpdate = BeginUpdateResource(FilePath, false);
var BMP = File.ReadAllBytes(BmpPath);
UpdateResource(hUpdate, "2", 123, 1033, BMP, (uint)BMP.Length);
UpdateResource(hUpdate, "#2", 123, 1033, BMP, (uint)BMP.Length);
UpdateResource(hUpdate, "RT_BITMAP", 123, 1033, BMP, (uint)BMP.Length);
UpdateResource(hUpdate, "BITMAP", 123, 1033, BMP, (uint)BMP.Length);
EndUpdateResource(hUpdate, false);

上述UpdateResource次调用均无效。他们在名为#2, RT_BITMAP, BITMAP的新资源类型下添加新资源,而不是更新现有资源。

UpdateResource的P / Invoke声明中,如果我将string lpType重载为IntPtr lpType并将其传递给new IntPtr(2),一切正常但我不想使用这个解决方案是因为有时我还需要string lpType来定制自定义资源类型,而且我的当前代码设计需要进行太多的更改。

MSDN:

  

lpType [in]

     

类型:LPCTSTR

     

要更新的资源类型。或者,而不是指针,   此参数可以是MAKEINTRESOURCE(ID),其中ID是整数   表示预定义资源类型的值。如果是第一个字符   字符串是井号(#),然后是剩余的字符   表示一个十进制数,指定整数标识符   资源类型。例如,字符串“#258”表示   标识符258。

任何想法为什么我不能通过传递lpType一个字符串来更新现有的位图?我正在完成MSDN中所述的内容。

PS:我绝对需要传递lpType一个字符串,由于上述原因而无法通过重载使用IntPtr(当前代码需要进行太多更改)设计)。

1 个答案:

答案 0 :(得分:3)

很可能MSDN错了。

lpName参数的文档说"创建新资源时,请不要使用以'#'开头的字符串。此参数的字符"。我想同样的限制适用于lpType

您可以在不改变代码其余部分结构的情况下解决此问题。

定义UpdateResource的两个重载,但将它们设为私有并重命名(可能为UpdateResourceW)。

然后在C#中定义您自己的公共UpdateResource函数。这应检查lpType参数。如果类型以#开头,则将其转换为整数并调用IntPtr lpType重载,否则请使用string lpType重载。

因此,您可以在整个代码中使用字符串作为资源类型,并在一个位置处理此详细信息。