2014-05-22 89 views
5

的P/Invoke声明:UpdateResource不lpType工作作为字符串

[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的新资源类型下添加新资源,而不是更新现有资源。

在的P/Invoke的UpdateResource声明,如果我超载string lpTypeIntPtr lpType并把它传递一个new IntPtr(2),一切正常,但我不希望因为我有时也需要string lpType自定义资源类型和重载意愿使用此解决方案在我当前的代码设计中需要进行太多更改。

MSDN:

lpType [IN]

类型:LPCTSTR

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

任何想法,为什么我不能更新通过传递lpType字符串现有的位图?我正在做什么在MSDN中陈述。

PS:我绝对需要通过lpType字符串,不能因上述(当前代码设计需要太多的变化)所描述的理由超载使用IntPtr

+0

是的,我知道,从这个问题:'超载将需要我目前的代码设计太多的变化。' 没有办法只用一个字符串呢?我无法清楚解释为什么我无法使用IntPtr的原因更多。 – user3666697

+0

你可能做错的唯一可能的事情不是尝试它。 –

回答

3

最有可能的MSDN是错误的。

lpName参数的文档说“创建新资源时不要使用以该参数的'#'字符开头的字符串”。我想象一下lpType也有同样的限制。

您可以修复此问题而不更改其余代码的结构。

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

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

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

+0

太简单了。为什么我没有想到这个? – user3666697

+0

MSDN对此也是错误的:'创建新资源时不要使用以该参数的'#'字符开头的字符串该语句暗示在不创建新资源时,即替换现有资源时,可以使用'#'字符。但即使这样也不会更新现有资源,它会添加另一个名为“#123”的名称。 – user3666697